This post is for other web developers. Whilst we normally write with our clients and potential clients in mind, occasionally we come across something we think may be useful for other web developers and want to share.
Block templates allow a web developer to specify which blocks automatically appear in the editor when you create a new post or custom post type.
In our case, we’ve created a portfolio custom post type and I want to specify that there’s an embed block, a table block (with Director, Producer, Actors headings) and a gallery block.
There are some great resources to get you started on using block templates such as The WordPress Handbook and Bill Erickson’s Using Block Templates with Gutenberg.
In our case whilst registering the portfolio custom post type with register_post_type
we can just add template
to our $args such as:
'template' => array(
array( 'core/embed', array() ),
array( 'core/table', array() ),
array( 'core/gallery', array() ),
),
But… how to automatically add three two-column rows to our table block with Director, Producer, Actors headings?
Turns out you can specify the attributes for a block and the example given in the WordPress Handbook covers some attributes for the image, heading and paragraph blocks.
'template' => array(
array( 'core/image', array(
'align' => 'left',
) ),
array( 'core/heading', array(
'placeholder' => 'Add Author...',
) ),
array( 'core/paragraph', array(
'placeholder' => 'Add Description...',
) ),
),
The WordPress handbook says: “To find a comprehensive list of all block attributes that you can define in a template, consult the block’s block.json
file, and look at the attributes
and supports
values. You can find block.json
files inside wp-includes/blocks/heading/block.json
.”
So I had a look at the table block’s block.json file and as someone who hasn’t delved much into json I struggled to understand the structure I needed. I turned to Google once more but I could not find any example of a block template that uses the table block (hence this post).
Here is what we eventually found to work and I’ll explain after what tools we used to help us get there:
'template' => array(
array( 'core/embed', array() ),
array( 'core/table', array(
'body' => array(
array( //row
'cells' => array(
array( //element
'content' => 'Director',
'tag' => 'th'
),
array( //element
'content'=>'',
'tag' =>'td'
),
),
),
array( //row
'cells' => array(
array( //element
'content' => 'Producer',
'tag' => 'th'
),
array( //element
'content'=>'',
'tag' =>'td'
),
),
),
array( //row
'cells' => array(
array( //element
'content' => 'Actors',
'tag' => 'th'
),
array( //element
'content'=>'',
'tag' =>'td'
),
),
),
),
)),
array( 'core/gallery', array() ),
),
The table block has attributes for hasFixedLayout
, caption
, head
, body
, and foot
. The head, body and foot are expecting arrays of rows with arrays of cells defined as an array of their content and tag (td or th) defined. To be honest, it feels like I have one extra level of arrays but all I can say is the above works – if anyone can shed further light on this please let me know in the comments.
So how did we get this figured out? I tried my usual approach of trial and error but could not figure it out. Then my 18yo son, Charlie, came home from school. He’s doing Computer Science A-Level and hopes to study Computer Science at University starting in September. So I threw it at him as a challenge.
First, he pointed me to using the browser console dev tool to run JSON.stringify(wp.data.select( 'core/block-editor' ).getSelectedBlock().attributes);
and the output of this helped us identify the structure a bit better:
{"hasFixedLayout":false,"caption":"","head":[],"body":[{"cells":[{"content":"Director","tag":"td"},{"content":"","tag":"td"}]},{"cells":[{"content":"Producer","tag":"td"},{"content":"","tag":"td"}]},{"cells":[{"content":"Actors","tag":"td"},{"content":"","tag":"td"}]}],"foot":[]}
We then took a shortcut and used json_decode
in our register_post_type
function which worked too:
'template' => array(
array( 'core/table', json_decode( '{"hasFixedLayout":false,"caption":"","head":[],"body":[{"cells":[{"content":"Director","tag":"td"},{"content":"","tag":"td"}]},{"cells":[{"content":"Producer","tag":"td"},{"content":"","tag":"td"}]},{"cells":[{"content":"Actors","tag":"td"},{"content":"","tag":"td"}]}],"foot":[]}' )),
),
After that, I worked through and converted the above into the PHP structure.
All I can say is thank goodness for teenagers and THANK YOU CHARLIE!
ps he’s available for intern work in the summer holidays 🙂
Leave a Reply