Gutenberg Support

I have been investigating a bit about Gutenberg and how can we implement it on Frontity. We still have to do some research, but I wanted to share what I have found useful until now. Let’s use this topic to discuss the best solution.


How Gutenberg core blocks work

As @luisherranz realized, all the styles of the core blocks of Gutenberg reside in two files. Our test:

  • /wp-includes/css/dist/block-library/style.min.css?ver=5.2.2 .
  • /wp-includes/css/dist/block-library/theme.min.css?ver=5.2.2 .

It seems that the content of these files is independent of which blocks you use in each post, or if you change its settings. The files are prepared to support all the block configurations. The css of these files is always the same, although it may change between versions.

Gutenberg changes block classes depending on the configuration, and each class corresponds to a specific style, defined in these files. For example, while using table block you can select a background color (blue, green or red). If you choose green it will add a class similar to .has-green-background-color instead of changing the css. Inside the above files, it will be defined something like:

.has-green-background-color{
    background-color: green;
}

From Frontity, as the classes are shown in the REST API, they are included in the content. This way, adding somehow the content (css) of these two files, would make Gutenberg core blocks compatible.

Moreover, while configuring a block, sometimes you can add some custom styles. For example, in paragraph block , you can select font-size: normal/big/huge and it will change the class to something like .has-normal-font-size/ .has-big-font-size/ .has-huge-font-size for each case as in the table block . But you can also customize the size and select 50px . In this case, it will add an inline style <p style="font-size: 50px"> , which will be shown in the REST API and Frontity will read it, so no problem here.

I guess the htmlPurifier could cause troubles, but as Gutenberg is meant to have structured and valid HTML, it won’t be needed right?

Apart from that, each theme should take care of styling the common tags as <h1>, <h2>, <p>, <table>, <ol>, <ul>, etc . Gutenberg blocks don’t style them, and WP themes take care of it, so I guess in Frontity should be the same.

Wordpress.com

I haven’t tested it too much, but WP.COM seems to work slightly different. The styles of the blocks reside in a unique file, which also contains more css not related to the blocks.

However, I could see that blocks work the same way as in wordpress.org. It changes classes depending on the settings and all the styles (apart from the inline) resides in that file. Moreover, the classes it uses seem to be exactly the same as wordpress.org, so if we are able to access wordpress.org files, they may be compatible with WP.COM too.

Just in case it is useful, the file in our case looks like this:

  • https://s2.wp.com/_static/??-eJydk9tuwjAMQH9oIWIbaHuY9i1JY4ppbopTVfz9nAQYpaMPk6oqdnx8iy2nKLrgM/gs3SiiHXv0JKfYBSfIoYXzg7TpiF7kHaZt6G+gU2mAjL4XWiXJpnPNOjyFZJQh2duglV3Y3uWXwKoMRsRA+UFawywOQPIEOapuEFW6maPv7Gj4uiRtkGpu1Uonlc6S8tnCxqFfBLh670IlSG43W/7unNCm0XpEa57yh9FaQZhBgMHasXYja12cCGVR3TXPj9q1wruQgPUuqlwsHAdQYMGx2Rrm4v5KleNRlVJW7NugaB0TEAn+OxydyEcOtMoxVVJpL1IfYKZpKEofMjJNt8Oazx48pGb+53HBtjRlHLVEbyAC/zgDlrnHR0ji9TID/wBLSZdJ+AfNo9lCi9rg1RdA0wOvBIx8GwYEYdUkM7hYVoSeVDBrWxCcqMoY/EwQB6twucCzpSzbzMe+1vsrFujbfW13+7fdx27/+X76AV2TroI=?cssminify=yes

Custom Blocks

I haven’t been able to test too many ways but I have tried:

They seem to work really similar. They create a new file.css for each new block with the style needed for it. I supposed these should be added the same way we will add Gutenberg core files.

How to support Gutenberg in Frontity

Here I am completely lost, you may know better @development-team. I share my insights just in case they help. I have two main questions:

  • How do we get the data from the css files ?
    Here I can imagine two scenarios:
    1. As that files don’t change until a new version is released, we could “copy” that code in @frontity/gutenberg package, so it can be consumed if wanted. We should allow people to choose what version of those files they want to use in order to avoid incompatibilities, but they would have to update it each time they update WordPress right? Apart from that, for supporting custom blocks people should add the css themselves.
    2. I am not sure if this one is technically possible of it is horrible for performance, but I guess another solution could be getting the files.css directly from WordPress. Maybe with this we could avoid versions incompatibilities. Moreover, if we are able to select more files to get from WordPress, users could select the directories of their custom blocks and support them with the same code. As said, not sure if this is even possible.
  • How to consume the data we get?
    I guess the easiest solution would be to add all this css at <Global >, but this way it would be loaded all the css although it is not used right? Would be a way to look for the class and add the styles just needed as Emotion css prop ?

Extra: Elementor

Again, just in case it is useful and it affects the possible solution:

After looking at how Gutenberg works and how this could be supported by Frontity, I took a quick look at Elementor, as it could be similar. What Elementor seems to do, and I maybe more customizers, is adding specific classes to each block, as Gutenberg. From here, they create a global.css file, containing most of the default values for each block, and then it generates another file for each post/page where you use elementor, with a unique id.

elementor-test_%E2%80%93_gutenberg-frontity

So each page or post you create with Elementor will have their blocks, with specific classes, and the styles defined in these two files: one global, common for all the pages and posts, and one for the specific page/post.

The identifier it is also in the API, and it is the postId/pageId WordPress defines.

Maybe if we are able to get the css files directly from WordPress these integrations are easier in the future? No idea :neutral_face:


