WordPress / Tutorials / Gutenberg
Posted 4.17.2018
By Matt Glaser

Gutenberg Blocks and the WordPress REST API

With a little help, Gutenberg block data makes the WordPress REST API a great fit for React.

At Aleph, we’ve done a lot of work to allow our clients to use WordPress as a content-management system behind a front-end interface driven by React/Redux. It has worked very well both on large and smaller projects, but there are a lot of hoops to jump through to get even some very basic features in WordPress to play nice in the React world. 

Gutenberg, if you hadn’t heard, is the New Way over in WordPresstown. It’s a big change to the fundamental way that the WordPress post edit screens work, and if you’re only hearing about this now, it’s time to get ready for it. There is currently a lot of writing going on about what it all means and how it will affect the WordPress community. The article you're reading is an attempt to add a couple of specific tips to the mix.

There are a lot of hoops to jump through to get even some very basic features in WordPress to play nice in the React world.

Since Gutenberg encourages block-based content management, does this make it easier to integrate front-end applications with the WordPress API?

The tldr; answer is...
Yes, sort of, and the future is possibly pretty bright.

Rendering WordPress content in React is a drag

Getting a front-end application to spit out content from the WordPress API is really no big deal. Putting that information into the application's "state" is slightly tougher, but not hard when you’ve done it once or twice. The thing is, getting it to spit out post_content is riddled with difficult issues, and if you’ve never had to do it, I envy you.

While there are many, many issues to face here, the single biggest one is how to handle WordPress shortcodes and embeds. To try and put it briefly, there are some shortcodes that only render HTML, so parsing them via PHP and sending them that way through the API is fine, but what about stuff that requires JavaScript to work? Or complex formatting that probably needs its own component like the WordPress [gallery] shortcode? These are best handled by parsing them in React, which leads to all sorts of issues that we’ll write a whole other article on later.

Regardless of how you want to handle this stuff, here’s a sample bit of content showing what you get from the WordPress API in post_content as it stands pre-Gutenberg (snipped):

Loading...

Look at all that "awesome" HTML in our database! There’s a YouTube embed in there, a blockquote, some headers, etc. How would we put this into a React component?

Sure, just wrap it all in dangerouslySetInnerHTML and call it a day, right? Then you just have a style scheme that handles your headers and blockquotes and…

Uh oh. That’s not really the React Way, is it? What we actually want to do is parse out each one of these HTML tags as its own component, apply styles at a component level, and re-use code wherever we can. That means that we have to either: 1. Actually parse the HTML in JavaScript and create React components from it, which is super-lame, or 2. Separate each HTML tag into like Advanced Custom Fields that we can then render in the API, making the WordPress interface a huge, one-off mess.

We’ve been doing a lot of approach number 1 to get this done. Shortcodes really make this an adventure. There is hope on the horizon, however…

Gutenberg is Blocks as React Components

It is awesome that now, instead of having all the above code pasted into a single WYSIWYG field, Gutenberg will allow us to break the whole thing up into logical blocks. Now, from the editor standpoint, I have:

  1. A block type called “heading” that contains just the H1 content
  2. A few paragraph blocks with “rich text” basic formatting in it, like <em> and <strong> tags, and links too.
  3. A YouTube block with the embedded Monorail Cat Video in it.
  4. A block type called “Blockquote” with the blockquote in it.

This is tantalizing, because as a web developer I can see a 1:1 relationship between a Gutenberg block in the editor and a module on the front end:

  • Heading Block → → Heading Component
  • Paragraph Block → → Paragraph Component
  • YouTube Block → → YouTube Component
  • Blockquote Block → → Blockquote Component

This feels just right to me! So after I create my Gutenberg post I check the API response to see my sweet blocks and I see… no change whatsoever.

For some reason, at the moment (and things change rapidly so who knows what’s gonna happen) Gutenberg does not break out block content in the API. Instead, it stores the block data as HTML comments in the post, which as raw text looks like this:

Loading...

WordPress has helper functions that parse this kind of markup, transparently rendering posts properly in PHP and in the editor. How, though, can we get the blocks from the API in a front-end application?

There is a somewhat complicated and evidently controversial conversation addressing this very issue, but in lieu of that, we have to do some hacky workarounds to get what we want. As we said, WordPress has a helper function called gutenberg_parse_blocks that will parse the raw HTML into an array for us.  Adding this snippet somewhere in your theme or a plugin does the trick:

Loading...

NB! This is directly cribbed from this blog post (thanks!) but their version created some blocks with no content or attributes other than line breaks, which we probably don’t want, so I added a foreach that only pulls in blocks that have a blockName attribute.

With this in our code, we get this new blocks array in our WordPress API post response:

Loading...

Now, our vision of a 1:1 relationship between WordPress and our frontend app is beginning to take shape! Note that this is just the tip of the ice(Guten)berg. We need a bunch of PHP and WordPress logic to keep this from breaking or getting out of hand, and we’re still going to have to dangerously set HTML all over the place, but this at least keeps HTML parsing in JavaScript to a minimum.

Hopefully this mini proof-of-concept that demonstrates pretty clearly that the block API data is going to be really useful to front-end projects when it makes its way into the WordPress Core API.