Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template parts break query block layout controls #49072

Open
tomjn opened this issue Mar 14, 2023 · 12 comments
Open

Template parts break query block layout controls #49072

tomjn opened this issue Mar 14, 2023 · 12 comments
Labels
[Block] Post Template Affects the Post Template Block [Block] Query Loop Affects the Query Loop Block [Block] Template Part Affects the Template Parts Block [Type] Bug An existing feature does not function as intended

Comments

@tomjn
Copy link
Contributor

tomjn commented Mar 14, 2023

Description

If I put a post template inside a template part, and put that template part inside a query block, the layout/column controls no longer work!

The site editor displays the blocks correctly, but the frontend does not.

I encountered this while building a block based theme

Step-by-step reproduction instructions

Create a query block with 4 posts and 4 columns containing a template part, for example:

<!-- wp:query {"queryId":15,"query":{"perPage":"4","pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"exclude","inherit":false},"displayLayout":{"type":"flex","columns":4}} -->
<div class="wp-block-query"><!-- wp:template-part {"slug":"posts-template","theme":"mytheme"} /--></div>
<!-- /wp:query -->

And the associated template part:

<!-- wp:post-template -->
<!-- wp:post-title /-->

<!-- wp:post-date /-->
<!-- /wp:post-template -->

Screenshots, screen recording, code snippet

No response

Environment info

WordPress v6.1

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

@Mamaduka Mamaduka added Needs Testing Needs further testing to be confirmed. [Block] Query Loop Affects the Query Loop Block [Block] Template Part Affects the Template Parts Block labels Mar 15, 2023
@Thelmachido
Copy link

Thelmachido commented Mar 15, 2023

I added a Query Loop block to my site's footer and then moved things around such that the Query Loop block is the main parent block. The blocks and post columns/controls are displayed as expected on the front end just as shown in the screenshot.

Screenshot 2023-03-15 at 13 08 35

Can you confirm that I followed the correct steps to replicate the bug?

@Thelmachido Thelmachido removed the Needs Testing Needs further testing to be confirmed. label Mar 15, 2023
@carolinan
Copy link
Contributor

The post template only has one allowed parent block, the query,"parent": [ "core/query" ],
In a code editor, yes, we can copy paste any block anywhere, but it won't work correctly.

  • I understand there are uses cases for it. I have tried to do this myself more than once.
  • I also understand that our code editors do not yet have a way to validate the HTML markup and tell us that a block only has one allowed parent.
  • And there is no warning or similar when we open this combination in one of the editors.
@carolinan carolinan added the [Block] Post Template Affects the Post Template Block label Mar 15, 2023
@tomjn
Copy link
Contributor Author

tomjn commented Mar 15, 2023

@carolinan this issue has an associated ticket in #49073 where I try to put the block template part inside the post template block so it's a direct descendent of the query block, but no context is provided to the blocks inside the template part

@Thelmachido you didn't reproduce the problem, there are no template part blocks inside your query block like this:

Screenshot 2023-03-15 at 10 12 32

Moving the post template block up and out of the template part results in #49073

@tomjn
Copy link
Contributor Author

tomjn commented Mar 15, 2023

@carolinan might the problem here be that the query loop isn't enforcing the direct descendent rule you mentioned? Happy to rewrite the issue accordingly if so

@tomjn
Copy link
Contributor Author

tomjn commented Mar 15, 2023

Also, would it make sense to allow the post template block to specify its own template part? This would allow a common classic theme building pattern of get_template_part( 'content', 'post' ) inside a post loop to be reproduced in block themes without the issues of #49071 #49072 or #49073

@tomjn
Copy link
Contributor Author

tomjn commented Mar 15, 2023

Noting that this pattern sidesteps this issue:

Screenshot 2023-03-15 at 13 15 49

Although it sometimes doesn't show right in the site editor until a hard refresh is made, see #49073

@jordesign jordesign added the [Type] Bug An existing feature does not function as intended label Jul 26, 2023
@jordesign
Copy link
Contributor

Hey @tomjn - I also asked this re: #49073 but I'm curious as to whether using Synced Patterns instead of Template Parts works differently?

@tomjn
Copy link
Contributor Author

tomjn commented Jul 26, 2023

Possibly, but at the time the issue was created reusable blocks/synced patterns was not an option, and it still isn't. What needed doing had to be done with only files in the filesystem in a block theme. Distributing a WXR or telling people to manually set up something in the DB or automate it was not an option.

I also needed to be able to satisfy those requirements, and allow editing by the user.

Even if I did use it though, the moment a synced pattern was put inside a template part I'm back to square 1

@tomjn
Copy link
Contributor Author

tomjn commented Jul 26, 2023

From what I gather putting a block template inside a post template block results in it showing a single placeholder post.

If you then save, and load the site editor with that arrangement of blocks already in place then it will load in the appropriate posts, but modifying the query will bring the problem back

@dinhtungdu
Copy link
Contributor

dinhtungdu commented Feb 19, 2024

As far as I understand the rendering logic of the template part, this is an expected limitation of the current implementation. The core/template-part doesn't consume any context, and the content of that block is rendered from the string as a new tree, which is disconnected from its original block tree.

However, it's still possible to carry the context over the inner blocks of the template part and render its content with context:

  1. Filter the block registry to alter the core/template-part metadata to consume context from the core/query block.
  2. Manually render the template part with the (now available) context.
add_filter( 'block_type_metadata', function($metadata) {
    if( 'core/template-part' === $metadata['name']) {
        $metadata['usesContext'] = [
    		"queryId",
    		"query",
    		"queryContext",
    		"displayLayout",
    		"templateSlug",
    		"previewPostType",
    		"enhancedPagination"
    	];
    }
    return $metadata;
} );

add_filter( 'render_block', function( $content, $block_attr, $block ) {
    if (
        'core/template-part' !== $block_attr['blockName'] ||
        '<template-part-slug>' !== $block_attr['attrs']['slug']
    ) {
        return $content;
    }

    $template_part = get_block_template( '<your-theme-slug>//<template-part-slug>', 'wp_template_part' );
    $content = '';
    foreach ( parse_blocks( $template_part->content ) as $parsed_block ) {
        $content .= ( new WP_Block( $parsed_block, $block->context) )->render();
    }
    return $content;
}, 10, 3 );
@dinhtungdu
Copy link
Contributor

dinhtungdu commented Feb 19, 2024

If I put a post template inside a template part, and put that template part inside a query block, the layout/column controls no longer work!

AFAIK, not only layout control doesn't work, but also other things won't work as well. Instead of using the defined settings in the core/query block, the default setting will be used. For example, even if the posts per page is set to 2 in core/query, the core/post-template inside a template will still render the default posts per page.

@dinhtungdu
Copy link
Contributor

dinhtungdu commented Feb 19, 2024

If the template part is the direct child of the core/query block, we can modify the context directly instead of modifying the block registry.

add_filter( 'render_block_context', function( $context, $parsed_block, $parent_block ) {
    if (
        'core/template-part' === $parsed_block['blockName'] &&
        isset( $parent_block->name ) &&
        'core/query' === $parent_block->name
    ) {
        $context = array_merge( $context, $parent_block->attributes );
    }

    return $context;
}, 10, 3 );

add_filter( 'render_block', function( $content, $block_attr, $block ) {
    if (
        'core/template-part' !== $block_attr['blockName'] ||
        '<template-part-slug>' !== $block_attr['attrs']['slug']
    ) {
        return $content;
    }

    $template_part = get_block_template( '<your-theme-slug>//<template-part-slug>', 'wp_template_part' );
    $parsed_blocks = parse_blocks( $template_part->content );

    if ( ! empty( $parsed_blocks ) ) {
        $content = '';
        foreach ( $parsed_blocks as $parsed_block ) {
            $content .= ( new WP_Block( $parsed_block, $block->context ) )->render();
        }
    }

    return $content;
}, 10, 3 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Post Template Affects the Post Template Block [Block] Query Loop Affects the Query Loop Block [Block] Template Part Affects the Template Parts Block [Type] Bug An existing feature does not function as intended
6 participants