The state of child themes

This post reflects on the state of child themes in WordPress 5.8 in August 2021, where I walk you through some experiments I recently did with block child themes.

Estimated reading time: 8 minutes

Can you create full site editing child themes?

To answer a common question, yes, it is possible to create child themes for block themes.
You can create child themes for other block themes or for a classic PHP-based theme.

What about grandchild themes? I have not tried; let me know if you have tested this!

Child themes for block themes

Learning what works and what doesn’t

In my first experiment, I set out to create a child theme for my theme Armando.
In the spirit of the two major football tournaments going on at that moment, I named my theme ”Armandinho”.

First, I created a style.css file for my child theme. It is a standard style.css file with the parent theme slug added as Template:

/*
Theme Name: Armandinho
Author: Carolina Nymark
Author URI: https://fullsiteediting.com
Theme URI:
Version: 1.0.0
Description: An experimental full site editing child theme.
Tags: full-site-editing, blog, one-column, two-columns, editor-style, block-styles
Text Domain: armandinho
Requires at least: 5.5
Requires PHP: 7.2
Tested up to: 5.8
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Template: armando

All files, unless otherwise stated, are released under the GNU General Public
License version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html)

This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned
with others.
*/

Child themes does not inherit Theme.json

When I activated the child theme, the first noticeable thing was that it did not inherit the theme.json file from the parent, and the site editor was not available.

On the front, there were no templates visible. There were no notifications or error messages, but all pages were empty.

I expected the theme.json to be inherited from the parent theme, and to be able to override settings by adding a theme.json to my child theme.

So I tried two different things:

  1. I created a theme.json file that was valid but only included the version number.
    With this change, the block templates loaded without the preset and settings from the parent theme.json file.
  2. I copied the entire theme.json from the parent theme into my child theme.
    -Of course, this felt like going against the purpose of creating a child theme, because I did not want to repeat what is already in the parent theme. I made the changes I wanted, including updating the color palette.

Parent theme template parts do not work

Secondly, the parent theme’s block template parts did not work -they were not found in the editor or front.
I was surprised because I had expected them to be inherited from the parent theme. But I was less concerned about the template parts than theme.json because I knew I wanted to change these in the child theme.

So I created a block-template-parts folder and copied over the template parts for header, footer, main loop, comments, and sidebars. This worked well, and the parts loaded correctly.

From here, I made the changes to the template parts that I needed to make the child theme unique.

Child theme templates override parent theme templates

I created the block-templates folder and added a new index.html file. I did this to confirm that it was possible to override the parent template files, and it worked well.

Parent templates can not be removed

Then I decided that I did not want the templates with the sidebars to be available in the child theme. So how would I remove them?

At the bottom of my the child themes theme.json file, the custom templates were still listed:

"customTemplates": [
		{
			"name": "post-sidebar-right",
			"title": "Two columns, right sidebar",
			"postTypes": [ "post" ]
		},
		{
			"name": "post-sidebar-left",
			"title": "Two columns, left sidebar",
			"postTypes": [ "post" ]
		},
		{
			"name": "page-sidebar-right",
			"title": "Two columns, right sidebar",
			"postTypes": [ "page" ]
		},
		{
			"name": "page-sidebar-left",
			"title": "Two columns, left sidebar",
			"postTypes": [ "page" ]
		},
		{
			"name": "page-template-patterns",
			"title": "Template for block pattern layouts",
			"postTypes": [ "page", "post" ]
		}
	]

But deleting this part of theme.json did not change anything and the templates were still available in the Template selection in the block editor:

The template select list in the block editor includes the names of all templates in the parent theme.

Next, I created a functions.php file and turned to using the theme_page_templates() filter:

function armandinho_remove_page_templates( $page_templates ) {
	unset( $page_templates['page-sidebar-left'] );
	unset( $page_templates['page-sidebar-right'] );
	unset( $page_templates['post-sidebar-left'] );
	unset( $page_templates['post-sidebar-right'] );

	return $page_templates;
}
add_filter( 'theme_page_templates', 'armandinho_remove_page_templates' );
add_filter( 'theme_post_templates', 'armandinho_remove_page_templates' );

