Adding Custom Blocks Patterns to Labre Blocks

Note: This post is part 2 of leaning efforts to understand and use full site editing (FSE) and block-based themes. This learning post is still in active development and updated regularly.

In the previous learning post, I partially customized Quadrat child theme for my own personal project site, by modifying the most basic fonts, typography, link color control. Other modifications are still work-in-progress.

The Quadrat blocks theme comes with patterns primarily related to podcasts. Because, I have modified the Quadrat block to use as blog, I wanted to create my own customized patterns that more general and suitable for blog post contents. WordPress block patterns were introduced with the WordPress 5.8 release.

New block patterns make it simple to create complex, beautiful page and post layouts, using combinations of blocks that you can mix and match. You will also find block patterns in a wide variety of plugins and themes, with more added all the time. WordPress 5.5 release

I have been a big fan of block patterns, like many other developers. I fully agree that patterns are going to change the way we display and present our contents. For many creative designers, patterns provide an appropriate avenue to show their creativity.

Learning Goals
Part 1: Modifying Fonts & Basic Typography
Part 2: Adding Custom Block Patterns (this post)
Part 3: Creating a RSS Blog Feed page using RSS Block

The objective of this learning post is start exploring block patterns, learn to register and create customized patterns, and replace the Quadrat bundled patterns with my own customized patterns.

Resources on Creating Patterns

Before starting to create my own block patterns, I did a brief google search for useful guide and tutorials on creating patterns and found the following useful for my project.

  • Introduction to block patterns. In this article, Carolina describes what patterns are and a step-by-step procedure to create patterns with ready to use code snippets.
  • WordPress Block Patterns: The Ultimate Guide. In this guide, Kristen Wright goes into detail describing patterns with step-by-step guide to create customized block patterns.
  • Patterns. This WordPress official documentation of patterns describes the basic elements of registering customized block patterns and their properties.

Block patterns can be created using WordPress block pattern API either as a custom plugin or bundled with a theme’s functions.php file.

An Overview of Block Patterns

Before creating our custom block patterns, let’s first briefly overview block Pattern API, block pattern registration, block pattern properties.

Block Pattern API

A custom block pattern needs to be registered using the register_block_pattern function, which receives two arguments – title (name of the patterns), and properties ( an array describing properties of the pattern)

Block Pattern Registration

An example of registering a simple hello world paragraph pattern from this Theme Shaper post.

register_block_pattern(
    'my-plugin/hello-world',
    array(
        'title'       => __( 'Hello World', 'my-plugin' ),
        'description' => _x( 'Simple Paragraph.', 'Pattern description', 'my-plugin' ),
        'categories'  => An array of categories,
        'content'     => "<!-- wp:paragraph -->\n<p>Hello World</p>\n
                          <!-- /wp:paragraph -->",
    )
);

After registration, the register_block_pattern() function should be called from a handler attached to the init hook.

function my_plugin_register_my_patterns() {
  register_block_pattern( ... );
}
 
add_action( 'init', 'my_plugin_register_my_patterns' );

Once block patterns are registered they are visible in the block editor.

More detailed documentation is found in this Block Pattern Registration.

Block Pattern Properties

The block editor handbook lists the following pattern properties:

  • title (required): A human-readable title for the pattern.
  • content (required): Block HTML Markup for the pattern.
  • description (optional): A visually hidden text used to describe the pattern in the inserter. A description is optional but it is strongly encouraged when the title does not fully describe what the pattern does. The description will help users discover the pattern while searching.
  • categories (optional): An array of registered pattern categories used to group block patterns. Block patterns can be shown on multiple categories. A category must be registered separately in order to be used here.
  • keywords (optional): An array of aliases or keywords that help users discover the pattern while searching.
  • viewportWidth (optional): An integer specifying the intended width of the pattern to allow for a scaled preview of the pattern in the inserter.

As indicated above, the title and content are required properties while others properties are optional.

