Main query loop handling for block themes in 6.4

In WordPress 6.4, a change has been applied to how the main query loopLoop The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. is being handled for blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. themes. For singular content, the output of block templates (e.g. single.html or page.html) will be automatically wrapped in the main query loop.

Classic theme background

Historically, classic themes have included a main query loop (sometimes referred to as just “the loop”) in every template where any kind of WordPress posts from the database would be displayed. For reference, this is what the loop roughly looks like in most classic themes:

if ( have_posts() ) {
	while ( have_posts() ) {
		the_post();

		// Render the post.
	}
}

While the loop is primarily intended to iterate over the posts in a list of posts (such as the blogblog (versus network, site) or a categoryCategory The 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging. archive), even for singular content (e.g. a single post or page) this loop has been historically required for various reasons. For example, the in_the_loop() function is used by many plugins to check whether a post is currently being output.

The loop in block themes

Block themes do not use PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher templates, so they do not manually output a loop like the one shared previously. Instead, blocks are responsible for handling it, typically the “Query loop” block (core/query). It automatically takes care of rendering the loop correctly.

However, the core/query block is only intended for use in archives, or any content that displays a list of posts. It would not be suitable for singular content as it wraps the posts in list markup, which would be semantically incorrect. Furthermore, while using a loop on singular content has been common knowledge for classic theme developers, end users of WordPress may not be familiar with that concept, and it can certainly be confusing when you learn about it. In other words, there is not a good reason to bother WordPress end users with having to use blocks correctly to make sure the loop is entered.

However, this means that for singular content, there is no coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. block available for handling the loop. Prior to 6.4, the loop was still being established for most cases even on singular content, but it was using a problematic workaround that forced the loop to start based on specific post blocks like “Content” and “Featured imageFeatured image A featured image is the main image used on your blog archive page and is pulled when the post or page is shared on social media. The image can be used to display in widget areas on your site or in a summary list of posts.” being rendered (core/post-content and core/post-featured-image). This workaround was not reliable as the blocks could also be intentionally used outside of the main query loop, and therefore led to other bugs, such as, #58027.

Current solution

To address the above, two changes [56507] and [57019] were made as part of WordPress 6.4 to automatically wrap the entire block template in a main query loop under the following circumstances:

  • The current main query is for singular content (via the is_singular() function).
  • There is indeed only a single post in the main query result.
  • The current block template is part of the current theme.
    • This is almost always the case. An exception is plugins that may inject their own block templates for specific content.
  • There post is still available to render (via the have_posts() function).

This is generally considered safe because in this situation the loop only contains the single post anyway that the current block template is for. A search through the WordPress pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party directory has not found relevant blocks where this would pose a problem. However, if you are developing a custom block plugin that makes specific assumptions about the main query loop, it is recommended that you check your block’s implementation to be compatible with this change in WordPress 6.4. This may especially be relevant for custom blocks that can be used alternatively to the “Query loop” block from WordPress core.

For example, if your custom block contains a main query loop similar to the example shown before, you could update it as follows to maintain compatibility with the new behavior:

if ( is_singular() && in_the_loop() ) {
	// Render the post.
} elseif ( have_posts() ) {
	while ( have_posts() ) {
		the_post();

		// Render the post.
	}
}

Please visit #58154 and #59225 for additional context on these changes.

Props to @gziolo and @webcommsat for peer review.

#6-4, #dev-notes, #dev-notes-6-4