I Rebuild My Site as a Block Based Theme – Here Is What I Learned

, ,

I’ve been keeping my eyes on Full Site Editing within WordPress for quite some time now. And have made a few attempts at building a “Block-Based Theme”. The last time I had tried it was in December of 2020. And since then there has been a lot of movement.

So I wanted to try again and this time I was able to successfully migrate my site (the one you are most likely reading this on) over to be powered by a Block-Based Theme. 🎉

In this post, I will try to outline a few of the things that really impressed me and also a few areas that I have been struggling with a bit / have open questions about.

Please do keep in mind that Full Site Editing and Block Based Themes are still “experimantal” and activly being worked on. So what I am sharing here may have already changed or still is a work in progress.

This post has been written at the time of WordPress 5.8.1 with the Gutenberg Plugin Verison 11.5.0 activated.

🚀 Things I was impressed by:

I have to start this by saying that I am really impressed by the current state of Full Site Editing. Of course, there are areas that are still chunky. But in just over two days I was able to take my existing site and port it over to a block-based theme. And at the same time drastically reduced the amount of custom CSS and PHP needed for the site.

Reduction in Custom CSS needed

In my case, this theme probably already has one of the easiest possible designs to get converted to a Full Site Editing Theme. There are no sidebars, no complex navigation, and the entire site is a one-column layout. So I was able to heavily use color and spacing definitions in the theme.json file and ended up with a reduction of custom CSS written of 36,62 KiB. (46.4 KiB to 9.78 KiB)

This by no means is a scientific test. And I am not saying that the custom CSS I had in place before was super optimized & performant. But it comes to show how little custom CSS actually was needed to give the site back the personality it had previously without needing to write a tone of custom CSS.

Google Lighthouse Metrics

Another thing, that is kind of related to the previous point, I was very aware of while making this transition is the Google Lighthouse metrics of the site. Since I am moving all areas of the site to be block powered and reducing my custom CSS I wanted to, first of all, make sure that the accessibility score was not affected. And it wasn’t. I was actually able to improve all my stores to be in the high 90s or at 100 🎉

Custom Propertie all the things

In my previous theme, I always had a variables CSS file where all the custom properties (vars) lived. This has been removed completely in favor of using the custom properties created by the theme.json. And the benefit of going this is that the variables are changeable in the global site settings and just more exposed. Any by dropping IE11 support they also are just much more powerful because we can finally take advantage of the cascade of the custom properties and override values in different blocks.

This isn’t really an advantage that only relates to block-based themes. But since all of the styles coming from the theme.json are using custom properties in elements that already doesn’t support IE11 and therefore it just becomes easier to drop the support 🙂

Shared styling between the editor and the frontend

I’ve always been a huge advocate for the visual parity of all the things between the frontend of the site and the editor. And by using theme.json and add_editor_style to include the full frontend stylesheet in the editor makes it sooo much easier.

My site now has no custom CSS that is specific to the editor because the markup is a match and all the things have visual parity without additional effort. So that is great.

