Adding Default Blocks and Block Patterns to WordPress Post Types?

My colleague, Leon Rainbow, wrote about the advent of Block Patterns in the WordPress Gutenberg Editor back in March. With it, Web developers can assemble a set of blocks that could be reused within the editor to construct relatively complex page elements. Block Patterns can also be assembled without programming using a number of third-party plugins that have been developed.

Also, with the release of version 5.8, WordPress gives the option of adding templates to a theme that can be added/edited with blocks. These are the elements that surround the body of the post, such navigation, headers and footers, etc.

Availability of these features opens up a question, can you assign a default block pattern to a post? If so, you could easily specify all the content blocks for a new post without requiring an editor to add the pattern manually.

Alas, as of now you can not use a block pattern a default in a post type. However you can use any number or regular blocks, as well as nest these blocks, to construct a more complex pattern.

First Steps: A Block with Attributes

As discussed on the Block Templates API page, you can add a hook to your theme or plugin page to modify the “template” attribute of an existing post type. For example:

<?php
function myplugin_register_template() {
  $template = array(
    array('core/image', array(
      'align' => 'center',
      'url' => 'https://www.inforest.com/wp-content/themes/inforest-bootstrap/images/inforest-2017-logo.png',
      'alt' => 'Inforest Communications Web Design',
      'caption' => 'This is the Inforest Communications Logo',
      'title' => 'Inforest Communications',
      'href' => 'https://www.inforest.com',
      'linkTarget' => 'blank'
    ))
  );
  $post_type_object = get_post_type_object( 'post' );
  $post_type_object->template = $template;
}
add_action( 'init', 'myplugin_register_template',20 );

The result will have each new post start with a default image block of the Inforest logo. See screenshot below:

A screenshot of the WordPress editor showing the Inforest Logo image placed by default

In the above example, the template property of the $post_type_object ($post_type_object->template) is set to a multidimensional array. The first key value, “core/image” defines the type of block to be placed. The second array of key/value pairs define the attributes for each block. You can get a list of the available attributes for each block by viewing the block’s block.json file and noting all of the “attributes” and “supports” values listed. For the ‘core/image’ block, this can be found at /wp-includes/blocks/image/block.json or in the Gutenberg GitHub repository

Deciphering Block Attributes

In looking at block attributes, and how you might be able to define these, it is helpful to review the Block Attributes reference as it gives some clues as to how you can set these. I was particularly dumbfounded by the “query” attribute (which is used in the “core/gallery” block) until I saw the explanation and examples provided.

Here is my own explanation.

For the “core/gallery” block the “images” attribute definition looks like this:

"images": {
	"type": "array",
	"default": [],
	"source": "query",
	"selector": ".blocks-gallery-item",
	"query": {
	"url": {
		"type": "string",
		"source": "attribute",
		"selector": "img",
		"attribute": "src"
	},
	"fullUrl": {
		"type": "string",
		"source": "attribute",
		"selector": "img",
		"attribute": "data-full-url"
	},
	"link": {
		"type": "string",
		"source": "attribute",
		"selector": "img",
		"attribute": "data-link"
	},
	"alt": {
		"type": "string",
		"source": "attribute",
		"selector": "img",
		"attribute": "alt",
		"default": ""
	},
	"id": {
		"type": "string",
		"source": "attribute",
		"selector": "img",
		"attribute": "data-id"
	},
	"caption": {
		"type": "string",
		"source": "html",
		"selector": ".blocks-gallery-item__caption"
	}
}

Based on the above definition, in order to include a default set off images, my corresponding template property can be defined as follows:

$template = array(
    array('core/gallery', array(
      'images' => array(
        array(
          'url' => 'https://www.inforest.com/wp-content/uploads/2019/09/inforest-design.jpg',
          'alt' => 'Inforest Communications Web Design',
          'caption' => 'Web Design'
        ),
        array(
          'url' => 'https://www.inforest.com/wp-content/uploads/2019/09/inforest-seo.jpg',
          'alt' => 'Inforest Communications SEO',
          'caption' => 'SEO'
        ),
        array(
          'url' => 'https://www.inforest.com/wp-content/uploads/2019/09/inforest-ecomm.jpg',
          'alt' => 'Inforest Communications eCommerce',
          'caption' => 'eCommerce'
        ),
      ),
      
    ))
  );

This will result in a new post starting with a gallery. See screenshot below:

A screenshot showing the wordpress editor with a default gallery placed

Nesting Blocks to Create Complex Patterns

Finally, you can get something close to a block pattern by nesting blocks within other blocks. From the example provided on the Block Templates page, you can see an example of how this is done (also shown below)

$template = array(
    array( 'core/paragraph', array(
        'placeholder' => 'Add a root-level paragraph',
    ) ),
    array( 'core/columns', array(), array(
        array( 'core/column', array(), array(
            array( 'core/image', array() ),
        ) ),
        array( 'core/column', array(), array(
            array( 'core/paragraph', array(
                'placeholder' => 'Add a inner paragraph'
            ) ),
        ) ),
    ) )
);

In this case, we can see that for each block element in the array, the first key value is the type of block, the second array is for attributes and the third array is that of any nested blocks. Some blocks, such as “core/columns” and “core/column” don’t happen to have any attributes defined in the above example.

Locking your Templates

Finally, it is worth noting that there is a “template_lock” parameter for the post type object which can be set to “all” to prevent adding or moving blocks or “insert” to allow moving but not adding blocks. For the first example we would add “$post_type_object->template_lock = ‘all’; to prevent moving or adding blocks.

It’s really interesting to see where WordPress theme development is going as Gutenberg continues to spreads from being primarily a post content editing tool to editing widgets and finally editing/laying out themes. The challenge for developers remains how to give site editors more flexibility in laying out pages and posts while maintaining some level of consistency and keeping things simple. Adding default post blocks to a post type object is one way to make it easier for editors to have consistent use and arrangement content blocks across a post type.