Since WordPress 5.0, Gutenberg is the new default editor for content creators. The idea of ‘blocks’ is the main concept behind the new editor. They are components that can be used to add desired functionality to the content in easily manageable sections.
Gutenberg editor supports customized templates with pre-populated blocks, which will help you suggest what type of content should be expected in a post, page or custom post type.
In a previous article, we have shown you how to register a custom post type by creating a plugin. Now you will learn how to add a block template to it.
<?php
/*
Plugin Name: My Custom Post Types & Templates
Description: Add custom post types and templates
Author: Open4Tech
*/
function open4tech_custom_types() {
register_post_type( 'books', // The name of the custom post type
array(
'labels' => array(
'name' => __( 'Books' ), // A plural descriptive name for the post type
'singular_name' => __( 'Book' ) // Name for one object of this post type
),
'public' => true, // Controls how the type is visible to authors and readers
'show_in_rest' => true, // Enables REST API for Gutenberg
'template_lock' => 'all', // Prevents all operations like inserting, moving and removing blocks
'template' => array(
array( 'core/heading', array( 'level' => '2', 'content' => 'Introduction' ) ),
array( 'core/paragraph' ),
array( 'core/heading', array( 'level' => '2', 'content' => 'Analysis & Evaluation' ) ),
array( 'core/columns', array(), array(
array( 'core/column', array(), array(
array( 'core/image', array() ),
) ),
array( 'core/column', array(), array(
array( 'core/paragraph' , array(
'placeholder' => 'Information about the contents of the novel'
) ),
) ),
) ),
array( 'core/paragraph' , array(
'placeholder' => 'Present opinions about the book'
) ),
array( 'core/heading', array( 'level' => '2', 'content' => 'Conclusion' ) ),
array( 'core/paragraph' )
)
)
);
}
add_action( 'init', 'open4tech_custom_types' );
In this example, we add a block template when we register a custom post type “Books”. The template is declared as an array of block types (block name and optional attributes). Some blocks, like the container ones (columns blocks for example), also support nested templates.
As a result, the template will look like this:

A great feature is the ability to lock the template so that no additional blocks can be added or existing ones removed. This makes controlling the content structure easy and is achieved using the template_lock argument. It has two options – ‘all’, which prevents all operations (like the one that we used in the example above), and ‘insert’, which allows only moving (rearranging) of the existing blocks.
Of course, a template can be added to an existing post type (not only when declaring one). In the example below, we will add it to the ‘post’ type.
function open4tech_post_block_template() {
$post_type_object = get_post_type_object( 'post' ); // Post type to which we will add template
$post_type_object->template = array(
array( 'core/heading', array( 'level' => '2') ),
array( 'core/columns', array(), array(
array( 'core/column', array(), array(
array( 'core/image', array() ),
) ),
array( 'core/column', array(), array(
array( 'core/paragraph' ),
) ),
) ),
array( 'core/paragraph' )
);
}
add_action( 'init', 'open4tech_post_block_template' );

Notes:
- Currently, a comprehensive overview of the core block types and their attributes has not been written, because they are constantly changing. Use the following code in the browser console after all the Gutenberg scripts have been loaded (e.g. in the editor window of a post) to show all currently registered blocks, including their attributes.
console.log(wp.blocks.getBlockTypes());
- When you add a new template, it will apply only to the new posts (pages), not to the existing (older) ones.
- The argument ‘show_in_rest’ must be set to true or the Gutenberg editor will not be applied to custom post types and they will still use the classic editor.
- Function ‘register_post_type’ should only be invoked through the ‘init’ action because it may work incorrectly if called before or later.
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’,