I would still love the post editor to go one step further and show all the things that are defined in the “content” section of the given template that is selected for that post. (See #more-elements-in-post-editor)

🤔 Open Questions / Ideas:

While working on this refactor there also were several things where I am left with open questions or with ideas/wishes of how things could be improved. Some of these items might be by design. Others might still be a work in progress. So take these with a grain of salt as a snapshot of what my experience was rebuilding my site and not have been super involved in Full Site Editing up until now.

I will also try to add links to Issues on the Gutenberg Repository if I find a related ticket for the items I’m discussing here.

One of the areas I’ve been struggling with the most is dealing with Menus. And I am not sure whether that is because of my familiarity with the old system of the menu editor and having theme locations that can be assigned to navigation areas, or whether there are issues with the current approach.

My first question is how block-based themes should define menu areas with starter content. Is it correct to create a navigation with some items in it that have empty URL’s so that the user of the theme can see what the menu looks like and then needs to go into the template editor to change the menu?

<!-- wp:navigation {"itemsJustification":"center"} -->
	<!-- wp:navigation-link {"label":"Home","title":"Home","type":"page","url":"/"} /-->
	<!-- wp:navigation-link {"label":"About","title":"About","url":"#"} /-->
	<!-- wp:navigation-link {"label":"Work","title":"Worl","url":"#"} /-->
<!-- /wp:navigation -->

If that is the case does this mean that from that point on you are locked out of receiving updates for the template part the menu was located in because you have modified it? I’ll go into more detail around that in the next section (See #locked-out-of-template-updates)

How do you reuse a menu?

Another thing is how do you use the same menu twice on a site? I am very used to the idea of the structure of menus being managed separately from the visual representation of a menu location.

Let’s for example say I have different variations of my header template part. One that gets included on the index.html template and one that gets included in the page.html. Does that mean that I have to edit the items in the menu in two places now? Or should menus now be created as Reusable Blocks? If so what happens when I want the menu to be vertical in one place and horizontal in another?

Is there something that resembled the concept of a “menu location” in traditional WordPress?

What happens to menus when you switch Themes?

Finally, how do you keep your menu structure intact when you switch between themes? Since they are now part of the template that doesn’t transform over.

In “Classic” Themes if a menu location was created it may not be assigned to the correct spot in the new theme. But all you have to do is go into the menu editor and assign it to the correct location. But when it is part of the template a different theme will start from scratch.

Does making modifications to templates / template parts lock you out of recieving updates via the template / template part that ships in the theme?

I already touched on this lightly before in the Menu section, but what happens when you go into the template editor to change the background color of the header or add an item to the main navigation of the site. Are you now locked from receiving updates when the theme itself makes modifications in the header.html template part?

If I am understanding it correctly making modifications in the template editor effectively forks the template and you now have a separate version of that template in the database. And from that point on you are using that template instead of the one that is shipped in the theme.

And this is a really cool and flexible mechanism because it empowers you to make adjustments. I only fear that there isn’t really a path of how you ever are able to receive updates again if the theme adds new features or even minor accessibility improvements. And what worries me most about this is, that even traditional “content” changes like adding an item to the main navigation now are changes in the template part and therefore cause this forking to happen.

Sprcificity of styles coming from theme.json

While working on creating styles through theme.json there were quite a few instances where I needed to write !important into the style declaration in the theme.json itself.

It mostly happened when a global rule like settings.spacing.blockGap created a CSS rule with a higher specificity than a block specific rule styles.blocks.core/paragraph.spacing.margin.top.

{
	"styles": {
		"spacing": {
			"blockGap": "1.5rem",
			"customMargin": true,
			"customPadding": true
		},
		"blocks": {
			"core/image": {
				"spacing": {
					"margin": {
                                            "top":"calc(var(--wp--style--block-gap) * 3) !important",
                                        "bottom":"calc(var(--wp--style--block-gap) * 3) !important"
					}
				}
			}
		}
	}
}

I’m not sure how this can get implemented but semantically to me it would make more sense if styles that are defined on a block have a higher specificity than global rules. And you shouldn’t have to use !important rules in the theme.json unless you are doing some really sketchy things 🙂

Vertical Rythem adjustments

A pattern I’ve seen and used very often is that items that are aligned wide or full have larger vertical spacing than other block elements. Right now the blockGap value only targets the margin-top. So the workaround I used is setting the margin-top and margin-bottom value myself any time I wanted to increase the spacing. But I also needed to do that in my themes custom CSS because currently there is no selector in the theme.json to target block alignment.

Being able to target attributes like alignment would be super cool because it would allow you to scope styles to these options that are shared between many blocks.

Very verbosse usage of variables within theme.json itself.

This point is purely aesthetic, but it feels odd to me to be using variables that get created based on values set within the theme.json file within the theme.json file.

Every time you want to reference a specific color for example you are writing out the full custom property var(--wp--preset--color--primary). This has two problems in my mind.

For one there is no autocompletion or level of code hints that we can get from this approach. Which makes authoring these theme.json files a whole lot more difficult. And secondarily it locks the naming convention of the variables in because if there are any changes under the hood the references in here don’t automatically change also. There is this translation layer that transforms the theme.json and creates the custom properties for us. But we are not taking advantage of it in referencing the values.

Something like settings.color.presets.primary maybe a better way to write the same thing. It uses the schema of the JSON file and allows you to understand where the value that you are using is coming from. Without having to do the translation of the theme.json backward in your head.

I do also recognize that it is much more complicated than how I am making it out to be here and using the custom property also comes with benefits because the value of a given attribute is just a string that gets output in CSS. Effectively allowing us to use things like calc or any other CSS functions in our theme.json.

Ability to target styles and custom properties to template parts

In my example, I want to have the blockGap only apply within the actual site-content area and not the site-header or site-footer. But currently, I have to make these adjustments manually in CSS with very verbose selectors to beat the specificity of the theme.json rules.

On a larger note, I’m finding it somewhat difficult treating every single group block on the site the same. In the theme.json, there is no way of targeting specific groups.

This appears to already be discussed in issue number #27233

Difficulty discovering what attributes are available and very verbosse syntax

I’m always having difficulties finding out what block supports what attributes and which of those generate what classNames . Sadly because it is all just HTML comments there also aren’t any code hints being shown like when you create a block.

And also it just feels very redundant having to write out both the attribute and the class that would get generated from the block.

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

I would sometimes almost prefer to write these templates in something similar to the array syntax of InnerBlocks or only the HTML comments for blocks instead of having to write both the block comment and the markup manually.

This will become especially interesting when there are block deprecations. Is there such a thing as template deprecations? 🤔

Show more elements defined in the template within the post editor

At the moment the post editor itself still doesn’t look like what my post will look like in the frontend. This is due to the fact that elements like the featured image, post categories, publish date, etc are not shown in the post editor. They still are only metadata that can get set in the page sidebar. But they don’t visually show up in the editor.

This means that even with full site editing I’m still finding myself having to constantly switch back and forth between the actual preview in a new tab and the editor. And by seeing how nice it works in the template editor it seems like this could be fixed 🙂

Imagine seeing the featured image, categories, the publish date, etc. in the post editor

In the case of my site, this here is the single.html template. And if we take out the wp:template-part and render the rest in the post editor that would be a great editorial experience 🙂

<!-- wp:template-part {"slug":"header","tagName":"header","align":"full","backgroundColor":"light-primary","textColor":"dusk","className":"site-header","layout":{"inherit":true}
} /-->

<!-- wp:group {"tagName":"main","align":"full","className":"site-content"} -->
<main class="wp-block-group alignfull site-content">
    <!-- wp:post-featured-image {"align":"full"} /-->
    <!-- wp:group {"tagName":"header","className":"entry-header","layout":{"inherit":true}} -->
    <header class="wp-block-group entry-header">
        <!-- wp:post-title {"level":1} /-->
        <!-- wp:post-date /-->
        <!-- wp:post-terms {"term":"category"} /-->
    </header>
    <!-- /wp:group -->
    <!-- wp:post-content {"layout":{"inherit":true}} /-->
    <!-- wp:group {"layout":{"inherit":true}} -->
    <div class="wp-block-group">
        <!-- wp:post-comments /-->
    </div>
    <!-- /wp:group -->
</main>
<!-- /wp:group -->

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

There would need to be some sort of way to semi-lock those items because you don’t want to edit the template by mistake. But with the new locking mechanism and the learnings from reusable blocks, I believe this could be great.

Wrapping up

Coming out of this experience of rebuilding my site I have to say that I am really encouraged by where things are at. There is great progress being made and I’m becoming more and more comfortable with this new way of creating themes. There are still many open questions and I’m sure there will be things that will not be 100% there at the beginning.

My goal in writing this blog post is to share my thoughts and experiences using this experimental feature at this point in time. There are likely things in my findings that I misunderstood or did wrong. Or items that have been discussed several times before.

I was, and still kind of am, afraid of wasting people’s time because I haven’t been actively involved in many of the FSE related discussions and now all of the sudden am raising all these thoughts. So I want to thank Anne McCarthy and Carolina Nymark for encouraging me to share my findings and hope that somebody can gain something from myself sharing my experience. 🙂

If you are interested in the code of my theme it is up on GitHub here: https://github.com/fabian-kaegy-org/finn

5 Replies to “I Rebuild My Site as a Block Based Theme – Here Is What I Learned”

  1. Nice! I too have been keeping eye on block-based theme and recently started making my hands little dirty. I am using a slightly modified version of Quadrat [https://wordpress.org/themes/quadrat/] in one of my personal project site here [https://justwrite.atsixtyseven.com/this-site-is-powered-by-labre-blocks/].

    Still, the Qudrat blocks has areas that don’t seem too work as expected but Automattic theme team is working on them.

  2. Fabian! For starters, thanks for writing this up and for so kindly asking how best to share some of these larger questions you had. It’s wonderful to read a post unrestricted by GitHub issue formats so I deeply appreciate you taking the time. I was particularly excited to read both how quickly you were able to convert your theme and the gains you got in doing so.

    At this point, I’ll go over each item of feedback you have and, in a few places, encourage you to open up some GitHub issues. Of course, I’m happy to open them on your behalf too if that’s easier 🙂

    >Is it correct to create a navigation with some items in it that have empty URL’s so that the user of the theme can see what the menu looks like and then needs to go into the template editor to change the menu?

    I’ve mainly seen folks using an empty navigation block, relying on the navigation block placeholder, and situations where folks will add empty links for folks to edit (namely with patterns). I’m not sure if there’s a defined best practice here so I do think this would be a great issue to open in GitHub for further discussion as I’m sure I’m missing pieces too. In general though for now, I’d stick to the empty navigation block as it’ll allow the user more options from the start.

    >Finally, how do you keep your menu structure intact when you switch between themes? Since they are now part of the template that doesn’t transform over.

    This would be another great one to open issues for. I chatted with some themers at Automattic and they too have run into this! Sounds like a pattern and worthy of wider discussion.

    >Another thing is how do you use the same menu twice on a site?

    The best way to do this would be to place a navigation block within a specific template part so, as you’re editing the template part, it’s updated appropriately everywhere that same part is used!

    >Does making modifications to templates / template parts lock you out of recieving updates via the template / template part that ships in the theme?

    AFAIK, this is being discussed in this issue: https://github.com/WordPress/gutenberg/issues/27851 Definitely recommend chiming in here to offer the theme author perspective!

    >render the rest in the post editor that would be a great editorial experience

    This reminds me a bit of an issue on how to better view a template while editing a post as I imagine if this were more defined, it would provide the experience you’re looking for: https://github.com/WordPress/gutenberg/issues/27847

    At the same time, designs were previously shared to provide better placeholder content for the theme blocks to make it a more 1:1 experience. I agree this needs to be improved: https://github.com/WordPress/gutenberg/issues/30029

    Hope this helps provide more context 🙂 Your site looks awesome by the way.

Leave a Reply

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