Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #41629
    diegoliv
    Participant

    Hey guys! I’m working a little bit with Gutenberg and I have a question about attributes.

    Right now, all examples I saw for a custom block has an attributes object containing all sorts of attributes, but all of them are single attributes. Is there a way to store an object as an attribute? I’m asking because I’m trying to “nest” some attributes into a single one. For example, I have a collection of attributes related to styling of an specific component of my block, and I want to save it as a post meta, so I can access later using get_post_meta(). Saving each style attribute into a single attribute and a single meta is not practical at all, since I might end up with a dozen of different attributes and post meta’s.

    I did some quick tests, and I can set an object as an attribute, but saving updates to nested attributes is another thing. For example, this code doesn’t work:

    attributes: {
        navigationStyles: {
            type: 'object',
    	    default: {
    	        arrowSize: 10,
    	    },
    	},
        },
    },
    (...)
    edit: ( props ) => {
        const changeArrowSize = ( value ) => {
            props.attributes.navigationStyles.arrowSize = value;
    	props.setAttributes( { navigationStyles: props.attributes.navigationStyles } );
        };
    
        (...)
    },

    But for some reason, this works:

        const changeArrowSize = ( value ) => {
    	props.setAttributes( { navigationStyles: { arrowSize : value } );
        };

    But doing this would reset the object attribute every time.

    Any tips on this one? Thanks in advance!

    #41642
    diegoliv
    Participant

    Just found out a quick workaround, using object spread to clone the main attribute:

    const changeArrowSize = ( value ) => {
        const styles = { ...props.attributes.navigationStyles };
        styles.arrowSize = value;
    
        props.setAttributes( { navigationStyles: styles } );
    };

    There might be a better way to do it, but for now this works, in case anyone has the same issue as me.

    Now, another question, kind of off topic since it’s not 100% javascript related, but more Gutenberg related. I want to store this object attribute as a post meta. For this, I understand that I need to set my attribute like this:

    navigationStyles: {
        type: 'object',
        default: {
            arrowSize: 10,
        },
        source: 'meta',
        meta: 'navigation_styles',
    }

    And then, I need to make this attribute visible as post meta for the Rest API. Something like this:

    function my_blocks_meta_init(){
        register_meta('post', 'navigation_styles', array(
            'show_in_rest' => true,
            'type' => '??????',
        ));
    }
    add_action('init', 'my_blocks_meta_init');

    Removing the type argument for the register_meta call will store this post meta as an array. That’s fine for PHP, js objects can sometimes be just like multidimensional arrays. But even with all of this kind of “working”, when I try to save a post with this post meta, I only get this message: Updating failed. I suspect that this is related to the type argument somehow. Single attributes, with simpler types, like a string, are correctly saved.

    Again, any tips to figure out this one? Thanks!

Viewing 2 posts - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.