WordPress.org

WordPress Developer Blog

Upgrading the site-editing experience with custom template part areas

A recent search of the theme directory turned up one theme that looked as if it uses custom template part areas.

One theme. 

Whether developers aren’t finding uses for these handy tools or they just don’t know about them yet, template part areas are so useful that you probably are already using them in your block themes. (You just didn’t realize it …).

After this tutorial, maybe you’ll be psyched enough to experiment with custom template part areas in your themes.

But first, let’s look at how they work and how to register your own, so you’ll know exactly what you’re psyched about

What are template part areas?

Again, if you’ve built a block theme, you have likely used them. And, again, maybe you didn’t even know it.

Template part areas define an area of the page as a place where one of a specific set of template parts can live. For example, a Header area is meant for site headers. You can even stick the—you guessed it—Header template part in the Header area.

Confused yet? Why does WordPress have a Header area when there’s a Header template part already?

Think of it as a taxonomy of sorts. Your theme may very well have two, three, or even a dozen different headers that you want the user to choose from. Perhaps a dozen is overkill, but YOLO—you do your thing and have fun with it.

The great thing about this system is that your users can pick and choose the template part that they think works best in a given area.

WordPress defines three default areas:

  • header
  • footer
  • uncategorized (titled General in the UI)

You can use these areas when you register a custom template part in theme.json. Just make sure you define the area value, as you see below. By the way, these are of course the two most common template parts registered in block themes: Header and Footer:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"templateParts": [
		{
			"area": "header",
			"name": "header",
			"title": "Header"
		},
		{
			"area": "footer",
			"name": "footer",
			"title": "Footer"
		}
	]
}

Technically, you could name the Header and Footer template parts anything you want. Most theme authors use those names purely by convention. But to distinguish them from other headers, you might consider going with Site Header and Site Footer.

Notice, below, that in the Site Editor, you can see the Header and Footer areas under the Template panel:

One important role that this panel has is to help you navigate from area to area. If you click on the Header area, it will jump you to the Header in the template.

That might not seem like much when a template has only two parts. But when you’ve registered multiple custom areas in a more complex template, you’ll be glad you have some easy ways to get around that morass.

Plus, template part areas let you switch among all the template parts or block patterns you’ve registered for that area. 

To give this a test, select the Header area and then click the (Options) button in the toolbar. Now click the Replace Header option in the dropdown menu. That action will bring up a modal with the available template parts or patterns for that area:

From there, you can replace your existing Header with one you like better.

Before getting your hopes too high, this replacement feature is not currently supported for custom template part areas. Sorry. There is an open ticket to make that magic happen, but it never hurts to develop for the future. For now, you can only replace the Header and Footer.

Registering template part areas

Now for the fun part! It’s time to build your own template part areas.

A couple of common areas in theme templates are the sidebar and comments sections. Without custom areas, you would need to register them as uncategorized. The UI labels these as General, and if you have multiple uncategorized template parts on a page, you just as quickly have bought yourself a UX nightmare.

Let’s try improving this experience with a custom Sidebar template part area. After you register it, it will show up in the Site Editor like this:

Here’s how you do it. First, add a filter to the default_wp_template_part_areas hook. Your callback function should accept a single parameter named $areas, which is an array of area definitions.

Add this code to your theme’s functions.php file, and you will have registered your first Sidebar area:

add_filter( 'default_wp_template_part_areas', 'themeslug_template_part_areas' );

function themeslug_template_part_areas( array $areas ) {
	$areas[] = array(
		'area'        => 'sidebar',
		'area_tag'    => 'section',
		'label'       => __( 'Sidebar', 'themeslug' ),
		'description' => __( 'Custom description', 'themslug' ),
		'icon'        => 'sidebar'
	);

	return $areas;
}

Only four icons are supported for the icon argument. header, footer, sidebar, are the named icons; all other values revert to symbolFilledIcon. There is an open ticket to address this limitation, but it lacks the patch that would move it forward. This might be a “good first ticket” for someone to get involved with Gutenberg development.

