[ADR-0003] WYSIWYG Blocks Architecture

Turn P4 Blocks into WYSIWYG blocks.

  • Status: accepted

  • Deciders: Development & Design teams

Context and Problem Statement

Many blocks look broken in the editor. The editing experience was just ported from the old Shortcake blocks but it's not consistent with the native WP editing experience, which is made of WYSIWYG blocks.


Turn P4 Blocks into WYSIWYG blocks:

  • Port the Twig template into its JSX equivalent. Try to simplify the templates as much as possible in the process.

  • Deliver React in the frontend site and use it to render the blocks.

  • Turn the LayoutSelector component options into block styles for each block

  • Use the RichText component where possible for in-place editing.

Using React in the Frontend site

We decided to include React in the Frontend in order to render the blocks. This avoids having duplicate template logic, otherwise we would have a JSX version of the block for the editor, and a Twig template for the frontend.

The save() method is a client-side method expected to output static content, which is persisted as the block's content in the database. The usual way of rendering a dynamic block in Gutenberg is returning null in the block's save() function, then using the ServerSideRender component and render_callback() when registering the block in the PHP side. This is the way our blocks are currently rendered, thus it's the method we are deprecating in favor of the React approach.

As any changes in the block's save() method would trigger a validation error in the block editor, we first needed to add a deprecated property to the block, to let WP know that we are OK with our block changing from null to something else.

To accomplish this, we created two components: frontendRendered and FrontendBlockNode.

frontendRendered is meant to replace the save() function in a block definition.

It returns a function with the same parameters as the save() function, so it takes two arguments: attributes and className.

So the function returns a FrontendBlockNode which renders an empty div with some data attributes, which will be the placeholder for the block in the frontend site. This content is static and can be persisted safely to the database.

So Wordpress will only render that div with its attributes in the frontend site, then it's our job to make React render something inside of it.

This is done in the frontendIndex file, which has a new entry point in our webpack config, and iterates through these placeholder divs to render the blocks inside using React.

Extended details, block by block

A WYSIWYG ("What You See Is What You Get") block is a block you can edit directly in place, in the preview mode.

The way to think about WYSIWYG controls is starting from the final result, for example, this is a Counter block:

To make it editable in-place, as it is, Wordpress provides two basic ways:

  • Making some texts editable by clicking on them (e.g.: title, caption)

  • Moving options to the sidebar, specially for any controls that are pure configuration and not visible, for example: progress bar vs dial styles, an API url, or the tags for an Articles block, etc.

  • This is not specific to this issue but this is a list of places in the UI in which we can inject things with Gutenberg: https://developer.wordpress.org/block-editor/developers/slotfills/

This is pretty much the way native WP blocks work, the basic principle is: there should be nothing in the editor side that is not rendered in the frontend. No noise.

So how do we clean our UI to the point that there is nothing but the block itself (currently the "Preview")?

Counter block

What style of counter do you need?

There is native Wordpress way of doing this, it's documented here:

Automattic/gutenberg-block-styles: An example of a simple plugin that adds a block style to Gutenberg.

Title and Description

These are pure texts, and they are rendered as-is on the frontend. In this case, these fields should be removed, and we should make the Title and

Completed, Target, Text and API URL

And that's it, the rest is the Preview, where we should get rid of the "Preview" title.

So, the end result after these conversions is:

Before taking a look at our block, let's have a look at WP's native Gallery:

This is the native Gallery block:

Another example:

Then most options live on the sidebar.

The Layout Selector should be converted to Block Styles:

Articles block

The Title and Description, and Button Text can be edited in place, as they are not linked to any dynamic / automatic data from the site.

Covers block

Social Media Block

Columns Block

Cookies block

Happy Point Block

The Happy Point block is just a background. We should probably use the typical UI for uploading pictures in native WP components. Maybe we could add some placeholders to show how the form looks like in the Preview.

Split Two Columns

In this block, the two columns are independent but behave similarly. For the left column, selecting an issue will fill all the fields for you. The Select an issue field could be moved to the sidebar, along with the Issue Link Path (an URL) and the Select an Image button (or we can find a way to have that in the preview). Then the Issue Title, Issue Description and Issue Link Text fields could be editable in place.

The style options move to the sidebar:

As the slides move, I don't know if it makes much sense in trying to make the captions editable in place.

Media Block

The Title and Description fields of the block can be editable in place. The video poster image option can probably stay as is, it's pretty consistent with some native WP blocks.

Covers block

We could move the covers style to the side bar with the block styles option.

« Rows to display » dropdown menu could move to the side bar.

Title & description could be editable in place.

« select tags » + « select posts types» + « select posts » fields could move to the side bar.

Take Action Boxout

The Background Image could possibly be selected in the editor with the same UI Wordpress provides for some of its blocks:

Timeline Block

The Timeline Block relies heavily on a third party JS library. We can make the Title and Description editable. The rest of the options (Google Sheets URL, Language, Timeline navigation position, and Start at End) can be moved to the sidebar.

EN Form Block

These would be the steps to turn the current form into a WYSIWYG one.

The Layout Selector can be converted into a Block Style.

Engaging Network Live Pages and Select Goal can be moved to the sidebar.

The Thank You message settings are not visible unless you submit the form. So we need to decide what to do with those options. Maybe we can have them in the sidebar and have a way to show the Thank You screen on the preview also.

Last updated