WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
9.99k stars 4.01k forks source link

The Post Title block does not display the blog page name within template outside query #52668

Open likethegoddess opened 11 months ago

likethegoddess commented 11 months ago

Description

On https://github.com/WordPress/gutenberg/issues/22724, the Post Title block is designated as the equivalent to the single_post_title() tag. In classic theme dev, one use of the single_post_title() tag is to display the name of the blog page title before the loop on the index.php template.

I would expect that adding the Post Title block before the Query block on the index.html template would display the blog page title before the query results. Instead, nothing is displayed.

When I created a home.html template and added a Post Title Block before the Query block, the title of the first query result is displayed instead of the title of the page.

Step-by-step reproduction instructions

1) Go to template > index.html within a block theme. 2) Add <!-- wp:post-title /--> before

or

1) Go to template > index.html within a block theme. 2) Duplicate file and rename home.html. 3) Add <!-- wp:post-title /--> before

Screenshots, screen recording, code snippet

FSE HTML template

Classic PHP template

webmandesign commented 11 months ago

@likethegoddess I came across the same issue. The only solution I could find was to set up the Post Title context postId to the actual blog page ID using PHP. However, this only worked for brief amount of time as it seem it is going to be removed (still works with current Gutenberg 16.2.1).

The only future-proof solution I use is to build a "Blog page title" pattern (in twentytwentythree/patterns/blog-page-title.php, for example) containing a code such as:

<?php
/**
 * Title: Blog page title
 * Slug: twentytwentythree/blog-page-title
 * Categories: header
 */

$blog_page_id = get_option( 'page_for_posts' );

?>

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading"><?php

    if ( $blog_page_id ) {
        echo get_the_title( $blog_page_id );
    } else {
        echo esc_html_x( 'Blog', 'Fallback blog page title.', 'twentytwentythree' );
    }

?></h1>
<!-- /wp:heading -->

<?php if ( has_excerpt( $blog_page_id ) ) : ?>
<!-- wp:paragraph -->
<p><?php echo get_the_excerpt( $blog_page_id ); ?></p>
<!-- /wp:paragraph -->
<?php endif;

Then I insert the pattern into index.html template file using <!-- wp:pattern {"slug":"twentytwentythree/blog-page-title"} /-->.

likethegoddess commented 11 months ago

Thanks, @webmandesign, that's exactly what I needed. That's a shame the context is being removed. There has to be some way to accomplish this going forward.

twobyte commented 4 weeks ago

I am trying to return parsed post_content outside the loop via the rest api for a dynamic modal, and requiring the $post object to be global appears to be a breaking issue. The render_block_context filter is used to inject the post_id, which works for the core/post-featured-image block, but not the core/post-title block.

Example code:

if ($post->post_content && $post->post_status === "publish") {
    $this->modal_post = $post;
    $blocks = parse_blocks($post->post_content);
    $parsed_blocks = '';
    add_filter('render_block_context', function($context, $parsed_block, $parent_block) { 
         // Update the $context variable.
        $context['postId'] = $this->modal_post->ID;
        $context['postType'] = $this->modal_post->post_type;
        return $context; 
    }, 15, 3);
    foreach( $blocks as $block ) {
        $parsed_blocks .= apply_filters('the_content', render_block( $block ) );
    }
    $response = new WP_REST_Response(['post_content' => $parsed_blocks]);
}