I'm starting to develop a WordPress theme using Gutenberg. I've never worked with Gutenberg before, but since the support for Classic Editor might possibly end next year, I want to use it now since I don't want to rebuild the same site for the client again next year. I'm using Sage 10.

I've got the idea of how to build blocks (with ACF Pro or natively), but what confuses me is the theme structure/template hierarchy.

I've read all the documentation here: https://developer.wordpress.org/block-editor/how-to-guides/themes/.

But the structure with folders block-templates and block-template-parts is very confusing to me. There's no PHP and only HTML files. I don't see any files from the classic Template Hierarchy.

Basically, what I want to achieve is this: create templates for posts, CPT, and custom templates. I don't want the user to edit the blocks' order, I just want them to edit the content, nothing more. I want the content editor to choose a Template and then the blocks of that template are shown and he can edit them, just like the classic way.

I saw that you can do something like this where you can register a template and lock the blocks list, but I can't find a similar way for custom templates.

So, my questions are these:

  1. Is there a way to build a custom template with registered blocks and lock them, so when the editor chooses that template, he can only edit the block's content? What is the recommended way?
  2. Is there a template hierarchy in Gutenberg themes? What are block-templates and block-templates-parts?
  • You would still create templates the way you did in the past - at present the Gutenberg blocks are being exclusively loaded into the_content(). (Well, now also in Widgets.) I have never seen blocks being locked into templates and while I'm sure it's possible, I don't imagine it would be a simple process. (I may be wrong.) Block Templates and Block Template parts are just segmentations the way that templates and template parts are. For example, let's say you use a Block Template part in more than one Block Template, instead of duplicating the code, you'd just reference the template part. Commented Sep 21, 2021 at 14:49

1 Answer 1


There are technically two ways to build themes now. One is the old standard way, where you have PHP templates (that follow the traditional template hierarchy). The other is block based themes that use blocks for everything.

My recommendation is to stick with traditional for now. Full Site Editing, which is part of the block based theme work is still in its infancy and you can still use the Gutenberg editor with the old template method. I do this exclusively in my work.

What I typically do is include a blocks folder inside my theme that in turn has my package.json file. This is where I put all my Gutenberg specific theme stuff. So I'll have a sub folder (in blocks/src/) for blocks, plugins, block-styles, etc. I'll then add all the necessary JS to make all those blocks and plugins. Then, for templating, I use the standard .php template files (e.g. archive-post_type.php, single.php, etc.).

When registering a custom post type, you can specify a default "template" of blocks:

register_post_type('post_type_slug', array(
    // ...
    'show_in_rest' => true, // Make sure to include this so it loads the Gutenberg editor
    'template' => array(
        array('core/heading', array(
            'level' => 2)

You can also lock the templates if you want. See template_lock for your options.

I've written some other answers on SO for things like how to get and set custom post meta using Gutenberg, and general best practices I use when working with custom post types in Gutenberg. I'd suggesting checking those out as well.

  • Thanks for your insightful answer, and yes, I really like this way of adding blocks on an array for a template. My question though is: what about the case of custom templates? I want the user to create a page, choose a template, and then these chosen blocks by me are shown. Is there a similar way like CPT but for custom templates? How is your solution to this problem?
    – eripanci
    Commented Sep 16, 2021 at 7:21
  • I haven't done anything quite like that in my own work, but you could use useSelect to get the template (const template = useSelect((select) => select('core/editor').getEditedPostAttribute('template'));) then createBlock to insert whatever blocks you want (useDispatch('core/block-editor').insertBlocks(createBlock('core/heading'));). The one thing you'll want to consider is what to do with existing content if the user changes templates.
    – Phil
    Commented Sep 16, 2021 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.