5

I'm trying to add a dropdown to Wordpress core blocks to select a data attribute that will be added to the front-end (e.g. data-attr="value-from-dropdown").

I think the solution is to add a custom attribute to the core blocks, set it in the back-end and pass it to the front-end, but I can't for the life of me figure out how to add a new attribute to a core block. This here is the closest I've gotten, but this just lets me create a dropdown, running props.setAttribute() inside doesn't work.

https://wordpress.org/gutenberg/handbook/extensibility/extending-blocks/#editor-blockedit

Is there anything I can do, or is the functionality just not there yet?

4
  • 1
    I've created a tutorial here : jeffreycarandang.com/… . I hope this could help. Thanks! Commented May 1, 2019 at 1:56
  • @JeffreyCarandang that link gives a 404
    – kanga
    Commented Apr 27, 2023 at 17:51
  • @kanga It's all good now. Thanks! Commented Jun 2, 2023 at 11:06
  • Documentation Link is dead Commented Jul 3 at 15:51

2 Answers 2

6

You can add a custom attribute to any registered block by using the blocks.registerBlockType filter.

/**
 * Filter the attributes for all blocks to add custom ones
 *
 * Name can be used to only add the new attribute to a certain block.
 *
 * @param settings
 * @param name
 * @returns {*}
 */
function addCustomAttributes( settings, name ) {
    if ( settings.attributes ) {

        settings.attributes.customAttribute = {
            type: 'string',
            default: ''
        };

        settings.attributes.anotherCustomAttribute = {
            type: 'boolean',
            default: false
        };
    }
    return settings;
}

addFilter( 'blocks.registerBlockType', 'namespace/filterBlockAttributes', addCustomAttributes );
3

First inside the edit function declare a variable with your dropdown option -

const linkOptions = [
        { value: 'small', label: __( 'Small' ) },
        { value: 'normal', label: __( 'Normal' ) },
        { value: 'medium', label: __( 'Medium' ) },
        { value: 'large', label: __( 'Large' ) },
    ];

I'm assuming you will be showing the dropdown option in the Sidebar panel. Here's the code for panelbody and how to get the dropdown value -

<PanelBody>
  <SelectControl
    label={ __( 'Size' ) }
    value={ size }
    options={ linkOptions.map( ({ value, label }) => ( {
    value: value,
    label: label,
    } ) ) }
    onChange={ ( newSize ) => { setAttributes( { size: newSize } ) } }
   />
</PanelBody>

This will show a dropdown panel in the Inspector area, notice I'm using (ES6)Map function to iterate over the values and corresponding labels. Now, comes the RichText Component where you call the HTML nodes -

<RichText
      tagName={ 'span' }
      placeholder={ __( 'Enter Text' ) }
      value={ text }
      onChange={ (text) => setAttributes( { text: text } ) }
      formattingControls={ [ 'bold', 'italic', 'strikethrough' ] }
      className={`button-${size}`} /*ES6 Template Literals*/
      isSelected={ isSelected }
      keepPlaceholderOnFocus
/>

Notice, Depending upon the dropdown option. Button size gets attached to the HTML node classname. Now in the editor stylesheet, Add couple of css class and properties -

button-small
button-normal
button-medium
button-large

For the save function -

const save = ( props ) => {

    const {  size } = props.attributes;


    return (
        <div className={ `ubutton-${size}` }>

        </div>
    );
}
3
  • 2
    Thanks, but how do I edit a core block with this? From what I've seen, this only applies to creating a new block. Commented Oct 1, 2018 at 3:01
  • That's currently in "experimental phase". For more info check out this doc - github.com/WordPress/gutenberg/blob/master/docs/extensibility/… Commented Oct 1, 2018 at 8:15
  • 2
    That link is a 404. It's always best to link to a specific blob, rather than master, because master changes.
    – Ian Dunn
    Commented Apr 22, 2019 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.