Introduction to block patterns

Level: ,

Estimated reading time: 11 minutes

This lesson is an introduction to WordPress block patterns. You will learn how to create patterns, register custom pattern categories, disable them, and add them to block templates using the pattern block.

Updated May 22, 2022.

What is a block pattern?

A block pattern is a group of blocks that you combine to create reusable layout elements. Block patterns help users select premade designs that they can customize using an infinite number of color options and media.

You can preview patterns in the pattern explorer and place them in your content using the block inserter. You can add multiple copies of the same pattern to a post or page and freely edit the blocks.

In the pattern explorer, you can search for patterns provided by the theme, plugins, WordPress core, and featured items from the WordPress.org pattern directory. The editor lists patterns by category:

The block pattern explorer displays larger versions of the pattern compared to the block inserter sidebar.

How do block patterns benefit theme developers and designers?

By combining blocks with custom block styles and block variations, you can style and create patterns with different purposes for your theme. You can create time-saving layouts that look and feel unique with only minor changes by creating a pattern library.

You can reuse block patterns and place them anywhere in the content or a block theme. Patterns offer more flexibility than a customizer option or an options page because you can style them using built-in editor controls.
Patterns are easier to maintain than code created for the customizer since you don’t need to build your controls: The block editor provides text inputs, image uploads, and font- and color options.

How to create block patterns

The first step is to plan what you want your block pattern to do. Next, you can start grouping blocks together in the editor and try different styles. You will use the block markup code as a value in the block pattern.

Starting in WordPress 6.0 or if you have the Gutenberg plugin version 12.9 or newer active, there are two methods for creating patterns:

  • Using a PHP function. The register_block_pattern() function works in classic themes, full site editing themes, and plugins. This function is available from WordPress 5.5.0.
  • Placing PHP files inside a folder called patterns. This works in both classic themes and full site editing themes, and WordPress registers the pattern based on data in the file header.

I will describe both methods in this lesson. You are not limited to using one method and I recommend that you read about both.
If your theme has a minimum required WordPress version of 6.0, I recommend the folder method as I believe it is simpler and will save you time. Note that it is still not possible to register patterns using JavaScript.

Registering block patterns with PHP

You register block patterns using the PHP function register_block_pattern together with an init hook:

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

– If your theme supports WordPress versions below 5.5, you must first check if the
register_block_pattern function exists. Otherwise, you may cause PHP notices.

In my example, I am going to use and style a contact form provided by Ninja Forms, so I am also going to check if the plugin is active:

if ( function_exists( 'register_block_pattern' ) &&
        function_exists( 'ninja_forms' ) ) {
                register_block_pattern( ... );
        }
}

The first property inside the register_block_pattern function is a unique identifier.
The identifier includes a prefix or namespace; the theme slug, followed by a forward slash and a slug for the pattern. Examples:

