Latest Projects WordPress

Transforming a Single WordPress Block into a Block Variation with InnerBlocks

One minor victory in the latest updates to my RSVPMaker plugin was figuring out a block transform to turn a single block, RSVPMaker Upcoming, into a variation on the Query Loop block.

With this configured, the Transform To options displayed when you click on the calendar icon in the button bar include Query Loop — complete with a preview of what the transformed block will look like with my defaults applied.

The tricky part was turning a single block (rsvpmaker/upcoming) into a version of the Query Loop (core/query) with preset InnerBlocks for the Post Template (a container for the blocks representing the post title and other elements, in this case including the event date and time).

This related post explains what I was trying to achieve:

The official Transforms documentation covers a number of use cases, including a scenario where you are transforming one block that contains InnerBlocks to another — you take the InnerBlocks object passed in by the source and pass it in to the createBlock call for “Transform to” operation. In my case, I needed to create the blocks from scratch.

Here is my solution:

The createBlocksFromInnerBlocksTemplate uses a template defined as a nested array, similar to the one for my block variation definition (see below) to create the object passed as the third parameter to createBlock.

Both createBlock and createBlocksFromInnerBlocksTemplate need to be extracted from the same source as registerBlockType.

import { registerBlockType, createBlock, createBlocksFromInnerBlocksTemplate } from '@wordpress/blocks';

One of the joys of custom WordPress development is spelunking through imperfect documentation in search of understanding of how a specific function really works. As in, you find a straightforward example or tutorial that doesn’t quite match what you want or need to do. In this case, the createBlocksFromInnerBlocksTemplate function is the one that was challenging to track down. I’m sharing this in the hopes of shortcutting the process for someone else who might face a similar scenario.

Things that I tried that did not work:

  • Including the template array, rather than the compiled object, as the third parameter on createBlock
  • Including the namespace for my block variation (rsvpmaker/rsvpmaker-loop) instead of core/query in the Transform to definition

Choosing between two templates

In my scenario, the “old” RSVPMaker Upcoming block had a few formatting options but not as many as the Query Loop version provides. One that it did offer was the option of displaying a calendar grid above the event listing. People can then navigate from month to month and click on the event titles displayed within the calendar to see the specific event details.

My “Transform to” code receives the attributes from the RSVPMaker Upcoming block and uses them to determine whether to use the version of the template that has rsvpmaker/calendar included. If so, those attributes are also passed into the RSVPMaker Calendar block (which has several parameters in common with the RSVPMaker Upcoming block).

RSVPMaker’s Query Loop variations

This is not meant to be a complete tutorial on either block transforms or block variations — both of which I have just learned how to work with — but for completeness I’ve included my variations code below.

The virtue of block variations is they allow you to inherit all the best qualities of an existing block while adding a few tweaks, such as an InnerBlocks template or additional controls.

In my case, I wanted to set the post type for the Query Loop to “rsvpmaker” and provide an InnerBlocks template that includes event specific blocks for displaying the date and time, as well as the RSVP Now! event registration button.

I provide two variations, one of which includes the RSVPMaker Calendar block. These are essentially the same block templates used in the Transform To code described above. Registering them as variations makes them available in the block inserter as alternatives to the standard Query Loop block.

Adding different controls to a block variation

Note that in the Transform To user interface, my variations show up as Query Loop, not RSVPMaker Query Loop — if there’s a way to change that, I haven’t found it. However, the Transform To code includes this attribute:


That namespace distinguishes my variation from the standard Query Loop, allowing it to display some additional controls.

This function, imported from @wordpress/hooks, makes it possible for the withRSVPQueryControls functions to test whether that namespace is present and, if so, add to the default InspectorControls for the block.

addFilter( 'editor.BlockEdit', 'core/query', withRSVPQueryControls );

The additional controls make it possible to specify that the Query Loop should display past events, rather than current ones, and to include or omit a specific Event Type (category) from the listings. Those options were available in the RSVPMaker Upcoming block, so I wanted to ensure they would also show up in the Query Loop version.

I had to study the source for Ryan Welcher’s Advanced Query Loop plugin to figure out how the filtering of controls works, which I didn’t completely understand from the documentation.

Hopefully, my notes will help someone else clear those hurdles faster.


If you found this worthwhile, let me know and connect on, Mastodon (, or Twitter (a.k.a. “X”)

Leave a Reply

Your email address will not be published. Required fields are marked *