I tried the filter both with and without .html file endings.
This removed the templates from get_page_templates, but they were still available in the Template section (only, for some reason, they were re-ordered).

I did not try it with different priorities for the filter but resigned to supporting the sidebars in the child theme.
-If you know if the file endings and priority matters, send me a tweet or email and I will try it again and update the post. 🙂

The site editor is only available if the child theme includes index.html

As I mentioned, the site editor was not available when I first activated the child theme.
It was not until I added the index.html template that the menu appeared. So if you want to use the site editor with the theme, you must override this template.


Block child themes for classic themes

Why create a block child theme for a classic theme?

  • -You may want to explore how you can take advantage of the presets in theme.json before making updates to your existing theme.
  • -You may want to offer your users custom templates with template editing without affecting your existing theme.

For this experiment, I selected one of, if not the most basic of my themes, Miranda. I choose this over the default themes because they have dark mode and Sass and more complex designs.

As a first step, I created the theme folder and style.css file. Next, I added a functions.php file where I enqueued the parent themes style.css file, fonts and icons.

Inside the child theme’s root folder, I added a theme.json file with a version number, and a block-templates folder with a blank index.html file. I knew that I had to add the index.html to enable the site editor.

I wanted to see if the parent theme’s PHP templates would be inherited by the child theme and learn how to combine them.

Block child themes inherits (some) PHP templates from the parent theme

When I activated the child theme, the home, or index, was blank. But I found that if I viewed a single post or an archive page, the PHP template from the parent theme was used.

This means that theme developers can create custom front pages – but they also have to create a custom front page. There is no way to keep the current front page and use block templates for other pages.
So in other words, both types of themes follow the template hierarchy, but there are side effects to having to include an index.html in the child theme.

When I viewed the site editor, the PHP templates were not listed and could not be previewed. Here, I expected the PHP templates to not be editable. But it would be good to list the existing templates. I would have liked to see what templates are inherited from the parent theme.

Block child themes can override parent theme templates

I added a single.html template file inside the block-templates folder to confirm that the template would override the parent. I did not want to assume anything without testing, but this worked correctly, and the template was visible in the site editor.

Block child themes can include template parts

I expected child theme template parts to work, but because the first experiment showed that child themes do not inherit the parent template parts, I wanted to make sure.

When creating the new header template part, I added a navigation block and assigned it the same menu used in the PHP header template.
Being able to select existing menus is a neat feature with the navigation block.
-To make the navigation block match the existing menu, I had to add extra CSS. I have some concerns about the duplication of the CSS since the markup and class names are not the same. The more advanced your parent theme menu is, the more difficult it will be to make them match.

Styling for block child themes

I learned that the parent theme style.css file -and any files you enqueue from the parent theme, are also applied on the templates in the block child theme.
The settings you add in the child themes theme.json file, including the color palette and the layout, override the parent theme settings.

In my short experiment, I did not attempt to enqueue the parent themes editor styles, and the editor and front did not match.


Conclusion -Is it worth creating block child themes?

The question is if there are any benefits to creating child themes before the bugs have been fixed. Probably not.

The good news is that more developers are now working on improving the state of child themes. Because the Gutenberg plugin has a short release cycle, we may see improvements before WordPress 5.9. I am hopeful.

The themes team at Automattic has also explored creating child themes and generating the theme.json file. I have listed these child themes on the themes page.

I can see more benefits in creating a block child theme for a classic theme, and I had more fun exploring that process.

For child themes of block themes, well, if you have gone through all the trouble of creating a complete theme.json file, adding an index.html file, and including overrides for all template parts, then you have practically created a new parent theme.
To get a fully working child theme, you need to put more effort into it than what should be necessary for a child theme.