Unregistering Block Patterns

Any previously registered block pattern(s) can also be unregistered from themes and plugins with only one argument – title: the name of the block pattern to be unregistered, as shown in the following block pattern documentation example below:

unregister_block_pattern( 'hello world/my-plugin' );

Just like in the pattern registration, the unregister_block_pattern() should be called from a handler attached to the init hook.

function my_plugin_unregister_my_patterns() {
  unregister_block_pattern( ... );
}
 
add_action( 'init', 'my_plugin_unregister_my_patterns' );

Now let’s briefly look at how block patterns are used in the two WordPress default themes – Twenty Twenty-one and Twenty Twenty v1.8. (gitHub trac discussion here). When Twenty Twenty theme was released, blocks patterns were not available but added later and now available in the latest (v1.8) update.

How to create a Custom Block Pattern?

Kristen Wright in ithemes and Carolina in Full Site Editing describe step-by-step guide on how to create custom patterns using plugin method. The following steps adapted from Kristen’s article:

  • Step 1: Create a draft post. The first step is creating a new draft post with block editor, just like creating a new post.
  • Step 2: Add your preferred blocks. Then star adding preferred blocks. For example, text and quote in two column, cover image with two column text (eg. Kristen’s plugin example), two-column text with offset heading (used in this example), and any other pattern.
  • Step 3: For styling add CSS classes. For styling pattern, additional CSS classes can be added to blocks.
  • Step 4: Select and copy your block codes. Next we should grab the source code, first select the desired blocks from the draft post and click over on the “More Options” button (it’s three vertical dots) near the top of your editor and copy the source code and paste in a code editor (eg. VSCode).
  • Step 5: Escape the HTML Output. Because the HTML output needs to be escaped which can run through a online tool (for example, JSON Escape/Unescape tool). Escaped code can be obtained by clicking the Escape button. Then copy the Result String code provided in the second box.
  • Step 6: Add the content to plugin. The escaped content can be copied in the plugin’s content section (example below).

More detailed description with screenshot example is available in this Kristen Wright’s article – WordPress Block Patterns: The Ultimate Guide.

The following code example of a quote pattern example plugin from WordPress blog.

/* source:https://wordpress.org/news/2021/03/so-you-want-to-make-block-patterns/ */
<?php 
/*
Plugin Name: Quote Pattern Example Plugin
*/

register_block_pattern(
	'my-plugin/my-quote-pattern',
	array(
		'title'       => __( 'Quote with Avatar', 'my-plugin' ),
		'categories'  => array( 'text' ),
		'description' => _x( 'A big quote with an avatar".', 'Block pattern description', 'my-plugin' ),
		'content'     => '<!-- wp:group --><div class="wp-block-group"><div class="wp-block-group__inner-container"><!-- wp:separator {"className":"is-style-default"} --><hr class="wp-block-separator is-style-default"/><!-- /wp:separator --><!-- wp:image {"align":"center","id":553,"width":150,"height":150,"sizeSlug":"large","linkDestination":"none","className":"is-style-rounded"} --><div class="wp-block-image is-style-rounded"><figure class="aligncenter size-large is-resized"><img src="https://blockpatterndesigns.mystagingwebsite.com/wp-content/uploads/2021/02/StockSnap_HQR8BJFZID-1.jpg" alt="" class="wp-image-553" width="150" height="150"/></figure></div><!-- /wp:image --><!-- wp:quote {"align":"center","className":"is-style-large"} --><blockquote class="wp-block-quote has-text-align-center is-style-large"><p>"Contributing makes me feel like I\'m being useful to the planet."</p><cite>— Anna Wong, <em>Volunteer</em></cite></blockquote><!-- /wp:quote --><!-- wp:separator {"className":"is-style-default"} --><hr class="wp-block-separator is-style-default"/><!-- /wp:separator --></div></div><!-- /wp:group -->',
	)
);

