0

I am attempting to add some context to the Query Loop block and inherit that on the inner blocks like post title (so nested inside the Post Template block). I can filter it in on render_block_context and the context is available on the Query Loop block, but I was hoping to figure out how to automatically inherit that in the descendant blocks.

Here's my minimal example:

add_filter( 'render_block_context', function( $context, $parsed_block ) {
    if ( 'core/query' === $parsed_block['blockName'] ) {
        $context['helga/tacos'] = 'we love tacos';
    }
    return $context;
}, 10, 2 );
 
add_filter( 'block_type_metadata', function( $metadata ) {
    if ( 'core/query' === $metadata['name'] ) {
        $metadata['attributes'] ??= [];
        $metadata['attributes']['tacos'] = [
            'type' => 'string',
            'default' => 'default tacos',
        ];
 
        $metadata['providesContext'] ??= [];
        $metadata['providesContext']['helga/tacos'] = 'tacos';
    }
    if ( 'core/post-title' === $metadata['name'] ) {
        $metadata['usesContext'] ??= [];
        $metadata['usesContext'][] = 'helga/tacos';
    }
    return $metadata;
} );
 
add_filter( 'render_block_core/post-title', function( $block_content, $block, $instance) {
    return $block_content . json_encode( $instance->context );
}, 10, 3 );

Then insert a Query Loop block anywhere and look at the resulting output. I have the context json encoded after each post title... and it never includes the helga/tacos context key that I defined both in render_block_context but also set up providesContext and usesContext for in the loop and title blocks respectively.

I am trying to get the helga/tacos key available in the context in the post title block AND for it's value to be we love tacos.

1 Answer 1

2

Presumably, within your Query Loop block, you also have a Post Template block. When rendering the page server side, there is "barrier" in the context inheritance caused by the render_block_core_post_template():

$block_content = ( new WP_Block( $block_instance ) )->render( array( 'dynamic' => false ) );

It renders the content without any of its context (it is the second parameter to the WP_Block constructor).

Hence, we need to "save" the context value and pass them through this barrier. We can do this by hooking into render_block_context for child blocks. We do this by adding this hook just before the Post Template block is rendered and then remove the hook after rendering it:

// render_block_data is the last hook just before a block is rendered.
add_filter(
  'render_block_data',
  function( $block ) {
    if ( $block['blockName'] === 'core/post-template' ) {
      // This will add the context for any child block within this
      // `core/post-template` block we are about to render.
      $add_context = function ( $context ) {
        $context['helga/tacos'] = 'we love tacos';
        return $context;
      };
      add_filter( 'render_block_context', $add_context );

      // Unhook the context filter above, after rendering this
      // `core/post-template` block.
      $unhook = function ( $content ) use ( &$unhook, $add_context ) {
        // Unhook.
        remove_filter( 'render_block_context', $add_context );
        // Unhook this function too since it is no longer needed.
        remove_filter( 'render_block_core/post-template', $unhook );

        return $content;
      };
      add_filter( 'render_block_core/post-template', $unhook );
    }

    return $block;
  }
);
3
  • I have been stuck on this for a while and I also just finally noticed that WP_Block is not getting that 2nd param inside the post template render callback. I created an issue for that. I think you are on to something as a workaround, but I added it after my above snippets and there's no change, so something isn't quite right somewhere. Commented Jan 10 at 18:04
  • Seems to be working in this WordPress Playground which would suggest there could be some code (or otherwise) in your WordPress instance that is interfering. Commented Jan 10 at 18:32
  • You're right, my apologies, it was probably some copy/paste shenanigangs on my part. I hope the issue is fixed upstream, but this works for right now. Thank you! Commented Jan 10 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.