Search code examples
jquerywordpresssaveblockwordpress-gutenberg

Wordpress gutenberg block - jquery generated content not saved


I am new to Wordpress Gutenberg blocks. I created a gallery plugin and I want a user to be able to insert gallery shortcode by simply choosing the desired gallery from a popup window. I use jQuery text() function to inject shortcodes from the popup window with success but the content will not be saved. However, when I type in some text everything works fine.

Here is my Gutenberg js:

var el = wp.element.createElement,
registerBlockType = wp.blocks.registerBlockType,
RichText = wp.editor.RichText,
blockStyle = { backgroundColor: '#0000cc', color: '#fff', padding: '1%', margin: '1%', border: 'none', boxShadow: '5px 5px 5px #000', cursor: 'pointer' };

registerBlockType( 'prtxgal/block', {
    title: 'Protex gallery',

    icon: 'images-alt',

    category: 'common',

    attributes: {
        content: {
            type: 'string',
            source: 'html',
            selector: 'div',
        }
    },

    edit: function(props) {
        var content = props.attributes.content;

        function onChangeContent( newContent ) {
            props.setAttributes( { content: newContent } );
        }

        return[ el(
            'button', { className: 'button add_prtxgal', /*style: blockStyle*/}, 'Choose gallery'
            ),
            el (RichText,
            {
                tagName: 'div',
                className: props.className,
                onChange: onChangeContent,
                value: content,
            }
            ),
        ];
    },

    save: function(props) {
        var content = props.attributes.content;

        return el( RichText.Content, {
            tagName: 'div',
            className: props.className,
            value: content
        });
    },
});

Solution

  • The combination of jQuery and front end frameworks like React.js (in reality a library not framework) and Angular isn't considered a good combinations so it is recommended not to use it.

    Reason

    Frontend frameworks maintains the state of each component and if we change that component via jQuery or by accessing nodes with JS then those states aren't updated in framework. For updating states framework provides their own methods in React the method is setState(obj) while in Gutenberg the method is setAttributes(obj) which is actually a wrapper around React.js setState().

    Suggestion

    Here are the few suggestions how I suggest you to make this component (considering this is not a Server Side Block).

    1. I will use JSX instead of ES5 syntax of JavaScript. WordPress docs by default shows sample code of ES5 but there is a tab to change it to JSX.
    2. I will show the Add Item button which adds new Gallery Item. The implementation of that button can be same like core/gallery block (present on bottom while selecting more than one image).
    3. Clicking on this Add Item will add a new object in to my attributes which also appear on frontend and from frontend I add values into this new block. Gutenberg <RichText/> component is very helpful for manipulating text content.
    4. Update you state onChange event on <RichText/>.
    5. Similarly updating and deleting functionalities can be implemented.
    6. Clicking on update will take that whole new content and save it.

    Note:

    For better understanding of Gutenberg ecosystem I recommend you to familiarize yourself with following things:

    • ES6 syntax also knows as ES2015.
    • React.js.React Documentation is very good resource for this.
    • Redux not completely but just how to update object using pure functions logic (pure functions are functions that don't change input). Some Examples from Redux Docs
    • In the end look at the implementations of core blocks present in Gutenberg. Starts from easy one first like paragraph, quote, list etc.
    • Always update state using setState() or setAttributes() not directly by accessing this.props.attributesor this.props.state

    Bonus

    • You can make fetch data in ComponentDidMount lifecycle of React.js and then update the states. Data can be fetch through any API or even WordPress REST API.