The Query Block: The Loop in Block-Based Themes

The Query block is the foundation of every block-based theme. It shows the list of posts for the current page, and is the basis of all further customizations.

But if you are familiar with WordPress theme development, you’ll only know how to use PHP to do this. In fact the set of PHP instructions that we call The Loop is present in every single theme template.

So how do the two approaches compare?

In this article we’ll first analyze how PHP-based themes output posts. Second we will look at how block-based themes display posts.With that, we can compare the two approaches–both their commonalities and their differences. Lastly we will look at some sample use cases for this block.

Reminder: A basic WordPress loop

To start let’s look at an example loop in a WordPress theme:

<?php
while ( have_posts() ) :
    the_post();
   
    the_title();
    the_excerpt();
endwhile;
?>Code language: HTML, XML (xml)

So what are the moving parts here? Here’s a graphic to explain the different layers better.

A graphic shown all the layers involved in outputting posts in a PHP-based theme: the Main Query, The Loop, the post globals, and The Template Tags.
  • First we have the Main Query. This is the query that WordPress runs automatically based on the current URL.
    The Main Query is stored in the $wp_query global. And this what all the functions of The Loop rely on.
  • Second we have The Loop. This is the while ( have_posts() ) loop.
    The have_posts() function keeps track of the currently displayed post. It will return true until there are no more posts left. Therefore the code inside of the loop runs once for each post.
  • Thirdly we have the post globals. They are set by the call to the_post() function.
    It does two things:
    1. Advance the current post counter.
    2. Set up the global variables needed for the template tags to work.
  • Lastly we have the template tags. the_title() and the_excerpt() output data of the current post.

Since the example above is for a posts archive, let’s add a pagination to this.

<?php
if ( have_posts() ) :
    while ( have_posts() ) :
        the_post();
   
        the_title();
        the_excerpt();
    endwhile;

    the_posts_pagination();
endif;
?>Code language: HTML, XML (xml)

While this is old news for seasoned WordPress developers, there’s really a lot going on here. Because if any of these pieces is missing, the posts won’t display as desired.

In a block-based theme, this is a lot simpler. Let’s look at how we can use the Site Editor to implement a simple loop in a full-site editing compatible theme.

Introducing the Query block

To display a list of posts in a block-based theme, you can use the Query block:

The position of the Query block in the block inserter.

When you insert this block, it will offer you the choice of different layouts for the posts.

All available variations of the Query block.

We’re going to select the second option, as we only want the title and the excerpt. This is how this looks in the editor:

A list of posts in the site editor.

So what are we missing for our archive template? A posts pagination.

For that we need to scroll down to the bottom of the Query block. Then we click the block inserter, and we search for the Query Pagination block.

The Query Pagination block in the block inserter.

And this is how the pagination looks:

A query pagination block in the site editor.

Granted at this point it’s not much to look at, since we’re missing styles. But still–with only four clicks I was able to create an archive template. And all that without writing any code!

Now with the implementation done, let’s look at how this all works.

The Query Block explained

You might think that the Query block is just a single block. But there are two blocks that handle the post list display.

We can use the list view in the Site Editor to see all blocks in the template.

The list view of the index template.

We see that there’s both a Query block and a Query Loop block. Here’s a graphic to explain the different layers better.

A graphic shown all the layers involved in outputting posts in a block-based theme: the Query block, the Query Loop block, and the Post blocks.
  • First we have the Query block. This block provides the WP_Query instance containing the posts.
    By default the Query block inherits the Main Query, but you can also create a new query.
  • Second we have the Query Loop block. This block ensures that all posts in the query are displayed, and provides the necessary data for the Post blocks.
    There’s no need to setup the post globals for each post in the loop. The Query Loop block handles this automatically.
  • Lastly we have the Post blocks. They output the data of the current post.

Now looking at this explanation, you might consider that not much has changed compared to PHP-based themes.

But while the overall approach is still the same, the Query block is still a big move forward. It consolidates many of the functions used to get and display posts.

The Query block vs. PHP queries

The WordPress PHP APIs offer different ways to retrieve posts:

  • Using The Loop and the Main Query.
  • Using a new WP_Query.
  • Using get_posts().
  • Using query_posts().

The whole setup is quite complex, which is why Andrey “Rarst” Savchenko has written an entire post to make sense of WordPress post retrieval functions.

In full-site editing there is a single way to display posts: using the Query block. It is the central provider for the posts. And that no matter whether the source is the Main Query or an additional query.

The block has two different editing interfaces, depending on the case:

Inherit the Main Query

The Query block settings set to inherit the Main Query.

Run a secondary Query

The Query block settings to configure a secondary query.

When the Main Query is inherited, there’s no point in modifying the criteria for retrieving the posts. Being able to disable sticky posts is a nice touch though.

On the other hand you can use a complete query builder for any additional queries. The most important options from the WP_Query class are supported.

Query pagination made easy

If you are like me, you googled “WordPress pagination not working” at least once in your development career. Google has over one and a half million results for that key phrase alone. So it’s safe to say we’re not the only ones confused by this!

The reason why using functions like the_posts_pagination() in secondary loops doesn’t work is the reliance on the Main Query. Something which is obvious with some development experience. But very hard to understand for a beginner, or less technical users.

In full-site editing, this is no longer an issue–all Query blocks are independent.

To illustrate this, we added an additional Query block to the page: it displays all the latest posts and has a pagination:

Two Query blocks in the same template.

Now watch what happens when I click on the second page of the additional Query block:

Two Query blocks in the same template. The second block's pagination is on page 2, but everything continues to work.

The pagination works as expected and displays the second page of the additional post list. In addition, the URL of the page is updated, and ?query-2-page=2 is added. This allows users to link to this specific view if they wanted.

Maybe to some of you this seems like a detail. But it simplifies yet another aspect of WordPress development, and that is a step in the positive direction.

One block, many variations

As we have seen, the Query block is the one way to display posts in a block-based theme.

But what about the Posts List block? It’s a variation of the Query block. In fact there are many other possible use cases for the Query block. Imagine if the Recent Posts widget used it also internally: the the Query block would be the one foundational block for all other blocks dealing with posts.

But since block variations are nothing but a pre-configured block that is present in the block inserter, there are lots of possibilities here for customizations.

Take for example a plugin that uses a custom post type. This plugin could then register it’s own variation of the Query block so that users can place this content on their pages. Done are the days of fidgeting with shortcodes, or having to modify templates!

Full-Site editing is a new beginning for themes

This article has shown that in a block-based theme, a lot of the old approaches don’t work anymore. I have been building full-site editing themes since August 2020, like for example the Block-Based Bosco theme. These experiments have allowed me to build up new best practices for the future generation of WordPress themes.

I share my knowledge about building full-site editing in the Building Block Themes course. If you want to learn how build a full-site editing compatible theme in a day, check out the course.

Level Up Your WordPress Development Skills With One Email Per Week

Every Sunday, I send out tips, strategies, and case studies designed to help agencies and freelancers succeed with modern WordPress.

My goal is to go off the beaten path, and focus on sharing lessons learned from what I know best: building websites for clients.

100% free and 100% useful.

Feel free to check out the latest editions.