How to Build Patterns for the WordPress Block Editor

If you’re a theme or plugin developer in the page building ecosystem, now is a better time than ever to start capitalizing on arguably the most exciting addition to Gutenberg, since Gutenberg: Block Patterns.

Let’s dive in and discover how to leverage the new Block Patterns API and build beautiful patterns.

Block Patterns, a recap

Recently I published an article on the concept of Block Patterns and how they’re going to make page building in the block editor much more enjoyable. I am still very much in that camp, and I look forward to the introduction of Block Patterns in the upcoming WordPress 5.5 release.

To recap, Block Patterns are predefined block layouts, ready to drop on a page and tweak from there. Once added to a page, the individual blocks of a pattern can be edited in the same fashion as any other block.

An important trait of Block Patterns is that once a pattern has been added to a page, it no longer is linked to the original pattern source. The original pattern within the Block Pattern Library may be changed, or even removed, without affecting the Block Pattern added to your page.

Where should Block Patterns live

Block Patterns can exist both themes and plugins, though I lean towards building them into, or as, a plugin. Using this method, the patterns will still be available whenever the theme is changed. I honestly don’t see a point in tying a pattern to a specific theme, other than the marketability of the theme in question.

Building Block Patterns

Now here’s the meat and potatoes. We’ll be using the Block Pattern API, specifically the register_block_pattern() PHP function. But before we dive into the code, we’ll need to block out the pattern (i.e. design it within the block editor).

Step 1: Blocking the pattern

Block Patterns can technically have as many, or as little, blocks as you’d like. Here’s a pattern I blocked-out as an example:

Designing a Block Pattern for the WordPress block editor
Designing a Block Pattern for the WordPress block editor

The idea behind patterns is that a pattern should be something you’d want to repeat throughout your website. So if you’re designing something that’s very one-time-use oriented, it may not make for a great pattern.

Step 2: Copy the block content

Once the pattern has been blocked-out, you’ll need to grab the content of the pattern. For this set of blocks, I’ve selected all the blocks I’d like to make into a pattern, opened the More Menu within the block toolbar, and clicked “Copy”.

Copying the block content of a future Block Pattern
Copying the block content of a future pattern

Step 3: Register the pattern

Now here’s where we get to leverage register_block_pattern(). This function receives the name of the pattern as the first argument and an array describing properties of the pattern as the second argument.

Let’s look at an example:

function tabor_register_block_patterns() {

	if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {

                $content = '<!-- wp:heading {\"align\":\"center\"} -->\n<h2 class=\"has-text-align-center\"><strong>Our approach reflects the people we serve. We are diverse, yet the same.</strong></h2>\n<!-- /wp:heading -->\n\n<!-- wp:buttons {\"align\":\"center\"} -->\n<div class=\"wp-block-buttons aligncenter\"><!-- wp:button {\"borderRadius\":7,\"style\":{\"color\":{\"gradient\":\"linear-gradient(135deg,rgb(0,0,0) 0%,rgb(0,0,0) 50%,rgb(0,0,0) 100%)\"}}} -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-background\" style=\"border-radius:7px;background:linear-gradient(135deg,rgb(0,0,0) 0%,rgb(0,0,0) 50%,rgb(0,0,0) 100%)\">Learn More</a></div>\n<!-- /wp:button --></div>\n<!-- /wp:buttons -->\n\n<!-- wp:spacer {\"height\":59} -->\n<div style=\"height:59px\" aria-hidden=\"true\" class=\"wp-block-spacer\"></div>\n<!-- /wp:spacer -->\n\n<!-- wp:gallery {\"ids\":[621,624],\"sizeSlug\":\"full\",\"align\":\"wide\"} -->\n<figure class=\"wp-block-gallery alignwide columns-2 is-cropped\"><ul class=\"blocks-gallery-grid\"><li class=\"blocks-gallery-item\"><figure><img src=\"https://iceberg.test/wp-content/uploads/2020/07/home-image-3.jpg\" alt=\"\" data-id=\"621\" class=\"wp-image-621\"/></figure></li><li class=\"blocks-gallery-item\"><figure><img src=\"https://iceberg.test/wp-content/uploads/2020/07/home-image-2.jpg\" alt=\"\" data-id=\"624\" data-full-url=\"https://iceberg.test/wp-content/uploads/2020/07/home-image-2.jpg\" data-link=\"https://iceberg.test/?attachment_id=624\" class=\"wp-image-624\"/></figure></li></ul></figure>\n<!-- /wp:gallery -->';

		register_block_pattern(
			'tabor/call-to-action-gallery',
			array(
				'title'         => __( 'Call to Action Gallery', 'textdomain' ),
				'description'   => _x( 'A call to action with a beautiful two-column gallery below.', 'Block pattern description', 'textdomain' ),
				'content'       => trim($content),
				'categories'    => array( 'hero' ),
				'keywords'      => array( 'cta' ),
                                'viewportWidth' => 1400,
                                'blockTypes'    => array( 'core/gallery' ),
			)
		);

	}

}
add_action( 'init', 'tabor_register_block_patterns' );

