Add custom data attribute to every core Gutenberg Blocks

I found the solution:

  1. I removed addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps); as @TomJNowell recomended.
  2. I added the add_filter('render_block', 'theme_custom_add_custom_attributes', 10, 2); PHP code to functions.php:

So, here all the working code:

JS:

/**
 * 
 * Extends Core Gutenberg Blocks functionalities
 * 
 * @description Add data-delay and data-duration attributes to every Gutenberg Core Blocks
 * @package luxuryconcept
 * @author Stefano Fattori <[email protected]>
 * @copyright Stefano Fattori ©2024
 * @url www.stefanofattori.it
 * 
 */

(function(wp) {
    const { addFilter } = wp.hooks;
    const { createHigherOrderComponent } = wp.compose;
    const { Fragment } = wp.element;
    const { InspectorControls } = wp.blockEditor;
    const { PanelBody, TextControl } = wp.components;

    // Add new attributes to blocks
    const addCustomAttributes = (settings, name) => {
        if (typeof settings.attributes !== 'undefined') {
            settings.attributes = Object.assign({}, settings.attributes, {
                dataDelay: {
                    type: 'string',
                    default: '0',
                },
                dataDuration: {
                    type: 'string',
                    default: '0',
                },
            });
        }
        return settings;
    };

    // Add controls for the new attributes
    const withCustomControls = createHigherOrderComponent((BlockEdit) => {
        return (props) => {
            if (props.isSelected) {
                return wp.element.createElement(
                    Fragment,
                    null,
                    wp.element.createElement(BlockEdit, props),
                    wp.element.createElement(
                        InspectorControls,
                        null,
                        wp.element.createElement(
                            PanelBody,
                            { title: 'Custom Attributes', initialOpen: true },
                            wp.element.createElement(TextControl, {
                                label: 'Data Delay',
                                value: props.attributes.dataDelay,
                                onChange: function(newVal) {
                                    props.setAttributes({ dataDelay: String(newVal) });
                                },
                            }),
                            wp.element.createElement(TextControl, {
                                label: 'Data Duration',
                                value: props.attributes.dataDuration,
                                onChange: function(newVal) {
                                    props.setAttributes({ dataDuration: String(newVal) });
                                },
                            })
                        )
                    )
                );
            }
            return wp.element.createElement(BlockEdit, props);
        };
    }, 'withCustomControls');


    // Apply Gutenberg Filters
    addFilter('blocks.registerBlockType', 'luxuryconcept/add-custom-attributes', addCustomAttributes);
    addFilter('editor.BlockEdit', 'luxuryconcept/with-custom-controls', withCustomControls);

})(window.wp);

PHP:

/**
 * Adds custom attributes to Gutenberg core blocks (FrontEnd)
 * 
 * @see /assets/js/block-extension.js
 * 
 * @param mixed $block_content
 * @param mixed $block
 * @return mixed
 */
function theme_custom_add_custom_attributes($block_content, $block) {
    // Check if there are custom attributes 'dataDelay' e 'dataDuration'
    if ( isset($block['attrs']['dataDelay']) && !empty($block['attrs']['dataDelay']) ) {
        $block_content = add_custom_attribute($block_content, 'data-delay', $block['attrs']['dataDelay']);
    }
    if ( isset($block['attrs']['dataDuration']) && !empty($block['attrs']['dataDuration']) ) {
        $block_content = add_custom_attribute($block_content, 'data-duration', $block['attrs']['dataDuration']);
    }

    return $block_content;
}

/**
 * Functions to add data attributes to HTML blocks
 * 
 * @param mixed $block_content
 * @param mixed $attribute_name
 * @param mixed $attribute_value
 * @return mixed
 * 
 * @since 1.5.5
 */
function add_custom_attribute($block_content, $attribute_name, $attribute_value) {
    // Search the first tag HTML in the block content
    $pos = strpos($block_content, '>');

    if ($pos !== false) {
        // Insert the custom attribute after the first HTML tag
        $block_content = substr_replace($block_content, ' ' . $attribute_name . '="' . esc_attr($attribute_value) . '"', $pos, 0);
    }

    return $block_content;
}
add_filter('render_block', 'theme_custom_add_custom_attributes', 10, 2);

Thanks!

tech