Exploring Block Based Experimental Themes

Note: This post is part 2 of leaning efforts to understand and use full site editing (FSE) and block-based themes. This learning post is still in active development and updated regularly.

In the previous learning note post, we explored site-wide CSS styles through Global setting and Global styles in theme.json file of block themes. In this part 2 of this series, we will explore creating a basic block base theme.

Some features of Full Site Editor (FSE) are landing in the WordPress core release 5.8. The Block editor handbook describes block theme as:

A block theme is a WordPress theme with templates entirely composed of blocks so that in addition to the post content of the different post types (pages, posts, …), the block editor can also be used to edit all areas of the site: headers, footers, sidebars, etc.Block Editor Handbook

There are currently ten experimental blocks themes in the WordPress GitHub theme-experiment repository including Twenty Twentyone block (tt1-blocks), Twentynineteen-blocks, twentytwenty-blocks, gutenberg-starter-theme-blocks, emptytheme and others.

Though block-based themes are still in exploratory stage, some theme authors are already jumping in to create fully functional block themes. As of this writing there are only six experimental block themes in the WordPress theme directory. A few others are block-based “hybrid” themes. Because the header section and navigation section of the experimental block-themes are still not fully developed, their uses have not been fully adapted by theme authors.

Learning series
Part 1: Global Styles and Global Settings
Part 2: Exploring Block Based Experimental WordPress Themes (this post)
Part 3: Understanding Blockbase – A block base Parent Theme

In this learning note posts, I am also exploring block-based themes from the theme-experiment repository and making my hand dirty to get a feel of their structure and how the blocks are put together to build a functional block-based theme.

Resources and Learning Guides

In my brief google research I found the following posts useful to broaden my understanding on block-based themes (light weight) and future of current PHP-template based themes.

Helpful Video links

  • WordPress Gutenberg Blocks Basics – 2020 (WP Apprentice):  This 18:30min video lessons explain the basics of the blocks.
  • Introduction to Block-based themes (Kjell Reigstad): This 27:11min long video by Kjell provides an introduction to block-based themes, explain how they’re different from existing themes, and discuss what that means for both users and theme developers.
  • Creating a Block-based Theme (Imran Sayed – Codeytek Academy). This is 8-parts video tutorial series by Imran demonstrates how to create a block theme using FSE features. A great learning resource.

Block editor handbook has an excellent guide on creating a block based theme. WordPress theme review team member Carolina Nymark has written a very handy creating block-based themes guide.

An Overview of Block Theme

With the ongoing WordPress block editor and full site editing (FSE) development, block-based themes are also being introduced. A block theme contains HTML files where as the classic theme contains PHP files.

A block theme is a WordPress theme with templates entirely composed of blocks so that in addition to the post content of the different post types (pages, posts, …), the block editor can also be used to edit all areas of the site: headers, footers, sidebars, etc. Block Editor Handbook

Block Theme File Structure

The following is a typical block-theme file structure from the Editor handbook:

#! basic block-theme structure
theme
|__ style.css
|__ functions.php
|__ index.php
|__ theme.json
|__ block-templates
    |__ index.html
    |__ single.html
    |__ archive.html
    |__ ...
|__ block-template-parts
    |__ header.html
    |__ footer.html
    |__ sidebar.html
    |__ ...

A brief description of the above files and folders:

  • styles.css: contains theme’s style sheet.
  • functions.php: contains theme setup,  may include additional files, enable an editor style sheet and enqueue style.css, if any
  • index.php: An empty file to switch to default file in case the block-theme is activated without Gutenberg block editor.
  • theme.json: Optional configuration file used to enable or disable features and set default styles for both the website and blocks
  • block-templates: contains page templates that are composed of blocks. These follow the same template hierarchy as traditional themes.
    • index.html: the primary / fallback template to generate a post or page. (it’s analogous to index.php in traditional theme templates.)
    • single.html: template to generate single posts or pages.
    • archive.html: template to generate archive lists of posts.
  • block-template-parts: the common collections of blocks to be used in block templates.
    • header.html: global header block.
    • footer.html: global footer block.
    • sidebar.html: optional global sidebar block.

A list of theme blocks including that are specific to block themes is available in block editor handbook.

Block Templates and Block Template Parts

Block templates, as the name suggests, are made of blocks which might include reusable blocks parts (like header, footer) using “Template Parts”. Different blocks are used to compose a page template, for example, lists of blog posts, lists of products or a widget.