Now, registering an area will not automatically make it appear in the Site Editor. You also need to register at least one template part, and that template part must also be inside the template you are currently editing.

Adding template parts to custom areas

With your custom Sidebar area registered, you can start assigning template parts to it. 

Start by adding a sidebar.html file to your theme’s /parts folder. You can put whatever valid block markup you want in it.

Then, call that template part from anywhere in a top-level template, like /templates/single.html, or /templates/home.html, with this code:

<!-- wp:template-part {"slug":"sidebar"} /-->

Now, register the part for the area. Open your theme.json file and add your template part for the sidebar area:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"templateParts": [
		{
			"area": "header",
			"name": "header",
			"title": "Header"
		},
		{
			"area": "sidebar",
			"name": "sidebar",
			"title": "Sidebar"
		},
		{
			"area": "footer",
			"name": "footer",
			"title": "Footer"
		}
	]
}

Next, visit the Site Editor and make sure everything works: your sidebar should show up in any templates you’ve called it in, and the Sidebar area should appear in the Template panel.

Want more? Try registering a few more sidebar parts—maybe a couple for the homepage and your site’s shop:

//...
	{
		"area": "sidebar",
		"name": "sidebar-home",
		"title": "Sidebar: Home"
	{
		"area": "sidebar",
		"name": "sidebar-shop",
		"title": "Sidebar: Shop"
	}
//...

Be sure to add sidebar-home.html and sidebar-shop.html files to the /parts folder in your theme and call them in their respective top-level templates.

So now you know the secret sauce of blissful block-theme UI: template part areas. You’re in a prime position to keep expanding on these basics, to build all kinds of template part areas for your themes. 

Which ones will you add first?

Props to @marybaum, @bph, and @ndiego for feedback and review.

14 responses to “Upgrading the site-editing experience with custom template part areas”

  1. Dominique Pijnenburg Avatar

    I don’t completely understand why it’s necessary to register a template-area through PHP and the theme.json as well. What is PHP doing and what is theme.json doing?

    1. Justin Tadlock Avatar

      On the PHP side, you are registering the template part area. In theme.json, you are registering the template parts that go into registered areas. Essentially:

      PHP = area
      JSON = part

  2. Brian Gardner Avatar

    Great tutorial, Justin! I am testing this out as a possible feature for my Powder theme, but ran into one small issue. (Reported here)

  3. Tim Nicholson Avatar

    Justin, thanks so much for posting this!

    I’m adding this to my recently-published FSE theme called Flat Blocks and I’m only seeing the *sidebar* category in the Editor (with Gutenburg plugin active) even though I’m attempting to add several new areas. The areas that I add DO show up in the Template sections, just not as a category within the Patterns editor.

    Also, what is the ‘area_tag’ for? What are the valid values?

    Here is a code snippet:

    // Define our custom template part AREAS
    if ( ! function_exists( ‘flatblocks_template_part_areas’ ) ) :
    function flatblocks_template_part_areas( array $areas ) {

    $new_areas = array(
    array(
    ‘area’ => ‘title’,
    ‘area_tag’ => ‘section’,
    ‘label’ => __( ‘Title’, ‘flat-blocks’ ),
    ‘description’ => __( ‘Title templates for pages and posts’, ‘flat-blocks’ ),
    ‘icon’ => ‘header’
    ),
    array(
    ‘area’ => ‘sidebar’,
    ‘area_tag’ => ‘section’,
    ‘label’ => __( ‘Sidebar’, ‘flat-blocks’ ),
    ‘description’ => __( ‘Sidebar templates for pages and posts with sidebars’, ‘flat-blocks’ ),
    ‘icon’ => ‘sidebar’
    )
    );
    return array_merge( $areas, $new_areas );

    }
    endif;
    add_filter( ‘default_wp_template_part_areas’, ‘flatblocks_template_part_areas’ );

    1. Justin Tadlock Avatar

      The valid tags are the valid block-level HTML sectioning elements:

      div
      header
      main
      section
      article
      aside
      footer

      The missing areas in the Patterns sidebar is a bug in Gutenberg 16.2. It’s has been fixed in 16.3. It also works in WordPress 6.3 Beta 4 or newer (if Gutenberg 16.2 isn’t active).

  4. Guido Scialfa Avatar

    Nice article thanks. I’ve one doubt about the Template Areas still, the article does not explicitly say how the Area is intended and what’s possible to do with that. For instance, the following sentence

    Template part areas define an area of the page as a place where one of a specific set of template parts can live.

    From what I’ve seen by playing with the template parts, it is possible to have more than one of them in a page assigned to the same area and in different parts of the template. Also, within the template edit I cannot move them.

    Honestly I was expecting the Area to be something like a CSS Grid Area, something that would part of the layout of a template. Instead if my understanding of the code of the template part block is correct, the template area looks more a way to organize the Template Parts and a Key to obtain the configuration of the area in case one of the custom values like the `tag_area` is missed.

    Could you elaborate a bit more on this?

    1. Justin Tadlock Avatar

      Correct, areas are essentially categories for organizing template parts. In WordPress 6.2, you primarily get the “win” of easier navigation when editing a template. In WordPress 6.3, you’ll get nicer organization of these (now moved under the new Patterns panel in the navigation).

  5. HelgaTheViking Avatar

    Is it possible yet to register a custom template area from a plugin?

    1. Guido Scialfa Avatar

      Yes you can, as anything else which is related to integration via filters / actions can implemented in plugins. Even though I don’t know how much would make sense to have UI stuffs in a plugin rather than child themes.

      1. Duncan Cowan Avatar
        Duncan Cowan

        I would hazard a guess the request to register template areas from a plugin would be similar to a need to register a custom post type (CPT) from a plug.
        It’s practicle and convenient that WordPress autoloads templates, parts, and patterns from within the theme directory.
        Difficulties, or rather inconvenience does arise when trying to interact with a theme from a plugin. Plugins offer extensibility, encapsulation and modularity.
        Unfortunately, IFAIK, plugins are unable to create a page template.
        They can create “block templates”, which is a nice and finely grained feature. But do not quite fulfill all the needs a plugin CPT might desire.
        I will add a postscript that I, at times. am overwhelmed by WP admin bloat added by plugins and can see who exposing template authorship to the same authors may lead to … well more and more of the same.
        I have noted a lovely feature within the block metadata for a block to ‘autoinsert’ another block. And was delightled to discover the feature came with an opt out option for the user.
        But I drift from the main thread.
        Plugin authors do at times need access to include and mutate theme architecture

  6. Duncan Cowan Avatar
    Duncan Cowan

    Excellent article. Thanks Justin. Would like to discuss the following notation made in the article.
    – `” Technically, you could name the Header and Footer template parts anything you want. […]”`
    as we have recently had to rename many of our ‘header’ and ‘footer’ template parts from our preferrred ‘site-header, site-footer` to enable our theme to remain compatible with WooCommerce, which include templates expecting; ‘header, footer’ slugs
    We have not completed our research into potential or recent changes to template loading in WP or WC.
    Are you able to shed any light upon how WP will handle slug naming – moving forwards. Fallback template heirachy as per classic themes?

  7. uxl Avatar

    One oddity I recently noticed is that if you change the defined area of a template part after the template part has already been customized in the editor, the new area will appear to be missing.

    For example, theme contains a sidebar.html template part which was registered in the ‘uncategorized’ area, then after some time the theme author changes the registered area to ‘sidebar’ and updates the theme. Any users who have already made changes to the sidebar in the editor will continue to see the sidebar in the uncategorized/general area, and the sidebar area will not be available unless another new template part is also registered in that area. The older sidebar.html part will still only display in the uncategorized area though.

    So, it seems that any changes to a defined template part area does not force an update to the taxonomy relationship of the saved template part post (wp_template_part) in the database.

    1. Justin Tadlock Avatar

      That seems like it’d be the correct path since the template part the user has created belongs to Uncategorized and was never connected to the new area. It’s probably worth noting in the docs.

Leave a Reply

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