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?

3

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

Your Answer

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

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