The Query Loop block is a powerful tool that brings the WP Loop, a core WordPress function, to the block editor. Introduced in WordPress version 5.8 and continually updated and improved since then, the Query Loop block is a useful way to display a list of posts or other content in the block editor. In this article, we will explore the usefulness of the Query Loop block and how to extend its capabilities.
To get started, we will create a plugin to store our code. The quickest way to create a plugin scaffold is by using the WP-CLI command npx @wordpress/create-block loop-patterns
, which will generate the necessary files for us.
If you want more information on the create-block
script, you can check out the WordPress documentation.
Query Loop Variations
WordPress provides block variations as a way for developers to create custom versions of core blocks. To get started, we will need to create some directories to store our code. We can do this by running a few commands in the terminal.
We begin by creating a simple block variation called simple-query
, and adding a CSS folder to store minimal styles. We don’t want to change the theme styles already declared in the theme.json
file. To add our code, we will edit the simple-query/index.js
file.
We will use the registerBlockVariation()
function to register our block variation. If you are unfamiliar with block variations, you can learn more about them here.
This code defines a constant called SIMPLE_QUERY
, which is set to the string '
loop-patterns/simple-query
'
. This constant represents the name of a block variation that is being registered.
The wp.domReady()
function is a WordPress function that is called when the DOM (Document Object Model) is fully loaded and ready for manipulation. Inside the wp.domReady()
function, the wp.blocks.registerBlockVariation()
function is called with two arguments: 'core/query'
and an empty object {}
.
The wp.blocks.registerBlockVariation()
function is used to register a block variation. The first argument is the name of the parent block (in this case, 'core/query'
), and the second argument is an object that specifies the properties of the block variation being registered. In this case, the object is empty, so no additional properties are being set for the block variation.
As previously mentioned, the registerBlockVariation()
function takes two arguments: the first argument is the name of the parent block, and the second argument is an object that specifies the properties of the block variation being registered. Let’s review the properties of the object.
name
: This property specifies the name of the block variation being registered. In this case, the value of thename
property is the constantSIMPLE_QUERY
, which represents the string'loop-patterns/simple-query'
.title
: This property specifies the title of the block variation. This title will be displayed to the user in the block editor. In this case, the value of thetitle
property is'Simple Query'
.description
: This property specifies a description of the block variation. This description will be displayed to the user in the block editor. In this case, the value of thedescription
property is'Displays a Simple Query'
.return
: This property is a function that specifies the conditions under which the block variation should be displayed to the user. In this case, the function returnstrue
if thenamespace
variable is equal toSIMPLE_QUERY
and thequery.postType
variable is equal to'post'
. Otherwise, the function returnsfalse
.icon
: This property specifies the icon that should be displayed for the block variation in the block editor. In this case, the value of theicon
property is'edit-large'
, which represents a pencil icon.attributes
: This property is an object that specifies the attributes (i.e., data values) that the block variation should have. In this case, the object is empty, so no attributes are being set for the block variation.
Block Attributes
The next step will be adding our block attributes. Let’s take a look at the Query Loop block attributes.
Based on the screenshots, we can add the following to the attributes object in our script:
The attributes
object in this code defines the query parameters that will be used to retrieve posts from the WordPress database.
Here is what each attribute does:
perPage
: The number of posts to be displayed on each page.pages
: The number of pages to be displayed.offset
: The number of posts to skip before starting to display posts.postType
: The type of post to be displayed (e.g.,post
,page
, etc.).order
: The order in which the posts will be displayed (eitherasc
for ascending ordesc
for descending).orderBy
: The criteria used to order the posts (e.g.,date
,title
, etc.).author
: The ID of the author whose posts will be displayed.search
: A search term used to filter the posts that are displayed.exclude
: An array of post IDs to exclude from the query.sticky
: A value used to include or exclude sticky posts from the query.inherit
: A boolean value indicating whether the query should inherit the context of the current page.
These attributes can be used to customize the behavior of the query and fine-tune which posts are displayed.
Finally, we will build our template. We can use the innerBlocks
property to build our template by creating nested blocks within the parent block.
In this case, the innerBlocks
array has three nested blocks:
- The first nested block is an instance of the
core/post-template
block, which is a template block that can be used to display a single post. The second element of the array is an empty object{}
, which represents the attributes of the block. The third element of the array is another array, which represents the content of the block. In this case, the content of thecore/post-template
block consists of two blocks: thecore/post-title
block and thecore/post-excerpt
block. - The second nested block is an instance of the
core/query-pagination
block, which is used to display pagination links for a list of posts. - The third nested block is an instance of the
core/query-no-results
block, which is displayed when a query returns no results.
This is what our final code will look like::
Register Our Scripts
Now let’s test our simple query to make sure it is reading our code correctly. To do this, we need to change how we register our scripts in the **loop-patterns.php
**file. Replace the existing content with the following:
To make sure you are calling the script correctly, add the following to the src/index.js file:
And make sure that you’re calling the script correctly on src/index.js
. Add this:
Let’s visit the block editor and check out our new block variation. See how it appears in the block editor and on the frontend of the site.
While our custom variation is simple, it’s a good starting point. Now that we have a better understanding of how to register a query loop variation let’s create a flip cards variation for the Query Loop block. To create a new flip-cards
variation, we can follow the same steps we used to create the previous variation.
This code registers a new block variation for the core/query
block calledflip-cards
. The variation has a name, title, and description and is only active if the namespace is FLIP_CARDS
and the postType
attribute of the query
object is 'post'
. The variation also has a set of attributes, including a className
, tagName
, and query
object.
The variation is scoped to the block inserter and does not contain any inner blocks.
Inner Blocks
For our inner blocks, let’s do the following:
This code defines an array of inner blocks for the flip-cards
variation of the core/query
block. The inner blocks include a core/post-template
block, which is locked and has a specific className
. The core/post-template
block also contains a core/group
block, which in turn contains a core/columns
block. The core/columns
block contains two core/column
blocks, which each contain various blocks such as core/post-title
, core/post-date
, core/post-author
, and core/post-excerpt
.
The structure of the inner blocks creates a layout with flip cards, where each card has a front and backside. The front side of the card contains a featured image, and the back side contains the post title, date, author, and excerpt. The blocks are nested inside each other to create the desired layout and functionality.
If you’re having trouble understanding how to access the block’s attributes, a helpful resource is the block library on GitHub. Alternatively, you can view the block’s attributes by clicking the Code editor
option under the Editor
toolbar, or by referring to the attributes we registered earlier.
The same applies to all blocks, I found it very helpful when looking for the attributes.
Adding Styles
The finishing touch will be adding our styles, which are the following:
With all the pieces in place, we can now see the results of our custom query loop variation. In the block editor and on the frontend of the site, we should see:
I hope you’ve enjoyed this tutorial and have learned how to create custom query loop variations in the block editor. With these skills, you can give your content a unique look and feel and customize the Query Loop block to meet your needs. Thanks for following along, and I look forward to seeing what you create!