How to Add Block Templates to Your WordPress Theme or Plugin

While working on my Gutenberg Development Course, one of the hardest things I found to research was how to add block templates to your WordPress theme or plugin.

Example of a block template with and image and paragraph block
Example of a simple template with image and paragraph block

Block templates are a way to have certain blocks show up by default for a new post, page or custom post type.  You can also “lock” the template to prevent users from adding or removing blocks.


How Block Templates Work

Templates are added as a parameter when registering a post type in WordPress.  Sometimes this is done for your own custom post type.  But it can also be done for existing and native post types like Posts and Pages.

The block template setting itself is an array of blocks that you want included.  There is also an additional setting called “template_lock” that can be set to true or false to lock down the template to users.

You can also add additional configurations like custom placeholder text for blocks or set the alignment.

An Example of Block Templates

You can add the code below to any plugin or theme to modify template setting for post types of your choice.

function mytheme_block_templates( $args, $post_type ) {
// Only add template to 'post' post type
// Change for your post type: eg 'page', 'event', 'product'
if ( 'post' == $post_type ) {
// Optionally lock templates from further changes
// Change to 'insert' to allow adding other blocks, but lock defined blocks
$args['template_lock'] = 'all';
// Set the template
$args['template'] = [
// Example of including a core image block
// Optional alignment setting
'core/image', [
'align' => 'left',
// Example of including a core paragraph block
// Optional alignment placeholder setting
'core/paragraph', [
'placeholder' => 'The only thing you can add',
'align' => 'right',
// Example of including a custom block
// Optional placeholder setting
'custom/your-blocks', [
'placeholder' => 'Custom placeholder',
return $args;
// Hook function into post type arguments filter
add_filter( 'register_post_type_args', 'mytheme_block_templates', 20, 2 );

Some notes on this code:

  • Notice the conditional statement determining what post type to apply this to.  Can change for your own needs.
  • The template_lock argument determines whether users can add or remove blocks with this post type.
  • The name used for blocks is the name used when creating them.  See a list here of all default blocks, which you can use to lookup (or guess) the programatic name for a block.
  • You can add additional configurations like placeholder text, alignment, or other block attributes you want set by default.

Learn More About Gutenberg Development

To learn more about developing with blocks in WordPress, please check out my course Gutenberg Development Course.

16 thoughts on “How to Add Block Templates to Your WordPress Theme or Plugin

  1. Hi Zac,

    I am using a python function to write directly to my blog, but for some reason the block templates only load when I add a new post manually.

    Could it be because of the filter ‘register_post_type_args’ ?

    If so, how could I change it so the templates always load ?

    Thanks a lot for the tutorial,


    1. Hmm, actually I’m not sure exactly how to do that but there was a discussion about template parts in block plugins in the JavaScript for WordPress #Gutenberg Slack channel you might want to checkout


    1. You would just add some conditional PHP to only add the template if the current page ID is the ID you’re looking for. Haven’t tested this but it should work.


  2. Hi Zac, thanks for this. One thing I’m spinning my wheels on though – how to specify non-core blocks? If the core image block is ‘core/image’ how do I find out the equivalent for (say) Atomic Blocks or other plugin/custom blocks? I’ve hunted through endless help pages, codex etc and can’t find it anywhere. Thanks!


    1. You either need to find their source code so you can look it up or ask the plugin.

      The data API covered in my Advanced Gutenberg Course also shows how to get all registered block names with JavaScript but that is a but more complex.


      1. Thanks Zac — yes, I had a look through their source code, but there’s quite a lot of it, and i didn’t know where to look 😦 I did found a script that was supposed to do that (might even have been yours – I think it was on StackExchange) but I couldn’t get it to work… sigh…

        Meanwhile Atomic Blocks did get back to me quite quickly… with the registered name of that one block… but no help on how to find out the names of the others.

        Since Gutenberg, instead of just messing with php (which I rather like), I fear I’m going to have to finally get my head properly around js (which I hate), to be able to hack anything usefully. In general, it all feels a bit polarising — a bit like electronics from the 1970s to now — great new functionality, but all the mechanism disappearing into impenetrable black boxes that it’s unwise to mess with unless you’re a serious developer…


    2. The way I’ve been making templates is to add the blocks I want in the template, customise them as neccessary, and then switch to code editor view which shows all the block names and their properties.

      For an Atomic button, it might look something like this:



      The properties are within the braces, so the above would be declared like this in the template array:

      array(‘atomic-blocks/ab-button’, array(
      ‘buttonShape’ => ‘ab-button-shape-circular’,
      ‘buttonBackgroundColor’ => ‘#8c00a3’,
      ‘buttonSize’ => ‘ab-button-size-large’,

      If there are better ways of doing it, I’d love to know how.


  3. Minor tweak to your code above – I just discovered that template_lock => ‘insert’ does not allow insertion of additional blocks. From the Gutenberg Handbook, there are only two options:


    all — prevents all operations. It is not possible to insert new blocks, move existing blocks, or delete blocks.
    insert — prevents inserting or removing blocks, but allows moving existing blocks.

    Even ‘insert’ seems excessively restrictive to me. As soon as that’s set, the user can’t even start a new paragraph!

    Unless I’m missing something, the only way I can see to create a nested template that the user can create in but not break is by installing something quite heavy duty like Matt Watson’s plugin ‘Secure Blocks for Gutenberg’ which is way OTT for my purpose. Anway, hope the above is useful.


  4. 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 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’,


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s