I’ve passed an array with the pattern’s title, description, content (which is the escaped content from step three), keywords (for improved discoverability), a pattern category (for organization), viewportWidth (for how wide the scaled block preview should be displayed at), and blockTypes (for related blocks used by this pattern).

Toss this in your theme or plugin and you’ll have a new pattern at your disposal within the block editor. Too easy.

Our example Block Pattern added to the Patterns UI.
Our example Block Pattern added to the Patterns Library

Once added to your theme or plugin, you’ll see the new Block Pattern added to the Patterns Library in WordPress 5.5.  

Step 4: Register additional categories

While Gutenberg provides a few categories out of the box, my new pattern doesn’t quite fit in those defaults. Thankfully, it is quite easy to register an additional category to better organize third-party Block Patterns.

The new register_block_pattern_category() function receives the name of the category as its first argument, and an array describing properties of the category as the second argument-i.e. the label.

function tabor_register_block_categories() {
	if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {

		register_block_pattern_category(
			'hero',
			array( 'label' => _x( 'Hero', 'Block pattern category', 'textdomain' ) )
		);

	}
}
add_action( 'init', 'tabor_register_block_categories' );

And that’s it. The new category displays along the others, though it will be appended to the bottom of the list. I do think a welcome fast-follow to the Patterns Library is to make the categories alphabetically ordered, regardless of source.

A closer look at blockTypes

I recently updated this post to reference the newly added blockTypes object, which patterns can leverage to display as a suggested pattern for a specific block.

As of WordPress 5.8, patterns that declare associated blocks will show up in the new UI when a block is added to a page, like this:

Suggested patterns in the Social Links WordPress block
Suggested patterns in the Social Links WordPress block.

The one catch is that patterns must include associated blocks. I.e. you can’t just suggest a gallery pattern for the Social Links block — you need to actually use the core/social-links block in the pattern.

This is an interesting way to leverage patterns throughout the editor, but I’m not 100% sold on it just yet.

Iterating on Block Patterns

Block Patterns will make page building in the block editor much more streamlined, but there are a few improvements I’d like to see iterated upon.

For one, better categorization/organization. Block Patterns aren’t clearly distinguishable and aren’t really categorized. Perusing the library in its current state is not quite productive. The only discoverability methods are searching and scrolling through the single column list of patterns. The categories are almost invisible, and there’s no way to sort or filter patterns – which I think would be helpful.

A while back, I suggested a modal interaction for patterns, which I believe would lead to improved pattern discovery, perhaps with a categorized or filtering sidebar of sorts. Having a solid method to categorize and a more efficient way to browse will only help folks build pages faster and with more confidence.

Second, I would like to see a way for users to save a set of blocks as a Block Pattern, much like saving a Reusable block. Gutenberg aims to lower the technical barrier of publishing content-rich pages within WordPress, so naturally we should aim to reduce the technical effort it takes to make Block Patterns.

In all though, I’m all for Block Patterns, and I look forward to seeing the creative ways folks leverage patterns to improve page building in the block editor.

Are you planning on adding patterns to your theme or plugin?