It is crucial to become familiar with different ways to compose with WordPress blocks. Should you use a block pattern? Template part? Or, even a block variation? What about a block style?
Today, we’re going to focus on block variations, but will also compare and contrast with block styles to give you an overview of the differences.
Table of contents
Overview of block variations
Block variations are a means to extend an existing block’s attributes and inner blocks to create a unique variation.
A common example of an existing WordPress block variation is the Embed block, which has numerous variations of the same functionality for embedding different providers, e.g. YouTube, Twitter, and Facebook. The Embed block leverages a custom providerNameSlug
attribute to differentiate each embed’s icon and other attributes.
Before we go any further, it is important to distinguish between block styles and block variations. Below is an overview of the differences.
Comparing block styles and block variations
Block styles
Used to assign a custom selector (e.g. .is-style-blue-list
) and custom appearance to an existing block. Typically ideal if you need to just modify an existing block with some custom CSS.
Possible benefits
- Easy API to introduce a simple CSS variant
- Gives a distinguishable UI for editors to glance at and choose a variation
Possible downsides & pitfalls
- Be careful not to introduce too many block styles.
- Each style will require CSS, which can quickly become unscaleable
- Each style offers another option for an editor to have to choose from, which can quickly become overwhelming
Block variations
Used to extend an existing block’s attributes and even inner blocks.
It is possible to override the default block style by passing the className
attribute when creating a block variation.
Where block styles might be used to modify a block’s feel and appearance; block variations can do that and much more by modifying the substance of the block, and even its inner blocks.
Possible benefits
- Introduce a single new attribute to an existing block
- Multiple ways to surface in the UI of the editor:
inserter
,block
,transform
(more on this below)
Possible downsides & pitfalls
Be careful with how many block variations you’re introducing. While the Embed block has dozens of block variations it can become unwieldy and you may want to consider creating a unique, new block if you’re introducing too many block variations to a core block.
Hopefully, that helps give you some guidance to choose between whether to customize a block with a variation or a block style.
Now let’s focus on how you can register, unregister, and even some common use cases for block variations.
Adding block variations to a custom block
You can pass the variation
object when a block is registered to assign an array of fields. Here is an example from the Embed block:
variations: [
{
name: 'wordpress',
isDefault: true,
title: __( 'WordPress' ),
description: __( 'Code is poetry!' ),
icon: WordPressIcon,
attributes: { providerNameSlug: 'wordpress' },
},
{
name: 'google',
title: __( 'Google' ),
icon: GoogleIcon,
attributes: { providerNameSlug: 'google' },
},
{
name: 'twitter',
title: __( 'Twitter' ),
icon: TwitterIcon,
attributes: { providerNameSlug: 'twitter' },
keywords: [ __('tweet') ],
},
],
Code language: JavaScript (javascript)
An object describing a variation defined for the block type can contain the following fields:
name
(typestring
) – The unique and machine-readable name.title
(typestring
) – A human-readable variation title.description
(optional, typestring
) – A detailed variation description.category
(optional, typestring
) – A category classification, used in search interfaces to arrange block types by category.icon
(optional, typestring
|Object
) – An icon helping to visualize the variation. It can have the same shape as the block type.isDefault
(optional, typeboolean
) – Indicates whether the current variation is the default one. Defaults tofalse
.attributes
(optional, typeObject
) – Values that override block attributes.innerBlocks
(optional, typeArray[]
) – Initial configuration of nested blocks.example
(optional, typeObject
) – Example provides structured data for the block preview. You can set toundefined
to disable the preview shown for the block type.scope
(optional, typeWPBlockVariationScope[]
) – the list of scopes where the variation is applicable. When not provided, it defaults toblock
andinserter
. Available options:inserter
– Block Variation is shown on the inserter.block
– Used by blocks to filter specific block variations.Columns
andQuery Loop
blocks have such variations and are passed to the experimental BlockVariationPicker component, which is handling the displaying of variations and the ability to select one from them.transform
– Block Variation will be shown in the component for Block Variations transformations.
keywords
(optional, typestring[]
) – An array of terms (which can be translated) that help users discover the variation while searching.isActive
(optional, typeFunction|string[]
) – This can be a function or an array of block attributes. A function that accepts a block’s attributes and the variation’s attributes and determines if a variation is active. This function doesn’t try to find a match dynamically based on all block’s attributes, as in many cases some attributes are irrelevant. An example would be for theembed
block where we only care about the providerNameSlug attribute’s value. We can also use a string[] to tell which attributes should be compared as a shorthand. Each attribute will be matched and the variation will be active if all of them are matching.
Register or unregister block variations
You can register a block variation for an existing block with registerBlockVariation()
. This can be useful if you need to extend the Columns block to support a layout that does not exist but is useful to your client or editorial team. (More use cases below)
Example of how to register a block variation for an existing block
wp.blocks.registerBlockVariation( 'core/embed', {
name: 'custom',
attributes: { providerNameSlug: 'custom' },
} );
Code language: JavaScript (javascript)
You can unregister an existing block variation with unregisterBlockVariation()
. This could be useful to streamline and refine the options that your client or editorial team is presented with, especially when it comes to the Embed block.
Example of how to unregister an existing block variation
wp.blocks.unregisterBlockVariation( 'core/embed', 'youtube' );
Code language: JavaScript (javascript)
In both registering and unregistering a block variation you’ll need to reference the block slug, which is core/embed
for the Embed block in the examples above.
Block variation examples
Some common use cases for using block variations include:
- Custom Search block variation for custom post types and taxonomies
- Custom Columns block variation for missing column split
Let’s check out an example of how to extend the Search block to return results for a custom post type.
Example: Search block variation for a custom post type
By default, the Search block allows for the query
attribute to be passed as an object, which can be useful if you want to refine the search results to only return results for a custom post type or taxonomy.
Let’s say we had a Podcast post type and we want to have a search form available on the podcast landing page. We only want that search to return results for the Podcast post type.
Example of extending the Search block to query for the podcast post type
wp.blocks.registerBlockVariation( 'core/search', {
name: 'wpe-example/podcast-search',
title: 'Podcast Search',
attributes: {
query: {
post_type: 'podcast'
}
}
} );
Code language: JavaScript (javascript)
With the above code implemented, we can now search and add the new Podcast Search block variation (of the Search block) into our new podcast page, and voila.
Conclusion and further reading
The block-building world can often feel overwhelming with options. Hopefully, I’ve given you enough detail to navigate the decision-making that can go into composing and extending with block variations in WordPress.
Have you been exploring using these techniques and want to share? Don’t be shy and reach out on Twitter if you want to share or have any questions.