There are a lot of really good things coming out of WordPress’s addition of the Gutenberg editor — and the general direction of the CMS is something that Keen can agree with. Writing posts with
blocks instead of one archaic WYSIWYG field is a breath of fresh air and a long-awaited addition. In our opinion, the design of the interface is a massive improvement over the stale and aging UI of previous versions. But, we can’t use it, and that’s a bummer.
Why we want to use it
Keen has been building robust, completely customizable web interfaces for our clients using Advanced Custom Fields’ Flexible Content field type. It’s very, very similar to how Gutenberg Blocks work and this approach has a ton of benefits. Marketers can build not only posts, but their entire site — mega menus, complex footers, pages, and more — all with a layout building tool that’s deliberately designed and customized for the site at hand. This gives content editors the perfect level of customization — everything’s branded, deliberate and controlled, but it’s not to the level of a Visual Composer or similar. Those tools are way too open-ended, provide too much flexibility, and disturbing content combinations arise on the frontend as a result.
We’ve actually been taking this flexible content approach a step further by using WP in a headless role — completely scrapping WP’s PHP template rendering that has absolutely rotted over time and instead writing responsible, maintainable ReactJS interfaces which consume content from WP using its REST API.
See our boilerplate here:
A boilerplate for pairing the WP Rest API with a server-rendered React app - keen-studio/react-wp-rest
This allows for some pretty neat benefits. We can build React components that map one-to-one with their ACF layout compadres. Let’s take a Slider — it might have a title, a description, a style option that provisions for a few different layouts, and then the slides themselves. The slides could be custom-populated or allowed to be pre-filled by the most recent posts from any given post type. From within WP, we can allow content authors the ability to pick and choose where they want to use this slider and how.
The data can then be consumed by React and used to display a nice, tidy
Slider component filled with props from WP.
Same thing as Gutenberg Blocks, right?
So what’s the deal?
Content written and saved by the Gutenberg editor currently is stored in the database as a rendered mess of HTML. I understand why WP did this, because the
content of the post is made up from an arbitrary number of blocks, and there needs to be some sort of standardized way to mash up the content of the article — not to mention what the final, semantic format of the content ends up looking like. This is the way that the classic WP editor has always saved content into the database.
When you retrieve a post from the WP REST API that’s built with Gutenberg, its content might look like this:
<p>Here’s a test Gutenberg post. This is sample content placed into the first little block that pops up.</p> <figure class="wp-block-image"><img src="http://localhost:8080/wp-content/uploads/2018/10/space-1024x576.jpg" alt="Space" class="wp-image-2297" srcset="http://localhost:8080/wp-content/uploads/2018/10/space-1024x576.jpg 1024w, http://localhost:8080/wp-content/uploads/2018/10/space-300x169.jpg 300w, http://localhost:8080/wp-content/uploads/2018/10/space-768x432.jpg 768w, http://localhost:8080/wp-content/uploads/2018/10/space-640x360.jpg 640w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Here’s an image with a caption<br></figcaption></figure>
WP generally parses that mess of data using a hierarchy of Gutenberg-specific HTML comments, but when a post is prepared and sent via the REST API, the comments are all stripped out and we’re given a blob of HTML.
I hope I never have to crack into the PHP that parses a content HTML string into its respective blocks via its commented composition. To me, that’s a strange way to do things and I’ve never liked using comments for programmatic purposes. I imagine reverse-engineering that on the frontend to be able to use React components in concert with the data stored in the blocks via manipulating HTML comments, and I’d rather kick the bucket.
What we are used to and actually already have with the ACF to REST API plugin is a nice little JSON array ready for its React-y time to shine:
With this data, we can
map through the
blocks array, dynamically choose which component to grab via the
acf_fc_layout key, and fill the selected component with the props that it expects. Beautiful.
But, if you want to use a React frontend with Gutenberg as of now, you’d have to
dangerouslySetInnerHTML the entirety of the content in a
<div> — unable to make any use of React components at all.
Given the fact that today’s web ecosystem demands media-rich posts and highly dynamic, engaging content, the content of a post is where a component-based infrastructure provides the most value. Without that, there’s not much reason to even bring React into the frontend as it’d just be for the header and the footer of the site at the expense of a lot of added complexity, and that’s a shame.
All hope is not lost, because the WP team is actively evaluating adding an option to consume similarly structured data to its REST API. See here:
PHP APIs Overview · Issue #8352 · WordPress/gutenberg
This issue is an overview on the new PHP APIs remaining to be introduced or extended. Important aspects to keep in mind…
That simple addition to the REST API would get Keen on the Gutenberg bandwagon. For now, we get to dream and hang out in tech-2006.
Keen’s Suggested Approach
We don’t want WP to simply add an additional, duplicative set of the post’s content, structured by block keys, to API responses. API responses need to remain as tiny as possible which ideally means no duplicative content.
It would be amazing if we were given a query param, like the
_embed parameter — maybe something like
_with_blocks or similar, that replaces the default HTML sent in
content: rendered with a nicely formatted JSON structure.
There is a plugin that adds this type of formatted block JSON to API responses, but it’s pretty massive:
Saves Gutenberg data as an object / array and allows you to access it via REST API - royboy789/gutenberg-object-plugin
It adds an entirely new database table, duplicates the response content within
content:rendered, and … it’s another plugin. This should be built into the core and should definitely not add this level of complexity. No shade thrown to
royboy769, because I think we could get a beer and get along, and I think his head is clearly in the right place, but this responsibility lies with WP.
Anyway, what do you think? Any smart ideas out there?
PS — Keen is about to launch a few separate sites using the code and approach that we’ve alluded to in this post, and we’re extremely pleased with what we’ve been able to pull off. We’ll be talking in-depth about the build process of these projects and will be releasing articles to detail tips, tricks, and lessons learned in the coming months. Stay tuned for that.
In the meantime, maybe we’ll see you in 2006 cyberspace :)