Search code examples
wordpresswordpress-gutenberg

Block variation was switched back to the root block after its attributes are updated


I am writing a WordPress plugin that register a variation of the core query block. The variation add include to the query:

    attributes: {
        namespace: MASTER_QUERY_LOOP,
        query: {
            include: []
        },
    },

After I insert the variation into the editor and do some settings of the variation block, I update the block attributes:

    const newInclude = [1]; // just a test ID
    setAttributes({query: {include: newInclude}});

I expect my block variation Master Query Loop will show only one post with the ID=1, but it was switched back to the core Query Loop block and keep showing the loading indicator. Can anyone help me to explain this behavior?


Solution

  • Block variations require an isActive property so the Gutenberg Editor can tell if the block is the default block or a variation.

    If isActive is not defined, the Editor matches the block as the default - this is why you see the default query block as selected instead of your variant.

    When the query block continually displays the loading indicator, it means some part of the query is invalid. In this case include:[1] is not a valid query parameter to get a post by id. A better query parameter for your scenario is postIn:[1] which accepts an array of post ids.

    Eg.

    const MASTER_QUERY_LOOP = 'my-plugin/custom-query'; // Should be unique
    
    registerBlockVariation( 'core/query', {
        ...
        attributes: {
            namespace: MASTER_QUERY_LOOP,
            query: {
                postIn: []
            },
        },
        isActive: ( { namespace, query } ) => {
            return (
                namespace === MASTER_QUERY_LOOP
                // Using just the namespace is fine for query block variations
            );
        },
    });
    

    NB. If the default of postIn:[] is an empty array, postIn will return has_posts() as true. If you then set perPage:1 in the attributes, it will return just the most recent post.

    Reference: WP_Query