Skip to content
Daniel Shaw · WordPress & WooCommerce Developer Wellington, New Zealand

👋 Not available for new client work right now!

Gutenberg blocks for legacy content

I've recently started building custom blocks to help transition client websites with legacy content to WordPress 5.0. Big question: why start block-building now?

True, it appears we're still a way off seeing the Gutenberg plugin officially merged into WordPress core, but it feels like the plugin has started to stabilise. Crucially, my natural laziness and general wariness towards learning block development too early has started to wear off. It's extremely unlikely I'll be going as far as activating the Gutenberg plugin on live sites, but it does feel like the right time to start prepping sites to work with the new editor experience.

Building WordPress-powered websites within this brave new block world is going to require a new practice and approach. When it comes down to it, I'm choosing to start building blocks now in order to kickstart my brain into engaging on these new terms.

A new block for old content

It's important to note the discussion that follows is not about improving existing functionality or developing an optimal block solution. This is purely about ensuring an existing workflow can continue in the new editor environment.

A real-world case study

A repo with a complete plugin for this case study is here: Set Menu block

The Capitol website is a simple brochure-style website I set up a couple of years ago. When researching the local business competition it was interesting to see how many restaurant websites offer menus in a terribly unfriendly format: PDF. Capitol's dinner, lunch and breakfast menus are regularly updated, so I wanted to ensure updating these menus would be as easy and natural as possible for the restaurant owner.

The front-end display for these menus aligns a menu item description to the left, with the price sitting to the extreme right. This requires a way to target the price with its own style rule. Setting up custom fields to isolate these pieces of data is a common way to approach this, but in this case it felt like overkill. Plus, I'm always nervous about styling these types of fields in the admin view, something I would have chosen to do in order to keep each menu item's description and price inline.

In the end—and after a discussion with the restaurant owner about how she would like to edit menus—I stuck with the default WordPress page editor, using parentheses to denote the price.

Here's a menu snippet from the editor containing a few line items made up of a description and price:

Grilled ciabatta with local olive oil (4.50) Antipasto (27.50) Tomato & basil bruschetta (13.50) Shell pasta with salmon, roast red peppers & creme fraiche (23.50 / 33.50)

A consequence of using the default editor is each line automatically gets wrapped with a <p> tag.1 Filtering the_content() to wrap the price in a span and remove the parentheses generates mark-up that is easy to target with CSS, while removing any burden on the restaurant owner to remember special formatting rules.

Pretty simple stuff, and I think it's exactly this type of situation the new editor experience will make even easier.

Scope by constraint

Currently, a line entered like this in the WordPress editor:

Grilled ciabatta with local olive oil (4.50)

…will resolve as the following mark-up:

<p>Grilled ciabatta with local olive oil <span class="meal-price">4.50</span></p>

…to be displayed like this on the front-end:

Grilled ciabatta with local olive oil 4.50

Being constrained to replicating the existing mark-up helps maintain a clear scope for a new block. I especially don't want a reason to write new CSS because this will effectively mean I'm free to refactor everything else. The sole goal is to enable a block-driven approach to this legacy content with a minimum of effort.

What this means is, I'm:

  • not attempting to design an optimal block solution
  • not providing a free upgrade in functionality
  • avoiding re-writing new styles


A block plugin is born: see the completed block plugin. It was surprisingly straight-forward to build, though, being my first time there is no doubt I could have made some better choices.


Life is going to be very different for WordPress developers once this lands—I believe for the better (in the long-term, definitely). This is a good thing to happen to WordPress, but I don't have the smarts to tell whether it's the right thing. I wonder whether this will drive some developers away: the adjunct to working with modern javascript and tooling is, surely, to start working with modern frameworks.

Some thoughts I had while working on the plugin:


  • it now feels very natural to compose a content-driven interface
  • creating an icon for a block is a nice accent
  • it's a pleasure to have modern tooling a natural part of the WordPress development process


  • content is not saved as post meta by default
  • I became very tired of seeing the 'This block has been modified externally' notice while making tweaks during development
  • it wasn't always easy to quickly tell whether something was a bug or an error on my part, due to my inexperience and the current beta status of the Gutenberg plugin
  • it feels like there's a lot more work involved compared to how something similar would currently be achieved, and I don't thing this can be attributed solely to familiarity
  • who will save us from all the blocks?

Regarding the first 'con': it wasn't clear to me initially that values stored in a field-type interface would be stored in one big blob as post content. If there is one major improvement to the plugin I built here, it would be to set up field values to be saved as post meta. This would allow for these values to be easily repurposed, for example: setting up restaurant schema mark-up using something as granular as hasMenuItem would be horrific with a blob of post content.

Also, seeing the 'modified externally' message constantly appear during development tests made it clear it seems wise to make blocks dynamic, unless the block content will be something extremely trivial. It will be interesting to see the patterns that emerge around handling this, and whether there's something of a retreat to server-side rendering.

  1. I'm not a fan of conditionally juggling wpautop.