Title: Registering block templates via plugins in WordPress 6.7
Author: Justin Tadlock
Published: August 29, 2024
Last modified: October 15, 2024

---

 * [Showcase](https://wordpress.org/showcase/)
 * [Plugins](https://wordpress.org/plugins/)
 * [Themes](https://wordpress.org/themes/)
 * [Hosting](https://wordpress.org/hosting/)
 * [News](https://wordpress.org/news/)
    - [Learn WordPress](https://learn.wordpress.org/)
    - [Documentation](https://wordpress.org/documentation/)
    - [Education](https://wordpress.org/education/)
    - [Forums](https://wordpress.org/support/forums/)
    - [Developers](https://developer.wordpress.org/)
    - [Blocks](https://wordpress.org/blocks/)
    - [Patterns](https://wordpress.org/patterns/)
    - [Photos](https://wordpress.org/photos/)
    - [Openverse ︎](https://openverse.org/)
    - [WordPress.tv ︎](https://wordpress.tv/)
 *  - [About WordPress](https://wordpress.org/about/)
    - [Make WordPress](https://make.wordpress.org/)
    - [Events](https://events.wordpress.org/)
    - [Five for the Future](https://wordpress.org/five-for-the-future/)
    - [Enterprise](https://wordpress.org/enterprise/)
    - [Gutenberg ︎](https://wordpress.org/gutenberg/)
    - [Job Board ︎](https://jobs.wordpress.net/)
 * [Swag ︎](https://mercantile.wordpress.org/)
 * [Get WordPress](https://wordpress.org/download/)

Search in WordPress.org

 [ Get WordPress ](https://wordpress.org/download/)

[WordPress Developer Blog](https://developer.wordpress.org/news)

Registering block templates via plugins in WordPress 6.7

 * [Snippets](https://developer.wordpress.org/news/snippets/)
    - [Blocks](https://developer.wordpress.org/news/category/blocks/)
    - [Concepts](https://developer.wordpress.org/news/category/concepts/)
    - [Common APIs](https://developer.wordpress.org/news/category/common-apis/)
    - [Design](https://developer.wordpress.org/news/category/design/)
    - [Playground](https://developer.wordpress.org/news/category/playground/)
    - [Plugins](https://developer.wordpress.org/news/category/plugins/)
    - [Themes](https://developer.wordpress.org/news/category/themes/)
 *  - [About this site](https://developer.wordpress.org/news/about/)
    - [Updates](https://developer.wordpress.org/news/category/updates/)
    - [How to contribute](https://developer.wordpress.org/news/how-to-contribute/)
    - [Tips and guidelines](https://developer.wordpress.org/news/tips-and-guidelines-for-writers/)
 * [Subscribe](https://developer.wordpress.org/news/subscribe/)
 * [Developer Resources](https://developer.wordpress.org/)

 * [Snippets](https://developer.wordpress.org/news/snippets/)
    - [Blocks](https://developer.wordpress.org/news/category/blocks/)
    - [Concepts](https://developer.wordpress.org/news/category/concepts/)
    - [Common APIs](https://developer.wordpress.org/news/category/common-apis/)
    - [Design](https://developer.wordpress.org/news/category/design/)
    - [Playground](https://developer.wordpress.org/news/category/playground/)
    - [Plugins](https://developer.wordpress.org/news/category/plugins/)
    - [Themes](https://developer.wordpress.org/news/category/themes/)
 *  - [About this site](https://developer.wordpress.org/news/about/)
    - [Updates](https://developer.wordpress.org/news/category/updates/)
    - [How to contribute](https://developer.wordpress.org/news/how-to-contribute/)
    - [Tips and guidelines](https://developer.wordpress.org/news/tips-and-guidelines-for-writers/)
 * [Subscribe](https://developer.wordpress.org/news/subscribe/)
 * [Developer Resources](https://developer.wordpress.org/)

# Registering block templates via plugins in WordPress 6.7

By [Justin Tadlock](https://profiles.wordpress.org/greenshady/)

August 29, 2024

[Plugins](https://developer.wordpress.org/news/category/plugins/)

WordPress 6.7 development is moving along, and one of the biggest features of the
release has now landed in the Gutenberg plugin: [block templates via plugins](https://github.com/WordPress/gutenberg/pull/61577).

If you’ve ever built a plugin with front-end template output, you know how difficult
it can be to play nicely with themes while also attempting to output content generated
by your plugin. This is especially common when building custom post types, custom
taxonomies, or even virtual pages (i.e., custom URLs). And it’s been an issue for
well over a decade with no standard Core solution for addressing it. 

As of [Gutenberg 19.1](https://make.wordpress.org/core/2024/08/28/whats-new-in-gutenberg-19-1-28-august/),
which will eventually be merged into WordPress 6.7, you can begin registering block
templates and defining default content for your plugins. Because it’s all built 
on top of the block system, both themes and users can customize the template.

In this tutorial, I will walk you through the basics of registering block templates
from plugins, show you how to overwrite them via themes, and share some tips and
tricks along the way.

It’s important to remember that we are still in the midst of the WordPress 6.7 development
cycle. Anything could change with the methods shared in this tutorial at any time.
I will update any information that changes throughout the release cycle.

**Update:** The new functions mentioned in this article have been [updated to remove](https://github.com/WordPress/gutenberg/pull/65958)
the `wp_` prefix. Gutenberg 19.5 and WordPress 6.7 will not include this prefix.
The new functions will be named `register_block_template()` and `unregister_block_template()`.

Table of Contents

 1. [Requirements and setup](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#requirements-and-setup)
 2. [The basics of template registration](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#the-basics-of-template-registration)
 3.  a. [Registering a template with content](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#registering-a-template-with-content)
     b. [Pro tip: cleaner template block markup](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#pro-tip-cleaner-template-block-markup)
     c. [How to unregister a template](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#how-to-unregister-a-template)
     d. [How plugin block templates work with themes and user customizations](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#how-plugin-block-templates-work-with-themes-and-user-customizations)
 4. [Registering custom post, page, and CPT templates](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#registering-custom-post-page-and-cpt-templates)
 5.  a. [Creating a single template](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#creating-a-single-template)
     b. [Creating a custom template](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#creating-a-custom-template)
     c. [Registering an archive template](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#registering-an-archive-template)
     d. [Upgrading the user experience](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#upgrading-the-user-experience)
 6. [Building templates for virtual pages](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#building-templates-for-virtual-pages)
 7.  a. [Registering an entirely custom template](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#registering-an-entirely-custom-template)
     b. [Using the template on the front end](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#using-the-template-on-the-front-end)
     c. [Overwriting the template from a theme](https://developer.wordpress.org/news/2024/08/29/registering-block-templates-via-plugins-in-wordpress-6-7/#overwriting-the-template-from-a-theme)

## Requirements and setup

To test this new feature, you must be running the following in your development 
environment:

 * Gutenberg 19.1+
 * WordPress 6.6+ (preferably testing against trunk)

Let’s also go ahead and set up a test plugin for this tutorial. Create a new `devblog-
plugin-templates` folder in your WordPress `/plugins` directory. Then add a `plugin.
php` file within that folder with this code:

    ```php
    <?php
    /**
     * Plugin Name:       Developer Blog: Plugin Templates
     * Description:       Example code for registering plugin block templates with WordPress 6.7+.
     * Version:           1.0.0
     * Requires at least: 6.6
     * Requires PHP:      7.4
     * Requires Plugins:  gutenberg
     * Text Domain:       devblog-plugin-templates
     */

    add_action( 'init', 'devblog_register_plugin_templates' );

    function devblog_register_plugin_templates() {
    	// Add calls to register_block_template() here.
    }
    ```

Go ahead and activate this plugin.

You’ll notice that there’s a `devblog_register_plugin_templates()` function hooked
to `init` in the code. You will use this throughout the tutorial to register your
block templates.

## The basics of template registration

WordPress 6.7 will include a `register_block_template()` function, which lets you
add a new template to the Site Editor:

    ```php
    register_block_template( string $template_name, $args = array() )
    ```

The function accepts two parameters, which let you define how your template is registered:

 * **`$template_name`:** The name of the template in the form of `plugin_uri//template_name`(
   note that this requires a double `//`). `plugin_uri` should match the folder 
   name of your plugin.
 * **`$args`:** An array of arguments for defining the template:
    - **`title`:** An internationalized title for the template.
    - **`description`:** An internationalized description of the template.
    - **`content`:** The default content (block markup) for the template when rendered
      in the editor or on the front end.
    - **`post_types`:** An array of post type slugs to make available to users as
      per-post custom templates.

As of Gutenberg 19.1, it is technically possible to use any string for the `plugin_uri`
half of the `$template_name` parameter, and it will appear in the UI. But it won’t
be tied to any particular plugin. There is an open [ticket to restrict registration](https://github.com/WordPress/gutenberg/issues/64754)
to active plugins.

Let’s try registering a basic template named Example. Add this code inside your `
devblog_register_plugin_templates()` function in `plugin.php`:

    ```php
    register_block_template( 'devblog-plugin-templates//example', [
    	'title'       => __( 'Example', 'devblog-plugin-templates' ),
    	'description' => __( 'An example block template from a plugin.', 'devblog-plugin-templates' )
    ] );
    ```

Now go to **Appearance > Editor > Templates** in your WordPress admin. You should
see a brand new menu item with your plugin’s name (**Developer Blog: Plugin Templates**
in this case). On click, you will see the template you just registered:

![Templates screen in the WordPress Site Editor. A plugin panel is open that shows
a single empty template.](https://developer.wordpress.org/news/files/2024/08/plugin-
template-empty.webp)

You’ll notice that WordPress displays the **Empty template** text in this case because
you haven’t (yet) defined any content for it.

`register_block_template()` is a plugin-specific function and is not meant to be
used from within a theme at this time. Technically, it’s possible to “register” 
a custom template by putting any template file in your theme’s `/templates` folder,
but you can’t use the `register_block_template()` to add a title and description.
Instead, you’d need to filter [`default_template_types`](https://developer.wordpress.org/reference/hooks/default_template_types/).

### Registering a template with content

Let’s take this one step further and add some default content to the template. You
do this by adding some block markup to the `content` argument. Change your code 
so that it looks like this:

    ```php
    register_block_template( 'devblog-plugin-templates//example', [
    	'title'       => __( 'Example', 'devblog-plugin-templates' ),
    	'description' => __( 'An example block template from a plugin.', 'devblog-plugin-templates' ),
    	'content'     => '
    		<!-- wp:template-part {"slug":"header","area":"header","tagName":"header"} /-->
    		<!-- wp:group {"tagName":"main"} -->
    		<main class="wp-block-group">
    			<!-- wp:group {"layout":{"type":"constrained"}} -->
    			<div class="wp-block-group">
    				<!-- wp:paragraph -->
    				<p>This is a plugin-registered template.</p>
    				<!-- /wp:paragraph -->
    			</div>
    			<!-- /wp:group -->
    		</main>
    		<!-- /wp:group -->
    		<!-- wp:template-part {"slug":"footer","area":"footer","tagName":"footer"} /-->'
    ] );
    ```

You’ll notice that I kept this relatively simple with calls to the Header and Footer
template parts, some wrapping Group blocks, and a Paragraph block. The basic markup
was copied from the Twenty Twenty-Four theme.

In general, it would be good practice to copy any wrapping markup from the most 
current default theme for your plugin templates, which will make it the most compatible
with many other themes. This is because many theme authors use the default themes
as a starting point.
Because it’s all block markup, you can technically use anything,
and it’ll work with any block theme without errors. But it will likely not fit perfectly
into every theme’s design.

If you refresh the **Templates** screen, you should see your changes reflected in
the template preview:

![Templates screen in the WordPress Site Editor. A plugin panel is open that shows
a single template with demo content.](https://developer.wordpress.org/news/files/
2024/08/plugin-template-example-content.webp)

Of course, this template is completely customizable by the user, just like any other
template.

### Pro tip: cleaner template block markup

I’m not a fan of assigning block markup (HTML) to parameters in a PHP function. 
You lose things like syntax highlighting in your code editor, and it mostly just
makes perfectly readable code look messy. It’d be better to add template markup 
to individual files.

To address this issue, I created a custom function for grabbing the content of a
template file. We’ll use this function throughout the rest of the tutorial to keep
code clean, so go ahead and add this to your `plugin.php` file:

    ```php
    function devblog_get_template_content( $template ) {
    	ob_start();
    	include __DIR__ . "/templates/{$template}";
    	return ob_get_clean();
    }
    ```

You can use this function to get the content of a template file and assign it to
the `content` argument instead. 

Before you do that, create a new `/templates` folder and add an `example.php` template
file with your block markup:

    ```php
    <!-- wp:template-part {"slug":"header","area":"header","tagName":"header"} /-->

    <!-- wp:group {"tagName":"main"} -->
    <main class="wp-block-group">

    	<!-- wp:group {"layout":{"type":"constrained"}} -->
    	<div class="wp-block-group">

    		<!-- wp:paragraph -->
    		<p><?php esc_html_e( 'This is a plugin-registered template.', 'devblog-plugin-templates' ); ?></p>
    		<!-- /wp:paragraph -->

    	</div>
    	<!-- /wp:group -->

    </main>
    <!-- /wp:group -->

    <!-- wp:template-part {"slug":"footer","area":"footer","tagName":"footer"} /-->
    ```

Now update your original `register_block_template()` call to use this new function,
grabbing the block markup from `/templates/example.php`:

    ```php
    register_block_template( 'devblog-plugin-templates//example', [
    	'title'       => __( 'Example', 'devblog-plugin-templates' ),
    	'description' => __( 'An example block template from a plugin.', 'devblog-plugin-templates' ),
    	'content'     => devblog_get_template_content( 'example.php' )
    ] );
    ```

### How to unregister a template

WordPress will also introduce a new `unregister_block_template()` function for—you
guessed it—unregistering block templates. Try dropping this line into your `devblog_register_plugin_templates()`
function **_after_** your call for registering the Example template:

    ```php
    unregister_block_template( 'devblog-plugin-templates//example' );
    ```

The function takes a single parameter of `$template_name`. This parameter must include
both the plugin URI and template slug, separated by a double slash, as it was originally
registered.

`unregister_block_template()` can be called to unregister any plugin-registered 
template. But it cannot be used to unregister templates added by themes or users.

### How plugin block templates work with themes and user customizations

As with any other block templates, users can edit them directly from the **Appearance
> Editor > Templates** screen in the WordPress admin. This will give them more direct
control than ever over their sites, and they can customize using an interface that
they are already familiar with.

Because WordPress is introducing a standard method of registering templates, it 
means that plugins and themes will be able to integrate much easier than ever before.
Even when a theme doesn’t specifically add template support for your plugin, you
can still ensure that it works with any block theme.

If you’re a block theme author, you have the option of overriding the plugin’s default
template content by creating your own version of the template. All you need to do
is add the template to your theme’s `/templates` folder with any block markup you
want.

For example, if you added a `/templates/example.html` template to your theme, it
will appear like so under your theme’s template list in the UI:

![Templates screen in the WordPress Site Editor. The active theme's templates are
shown in a three-column grid.](https://developer.wordpress.org/news/files/2024/08/
plugin-template-example-theme.webp)

Once a template lives within a theme, it will be under the **Templates > Theme Name**
panel in the UI and no longer be listed under the original plugin panel.

You may have also noticed that the **Example** title now shows the template name
of **example** and the description is missing when adding the template from a theme.
There is a [pull request](https://github.com/WordPress/gutenberg/issues/64576) that
will fix this in Gutenberg 19.2.

## Registering custom post, page, and CPT templates

Let’s make this tutorial more interesting and look at a real-world use case, something
that you might encounter in your day-to-day life as a WordPress developer.

Suppose that you have a plugin that registers a custom post type that lets users
share books. You need to control the default output of how these books are rendered
on the front end, particularly for themes that don’t add support for the plugin.

First, register the `book` post type by adding this code to your `plugin.php` file:

    ```php
    add_action( 'init', 'devblog_register_book_type' );

    function devblog_register_book_type() {
    	register_post_type( 'book', [
    		'public'             => true,
    		'show_in_rest'       => true,
    		'capability_type'    => 'post',
    		'has_archive'        => 'books',
    		'menu_icon'          => 'dashicons-book',
    		'supports'           => [ 'editor', 'excerpt', 'title', 'thumbnail' ],
    		'labels'             => [
    			'name'          => __( 'Books',        'devblog-plugin-templates' ),
    			'singular_name' => __( 'Book',         'devblog-plugin-templates' ),
    			'add_new'       => __( 'Add New Book', 'devblog-plugin-templates' )
    		]
    	] );
    }
    ```

This is a bare-bones version of what your actual book post type might look like,
but it provides everything needed to test out the new feature. Feel free to flesh
it out by referencing the [`register_post_type()`](https://developer.wordpress.org/reference/functions/register_post_type/)
documentation.

The above code will add a new **Books** item to the WordPress admin menu. Now add
a few quick demo posts for testing:

![Books custom post type management screen in the WordPress admin. It lists three
published book posts.](https://developer.wordpress.org/news/files/2024/08/plugin-
templates-book-cpt.webp)

When working with custom post types, it’s important to understand and work with 
the [Template Hierarchy](https://developer.wordpress.org/themes/templates/template-hierarchy/).
By using the standard template slugs, you don’t have to worry about doing any special
front-end filtering. All that is required is registering the template itself for
any templates that exist in the hierarchy.

### Creating a single template

Let’s make a [single template](https://developer.wordpress.org/themes/templates/template-hierarchy/#singular-hierarchy)
for the book post type you registered above. First, create a blank `/templates/single-
book.php` file in your plugin’s folder. Then add this block markup to it:

    ```php
    <!-- wp:template-part {"slug":"header","area":"header","tagName":"header"} /-->

    <!-- wp:group {"tagName":"main"} -->
    <main class="wp-block-group">
    	<!-- wp:group {"layout":{"type":"constrained"}} -->
    	<div class="wp-block-group">
    		<!-- wp:spacer {"height":"var:preset|spacing|50"} -->
    		<div style="height:var(--wp--preset--spacing--50)" aria-hidden="true" class="wp-block-spacer"></div>
    		<!-- /wp:spacer -->

    		<!-- wp:post-title {"textAlign":"center","level":1} /-->

    		<!-- wp:spacer {"height":"var:preset|spacing|30","style":{"spacing":{"margin":{"top":"0","bottom":"0"}}}} -->
    		<div style="margin-top:0;margin-bottom:0;height:var(--wp--preset--spacing--30)" aria-hidden="true"
    			class="wp-block-spacer"></div>
    		<!-- /wp:spacer -->

    		<!-- wp:post-featured-image {"style":{"spacing":{"margin":{"bottom":"var:preset|spacing|40"}}}} /-->
    	</div>
    	<!-- /wp:group -->

    	<!-- wp:post-content {"lock":{"move":false,"remove":true},"layout":{"type":"constrained"}} /-->
    </main>
    <!-- /wp:group -->

    <!-- wp:template-part {"slug":"footer","area":"footer","tagName":"footer"} /-->
    ```

Again, this is using basic markup copied from the Twenty Twenty-Four theme. It displays
the Post Title, Post Featured Image, and Post Content blocks. Feel free to tinker
with it and add any blocks that you want.

Now register the template as you’ve done before inside the `devblog_register_plugin_templates()`
function in your `plugin.php` file:

    ```php
    register_block_template( 'devblog-plugin-templates//single-book', [
    	'title'       => __( 'Single Book', 'devblog-plugin-templates' ),
    	'description' => __( 'Displays a single book.', 'devblog-plugin-templates' ),
    	'content'     => devblog_get_template_content( 'single-book.php' )
    ] );
    ```

Take special note of the `single-book` slug used. This is the standard template 
name for a single post of the `book` post type. Using this slug will ensure that
it works without any further effort on your part.

If you visit the **Appearance > Editor > Templates** screen in the admin, you will
see the new **Single Book** template listed under the plugin panel:

![Templates screen in the WordPress Site Editor. It lists two templates under the
active plugin's panel.](https://developer.wordpress.org/news/files/2024/08/plugin-
template-single-book.webp)

Like any other template, this can also be overwritten by a theme or customized by
users.

### Creating a custom template

Aside from the normal single template for your post type, you can also create one
or more custom templates that users can choose for a single post. Let’s create a
new “Book: Canvas” template for the `book` post type, which gives the user an open
canvas that only displays the Header, Post Content, and Footer.

Add this block markup to a new `/templates/book-canvas.php` file in your plugin:

    ```php
    <!-- wp:template-part {"slug":"header","area":"header","tagName":"header"} /-->

    <!-- wp:group {"tagName":"main","layout":{"type":"default"}} -->
    <main class="wp-block-group">

    	<!-- wp:post-content {"lock":{"move":false,"remove":true},"layout":{"type":"constrained"}} /-->

    </main>
    <!-- /wp:group -->

    <!-- wp:template-part {"slug":"footer","area":"footer","tagName":"footer"} /-->
    ```

Custom templates do not have a standard template naming convention, so I chose `
book-canvas` in this case. The rule of thumb when naming is that you can use any
name as long as it’s not a reserved name in the Template Hierarchy.

Registering custom templates also introduces the `post_types` argument for `register_block_template()`.
This argument lets you register a custom template for one or more post types, and
users will be able to select this template when writing single posts.

Register the Book: Canvas template by adding this code inside your `devblog_register_plugin_templates()`
function:

    ```php
    register_block_template( 'devblog-plugin-templates//book-canvas', [
    	'title'       => __( 'Book: Canvas', 'devblog-plugin-templates' ),
    	'description' => __( 'An open template for use with single posts. Includes the Header, Post Content, and Footer.', 'devblog-plugin-templates' ),
    	'post_types'  => [ 'book' ],
    	'content'     => devblog_get_template_content( 'book-canvas.php' )
    ] );
    ```

Like other templates, it will appear for your plugin on the **Appearance > Editor
> Templates** screen. But it will also appear in a brand new location. 

First, head over to your **Books** admin screen and choose a book to edit. Under
the **Book** panel in the sidebar, find the **Template** option and click it. From
the popup, choose **Swap template**:

![WordPress post-editing screen. In the sidebar, the Template option has been selected
and the Swap Template option is highlighted.](https://developer.wordpress.org/news/
files/2024/08/plugin-template-swap.webp)

Now, you should see a modal overlay with an option for swapping to your **Book: 
Canvas** template. If you choose it, it will be used on the front end for this book:

![Popup modal on the WordPress post-editing screen for choosing a template. A single
template option is available.](https://developer.wordpress.org/news/files/2024/08/
plugin-template-choose.webp)

### Registering an archive template

Archive output is one thing most plugins that register post types will want to handle.
Just like single templates, this is a standard template in the hierarchy.

Create a new file named `/templates/archive-book.php` in your plugin with the following
block markup in it:

    ```php
    <!-- wp:template-part {"slug":"header","area":"header","tagName":"header"} /-->

    <!-- wp:group {"tagName":"main","align":"full","layout":{"type":"constrained"}} -->
    <main class="wp-block-group alignfull">

    	<!-- wp:query-title {"type":"archive","align":"wide","style":{"typography":{"lineHeight":"1"},"spacing":{"padding":{"top":"var:preset|spacing|20"}}}} /-->

    	<!-- wp:query {"query":{"perPage":10,"pages":0,"offset":"0","postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true},"align":"wide","layout":{"type":"default"}} -->
    	<div class="wp-block-query alignwide">
    		<!-- wp:group {"style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"0","right":"0"},"margin":{"top":"0","bottom":"0"}}},"layout":{"type":"default"}} -->
    		<div class="wp-block-group" style="margin-top:0;margin-bottom:0;padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">

    			<!-- wp:post-template {"align":"full","style":{"spacing":{"blockGap":"var:preset|spacing|30"}},"layout":{"type":"grid","columnCount":3}} -->

    			<!-- wp:post-featured-image {"isLink":true,"aspectRatio":"3/4","style":{"spacing":{"margin":{"bottom":"0"},"padding":{"bottom":"var:preset|spacing|20"}}}} /-->

    			<!-- wp:group {"style":{"spacing":{"blockGap":"10px","margin":{"top":"var:preset|spacing|20"},"padding":{"top":"0"}}},"layout":{"type":"flex","orientation":"vertical","flexWrap":"nowrap"}} -->
    			<div class="wp-block-group" style="margin-top:var(--wp--preset--spacing--20);padding-top:0">
    				<!-- wp:post-title {"isLink":true,"style":{"layout":{"flexSize":"min(2.5rem, 3vw)","selfStretch":"fixed"}},"fontSize":"large"} /-->
    			</div>
    			<!-- /wp:group -->

    			<!-- /wp:post-template -->

    			<!-- wp:spacer {"height":"var:preset|spacing|40","style":{"spacing":{"margin":{"top":"0","bottom":"0"}}}} -->
    			<div style="margin-top:0;margin-bottom:0;height:var(--wp--preset--spacing--40)" aria-hidden="true" class="wp-block-spacer"></div>
    			<!-- /wp:spacer -->

    			<!-- wp:query-pagination {"paginationArrow":"arrow","layout":{"type":"flex","justifyContent":"space-between"}} -->
    			<!-- wp:query-pagination-previous /-->
    			<!-- wp:query-pagination-next /-->
    			<!-- /wp:query-pagination -->

    		</div>
    		<!-- /wp:group -->
    	</div>
    	<!-- /wp:query -->

    </main>
    <!-- /wp:group -->

    <!-- wp:template-part {"slug":"footer","area":"footer","tagName":"footer"} /-->
    ```

As earlier, this was copied and modified from the Twenty Twenty-Four theme. Feel
free to customize it to your liking.

Now register the template by adding this code to your `devblog_register_plugin_templates()`
function in your plugin:

    ```php
    register_block_template( 'devblog-plugin-templates//archive-book', [
    	'title'       => __( 'Book Archive', 'devblog-plugin-templates' ),
    	'description' => __( 'Displays an archive of all book posts.', 'devblog-plugin-templates' ),
    	'content'     => devblog_get_template_content( 'archive-book.php' )
    ] );
    ```

Again, pay attention to the template slug, which is `archive-book`. This is the 
standard name recognized by WordPress in the [Archive Template Hierarchy.](https://developer.wordpress.org/themes/templates/template-hierarchy/#archive-hierarchy)

Like your other templates, **Book Archive** will now appear under your plugin’s 
panel on the **Appearance > Editor > Templates** screen. If you haven’t already 
tried, click on the template to edit it, which should look like this:

![WordPress template editing screen. It shows a Book Archive template, which lists
books and their featured images in a three-column grid.](https://developer.wordpress.
org/news/files/2024/08/plugin-template-cpt-archive.webp)

### Upgrading the user experience

The real power of plugin-registered block templates is what you can do with them
when coupled with features like Block Variations, Block Bindings, and more. As a
plugin developer, you no longer have to hack your way about in an attempt to insert
dynamic data into some unknown theme. Now, you’ll have control over exactly what’s
output (well, at least what’s output as a default).

Once you get the hang of registering your own templates, I highly recommend reading
the tutorial series that explains how to put all of these pieces together:

 * [Building a book review site with Block Bindings, part 1: Custom fields and block variations](https://developer.wordpress.org/news/2024/05/06/building-a-book-review-site-with-block-bindings-part-1-custom-fields-and-block-variations/)
 * [Building a book review site with Block Bindings, part 2: Queries, patterns, and templates](https://developer.wordpress.org/news/2024/06/06/building-a-book-review-site-with-block-bindings-part-2-queries-patterns-and-templates/)

## Building templates for virtual pages

Not all plugins register custom post types, taxonomies, or other standard object
types that are represented in the WordPress template hierarchy. There are times 
when you’re building custom URLs using the [Rewrite API](https://developer.wordpress.org/apis/rewrite/).

While building custom rewrite rules is outside the scope of this tutorial, I did
want to show a basic implementation of how to combine these types of virtual pages
with the block template system.

For the following sections, let’s suppose you want to register a template that’s
used when a site visitor lands on `yoursite.tld/?all-categories=1`, which lists 
all of a site’s categories. Of course, in a real project, you’d add a rewrite rule
for a pretty URL, but let’s keep this relatively simple for the purposes of this
demonstration.

### Registering an entirely custom template

Because WordPress doesn’t have a standard template for this scenario, the name you
use for the template doesn’t really matter (as long as it doesn’t conflict with 
standard template names). 

Create a new file named `/templates/all-categories.php` in your plugin folder with
this block markup:

    ```php
    <!-- wp:template-part {"slug":"header","area":"header","tagName":"header"} /-->

    <!-- wp:group {"tagName":"main"} -->
    <main class="wp-block-group">

    	<!-- wp:group {"layout":{"type":"constrained"}} -->
    	<div class="wp-block-group">

    		<!-- wp:spacer {"height":"var:preset|spacing|50"} -->
    		<div style="height:var(--wp--preset--spacing--50)" aria-hidden="true" class="wp-block-spacer"></div>
    		<!-- /wp:spacer -->

    		<!-- wp:heading {"level":1} -->
    		<h1 class="wp-block-heading"><?php esc_html_e( 'Categories', 'devblog-plugin-templates' ); ?></h1>
    		<!-- /wp:heading -->

    		<!-- wp:categories {"showHierarchy":true,"showPostCounts":true,"className":""} /-->

    	</div>
    	<!-- /wp:group -->

    </main>
    <!-- /wp:group -->

    <!-- wp:template-part {"slug":"footer","area":"footer","tagName":"footer"} /-->
    ```

The code calls the standard Header and Footer template parts and outputs Heading
and Categories blocks for the content area.

Now you need to make sure it’s registered with WordPress. Add this code to your `
devblog_register_plugin_templates()` function:

    ```php
    register_block_template( 'devblog-plugin-templates//all-categories', [
    	'title'       => __( 'All Categories', 'devblog-plugin-templates' ),
    	'description' => __( 'Displays a list of all categories.', 'devblog-plugin-templates' ),
    	'content'     => devblog_get_template_content( 'all-categories.php' )
    ] );
    ```

As with other templates, it will appear under your plugin’s templates list on the**
Appearance > Editor > Templates** page in the admin:

![A plugin's panel showing custom templates in a three-column grid in the Templates
screen in the Site Editor.](https://developer.wordpress.org/news/files/2024/08/plugin-
template-virtual.webp)

And as usual, this template can be customized by the user or overwritten by the 
active theme. The difference is that it’s not actually used anywhere on the front
end yet. You must tell WordPress when it should be applied.

### Using the template on the front end

When a visitor lands on `yoursite.tld/?all-categories=1`, they will not see your
plugin’s template by default. To ensure your template is used for that page, you
need to add a filter to the [`template_include`](https://developer.wordpress.org/reference/hooks/template_include/)
hook.

In particular, you’ll use two template functions to “locate” your plugin template:

 * [**`locate_template()`**](https://developer.wordpress.org/reference/functions/locate_template/)**:**
   This function attempts to find the highest-priority PHP template given a hierarchy
   of choices.
 * [**`locate_block_template()`**](https://developer.wordpress.org/reference/functions/locate_block_template/)**:**
   This function attempts to find the highest-priority block template from the list
   than the PHP template.

Add this code to your `plugin.php` file:

    ```php
    add_filter( 'template_include', 'devblog_template_include' );

    function devblog_template_include( $template ) {
    	// Return early if not viewing `?all-categories=1`.
    	if (
    		! isset( $_GET['all-categories'] )
    		|| 1 !== absint( $_GET['all-categories'] )
    	) {
    		return $template;
    	}

    	// Create a hierarchy of templates.
    	$templates = [
    		'all-categories.php',
    		'index.php'
    	];

    	// First, search for PHP templates, which block themes can also use.
    	$template = locate_template( $templates );

    	// Pass the result into the block template locator and let it figure
    	// out whether block templates are supported and this template exists.
    	$template = locate_block_template( $template, 'all-categories', $templates );

    	return $template;
    }
    ```

You’ll likely want to make some adjustments based on your specific scenario, but
make sure you change all instances of `all-categories` for custom projects.

Now you should see your template on the front end when visiting `yoursite.tld/?all-
categories=1`.

### Overwriting the template from a theme

As a theme author, one of the first things I wanted to test this with was my personal
theme. Despite using block markup copied from Twenty Twenty-Four, it worked reasonably
well:

![WordPress template editor with a custom All Categories template open.](https://
developer.wordpress.org/news/files/2024/08/plugin-template-virtual-default.webp)

It was by no means perfect, but it did give me a solid starting point for cleaning
it up to better match my theme.

So I added the following block markup to the `/templates/all-categories.html` file
in my theme. You’re welcome to try it with your own themes, but it could need further
adjustment.

    ```php
    <!-- wp:template-part {"slug":"header","className":"site-header"} /-->

    <!-- wp:group {
    	"tagName":"main",
    	"style":{
    		"spacing":{
    			"padding":{
    				"top":"var:preset|spacing|80",
    				"bottom":"var:preset|spacing|80"
    			}
    		}
    	},
    	"layout":{"type":"default"}
    } -->
    <main class="wp-block-group" style="padding-top:var(--wp--preset--spacing--80);padding-bottom:var(--wp--preset--spacing--80)">

    	<!-- wp:group {
    		"tagName":"article",
    		"layout":{"type":"default"}
    	} -->
    	<article class="wp-block-group">

    		<!-- wp:group {
    			"tagName":"header",
    			"style":{
    				"spacing":{
    					"blockGap":"var:preset|spacing|base"
    				}
    			},
    			"layout":{"type":"constrained"}
    		} -->
    		<header class="wp-block-group">
    			<!-- wp:heading {"level":1} -->
    			<h1 class="wp-block-heading">Categories</h1>
    			<!-- /wp:heading -->
    		</header>
    		<!-- /wp:group -->

    		<!-- wp:group {"layout":{"type":"constrained"}} -->
    		<div class="wp-block-group">

    			<!-- wp:categories {
    				"showPostCounts":true,
    				"className":"is-style-spread"
    			} /-->

    		</div>
    		<!-- /wp:group -->

    	</article>
    	<!-- /wp:group -->

    </main>
    <!-- /wp:group -->

    <!-- wp:template-part {"slug":"footer","className":"site-footer"} /-->
    ```

The theme-adjusted version of the template came out a little prettier:

![WordPress template editor with a custom All Categories template open.](https://
developer.wordpress.org/news/files/2024/08/plugin-template-virtual-theme.webp)

I realize this is an overly simplistic example of what’s possible, but I wanted 
to illustrate that plugins with front-end output can play nicely with themes within
this system. 

This feature is a huge step toward solving a decade-plus problem for WordPress extenders.
And I’m eager to start using it in real-world projects.

_Props to [@aljullu](https://profiles.wordpress.org/aljullu/), [@ndiego](https://profiles.wordpress.org/ndiego/),
and [@bph](https://profiles.wordpress.org/bph/) for feedback and review on this 
post._

**Share the post: **

**Categories:** [Plugins](https://developer.wordpress.org/news/category/plugins/)

**Tags:** [Template Hierarchy](https://developer.wordpress.org/news/tag/template-hierarchy/),
[Templates](https://developer.wordpress.org/news/tag/templates/)

## 19 responses to “Registering block templates via plugins in WordPress 6.7”

 1.  ![codersantosh Avatar](https://secure.gravatar.com/avatar/1c52f91d9bddedf340dafdafbb59d4b803c13a1f5573e5be74557b6b4c646004?
     s=40&d=identicon&r=g)
 2.  [codersantosh](https://profiles.wordpress.org/codersantosh/)
 3.  [August 29, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-10695)
 4.  Hi, I really enjoyed this tutorial—thank you! As a plugin developer, I’ve been
     eagerly anticipating features like these. The `wp_register_block_template` function
     could address many template-related challenges. I’m also curious if a similar 
     approach, using folders like ‘templates’ and ‘patterns’, could be applied to plugins
     for registering templates and patterns, similar to how it works for themes.
 5.  [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=10695#respond)
 6.   a. ![Justin Tadlock Avatar](https://secure.gravatar.com/avatar/8013a62d7397c006bae48b96d6832a573ea71a7d5d3597fe584210567b508c05?
         s=40&d=identicon&r=g)
      b. [Justin Tadlock](https://profiles.wordpress.org/greenshady/)
      c. [August 29, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-10696)
      d. I think that’s something that could be considered for future iterations. Templates
         would be tougher because there’s currently no mechanism for creating the title
         and description for “folder-registered” templates (this is part of the reason
         themes still need to filter `default_template_types`). That’d need to be in place
         first.
      e. I don’t see any reason it wouldn’t be possible to create an API for registering
         template and pattern “locations” for auto-registration.
      f. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=10696#respond)
      g.  a. ![codersantosh Avatar](https://secure.gravatar.com/avatar/1c52f91d9bddedf340dafdafbb59d4b803c13a1f5573e5be74557b6b4c646004?
             s=40&d=identicon&r=g)
          b. [codersantosh](https://profiles.wordpress.org/codersantosh/)
          c. [September 21, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-12202)
          d. Thank you for your positive feedback! I’ve written code for the [automatic registration of patterns within the “patterns” folder for active plugins](https://gist.github.com/codersantosh/d1740e1fb832df684601aab2e0451786),
             similar to how it works for themes:
              This could be a starting point if the core
             team agrees to implement automatic plugin pattern registration.
          e. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=12202#respond)
 7.  ![Aslam Doctor Avatar](https://secure.gravatar.com/avatar/ee57886265f56405752c1096ca7b84eb0de8c69850c7561bdf4f293dec5950f0?
     s=40&d=identicon&r=g)
 8.  Aslam Doctor
 9.  [September 1, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-10829)
 10. Awesome tutorial @Justin. This feature is definitely going to be a game changer.
 11. Just a note if someone is trying to experiment with this feature before 6.7 release,
     make sure to
      1. Install “WordPress Beta Tester” plugin and then upgrade WP version
     to 6.6.2+ 2. Install “Gutenberg” plugin. Should be version 19.1.0+
 12. Thank you.
 13. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=10829#respond)
 14. ![Samuel Wood (Otto) Avatar](https://secure.gravatar.com/avatar/250257111d1248c34046552bbcdf6999949ef56b2f992dd5eb39bf45cabeb18a?
     s=40&d=identicon&r=g)
 15. [Samuel Wood (Otto)](https://profiles.wordpress.org/otto42/)
 16. [September 1, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-10966)
 17. For your devblog_get_template_content function, wouldn’t it be easier to use file_get_contents?
 18. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=10966#respond)
 19.  a. ![Justin Tadlock Avatar](https://secure.gravatar.com/avatar/8013a62d7397c006bae48b96d6832a573ea71a7d5d3597fe584210567b508c05?
         s=40&d=identicon&r=g)
      b. [Justin Tadlock](https://profiles.wordpress.org/greenshady/)
      c. [September 1, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-11022)
      d. If the templates are plain HTML, that’d be the route I’d go. But the templates
         have PHP for internationalizing text strings that needs to be interpreted. In
         a more ideal scenario, I’d probably put any PHP inside of a pattern or custom
         block instead.
      e. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=11022#respond)
      f.  a. ![Marshall kim Avatar](https://secure.gravatar.com/avatar/0d3d3505e09c6e55942f09976377eb537b2e0d18c9e7545e36ad62ec601a7d14?
             s=40&d=identicon&r=g)
          b. [Marshall kim](http://www.mksalon.com)
          c. [September 3, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-11546)
          d. How can I take control my account from someone else created it for it for me
          e. He gave me correct username but incorrect password
          f. To change my password
              They send a link to his email He didn’t use my email 
             Would you please help me Thank you My email [marshallkim@mksalon.com](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/marshallkim@mksalon.com?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz--PuxmcOSK3d_uJgh_jq0lfxeK6tY7wKfqkEXKBQsKnhjE4De9G8gziqs29Sd675gbSFTgC&output_format=md)
             Website mksalon.com
          g. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=11546#respond)
          h.  a. ![Birgit Pauli-Haack Avatar](https://secure.gravatar.com/avatar/a7873a730eebbbf667e941eaefba2f3f16ee7fe49a5661507569ada7f46b94dc?
                 s=40&d=identicon&r=g)
              b. [Birgit Pauli-Haack](https://profiles.wordpress.org/bph/)
              c. [September 4, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-11619)
              d. Sorry Marshall, but on this blog, we don’t provide customer service. It seems
                 your hosting company is Network Solutions. You might need to consult their 
                 customer service to obtain access to your website.
              e. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=11619#respond)
 20. ![Mark Wilkinson Avatar](https://secure.gravatar.com/avatar/58a965bf457978ccc1ccc7bfb72e6381b2e17948b56b83d020c62fe68772ea25?
     s=40&d=identicon&r=g)
 21. [Mark Wilkinson](https://profiles.wordpress.org/wpmarkuk/)
 22. [September 4, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-11623)
 23. Thanks for detailed information on this, as usual it is well written and easy 
     to understand 👍
 24. I can’t help thinking though, that this is named incorrectly.
 25. It is named “Block templates” when it seems to me it is just WordPress (maybe 
     theme) templates.
 26. When I initially read this post title, I was thinking of templates for outputting
     blocks in WordPress, whereas this is standard WordPress templating which may or
     may not include blocks.
 27. I wonder why `wp_register_block_template` template was chosen over `wp_register_template`?
 28. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=11623#respond)
 29.  a. ![Justin Tadlock Avatar](https://secure.gravatar.com/avatar/8013a62d7397c006bae48b96d6832a573ea71a7d5d3597fe584210567b508c05?
         s=40&d=identicon&r=g)
      b. [Justin Tadlock](https://profiles.wordpress.org/greenshady/)
      c. [September 5, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-11652)
      d. It’s not a function for registering any template. It’s specifically for registering
         block templates. Templates are broken down into two types: PHP/classic and block.
         This API is specifically meant for the latter. If you try to assign something
         other than block markup for the `content` argument, it won’t work correctly.
      e. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=11652#respond)
 30. ![Guido Avatar](https://secure.gravatar.com/avatar/6d39b8d5cede59a2123551e756824be76d75405fab12f4e553be05328e9b1341?
     s=40&d=identicon&r=g)
 31. [Guido](http://guidoscialfa.com)
 32. [September 23, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-12235)
 33. Very good article as usual, thanks for that. I’ve played a bit with the new function
     and the possibilities; it wasn’t clear at the beginning we can specify the templates
     which are part of the template hierarchy and them are being overridden by the 
     theme (which is a really nice one to have).
 34. I’m not 100% sure but looks like there’s a wired issue when a template is registering
     using `//page` and it is affecting only the Editor view. Basically trying to access
     the Swap Template but doing nothing results in the block template being applied.
 35. Link: [https://github.com/WordPress/gutenberg/issues/65584](https://github.com/WordPress/gutenberg/issues/65584)
 36. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=12235#respond)
 37. ![Kathy Avatar](https://secure.gravatar.com/avatar/d4015f6437cf56ccff9d0beb2085f38f94e240969384f8301a540d3eee6d33d4?
     s=40&d=identicon&r=g)
 38. [Kathy](http://www.backcourt.io)
 39. [October 24, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-13072)
 40. Very thorough tutorial. Is it possible yet to register a template _part_? ie, 
     a section that might get rendered in another template? (Like the header and footer
     are)
 41. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=13072#respond)
 42.  a. ![Justin Tadlock Avatar](https://secure.gravatar.com/avatar/8013a62d7397c006bae48b96d6832a573ea71a7d5d3597fe584210567b508c05?
         s=40&d=identicon&r=g)
      b. [Justin Tadlock](https://profiles.wordpress.org/greenshady/)
      c. [October 24, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-13073)
      d. Not yet. The API was intentionally left to just top-level templates for this 
         release. I’d lean more toward using patterns at the moment to fill the need for
         part support. Of course, that doesn’t work for every use case.
      e. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=13073#respond)
 43. ![Simon Griffiths Avatar](https://secure.gravatar.com/avatar/c42aad41a862554bc66c9882974fdf17f1960b175c951dbb889cfee064476112?
     s=40&d=identicon&r=g)
 44. Simon Griffiths
 45. [November 13, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-13666)
 46. Yes, a nice article. Sadly it’s still no Advanced Custom Fields though. Sorry,
     this is not a political comment, just that you are obviously starting from a different
     perspective. My preference is to use ACF so that a customer can easily make changes
     later, this needs a level of technical knowledge that a typical customer doesn’t
     have. I’m sure this method is more efficient though. A genuine WordPress native
     alternative to ACF would be great however.
 47. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=13666#respond)
 48. ![Alexandre Buffet Avatar](https://secure.gravatar.com/avatar/7007f60de2e47db5e704b38ea6da6c7a37450098ae8198144e08550c47527ae1?
     s=40&d=identicon&r=g)
 49. [Alexandre Buffet](https://profiles.wordpress.org/alexandrebuffet/)
 50. [November 20, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-13881)
 51. Thanks for this tutorial!
 52. After several days of using this new API, I’ve noticed that I can’t register a
     template for a CPT that has underscore “_” in its key, it displays the error “
     Template names must contain a namespace prefix. Example: my-plugin//my-custom-
     template”.
 53. Is there any particular reason for this, or is it a (known) issue?
 54. For example, I have a plugin that declares a CPT “school_course” and if I declare
     its associated templates “my-plugin//archive-school_course” and/or “my-plugin//
     single-school_course” I get the error.
 55. This error seems to be displayed because the test on the template name via the
     REGEX ‘/^[a-z0-9-]+\/\/[a-z0-9-]+$/’ returns false in register method from WP_Block_Templates_Registry
     class.
 56. If this is an issue, is there any way to bypass by filtering template_include 
     for now?
 57. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=13881#respond)
 58.  a. ![Justin Tadlock Avatar](https://secure.gravatar.com/avatar/8013a62d7397c006bae48b96d6832a573ea71a7d5d3597fe584210567b508c05?
         s=40&d=identicon&r=g)
      b. [Justin Tadlock](https://profiles.wordpress.org/greenshady/)
      c. [November 21, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-13885)
      d. Have you [submitted a bug report](https://core.trac.wordpress.org/)? That’d be
         the best way to address this.
      e. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=13885#respond)
      f.  a. ![Alexandre Buffet Avatar](https://secure.gravatar.com/avatar/7007f60de2e47db5e704b38ea6da6c7a37450098ae8198144e08550c47527ae1?
             s=40&d=identicon&r=g)
          b. [Alexandre Buffet](https://profiles.wordpress.org/alexandrebuffet/)
          c. [November 22, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-13889)
          d. Yes that’s exactly what I did, I’ve added my comment to an issue opened a few
             days ago that addressed this problem! Here’s the link: [https://github.com/WordPress/gutenberg/issues/67066](https://github.com/WordPress/gutenberg/issues/67066)
          e. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=13889#respond)
 59. ![Paul Bystrzan Avatar](https://secure.gravatar.com/avatar/6d7616c0b4c9dde076ce99c3dd4c5d36b7a522d1f7a129957de2c35b3d33a976?
     s=40&d=identicon&r=g)
 60. [Paul Bystrzan](https://profiles.wordpress.org/inkm/)
 61. [November 28, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-13928)
 62. There are so many things for now, and you are again implementing half-hearted 
     solutions for nonsense things. I doubt it’s a necessity, as it would be more important
     to block ‘expand on click’ for images and galleries as long as it’s alpha stage–
     99% of users even if they have the lightbox plugin installed still don’t know 
     that ‘that’s not clickable’, just like the one from images and ‘rounded’ not knowing
     what it is in fact (could be good if aspect ratio, but now everytime I’m doing
     a site for someone i need to deregister in js this annoying style and in THEME!!!
     blocking pseudo-lightbox that can’t even work properly with one image). There 
     are many things like this – and even more – such as a simple good API for multilingual
     and Block Themes, but why….
 63. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=13928#respond)
 64.  a. ![Justin Tadlock Avatar](https://secure.gravatar.com/avatar/8013a62d7397c006bae48b96d6832a573ea71a7d5d3597fe584210567b508c05?
         s=40&d=identicon&r=g)
      b. [Justin Tadlock](https://profiles.wordpress.org/greenshady/)
      c. [December 2, 2024](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/#comment-14080)
      d. I (and many plugin authors) would disagree that it’s a nonsense feature. This
         is something that’s been needed for well over a decade and a common pain point
         for developers. A standardized template registration system gives us the ability
         to better integrate front-end output with themes.
      e. For lightbox, I’m not entirely sure what you’re explaining, but please [open a ticket](https://github.com/WordPress/gutenberg/issues)
         and describe your issue.
      f. [Reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?replytocom=14080#respond)

### Leave a Reply 󠀁[Cancel reply](https://developer.wordpress.org/news/2024/08/registering-block-templates-via-plugins-in-wordpress-6-7/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz--PuxmcOSK3d_uJgh_jq0lfxeK6tY7wKfqkEXKBQsKnhjE4De9G8gziqs29Sd675gbSFTgC&output_format=md#respond)󠁿

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

Comment *

Name *

Email *

Website

 Save my name, email, and website in this browser for the next time I comment.

 Notify me of follow-up comments by email.

 Notify me of new posts by email.

Δ

## Have an idea for a new post?

### 󠀁[Learn how to contribute](https://developer.wordpress.org/news/how-to-contribute/)󠁿

Share your knowledge with fellow WordPress developers.

Search

### 󠀁[Review tips and guidelines](https://developer.wordpress.org/news/tips-and-guidelines-for-writers/)󠁿

Everything you need to know about writing for the Blog.

## Subscribe to the Blog

  Email Address

 Join 1,773 other subscribers

 * [About](https://wordpress.org/about/)
 * [News](https://wordpress.org/news/)
 * [Hosting](https://wordpress.org/hosting/)
 * [Privacy](https://wordpress.org/about/privacy/)

 * [Showcase](https://wordpress.org/showcase/)
 * [Themes](https://wordpress.org/themes/)
 * [Plugins](https://wordpress.org/plugins/)
 * [Patterns](https://wordpress.org/patterns/)

 * [Learn](https://learn.wordpress.org/)
 * [Documentation](https://wordpress.org/documentation/)
 * [Developers](https://developer.wordpress.org/)
 * [WordPress.tv ](https://wordpress.tv/)

 * [Get Involved](https://make.wordpress.org/)
 * [Events](https://events.wordpress.org/)
 * [Donate ](https://wordpressfoundation.org/donate/)
 * [Swag ](https://mercantile.wordpress.org/)

 * [WordPress.com ](https://wordpress.com/?ref=wporg-footer)
 * [Matt ](https://ma.tt/)
 * [bbPress ](https://bbpress.org/)
 * [BuddyPress ](https://buddypress.org/)

 The WordPress® trademark is the intellectual property of the WordPress Foundation.

 * [Visit our X (formerly Twitter) account](https://www.x.com/WordPress)
 * [Visit our Bluesky account](https://bsky.app/profile/wordpress.org)
 * [Visit our Mastodon account](https://mastodon.world/@WordPress)
 * [Visit our Threads account](https://www.threads.net/@wordpress)
 * [Visit our Facebook page](https://www.facebook.com/WordPress/)
 * [Visit our Instagram account](https://www.instagram.com/wordpress/)
 * [Visit our LinkedIn account](https://www.linkedin.com/company/wordpress)
 * [Visit our TikTok account](https://www.tiktok.com/@wordpress)
 * [Visit our YouTube channel](https://www.youtube.com/wordpress)
 * [Visit our Tumblr account](https://wordpress.tumblr.com/)