admin管理员组

文章数量:1122832

I'm adding two custom attributes to core Gutenberg blocks, data-delay and data-duration. I want to add these attributes to manage animations blocks on my custom theme.

I wrote this JS code into block-extension.js:

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

    // Aggiungi nuovi attributi ai blocchi
    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;
    };

    // Aggiungi controlli per i nuovi attributi
    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');

    // Aggiungi gli attributi ai wrapper HTML del blocco
    const addCustomProps = (saveElementProps, blockType, attributes) => {
        if (attributes.dataDelay) {
            saveElementProps['data-delay'] = attributes.dataDelay;
        }
        if (attributes.dataDuration) {
            saveElementProps['data-duration'] = attributes.dataDuration;
        }
        return saveElementProps;
    };

    // Applica i filtri di Gutenberg
    addFilter('blocks.registerBlockType', 'luxuryconcept/add-custom-attributes', addCustomAttributes);
    addFilter('editor.BlockEdit', 'luxuryconcept/with-custom-controls', withCustomControls);
    addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps);
})(window.wp);

and PHP code into functions.php:

function my_custom_gutenberg_extension() {
    wp_enqueue_script(
        'block-extension',
        get_template_directory_uri() . '/assets/js/block-extension.js', 
        array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-compose', 'wp-hooks'),
        filemtime(get_template_directory() . '/assets/js/block-extension.js'),
        true
    );
}
add_action('enqueue_block_editor_assets', 'my_custom_gutenberg_extension');

I got this in every blocks:

But when I add a block into Gutenberg Editor I got these JS errors on every block:

I think because the original content is different from that with the two data attributes added, but I don't know to manage it.

Thanks

--EDIT--

So I have to remove

addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps);

and add this PHP code to get attributes:

function theme_custom_add_custom_attributes($block_content, $block) {
    // Verifica se l'attributo è stato impostato e non è vuoto
    $data_delay = get_field('data-delay', $block['id']);
    $data_duration = get_field('data-duration', $block['id']);

    // Aggiungi gli attributi al blocco solo se sono stati impostati
    if ($data_delay && !empty($data_delay)) {
        $block_content = str_replace('<div', '<div data-delay="' . esc_attr($data_delay) . '"', $block_content);
    }
    if ($data_duration && !empty($data_duration)) {
        $block_content = str_replace('<div', '<div data-duration="' . esc_attr($data_duration) . '"', $block_content);
    }

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

But I don't know how to save them in PHP.

I'm adding two custom attributes to core Gutenberg blocks, data-delay and data-duration. I want to add these attributes to manage animations blocks on my custom theme.

I wrote this JS code into block-extension.js:

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

    // Aggiungi nuovi attributi ai blocchi
    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;
    };

    // Aggiungi controlli per i nuovi attributi
    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');

    // Aggiungi gli attributi ai wrapper HTML del blocco
    const addCustomProps = (saveElementProps, blockType, attributes) => {
        if (attributes.dataDelay) {
            saveElementProps['data-delay'] = attributes.dataDelay;
        }
        if (attributes.dataDuration) {
            saveElementProps['data-duration'] = attributes.dataDuration;
        }
        return saveElementProps;
    };

    // Applica i filtri di Gutenberg
    addFilter('blocks.registerBlockType', 'luxuryconcept/add-custom-attributes', addCustomAttributes);
    addFilter('editor.BlockEdit', 'luxuryconcept/with-custom-controls', withCustomControls);
    addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps);
})(window.wp);

and PHP code into functions.php:

function my_custom_gutenberg_extension() {
    wp_enqueue_script(
        'block-extension',
        get_template_directory_uri() . '/assets/js/block-extension.js', 
        array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-compose', 'wp-hooks'),
        filemtime(get_template_directory() . '/assets/js/block-extension.js'),
        true
    );
}
add_action('enqueue_block_editor_assets', 'my_custom_gutenberg_extension');

I got this in every blocks:

But when I add a block into Gutenberg Editor I got these JS errors on every block:

I think because the original content is different from that with the two data attributes added, but I don't know to manage it.

Thanks

--EDIT--

So I have to remove

addFilter('blocks.getSaveContent.extraProps', 'luxuryconcept/add-custom-props', addCustomProps);

and add this PHP code to get attributes:

function theme_custom_add_custom_attributes($block_content, $block) {
    // Verifica se l'attributo è stato impostato e non è vuoto
    $data_delay = get_field('data-delay', $block['id']);
    $data_duration = get_field('data-duration', $block['id']);

    // Aggiungi gli attributi al blocco solo se sono stati impostati
    if ($data_delay && !empty($data_delay)) {
        $block_content = str_replace('<div', '<div data-delay="' . esc_attr($data_delay) . '"', $block_content);
    }
    if ($data_duration && !empty($data_duration)) {
        $block_content = str_replace('<div', '<div data-duration="' . esc_attr($data_duration) . '"', $block_content);
    }

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

But I don't know how to save them in PHP.

Share Improve this question edited Jul 11, 2024 at 14:30 Stefano asked Jul 11, 2024 at 13:15 StefanoStefano 636 bronze badges 2
  • 1 have you considered not using HTML to store these attributes then adding the HTML attributes in PHP? Anything that modifies the save components of a block usually leads towards problems and technical debt, especially in core blocks. You're already storing the attributes right instead of pulling them from the block HTML, so remove the save component stuff and write that part in PHP using render_block filters – Tom J Nowell Commented Jul 11, 2024 at 13:56
  • 1 @TomJNowell thanks. I edited the post but I don't know how save attributes by PHP – Stefano Commented Jul 11, 2024 at 14:30
Add a comment  | 

1 Answer 1

Reset to default 2

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!

本文标签: phpAdd custom data attribute to every core Gutenberg Blocks