An example of template from Block Editor handbook.

<!-- wp:site-title /-->
 
<!-- wp:image {"sizeSlug":"large"} -->
<figure class="wp-block-image size-large">
    <img src="https://cldup.com/0BNcqkoMdq.jpg" alt="" />
</figure>
<!-- /wp:image -->
 
<!-- wp:group -->
<div class="wp-block-group">
    <!-- wp:post-title /-->
    <!-- wp:post-content /-->
</div>
<!-- /wp:group -->
 
<!-- wp:group -->
<div class="wp-block-group">
    <!-- wp:heading -->
    <h2>Footer</h2>
    <!-- /wp:heading -->
</div>
<!-- /wp:group -->

The classic theme templates are php files where as block themes are html file with block “grammar” markups.

Creating Block Templates

One of the goals of the FSE feature of block editor is to allow authorized users to provide access block templates in the WordPress admin to “edit them in dedicated views and potentially export them as a theme“.

As of Gutenberg 10.7, block templates and template parts can be created by following three ways but it may change because FSE development is being actively iterated.

  • Using the template editing mode in the block editor.
  • Using Full Site Editor.
  • Manually, by creating HTML files containing block markup.

Brief descriptions of creating template in the site editor and template editing mode is available in Block Theme handbook.

Styling Block Theme

In the classic themes, we write the styling rules in a style.css file. In block themes, styling is more challenging because CSS style comes from different sources (e.g. core blocks, themes, users). To address this growing pains, a concept of GlobalStyles have been introduced to consolidatethe various APIs related to styles into a single point – a theme.json file that should be located inside the root of the theme directory“.

The theme.json file is designed to offer more granular styling structure for theme authors with options to manage and customize CSS style coming from various origins (themes, users, core CSS). For example, a theme author may set certain styling features (i) hidden from users, (ii) the default colors, font sizes… available to the user, and (iii) may defines the default layout of the editor. The theme.json also provides authors to customize styling per block.

Hybrid/Universal Themes

There are ongoing discussions about Hybrid themes to facilitate both the theme developers and end users to transition from classic themes to FSE block themes. In the discussion a concept of universal theme (that can be loaded in a classic context or block editor context without a problem) is being discussed.

At the of writing, theme documentation include hybrid/universal themes are are still in discussion phase only.

Getting Started with Block Theme

Let’s first start creating very basic block theme. There are couple of ways, we can start our theme development process. We could either (i) clone emptytheme or any other experimental-themes and customize it, or (ii) create our block theme from the scratch following create block theme tutorial. In this learning post, we will follow the second approach.

Basic Requirement

At its core, block theme has only two requirements:

  • Gutenberg plugin: Because full site editing (FSE) features are still in developmental stage and are available as plugin only, a latest Gutenberg plugin is required to access block-based themes.
  • Required Files: Just like in classic theme, only two files index.php and style.css are required to activate any theme, block theme requires index.html inside block-templates folder and a style.css file.

A block based theme optionally may include function.php, theme.json (to handle Global styles) and other files and folders (block-template-parts) to enhance functionality of block themes.

Section 1: Setting Up a Black Theme

Let’s first create a folder under wp-content/themes/ in our local WordPress install and give it a name myblocktheme, that will be the name of our block theme.

Alternatively, an emptytheme starter block theme from the GitHub theme-experiments repository can be used to setup a black theme and edit to customized as desired.

Step 1: Create an Empty Block Theme Structure

Following block theme tutorial, I set up a black theme named myblocktheme theme with the following file structure:

#! empty theme structure
myblocktheme
 |__ style.css
 |__ index.php
 |__ block-templates
 	|__ index.html
 |__ block-template-parts
 	|__ (empty folder)

In the above file structure, all the files are empty except the style.css file with the same header structure of a classic theme but no style rules.

/*
Theme Name: My Block Theme
Theme URI:
Author: TinjureWP
Author URI: https://learncode.tinjurewp.com/
Description: A basic scafold block based theme learning project.
Tags: full site editing, 
Version: 1.0.0
Requires at least: 5.0
Tested up to: 5.4
Requires PHP: 7.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: myblocktheme
 
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.
*/
Step 2: Upload and Activate the Empty Block Theme

Uploaded the theme folder in a test local WordPress installation and activated the myblocktheme theme. A blank block-based theme is seen in the theme folder. Because this is just an empty theme – a white screen appears. Now let’s start adding contents to the files and began creating our first block theme.