?>
Using Block Patterns in Themes

The TT1 Blocks theme and the default Twenty Twenty-one theme showcase how block patterns can be in the themes’s functions.php file.

In the TT1 Blocks experimental-theme, this block-pattern.php file contains eight block patterns, which is added to the functions.php as an include as shown here.

In the Quadrat theme, block patterns are used by refactoring block-pattern.php file into block-patterns.php, where blocks are registered and patterns contents are called as return arrays as shown in this code example.

Adding Block Patterns Library in Labre Blocks

Because I have renamed the Quadrat theme as Labre Blocks in my recent experimental theme, I wanted to add the block patterns that are more appropriate for my site, such as text with quote, two column text with offset heading, heading-image-text pattern like in the Eksell theme and similar others.

In this use case example, I am describing only one of the patterns from my Labre blocks library – Two columns of text with offset heading from WordPress pattern directory, following Quadrat patterns library method.

Because the block patterns is already created, I just copied the pattern and modified some codes, curating text string for HTML escape with esc_html__( ) and little bit of styling.

Step 1: Copy the pattern and paste in VS Code editor

Copy the source code and paste in a VS Code editor.

Step 2: HTML Escape the Text Strings with esc_html__() function

Because the text strings in  the heading, and paragraph blocks are not HTML escaped, they must be escaped before the code can be added in our pattern. For example the

/* HTML string esc_html__() curation */
<h3 class="has-text-color has-primary-color"><strong>' . esc_html__('Oceanic Inspiration', labreblocks) . ' </strong></h3>

Likewise, paragraph blocks text string were HTML escaped, manually.

Step 3: Adding the pattern in our theme

Because my Labre theme (renamed from Quadrat to preserve my changes from future updates), in Quadrat block pattern names are added in block-pattern.php file. The modified block-pattern.php file in my Labre theme looks as follows:

<?php
/**
 * Labre Blocks Theme: Block Patterns
 *
 * @package Labre Blocks
 * @since   1.0.0
 */
if ( ! function_exists( 'labreblocks_register_block_patterns' ) ) :

	function labreblocks_register_block_patterns() {

		if ( function_exists( 'register_block_pattern_category' ) ) {
			register_block_pattern_category(
				'labreblocks',
				array( 'label' => __( 'Labre', 'labreblocks' ) )
			);
		}

		if ( function_exists( 'register_block_pattern' ) ) {
			$block_patterns = array(
				'headline-button',
				'headlines-and-buttons',
				'offset-heading-with-two-column-text',
				'heading-image-text',
				'media-text-button',
				'paragraph-with-quote',
			);

			foreach ( $block_patterns as $block_pattern ) {
				register_block_pattern(
					'labreblocks/' . $block_pattern,
					require __DIR__ . '/patterns/' . $block_pattern . '.php'
				);
			}
		}
	}
endif;

add_action( 'init', 'labreblocks_register_block_patterns', 9 );

In the code example above, each pattern listed in the $block_patterns = array ( ) is called by foreach () statement (lines: 29-34) which requires ‘patterns‘ directory file with the listed pattern name in the array  (line 32) which we will add in the next step.

Step 4: Adding pattern file in /inc/patterns folder

In this step, we should have all the listed patterns file in the $block_patterns = array ( ) statement (lines: 21-26) and code example of one of the pattern file,  two-column-text-with-offset-heading.php is shown below.

<?php
/**
 * Two column text with offset heading.
 *
 * @package labreblocks
 */