This is all the research I have made until now, I have to test it deeper. If you have any questions, insights or you think we should consider something else just let us know please :grin:

3 Likes

That’s right, people using Gutenberg don’t need the HTML purifier, although we should now make some things optional, like for example the removal of the inline styles.

Yes, we can do that with Html2React.

Yes, that’s right. We can inject the latest CSS by default unless they want to specify a version in the package settings.

One question for @jesus.designer or any other developer with experience creating Gutenberg blocks:

How does the CSS of custom blocks work? Does it work the way Mario described or is there something we are still missing?

It is possible to enqueue the files from the block registration function

register_block_type('name', [ 'style' => 'name-css-registed', ])

Another way I use is enqueue the files when you have to render the block through has_block ()

Many block collections include CSS or JS of the frontend without tied to specific block, I can’t think a simple way to include all assets

A possible solution could be a wordpress plugin, where the list of assets appears and you can mark which ones you want to include in your frontity frontend

I see. Thanks @jesus.designer!

Maybe we should add support for the default Gutenberg blocks and then think about how to support custom ones :slight_smile:

1 Like

It looks like the officially recommended way to include scripts is the register_block_type('name', [ 'style' => 'name-css-registed', ]) one so maybe we should support that.

1 Like

This part of the Block Editor Handbook is very interesting:
https://developer.wordpress.org/block-editor/developers/themes/theme-support/

It looks like themes should use add_theme_support() to opt-in to several Gutenberg features. Some for the editor and some for the frontend.

These are some of the optionns:

add_theme_support( ‘wp-block-styles’ );

This enqueues the /wp-includes/css/dist/block-library/theme.min.css file.

The /wp-includes/css/dist/block-library/style.min.css is always enqueued, no matter what.

The definition of this feature is:

Core blocks include default styles. The styles are enqueued for editing but are not enqueued for viewing unless the theme opts-in to the core styles. If you’d like to use default styles in your theme, add theme support for wp-block-styles.

–> What should we do in @frontity/gutenberg?

Maybe this could be optional in our package as well.

add_theme_support( ‘align-wide’ )

This only adds two new options for images.

If it’s not active, images can be center, aligned right or aligned left:

but if it’s active, two new options appear: width wide and full width:

With no-alignment (nothing selected), the HTML of an image is:

<figure class="wp-block-image">
  <img ...>
</figure>

With align left, the HTML of an image is:

<div class="wp-block-image">
  <figure class="alignleft">
    <img ...>
  </figure>
</div>

With align right, the HTML of an image is:

<div class="wp-block-image">
  <figure class="alignright">
    <img ...>
  </figure>
</div>

With align center, the HTML of an image is:

<div class="wp-block-image">
  <figure class="aligncenter">
    <img ...>
  </figure>
</div>

With wide width, the HTML of an image is:

<figure class="wp-block-image alignwide">
  <img ...>
</figure>

And finally with full width, the HTML of an image is:

<figure class="wp-block-image alignfull">
  <img ...>
</figure>

An example of this styles is in https://codepen.io/joen/pen/zLWvrW.

I’ve tested all the images with the /wp-includes/css/dist/block-library/style.min.css and all they work fine.

–> What should we do in @frontity/gutenberg?

This should work out of the box at soon as we include the CSS from block-library/style.min.css.

add_theme_support( ‘responsive-embeds’ )

This only adds a class wp-embed-responsive to the body. When that class is present, embeds become responsive. The work is done by the /wp-includes/css/dist/block-library/style.min.css styles.

–> What should we do in @frontity/gutenberg?

This should work out of the box at soon as we include the CSS from block-library/style.min.css.

add_theme_support( ‘editor-color-palette’ )

A default set of colors is provided, but themes can register their own and optionally lock users into picking from the defined palette.

function mytheme_setup_theme_supported_features() {
    add_theme_support( 'editor-color-palette', array(
        array(
            'name' => __( 'strong magenta', 'themeLangDomain' ),
            'slug' => 'strong-magenta',
            'color' => '#a156b4',
        ),
        array(
            'name' => __( 'light grayish magenta', 'themeLangDomain' ),
            'slug' => 'light-grayish-magenta',
            'color' => '#d0a5db',
        ),
        array(
            'name' => __( 'very light gray', 'themeLangDomain' ),
            'slug' => 'very-light-gray',
            'color' => '#eee',
        )
    ));
}
 
add_action( 'after_setup_theme', 'mytheme_setup_theme_supported_features' );

–> What should we do in our frontity-wp-plugin?

I’ve tested this code in a plugin (instead of a theme) and it works. That means we can include a color picker in our Frontity plugin and let people create their own Gutenberg color palettes.

add_theme_support( ‘editor-font-sizes’ )

A default set of sizes is provided, but themes can register their own and optionally lock users into picking from preselected sizes.

function mytheme_setup_theme_supported_features() {
    add_theme_support(
			'editor-font-sizes',
			array(
				array(
					'name'      => __( 'Small', 'twentynineteen' ),
					'shortName' => __( 'S', 'twentynineteen' ),
					'size'      => 19.5,
					'slug'      => 'small',
				),
				array(
					'name'      => __( 'Normal', 'twentynineteen' ),
					'shortName' => __( 'M', 'twentynineteen' ),
					'size'      => 22,
					'slug'      => 'normal',
				),
				array(
					'name'      => __( 'Large', 'twentynineteen' ),
					'shortName' => __( 'L', 'twentynineteen' ),
					'size'      => 36.5,
					'slug'      => 'large',
				)
			)
		);

}

add_action( 'after_setup_theme', 'mytheme_setup_theme_supported_features' );

–> What should we do in our frontity-wp-plugin?

This is similar to the color palette and also works in a plugin, so we can do the same.

1 Like