Step 3: Adding a Optional functions.php File

Let’s create functions.php file where we enqueue style.css, enable editor style and add theme support.

/* functions.php */
<?php
if ( ! function_exists( 'myblocktheme_theme_setup' ) ) :
	/**
	 * Sets up theme defaults and registers support for various WordPress features.
	 *
	 * Note that this function is hooked into the after_setup_theme hook, which runs
	 * before the init hook. The init hook is too late for some features, such as indicating
	 * support for post thumbnails.
	 */
	function myblocktheme_setup() {
		/**
		 * Add default posts and comments RSS feed links to <head>.
		 */
		add_theme_support( 'automatic-feed-links' );

		/**
		 * Enable support for post thumbnails and featured images.
		 */
		add_theme_support( 'post-thumbnails' );

		add_theme_support( 'editor-styles' );

		add_theme_support( 'wp-block-styles' );
	}
endif;
add_action( 'after_setup_theme', 'myblocktheme_setup' );

/**
 * Enqueue theme scripts and styles.
 */
function myblocktheme_scripts() {
	wp_enqueue_style( 'myblocktheme-style', get_stylesheet_uri() );
}
add_action( 'wp_enqueue_scripts', 'mtblocktheme_scripts' );

To begin with, we added the above code from block theme handbook and create block theme tutorial. Later we will update based on TT1 Block theme, an official default block theme being developed by the Gutenberg dev team.

Step 4: Create a theme.json file and add to the theme root folder

A very basic theme.json file similar to emptytheme was created to begin with which we will expand as we start styling our theme components in the later sections.

{
	"version": 1,
	"settings": {
		"color": {
			"gradients": [],
			"link": true,
			"palette": []
		},
		"spacing": {
			"customPadding": true
		},
		"typography": {
			"customLineHeight": true,
			"fontFamilies": [],
			"fontSizes": []
		},
		"layout": {
			"contentSize": "840px",
			"wideSize": "1100px"
		}
	}
}

Here we defined site-wide (global) content widths for our layout, which matches the default blocks editor width too.

Section 2: Creating Block Templates and Template Parts

In this section, we will create block template and template parts manually as following creating a block theme and  full site editing tutorials.

Step 1: Creating Header and Footer Template Parts

First let’s create header.html file inside /template-parts/ folder and add the following block html markup for site title and site tagline.

The block handbook describes the block markup (block grammar) as self closing html comments with wp: prefix and the opening and the closing tags should be in the same template.

<!-- wp:site-title /-->
<!-- wp:site-tagline /-->

This is very basic header at this stage, we will revisit later to add navigation and give some basic styling.

Similarly, let’s also create footer.html file inside the template-parts folder add the following snippets to create a credit text paragraph markup.

<!-- wp:paragraph {"align":"wide"} -->
<p class="has-text-align-center">Proudly powered by 
<a href="https://wordpress.org/">WordPress</a>.</p>
<!-- /wp:paragraph -->

In the above wp:paragraph markup, we added the align:center attribute in the block comment, and the has-text-align-center CSS class on the paragraph to add basic alignment styling to footer credit.

Step 2: Adding Header and Footer template-parts to Block Template

Lets add the header and footer template parts to index.html template inside template folder. To add template parts to block template, we should use block template markup wp:template-part followed by its slug (template identifier) which is file name without file extension.

For example, to add our header.html and footer.html template (from step 1) to we should add the following markup:

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

As shown above, the wp:template-part comment also contains two curly brackets and the key, slug, together with the name of the template part.

According to the tutorial doc, template-parts use a <div> tag by default, a tagName attribute is added to change . With the added tagName attribute the wp:template-part markup now looks as below:

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

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

The tagName attribute changes the HTML element to <header> and <footer>.

From the tutorial doc: If you are not sure what the correct block markup is, you can add the block in the block editor and copy the block markup from the code editor mode to your theme files.

Recently, layout support was added to the theme.json file, lets also add layout support as well to our header and footer with"layout":{"inherit":true} attribute.

<!-- wp:template-part {"slug":"header","tagName":"header","className":"site-header",
"layout":{"inherit":true}} /-->

<!-- wp:template-part {"slug":"footer","tagName":"footer","className":"site-footer",
"layout":{"inherit":true}} /-->

Carolina’s Full Site Editing tutorial describes that when layout is added then “default layout is inherited, the blocks inside the template parts will be centered by default and the width will be the one that you defined for the contentSize. In our example, 840px. This setting also enables the options for wide width, full width and left, center, and right align.”

