A plan to ease transition to block-based themes


2 weeks ago we had our first meeting for the future of WordPress themes, also known as block-based themes. In that meeting, we discussed how future themes will be structured and touched on the way they can be built.

The future is bright, but there are thousands of themes that are not built as block-based themes. These will continue to function properly for years, WordPress has always been a platform that embraced backwards-compatibility and very rarely (if ever) deprecates functionality.

It is inevitable that some existing themes will want to take advantage of the new structure and benefits that Full Site Editing has to offer. The problem is that it is a significantly different implementation to what we currently use, and there is no easy way to transition to that new structure.

This is where this post comes in: Figuring out a plan to ease the transition to block-based themes in a way that makes sense. Start a discussion with theme-authors and find a way to move forward.

Current WordPress themes use PHP templates and a lot of settings in the Customizer to define colors, typography options, settings that change the markup of some areas etc. Future themes, however, will not have PHP templates. Instead, templates will be defined in .html files containing a “preset” for how blocks will be arranged on the screen. Users will be able to override these “presets” and edit them in their editor. Most of the Customizer’s duties will be handled by the global-styles implementations currently being worked-on in Gutenberg.

So, how do we ease migrating from hardcoded PHP templates to a blocks structure?

As a first idea, we have started experimenting with code that will allow authors to define an upgrade path. So if they have a simple header that has the following components:

  • Green background
  • White text
  • Site-logo on the left
  • Navigation on the right

then that could be translated to the editor as a group block with green background and white text, containing 2 columns; In the 1st column we can have the site-logo block and on the 2nd column a navigation block.

A theme author wanting to transition to a blocks-based structure would do something like this:

/**
 * Return markup with blocks.
 *
 * Takes existing settings and migrates them to a blocks structure.
 *
 * @return string
 */
function mytheme_get_header_blocks_migration_markup() {

	// Open group block.
	$open_group = '<!-- wp:group {"backgroundColor":"' . get_theme_mod( 'header_background', '#fff' ) . '","textColor":"' . get_theme_mod( 'header_text_color', '#000' ) . '","align":"full"} --><div class="wp-block-group alignfull has-text-color has-background"><div class="wp-block-group__inner-container">';

	// Open columns block.
	$open_columns = '<!-- wp:columns --><div class="wp-block-columns">';

	// Build 1st column.
	$first_column = '<!-- wp:column {"width":33.33} --><div class="wp-block-column" style="flex-basis:33.33%"></div><!-- /wp:column -->';

	// Build 2nd column.
	$second_column = '<!-- wp:column {"width":66.66} --><div class="wp-block-column" style="flex-basis:66.66%"></div><!-- /wp:column --></div>';

	// Close columns & group.
	$closer = '<!-- /wp:columns --></div></div><!-- /wp:group -->';

	return $open_group . $open_columns . $first_column . $second_column . $closer;
}

// Migrate header template-part.
new \WPTRT\Blocks_Migration( [
	'content' => mytheme_get_header_blocks_migration_markup(),
	'slug'    => 'header',
] );

The above code is a simple and incomplete example, but it does show the basis of this idea:
We created the structure we needed in the editor using core blocks.

Then we switch our editor from “Visual Editor” to “Code Editor”, and we have our blocks code there. We can take that code, put it in a function and replace the variables we need. In our case that meant using the header_background and header_text_color settings, retrieved using get_theme_mod(). In our example theme we can then remove these settings from the Customizer since they will now be controlled from the blocks.

After the author creates the blocks-based markup, they can call the migration class. When this class runs in our example, it will do the following:

  1. Check if there is a template-part with the slug we have defined.
  2. If a template-part with that slug exists, then exit early, there’s nothing to do here since either the user has created their own header (in which case we don’t want to overwrite it), or the migration has already run. If a template-part with the defined slug does not exist, then move on to the next step.
  3. Create a new template post (that is a post in the templates custom post-type that full-site editing will use), and add the contents in there.

Once the migration script creates the header template-part post, that is going to override the “preset” .html template that we have in our theme.
When a user first installs the theme (new installations), they will use the preset (which will contain the defaults and is a basis which users can then customize).
When a user upgrades their installation to the blocks-based version, the theme will retrieve their Customizer settings, build the markup based on what the author has written and created the post which will override the “preset”.

Most things that themes use already exist as blocks in core, or are getting added to make the Full-Site Editing easier.
But there will be things that cannot be directly ported.
One of these things is widgets. Since core widgets already exist as blocks, it is possible to translate them to that new structure. However 3rd-party widgets that don’t exist as blocks will not be easy to be auto-detected and translated.

So far we are running some tests with simple structures and we can say that it is possible to build something to ease transitioning existing themes to block-based themes. But before we start building a proof of concept implementation that we can iterate on and experiment with, we need your assistance and feedback.

What are the things that you feel Full-Site editing would need to have in order for theme-authors to be able to build themes?

If you have ideas on how to ease the transition from widget-areas to blocks, we’d love to hear them.

Other than non-core widgets, do you foresee issues with converting existing themes to block-based?