Creating WordPress block themes

Level: ,

This lesson is the first in a series of exercises to learn how to create block themes.
You will learn about the minimum file requirements, theme setup and file structure. I will also point out some important differences between classic themes and block themes.

By the end of this lesson, you will have created an empty WordPress theme with support for full site editing. You will continue to build upon this theme over the next lessons.

  • In lesson two you will learn about the block markup that you will use in the theme templates.
  • In lesson three you will add functional templates such as single post, page and archive.

For this lesson, you will need your favorite code editor and a WordPress installation to test your theme on.

Estimated reading time: 7 minutes

Updated June 5, 2022.

Introduction

The new Site Editor (Added in WordPress 5.9) will be one of your primary tools for creating WordPress block themes. For most block theme projects, that is where you will assemble, style, and edit blocks.

But the Site Editor will not expose all settings. Knowing how to make manual edits to the theme files is perhaps not as exciting, but it is good basic knowledge.

You need to install and activate a block theme before you can use the Site Editor. That is why the first lessons in this chapter will be about manually creating a theme.

You can follow along and create a block theme with me, or use the “super quick start guide” and only use this page as a reference.

Super quick start guide for eager theme developers

1. Create a new theme folder inside wp-content/themes.
2. Create a style.css file for your new theme.
3. Create two new folders inside the theme folder: templates and parts.
4. Inside the parts folder, create an HTML file called header.html.
5. In header.html, add the following code: <!-- wp:site-title /--> and save.
6. Inside the templates folder, create an HTML file called index.html.
7. In index.html, add the block code below, and save:

<!-- wp:template-part {"slug":"header"} /-->
<!-- wp:query -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title /-->
<!-- wp:post-date /-->
<!-- wp:post-content /-->
<!-- /wp:post-template -->
</div>
<!-- /wp:query -->

8: Activate the theme.

Step 1: Create the theme folder and style.css

You can expect that the theme setup will be more straightforward and require fewer files in the future. It is even possible that the only file you will need is the new theme.json configuration file. But let’s look at the theme file structure and block templates required to create block themes today.

Minimum requirements

Since version 6.0, WordPress no longer requires full site editing themes to include an index.php file. Instead, the minimum required files are style.css and an index.html file placed inside a folder called templates.

First, select a theme name and use the slug to create your new theme folder inside
wp-content/themes. If your theme name is “FSE,” short for full site editing, your folder will be:

wp-content/themes/fse

Create a style.css file in the root folder of the theme.
Full site editing themes use a standard style.css file header.
Copy and paste the following code into the file. Update the fields as needed:

/*
Theme Name: Name of the theme.
Author: The name of the individual or organization who developed the theme.
Description: A short description of the theme.
Version: The version, written in X.X or X.X.X format.
Requires at least: The oldest main WordPress version supported, written in X.X format. 
Tested up to: The last main WordPress version the theme has been tested up to, i.e. 5.9. Write only the number.
Requires PHP: The oldest PHP version supported, in X.X format, only the number.
License: The license of the theme.
License URI: The URL of the theme license.
Text Domain: The string used for textdomain for translation. The theme slug.
*/

Start with an empty style.css file

Our theme will rely on block styles and the theme.json configuration file as much as possible.
I suggest that you start with an empty style.css except for the file header. Using an empty style.css file is an excellent way to learn the strengths and limitations of theme.json.

Step 2: Add your first block template

Block templates are your base HTML files and just like PHP files in classic themes, they follow the WordPress template hierarchy.

/templates/index.html is the equivalent of index.php in a classic theme.
/templates/404.html is the equivalent of 404.php and so on.

For Gutenberg and WordPress to recognize that the active theme has support for full site editing, the theme must include an index.html file, and you must place it inside a folder called templates.

– Go ahead and create the folder and the empty index file before continuing to the next step. You will add content to this file in lesson three.

The template hierarchy -refresher

The following default templates are supported in the WordPress template hierarchy:
index,
404,
archive,
author,
category,
tag,
taxonomy,
date,
embed,
home,
front-page,
privacy-policy,
page,
search,
single,
singular,
and attachment.

https://developer.wordpress.org/themes/basics/template-hierarchy/

Step 3: Create the theme.json configuration file

Theme.json is a configuration file for enabling and disabling block settings and for applying styles to blocks. I will describe how to use theme.json in detail in upcoming lessons, so do not worry if you are not familiar with this format yet.

In this lesson, you will add the layout setting: Block themes use this setting to support wide width, full width and left, center and right alignments.

Create the theme.json file in the root folder, and copy paste the following code:

{
        "version": 2,
	"settings": {
		"layout": {
			"contentSize": "840px",
			"wideSize": "1100px"
		}
	}
}

You have now set the content width to 840px and the wide width to 1100px. These two values match the defaults widths in the editors, but you can adjust them.

— There is no setting for full width because it is not needed: WordPress handles the width limitations by setting a max-width on the blocks using CSS.

Tip! 840px gives your website a high number of characters per line which can be difficult to read. Adjust the width to a comfortable reading length using your selected font family and size.

Your theme structure should now look like this:

templates/
	index.html
style.css
theme.json

Step 4: Include functions.php and theme support (optional)

Themes do not require functions.php to work. You can include functions.php in your block theme if you need to enqueue stylesheets or JavaScript, add custom block styles, custom image sizes, or use hooks that are not available for blocks.

Create a new file in the root folder and name it functions.php.
Add the file header, and if you like, enqueue the style.css file for later use with wp_enqueue_style():

<?php
/**
 * Functions and definitions
 *
 * @link https://developer.wordpress.org/themes/basics/theme-functions/
 *
 * @package FSE
 * @since 1.0.0
 */

/**
 * Enqueue the style.css file.
 * 
 * @since 1.0.0
 */
function fse_styles() {
	wp_enqueue_style(
		'fse-style',
		get_stylesheet_uri(),
		array(),
		wp_get_theme()->get( 'Version' )
	);
}
add_action( 'wp_enqueue_scripts', 'fse_styles' );

You do not need to enqueue the comment-reply script commonly used in classic themes, because the comments block enqueues this automatically.

Theme support

The following theme support is automatically enabled for block themes:
post-thumbnails, editor-styles, responsive-embeds, automatic-feed-links, html5 styles, and html5 scripts.

You do not need to include add_theme_support( 'title-tag' ) in the setup function, because WordPress already renders the title tag for full site editing themes (View the source).

Adding theme support for the block-style CSS file is optional. This file includes the combined CSS from the theme.scss file for individual blocks. For example the padding when you add a background color to a group block and the default border of the quote block.

if ( ! function_exists( 'fse_setup' ) ) {
	function fse_setup() {
            add_theme_support( 'wp-block-styles' );
        }
}
add_action( 'after_setup_theme', 'fse_setup' );

Similarly, you do not need to register widget areas and menus and add theme support for a custom logo, custom header, or colors.

Templates are loaded in the body element

Templates and template parts use block markup and not plain HTML. One thing I get asked about frequently is how to make updates to the meta tags in the header of the theme.

When you create the templates in the next few lessons, you will find that the header template part does not include a <!DOCTYPE>,<html>, or <head>. There is also no <body> element.

WordPress already adds the necessary HTML elements and hooks. The complete code is:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>" />
	<?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
<?php wp_body_open(); ?>

(template)

<?php wp_footer(); ?>
</body>
</html>

Source

If you need to make changes to the meta tags, you need to use the hook and available filters, not direct markup.

On the front, your templates and all your blocks are loaded in the <body> element, inside a <div> with the class wp-site-blocks. There is no way to remove this div.

<body>
<div class="wp-site-blocks">
...
</div>
</body>