Let’s save the file index.html and view in a browser, we should see the following with our site title, site description and a footer.

Screenshot showing header and footer template parts.

At this stage, the index.html template is empty with only header and footer. We will add query blocks to display list of posts in the next step.

Step 3: Adding Blog Template

In this step, following block theme tutorial doc, we will add query block and query loop block to display list of post.

(a) Add a wrapper block in index.html file

Let’s add the following “main” wrapper block in between the header and footer template-parts.

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

<!-- wp:group {"layout":{"inherit":true},"tagName":"main"} -->
<main class="wp-block-group"></main>
<!-- /wp:group -->

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

In the wp:group block, we also enabled width option by using "layout": {"inherit": true } and tagName attribute to change the default <div> to <main> element.

(b) Add query block inside the group block

Next, we will add query and query loop blocks inside the group block. The query block works in combination with query loop block.

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

<!-- wp:query -->
<div class="wp-block-query"><!-- wp:query-loop -->
<!-- wp:post-title /-->
<!-- wp:post-date /-->
<!-- wp:post-excerpt /-->
<!-- /wp:query-loop --></div>
<!-- /wp:query -->

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

(c) Add query pagination block inside the query block

Pagination block should be added inside the query block but outside of the query block as shown below:

<!-- wp:query -->
<div class="wp-block-query"><!-- wp:query-loop -->
<!-- wp:post-title /-->
<!-- wp:post-date /-->
<!-- wp:post-excerpt /-->
<!-- /wp:query-loop -->
 
<!-- wp:query-pagination -->
<div class="wp-block-query-pagination">
<!-- wp:query-pagination-previous /-->
<!-- wp:query-pagination-numbers /-->
<!-- wp:query-pagination-next /--></div>
<!-- /wp:query-pagination -->
 
</div>
<!-- /wp:query -->

Query loop block have many other options to display post-title link, showAvatar, post-terms and others. Now our final index.html template looks as follows:

<!-- wp:template-part {"slug":"header","tagName":"header","className":"site-header",
"layout":{"inherit":true}} /-->

<!-- wp:group {"tagName":"main","layout":{"inherit":true}} -->
<main class="wp-block-group">
	<!-- wp:query -->
        <div class="wp-block-query">
	<!-- wp:query-loop -->
	<!-- wp:post-featured-image /-->
	<!-- wp:post-title {"isLink":true} /-->
	<!-- wp:post-author {"showAvatar":false} /-->
	<!-- wp:post-date /-->
	<!-- wp:post-terms {"term":"category"} /-->
	<!-- wp:post-excerpt /-->
	<!-- /wp:query-loop -->
	<!-- wp:query-pagination -->
	<div class="wp-block-query-pagination">
		<!-- wp:query-pagination-previous /-->
    <!-- wp:query-pagination-numbers /-->
		<!-- wp:query-pagination-next /-->
	</div>
	<!-- /wp:query-pagination -->
        </div>
	<!-- /wp:query -->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer","className":"site-footer",
  "layout":{"inherit":true}} /-->

In the query loop blocks, we enabled link with "isLink": true and disabled avatar with "showAvatar": false and added wp:post-terms {"term":"category"}.

After saving index.html (blog) template, if we view in a browser, it should look as follows:

Screenshot showing list of posts, posts pagination along with header and footer.
Step 4: Creating Single Posts and Pages Templates

To create a single posts and pages display, we should create single.html and page.html blocks inside block-templates folder.

(a) Creating single posts Block

The single post block is similar to our blog (index.html) block except the loop to display list of posts. Therefore, we can copy the header and footer and group (container) block from the index.html and add other blocks listed in block editor handbook inside the container block.

<!-- wp:template-part {"slug":"header","tagName":"header","className":"site-header",
 "layout":{"inherit":true}} /-->
<!-- wp:group {"tagName":"main","layout":{"inherit":true}} -->
<main class="wp-block-group">
	
  <!-- //  insert desired blocks here -->
    
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer","className":"site-footer",
 "layout":{"inherit":true}} /-->

Next, we add new post-title, post-author, post-date, featured images, post contents .. and other desired blocks inside container group block.

<!-- wp:template-part {"slug":"header","tagName":"header","className":"site-header",
 "layout":{"inherit":true}} /-->
