Define block templates for new pages, posts, and custom post types

WordPress’ block editor comes with the feature of block templates. This allows us to defined a set of blocks that will be present in the content of new pages, posts and/or custom post types. This post shows you how to use that functionality and how to use reusable blocks in templates.

What are block templates good for?

Let us assume, editors of a website need to insert the same blocks on almost all pages they create, for example, a group block containing a heading block.

For those cases, it is helpful to directly have these blocks in the content when creating the page, instead of the default paragraph block.

And for this, we have block templates.

Create a block template

Post type objects have an attribute template, that accepts an array of blocks.

To add a template to an existing post type, we hook into the init action and modify the wanted object. The code for an easy block template for pages can look like this:

/**
 * Add group block to new pages.
 * 
 * @link https://developer.wordpress.org/block-editor/developers/block-api/block-templates/
 */
function slug_post_type_template() {
	$page_type_object = get_post_type_object( 'page' );
	$page_type_object->template = [
		[ 'core/group', [], [
			[ 'core/paragraph' ],
		] ],
	];
}
add_action( 'init', 'slug_post_type_template' );

Like said, we use the init action for our function. Inside the function, we get the post type object of pages and add a block array as the template.

This array contains one or more arrays for the first-level-blocks (in our case, a group block that is going to come with WordPress 5.3). With the second value of a block array, we could set attributes of the block, that could be the background and text color for the group block. We leave that empty for now.

The third value is an optional array of additional block arrays, which are added inside the parent block. Our example adds a paragraph block inside the group block. That works – of course – only for blocks that allow inner blocks.

Set block attributes

I already mentioned it: it is possible to set attributes of blocks with the second value of a block array. To set a background color for the group block, we pass the slug of a color that was added via an add_theme_support() call like described in the theme support reference on developer.wordpress.org:

/**
 * Add group block to new pages.
 * 
 * @link https://developer.wordpress.org/block-editor/developers/block-api/block-templates/
 */
function slug_post_type_template() {
	$page_type_object = get_post_type_object( 'page' );
	$page_type_object->template = [
		[ 'core/group', [ 'backgroundColor' => 'light' ], [
			[ 'core/paragraph' ],
		] ],
	];
}
add_action( 'init', 'slug_post_type_template' );

Use reusable blocks in block templates

If you want to use a reusable block in block templates: that is possible, too. A reusable block has the type core/block and gets the ID of the block post for the ref attribute (reusable blocks are stored via a custom post type).

So we need the ID of the post and use it in the block template. That could look like this:

$unsere_leistungen_block = new WP_Query(
	[
		'post_type' => 'wp_block',
		'title' => 'Services',
	]
);

if ( ! empty( $unsere_leistungen_block->posts ) ) {
	$page_type_object->template = [
		[ 'core/block', [ 'ref' => $unsere_leistungen_block->posts[0]->ID] ],
	];
}

First, we search for the blocks with the title »Services« via a WP_Query, check if we got blocks and use the ID of the first block for the ref attribute of the core/block block we use in the template.

If the title of the block changes, you need to adjust the code.

Use block template for posts and custom post types

With the same procedure, we can define templates for posts and custom post types. For that, we adjust the parameter of the get_post_type_object() call, for example, to post instead of page, if we want to create a template for posts.

If you want to set a template for your own custom post type, you can do that directly when calling register_post_type() – the function accepts a template key in the parameter array, that gets the block arrays as a value.

An example of that and more can be found on the templates page in the block editor reference. There you can also see how to lock a template so that the user cannot remove or add blocks, or move them around.

Related posts

12 comments on »Define block templates for new pages, posts, and custom post types«

  1. ceylan

    Hello, is there a way to define a block template by prohibiting to insert a block before the template? Thank you for your tutorials, some of them have been very useful for me.

    Reply
    1. Florian Brinkmann

      Hi Ceylan,

      thanks for your comment, great to hear that my posts are useful 🙂

      To your question: Do I understand it correctly, that you want to prevent the user from inserting blocks before the template blocks, but allow blocks after the template? If that is correct, I do not know a way to do this, sorry.

      Best,
      Florian

      Reply
      1. ceylan

        The most important thing for me is forbid the user to insert a block before the template. For the insertion of block after the template, it is less important.

        Reply
          1. ceylan

            thanks for the answer, I had already watched Locking, but it's too restrictive. I am doing a wordpress template. I have a lot of template (custom post type etc.). For all the templates, I need to forbid the insertion before the template. Regarding insertion after, it depends on the template ...

  2. ceylan

    Thank you for the answer, I'll try this in the next few days. I have another question. Is it possible to make a template for a single page thanks to its id? Because the templates here are only possible thanks to the post type.

    Reply
      1. ceylan

        I have not found a way to do it directly, but the bottom code seems to work more or less.

        function wp4378295342_maybe_add_template() {
            if ( ! is_admin() || ! isset( $_GET['post'] ) || '1234' !== $_GET['post'] ) {
                // This is not the post/page we want to limit things to.
                return false;
            }
        
            $post_type_object = get_post_type_object( 'post' );
            $post_type_object->template = array(
                array( 'core/paragraph', array(
                    'placeholder' => 'Add Description...',
                ) ),
            );
            $post_type_object->template_lock = 'all';
        }
        add_action( 'init', 'wp4378295342_maybe_add_template' );
        Reply
  3. James

    Thanks for sharing this tutorial. Can you also please guide me how can I create a block template? I am doing the same using this resource https://wpitech.com/create-wordpress-gutenberg-block-templates/ but it’s giving an error and I am having some programming lines in front end. This is the code
    add_action( ‘init’, function() {
    $args = array(
    ‘public’ => true,
    ‘label’ => ‘News’,
    ‘show_in_rest’ => true,
    ‘template_lock’ => ‘all’,
    ‘template’ => array(
    array( ‘core/paragraph’, array(
    ‘placeholder’ => ‘Breaking News’,

    Reply

Leave a Comment

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