register_block_pattern(
	'prefix/pattern-slug',
         ...
register_block_pattern(
	'twentytwentytwo/contact-form',
         ...

Properties

The identifier is followed by an array of properties:

register_block_pattern(
	'twentytwenty/contact-form',
	array(
		'title'         => The visible name in the editor,
		'viewportWidth' => The width of the pattern preview (int),
		'categories'    => An array of categories,
		'description'   => A description of the pattern,
		'keywords'      => An array of keywords used in the search,
		'blockTypes'    => An array of blocks. Adding these blocks in the editor will display a preview of the block pattern.
		'inserter'      => false,
		'content'       => The block markup,
	)
);

The required items are:

  • title, which is the visible name in the block editor
  • content, where you place the block markup.

The function also has six optional properties:

  • Each pattern comes with its own preview. The viewportWidth property lets you specify the width of the pattern inside the preview, which is helpful if the pattern is extra tall or narrow.
  • The description is a visually hidden text that describes the pattern. It complements the visual preview for visually impaired users, who may use a screen reader to use the editor.
  • Inserter lets you choose if the pattern should be available in the block inserter or not, which is useful when you want to use a pattern more as structural elements than designs for the user to select.

By adding an array of blocks to the blockTypes property, you can preview and select the pattern directly in the inserter instead of the plain block. It is a faster way for your users to place your block patterns:

The pattern inserter can display the block as well as block patterns that use the blockTypes attribute.

The final two properties also help users find your block pattern in the editor: Keywords and categories. You need to format both these properties as an array. You can add any suitable words as your keywords. Remember to wrap the word inside a translation function.

Adding block markup to the pattern

Copy the markup for your patterns from the block editor and paste it into content.
In my example pattern, I am using a cover block with a background image and a gradient, a heading, and the contact form:

'content'     => '
	<!-- wp:cover {"url":"http://localhost:8888/wp-content/uploads/2020/08/flora.png",
"id":2038,"gradient":"blush-light-purple","contentPosition":"top center","align":"wide"} -->
	<div class="wp-block-cover alignwide has-background-dim has-background-gradient 
has-custom-content-position is-position-top-center"
style="background-image:url(http://localhost:8888/wp-content/uploads/2020/08/flora.png)">
	<span aria-hidden="true" class="wp-block-cover__gradient-background 
has-blush-light-purple-gradient-background"></span>
	<div class="wp-block-cover__inner-container">
	<!-- wp:heading {"align":"center","style":{"typography":{"fontSize":60}}} -->
	<h2 class="has-text-align-center" style="font-size:60px">' . __( 'Book an appointment', 'text-domain' ) . '</h2>
	<!-- /wp:heading -->
	<!-- wp:ninja-forms/form {"formID":1,"formName":"Contact Me ( ID: 1 )"} -->
	<div class="wp-block-ninja-forms-form">[ninja_forms id=1]</div>
	<!-- /wp:ninja-forms/form --></div></div>
	<!-- /wp:cover -->
',

I prefer to wrap my code inside single quotes. If you want to use double quotes, remember to escape the double quotes inside the HTML code with a backslash.

This simple pattern only has one custom text string, “Book an appointment,” and the text needs to be translation-ready. Add the translation function to the string:

<!-- wp:heading {"align":"center","style":{"typography":{"fontSize":60}}} -->
<h2 class="has-text-align-center" style="font-size:60px">' . 
__( 'Book an appointment', 'text-domain' ) . '</h2>
<!-- /wp:heading -->

For the cover block’s background image to work, you need to replace “localhost” with a path in the theme. Place the image inside the themes images folder, and include it with get_theme_file_uri:

<!-- wp:cover {"url":"' .
esc_url( get_theme_file_uri( 'assets/images/flora.png' ) ) . '",
"id":2038,"gradient":"blush-light-purple","contentPosition":"top center","align":"wide"} 
-->
Example block pattern using Ninja Forms and a cover block.

Registering block patterns using the patterns folder

In your full site editing theme, create a new folder on the root level called patterns.
Create a single PHP file for each pattern you want to add and place them in the patterns folder. The file must be a PHP file, .php is the only supported file format.

The only required properties are title and slug. You add all properties in a comment inside the file header, except for the content which you place in the main part of the file.
Categories, keywords, and block types accept multiple values, separate by a comma.

Example

Filename: footer-links.php

<?php
/**
 * Title: Footer links -The visible name in the pattern inserter
 * Slug: theme-slug/footer-links
 * Categories: text, site-footer 
 * Description: A description of the pattern
 * Keywords: footer, links, copyright, keywords used in the search
 * Block Types: core/navigation, core/site-title, core/social-links
 */
?>

After closing the comment, you can add the block markup as plain text, or you can combine the markup with PHP.
A difference between adding PHP in the block pattern file and adding it in the content of register_block_pattern() is that in the pattern file, you need to use echo:

<?php
/**
 * Title: Footer links -The visible name in the pattern inserter
 * Slug: theme-slug/footer-links
 * Categories: text, site-footer 
 * Description: A description of the pattern
 * Keywords: footer, links, copyright, keywords used in the search
 * Block Types: core/navigation, core/site-title, core/social-links
 */
?>
<!-- wp:group {"layout":{"type":"flex","allowOrientation":false,"justifyContent":"space-between"}} -->
<div class="wp-block-group"><!-- wp:group {"layout":{"type":"flex","allowOrientation":false}} -->
<div class="wp-block-group"><!-- wp:paragraph {"fontSize":"extra-small"} -->
<p class="has-extra-small-font-size"><?php esc_html_e( 'Copyright', 'text-domain' );
echo ' ' . date_i18n( _x( 'Y', 'copyright date format', 'text-domain' ) ); ?></p><!-- /wp:paragraph -->
<!-- wp:site-title {"level":0, "fontSize":"extra-small"} /-->
<!-- wp:social-links {"className":"is-style-logos-only"} -->
<ul class="wp-block-social-links has-icon-color is-style-logos-only"><!-- wp:social-link {"url":"https://wordpress.org","service":"wordpress"} /--></ul>
<!-- /wp:social-links -->
</div><!-- /wp:group -->
</div><!-- /wp:group -->

You can also add additional file header data without breaking the parser:

<?php
/**
 * Title: Footer links -The visible name in the pattern inserter
 * Slug: theme-slug/footer-links
 * Categories: text, site-footer 
 * Description: A description of the pattern
 * Keywords: footer, links, copyright, keywords used in the search
 * Block Types: core/navigation, core/site-title, core/social-links
 *
 * @package theme-slug
 * @since 1.0.0
 */
?>

If you are also thinking, “Wait a minute, that is exactly how we added custom templates to classic themes,” -You are right, and I found that both confusing and that it reduces the complexity.

How to add a CSS class to a block pattern

You can add a CSS class to the wrapper element, and use that selector to style your pattern.
In the example, I am using the cover block as the wrapper.

First, add the className attribute inside the block comment, where the value is the CSS class.

<!-- wp:cover {"className":"prefix-contact-form", ...

You need to duplicate this for the wrapping div. Place the class name inside the class attribute:

<div class="wp-block-cover prefix-contact-form 

Block pattern categories

For the categories, you have two options: Either use a category provided by WordPress or register your own. The available categories are:

  • Buttons
  • Columns
  • Gallery
  • Header
  • Text
  • Query

Source

If the theme allows showing patterns from the WordPress.org pattern directory, WordPress also registers a category called “Featured”. Source.

You can register categories with the help of register_block_pattern_category.
The function uses two properties: The slug, in this case, forms, and the visible label:

if ( function_exists( 'register_block_pattern_category' ) ) {
    register_block_pattern_category(
      'forms',
      array( 'label' => __( 'Forms', 'text-domain' ) )
   );
}

You then use the slug inside the categories property of your pattern. You can register multiple categories separated by a comma.

register_block_pattern(
	'prefix/pattern-slug',
	array(
         	'categories'  => array( 'forms', 'example' ),
        ...
        )
);

The pattern will be visible under both categories in the editor. If you choose not to add a category, the pattern will be visible under the label Uncategorized.

How to remove block patterns

Both block patterns and most block pattern categories can be unregistered.
To remove all WordPress default block patterns here is a handy trick that will feel familiar to most theme authors:

remove_theme_support( 'core-block-patterns' );

You need to add this code using an init hook or after_setup_theme, and you will most likely place this inside a function together with the rest of your theme support.

To remove a single block pattern, use the PHP function unregister_block_pattern together with the pattern prefix and slug:

unregister_block_pattern( 'prefix/my-awesome-pattern' );

If you want to remove a pattern that is included in WordPress, core, use core as the prefix:

unregister_block_pattern( 'core/two-buttons' );

This also works for block patterns created by plugins; all you need is the prefix and name of the pattern.

How to hide block patterns from the pattern directory

You can prevent loading patterns from the WordPress.org pattern directory with a filter called should_load_remote_block_patterns. Example:

add_filter( 'should_load_remote_block_patterns', '__return_false' );

Removing block pattern categories

To remove a category, use the function unregister_block_pattern_category together with an init hook.

function prefix_unregister_category() {
	unregister_block_pattern_category( 'buttons');
}
add_action( 'init', 'prefix_unregister_category' );

The uncategorized block pattern category is used as a fallback when a pattern does not have a category, and it can not be unregistered with this function.

How to use the pattern block to place block patterns in templates

Earlier I mentioned the inserter property in register_block_pattern and how you can use it to hide the pattern. This method is useful when you need to use PHP strings and translations in your block templates and template parts. You add your PHP code as part of a block pattern and then include that pattern in the template. Users can not preview or insert the pattern, but they can still edit the blocks in the editor.

The markup for the pattern block is:

<!-- wp:pattern {"slug":"prefix/pattern-slug"} /-->

Troubleshooting block patterns

I have run into the problem where my pattern markup is invalid countless times. Many times, the message that is shown when I try to resolve a block markup error is not helpful at all.

What I try to do to solve markup problems is:

  • First, double-check that I have copied all the tags correctly and that there are no missing closing tags.
  • Adjust the spacing between the block patterns in the HTML code; try removing extra empty lines.
  • Remove blocks from the pattern one at a time to identify where the problem is.

Finally, re-create the pattern in the editor, copy all the code again and hope for the best! 🙂

Should block patterns contain default content?

It depends. Who is the pattern for, what is it for, and how much content is there?
It can be easier for users to get started if you include sample content. It may be easier to edit content already in place than add new content.

Local images included in patterns are lost when the user switches themes. Encourage users to add their own media.

Resources

To learn how to feature patterns from the pattern directory using theme.json, please see
my lesson about global styles and theme.json.

The WordPress.org pattern directory

The WordPress training team has an introduction video about finding and using block patterns. You can share this with your users to help them become familiar with patterns.

https://learn.wordpress.org/workshop/intro-to-block-patterns/