<!-- wp:group {"tagName":"main","layout":{"inherit":true}} -->
<main class="wp-block-group">
    <!-- wp:post-featured-image /-->
    <!-- wp:post-title /-->
    <!-- wp:post-author {"showAvatar":false} /-->
    <!-- wp:post-date /-->
    <!-- wp:post-hierarchical-terms {"term":"category"} /-->
    <!-- wp:post-content {"align":"full","layout":{"inherit":true}} /-->
    <!-- wp:post-terms {"term":"post_tag"} /-->
    <!-- wp:post-navigation-link {"type":"previous"} /-->
    <!-- wp:post-navigation-link /-->
    <!-- wp:heading {"className:"comments-title"} -->
    <h2 class="comments-title">Comments</h2>
    <!-- /wp:heading -->
    <!-- wp:post-comments /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer","className":"site-footer",
"layout":{"inherit":true}} /-->

In the above code example from Carolina’s tutorial, we added post featured image, post navigation, comments blocks and metadata block. For readability basic styling and a spacer block is also added.

Screenshot showing a single post block displaying post terms, navigation and comments.

(b) Creating page block template

The page block is similar to single post except meta data (authors, date, categories and navigation), we will copy the single.html and renamed as page.html and edit as desired.

<!-- wp:template-part {"slug":"header","tagName":"header","className":"site-header",
 "layout":{"inherit":true}} /-->
<!-- wp:group {"tagName":"main","layout":{"inherit":true}} -->
<main class="wp-block-group">
  <!-- wp:post-featured-image /-->
  <!-- wp:post-title /-->
  <!-- wp:post-content {"align":"full","layout":{"inherit":true}} /-->
  <!-- wp:heading {"className:"comments-title"} -->
  <h2 class="comments-title">Comments</h2>
  <!-- /wp:heading -->
  <!-- wp:post-comments /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer","className":"site-footer",
"layout":{"inherit":true}} /-->

As shown in the example, single post and pages are structurally similar and optionally could be used only one singular.html block to display both posts and pages, as done in classic themes.

Step 5: Creating Archive Block Templates

A theme may contain archive templates for displaying lists of blogs, categories, tags or search results. However if an archive file is missing then WordPress uses index.html as default fallback. To display correct results, the handbook doc recommends using an attribute inherit to  apply “filters the query depending on the page” being viewed.

<!-- wp:template-part {"slug":"header","tagName":"header","className":"site-header",
 "layout":{"inherit":true}} /-->
<!-- wp:group {"tagName":"main","layout":{"inherit":true}} -->
<main class="wp-block-group">
    <!-- wp:heading {"level":2} -->
    <!-- wp:query-title {"type":"archive"} /-->
	<!-- /wp:heading -->
	<!-- wp:term-description /-->
	<!-- wp:query -->
    <div class="wp-block-query">
	<!-- wp:query-loop -->
	<!-- wp:post-featured-image /-->
	<!-- wp:post-title {"isLink":true} /-->
	<!-- wp:post-author {"showAvatar":false} /-->
	<!-- wp:post-date /-->
	<!-- wp:post-terms {"term":"category"} /-->
	<!-- wp:post-excerpt /-->
	<!-- /wp:query-loop -->
	<!-- wp:query-pagination -->
	<div class="wp-block-query-pagination">
		<!-- wp:query-pagination-previous /-->
		<!-- wp:query-pagination-next /-->
	</div>
	<!-- /wp:query-pagination -->
        </div>
	<!-- /wp:query -->
</main>
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer","className":"site-footer",
"layout":{"inherit":true}} /-->

In the above modified archive page template example from Caroline’s tutorial, for the query title  <!-- wp:query-title {"type":"archive"} /--> is used (line 6) which displays the archive title as below:

Screenshot showing archive page header display in a browser.

With the query title attribute type {"type":"archive"} enabled in query title, it displays both the tags and categories archives. For a theme theme though, we should add 404.html and search.html block templates.

Adding Navigation is not discussed in both Create a block theme (Block Editor Handbook) and Creating a block based theme (Carolina Nymark). Adding navigation block will be discussed in the part 3 of this series.

Wrapping Up

In this exploratory learning note post, how to create a very simple bare-bone block base theme was discussed. Header navigation, an important component of a theme is missing, so as the styling, which will be discussed in next part of this learning series.

Useful Resources

The following is a list of references link that I gathered during my brief research. While preparing this post, I have also referred some following references extensively. Please to refer to original posts for more detailed information.