return array(
	'title'      => __( 'Two column text with offset heading', 'labreblocks' ),
	'categories' => array( 'labreblocks' ),
	'content'    => '<!-- wp:group {"align":"wide"} -->
		<div class="wp-block-group alignwide "></div><!-- wp:spacer {"height":70,"className":"two-columns-text-with-offset-heading"} -->
		<div style="height:70px" aria-hidden="true" class="wp-block-spacer two-columns-text-with-offset-heading"></div>
		<!-- /wp:spacer -->

		<!-- wp:columns {"verticalAlignment":"center","align":"wide"} -->
		<div class="wp-block-columns alignwide are-vertically-aligned-center"><!-- wp:column {"width":"50%"} -->
		<div class="wp-block-column" style="flex-basis:50%"><!-- wp:paragraph {"style":{"typography":{"lineHeight":"1.1"},"color":{"text":"inherit"}},"fontSize":"extra-large"} -->
		<h3><strong>' . esc_html__( 'Oceanic Inspiration', 'labreblocks' ) . '</strong></h3>
		<!-- /wp:paragraph --></div>
		<!-- /wp:column -->

		<!-- wp:column {"width":"50%"} -->
		<div class="wp-block-column" style="flex-basis:50%"><!-- wp:separator {"customColor":"#b3b9c5","className":"is-style-wide"} -->
		<hr class="wp-block-separator has-text-color has-background is-style-wide" style="background-color:#b3b9c5;color:#b3b9c5"/>
		<!-- /wp:separator --></div>
		<!-- /wp:column --></div>
		<!-- /wp:columns -->

		<!-- wp:columns {"align":"wide"} -->
		<div class="wp-block-columns alignwide"><!-- wp:column -->
		<div class="wp-block-column"></div>
		<!-- /wp:column -->

		<!-- wp:column -->
		<div class="wp-block-column"><!-- wp:paragraph {"dropCap":true,"style":{"color":{"text":"#b3b9c5"}},"fontSize":"extra-small"} -->
		<p class="has-drop-cap has-text-color has-extra-small-font-size" style="color:#b3b9c5">' . esc_html__( 'Winding veils round their heads, the women walked on deck. They were now moving steadily down the river, passing the dark shapes of ships at anchor, and London was a swarm of lights with a pale yellow canopy drooping above it. There were the lights of the great theatres, the lights of the long streets, lights that indicated huge squares of domestic comfort, lights that hung high in air.', 'labreblocks' ) . '</p>
		<!-- /wp:paragraph --></div>
		<!-- /wp:column -->

		<!-- wp:column -->
		<div class="wp-block-column"><!-- wp:paragraph {"dropCap":true,"style":{"color":{"text":"#b3b9c5"}},"fontSize":"extra-small"} -->
		<p class="has-drop-cap has-text-color has-extra-small-font-size" style="color:#b3b9c5">' . esc_html__( 'No darkness would ever settle upon those lamps, as no darkness had settled upon them for hundreds of years. It seemed dreadful that the town should blaze for ever in the same spot; dreadful at least to people going away to adventure upon the sea, and beholding it as a circumscribed mound, eternally burnt, eternally scarred. From the deck of the ship the great city appeared a crouched and cowardly figure, a sedentary miser.', 'labreblocks' ) . '</p>
		<!-- /wp:paragraph --></div>
		<!-- /wp:column --></div>
		<!-- /wp:columns -->',
);

Now, if we look at the block patterns is visible in our block editor, the Two columns of text with offset heading should be available for our use.

Screenshot showing custom patterns in block pattern pane.

The following screenshot showing the newly created Two columns of text with offset heading pattern in use.

Screenshot showing Two columns of text with offset heading pattern in use.
This is Work-in-Progress

Adding other desired patterns that I commonly use in my writing is work-in-progress learning project. In the immediate future I plan to add a few more patterns in my Labre theme.

Wrapping Up

In this learning post, we learned to register and create customized patterns and replaced the a most of the Quadrat bundled patterns with my own customized patterns. In the next part of this this learning series, we will explore how to create a page template using RSS Blocks to display contents from different sites after Tammie Lister.

NEXT: Creating a page template using RSS Blocks

Useful Resources

The following is list of references link that I gathered during my brief research. While preparing this post, I have also referred some of the following references extensively.