# Why I Spent 16 Months Turning 400+ Holiday Cottages Into WordPress Blocks

- Link: https://elliottrichmond.co.uk/why-i-spent-16-months-turning-400-holiday-cottages-into-wordpress-blocks/
- Published: 2026-07-07T08:41:19+00:00

**TL;DR:** I rebuilt [kate & tom’s](https://kateandtoms.com), a 400+ property holiday
cottage site, from Advanced Custom Fields flexible content into a native WordPress
block theme. The client can now build pages from patterns instead of waiting on 
me to code a new widget every time. The hard part was migrating 10,590 widgets out
of post meta and into blocks, which I did with a purpose-built plugin re-run against
fresh production snapshots throughout development. I trained the team using WordPress
Playground so they could break things safely, and even before any tuning the new
block theme already outscores the old classic theme on PageSpeed. It took sixteen
months because the site is genuinely that complex, and it was a one-man job. Checkout
the WordPress blocks migration here.

Last week I launched a site for [kate & tom’s](https://kateandtoms.com), a luxury
cottage holiday company with houses dotted right across the UK. Over 400 of them,
in fact, each one pulling its own live availability from a third-party booking API.
That’s not a small site by anyone’s measure, and it’s taken sixteen months to get
here. I want to explain why.

![Old WordPress vs New WordPress](https://elliottrichmond.co.uk/wp-content/uploads/
2026/07/old-vs-new-migrating-old-form-based-acf-to-modern-wordpress-native-blocks-
1024x782.png)

That’s the shift in one picture. On the left, the old backend: a stack of form-based
ACF widgets the client filled in field by field. On the right, the same house rendered
from native blocks in a modern block theme. Getting from one side of that arrow 
to the other, 400-odd times over, is what this post is about.

## The old site worked, it just didn’t work for them

The previous build was Advanced Custom Fields flexible content, and to be fair to
it, flexible content did its job for years. The client could drop widgets onto a
page and build something reasonably varied without touching code.

The catch was what happened when they wanted a new type of widget. That meant coming
to me. I’d have to build the logic behind it, test it across desktop and mobile,
then deploy it before they could actually use the thing. For a marketing team that
wanted to move quickly, that’s a real blocker, and it was the main reason for moving
to a block theme.

## What the site actually is

Each of the 400+ houses has its own landing page, with child pages underneath it
for availability, key facts, book now, and a gallery. That parent-child structure
alone gives you a sense of the scale, but the taxonomy behind it is where it gets
properly hairy. Locations run to 62 terms. Activities sit at 109. Sizes cover 16
options, types 7, occasions 30. Features alone come in at 73 terms, which is the
kind of number that makes you double check you’ve read it right.

On top of that there’s an enquiry form wired up per house, so the marketing team
can actually see where enquiries are coming from across the whole portfolio rather
than one big anonymous inbox. And then there’s the booking calendar itself, where
a visitor picks a couple of dates and gets shown available periods around them, 
all pulled live from the third-party API. None of that is decorative. It’s the stuff
that actually earns the client money.

## Blocks over widgets

The move to a modern block theme was about handing that flexibility back to the 
client. Instead of asking me for a new widget every time marketing wants to try 
something, they can now build pages themselves from a library of patterns, no development
time required. That’s the whole point of the block editor when it’s set up properly.
It’s not just a nicer interface, it removes a dependency that was slowing them down.

## The migration itself was the hard part

Here’s the bit that ate most of the sixteen months. All that old flexible content
lived in post meta, and none of it transfers to blocks on its own. And there was
a lot of it. When I actually counted, there were 10,590 widgets across all the houses,
an average of 25.9 per house, with 401 houses carrying 21 or more each. Every one
of those had to end up as a block.

![Some existing widget placement stats from an old WordPress site that needed migrating
to a new Block theme WordPress site](https://elliottrichmond.co.uk/wp-content/uploads/
2026/07/some-existing-widget-placement-stats.png)

Numbers like that are exactly why manual conversion was never on the table. You 
don’t hand-edit ten and a half thousand widgets. So the job split into two stages.

First, I had to build a library of block patterns that matched every existing ACF
widget, one for one. Only once those existed could I even start on the second stage,
which was writing a migration script to convert the actual content, pulling everything
out of post meta and rebuilding it as post content in blocks.

I won’t pretend it was clean. Some of that conversion came out flaky, and a chunk
of pages needed manual fixing afterwards because of how the block editor parses 
and serialises content. Get the `innerHTML` and `innerContent` even slightly out
of step and the editor throws up its “Attempt Block Recovery” prompt, which is the
sort of thing that eats an afternoon. That’s the honest version of events, not the
tidy one. Given the size of the site, I think sixteen months is a fair reflection
of the actual work rather than scope creep, but it’s still a long time to be inside
one project.

I wrote up the technical side of all this in far more depth about a year ago, back
when I was first getting my head around it, including the pattern-based approach
and the `Pattern_Handler` class that does the heavy lifting. If you want the code-
level version of this story, [that case study is here](https://elliottrichmond.co.uk/migrating-legacy-wordpress-content-to-the-block-editor-a-real-world-case-study/).

Worth a note if you read that earlier piece: back then I put the scale at roughly
200 house listings and 500 widgets. That was an early estimate before I’d properly
audited the data, and it turned out to be a fair way short. The real figures were
400-plus houses and over ten thousand widgets. That gap is a lesson in itself, really.
Until you actually count, you’re guessing, and migration guesses tend to run low.

## The migration ran as a plugin, in a fixed order

All of that logic lives in a dedicated plugin I built just for this job, rather 
than a throwaway script. The reason it’s a proper plugin is that I ran it over and
over throughout development, not once at the end.

Here’s the wrinkle a lot of migration write-ups skip. Development ran for months,
but the real site was live the whole time, and its data kept moving. Special offer
dates rolled into the past, availability changed, content got tweaked. If I’d worked
from a single old export, the migrated site would have drifted further from reality
every week.

So the workflow was to take periodic snapshots of the live production database, 
pull each one down locally, and then re-run the whole migration against fresh data.
A shell script handled the sequence, refreshing the local database and then firing
each migration function in order through WP-CLI `eval` calls. Roughly, it goes like
this:

 1.  Build the page header banner and title widgets
 2.  Convert the house photo galleries
 3.  Set the thumbnail featured images
 4.  Clean up the existing house sub-pages
 5.  Run the main widgets-to-patterns conversion across all houses
 6.  Rebuild the house sub-pages (availability, book details, calendar)
 7.  Wire the availability calendar up to the booking API
 8.  Append the galleries and key facts to their pages
 9.  Add the seasonal and availability header banners
 10. Stamp the signature styling across the sub-pages

Order matters here. You can’t append galleries to sub-pages that haven’t been rebuilt
yet, and you can’t wire up a calendar before the book details page exists. Each 
step assumes the one before it has already run, which is exactly why it lives in
a script rather than being fired by hand. Refresh the database, run the script, 
and a few minutes later you’ve got an up-to-date migrated site to test against. 
That repeatability is the thing that made a sixteen-month migration survivable.

## Training the client without the fear of breaking anything

Once the new site was ready, there was still a training problem. Five or six people
at kate & tom’s needed to get comfortable with the block editor, having only ever
known the old widget system. For that I used [WordPress Playground](https://playground.wordpress.net/)
and a Blueprint that loaded their actual theme, plugin, and a slice of their real
content into a disposable, in-browser WordPress instance. If they broke something,
a refresh put it straight back. I’ve written about how that setup works in more 
detail in [wordpress-playground-blueprints-client-training](https://elliottrichmond.co.uk/why-i-spent-16-months-turning-400-holiday-cottages-into-wordpress-blocks/wordpress-playground-blueprints-client-training),
so I won’t repeat it here, but it turned out to be one of the best training tools
I’ve used with a client.

## An early word on performance

Here’s something I didn’t go looking for but was pleased to see. I ran the new site
through Google PageSpeed Insights and compared it to a snapshot of the old classic
theme from October 2022.

![Page speed insights from a WordPress Classic theme ](https://elliottrichmond.co.
uk/wp-content/uploads/2026/07/page-speed-insights-before-882x1024.png)

![Page speed insights for a new WordPress Block theme ](https://elliottrichmond.
co.uk/wp-content/uploads/2026/07/page-speed-insights-after-850x1024.png)

The old theme scored 22. The new block theme scores 67 straight out of the gate.
Total Blocking Time went from a painful 2,410ms down to 200ms, First Contentful 
Paint dropped from 3.2s to 2.0s, and Cumulative Layout Shift went from 0.1 to basically
nothing at 0.009. For a straight conversion with zero performance work done on the
new site yet, that’s a genuinely good starting point.

Now, I want to be honest about what this is and isn’t. It’s not an acid test. The
two snapshots were captured four years apart, on different emulated devices, using
different versions of Lighthouse, so it’s a rough comparison rather than a controlled
one. And that 128.6s Largest Contentful Paint figure on the new report is obviously
nonsense, almost certainly a measurement artefact from a lazy-loaded hero image 
or the cookie banner tripping up the test, not a real load time. I’ll be digging
into that.

So take it for what it is. A modern block theme, before any tuning, comfortably 
outperforming the old classic theme it replaced. That’s the pattern I’d expect, 
and there’s plenty more to claw back once I actually sit down and optimise it.

## Was it worth sixteen months?

The client is genuinely pleased with it, and so am I, mind. I got a bottle of bubbly
out of the launch, which never happens, so that tells you something. Here’s how 
one of the team put it:

> It’s been a long awaited and exciting upgrade and, despite being a little nervous
> about using the new backend, I have found it extremely straightforward to get 
> used to already. It offers so many more features and capabilities than the old
> site and it’ll enable us to streamline a lot of our day-to-day tasks and progress
> with long-awaited upgrades to how the website looks and functions. Thank you!

That “nervous about the new backend” bit is exactly why the Playground training 
mattered. The whole job is only a win if the people using it every day feel confident,
not just the developer who built it. I shared that before-and-after shot [on X](https://x.com/elliottrichmond/status/2072685735656706441)
when it launched, and there’s a proper video coming on my YouTube channel walking
through the ACF-to-blocks migration approach in more depth, because I think it’s
a route more agencies are going to need soon whether they like it or not.

If you’re still running a client site on [Advanced Custom Fields](https://www.advancedcustomfields.com/)
flexible content and every new layout idea means booking in development time, it’s
worth asking whether the block editor could take that job off your plate. I’ve written
more about the block theme side of things over on [my site](https://elliottrichmond.co.uk).

### Share this:

 * [  Facebook ](https://elliottrichmond.co.uk/why-i-spent-16-months-turning-400-holiday-cottages-into-wordpress-blocks/?share=facebook)
 * [  X ](https://elliottrichmond.co.uk/why-i-spent-16-months-turning-400-holiday-cottages-into-wordpress-blocks/?share=x)

### Like this:

Like Loading…
