Artikel: Extending Core Blocks
1. Block supports
register_block_type_args
function modify_paragraph_spacing_args($args, $block_type) {
if ($block_type === 'core/paragraph') {
$args['supports']['spacing'] = [
'margin' => true,
'padding' => false
];
}
return $args;
}
add_filter('register_block_type_args', 'modify_paragraph_spacing_args', 10, 2);This method works well in most cases, but since it modifies the block after it has already been registered, it can sometimes be overridden by other plugins or themes that modify the same block later in the process.
block_type_metadata
A more structured approach in this case could be to override the block’s metadata directly.
function mytheme_modify_paragraph_spacing($metadata) {
if ($metadata['name'] === 'core/paragraph') {
$metadata['supports']['spacing'] = [
'margin' => true,
'padding' => false
];
}
return $metadata;
}
add_filter('block_type_metadata', 'mytheme_modify_paragraph_spacing');Neither approach is inherently better than the other — it just depends on when you want to modify the block and how persistent you want the change to be.
2. Registering block styles
Inline CSS
Since the block editor allows registering and unregistering block styles, we can remove existing styles and replace it with a custom version.
- unregister_block_style
- register_block_style
function modify_image_block_rounded_style() {
// Remove the default "Rounded" style
unregister_block_style( 'core/image', 'rounded' );
// Register a new "Rounded" style with custom CSS
register_block_style(
'core/image',
array(
'name' => 'rounded',
'label' => __( 'Rounded', 'your-text-domain' ),
'inline_style' => '
.wp-block-image.is-style-rounded img {
border-radius: 20px; /* Adjust this value */
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); /* Optional shadow */
}
',
)
);
}
add_action( 'init', 'modify_image_block_rounded_style' );While inline style works well for simple styles, it’s not ideal for maintainability. A better approach is to define styles in an external CSS file and enqueue it instead.
External CSS
To do this, create a new CSS file, e.g., custom-block-styles.css
Next, enqueue the CSS file in functions.php:
function enqueue_custom_block_styles() {
wp_enqueue_style(
'custom-block-styles',
get_template_directory_uri() . '/css/custom-block-styles.css',
array(),
'1.0'
);
}
add_action('wp_enqueue_scripts', 'enqueue_custom_block_styles');
add_action('enqueue_block_editor_assets', 'enqueue_custom_block_styles');Now, instead of using inline style, you can register the style without embedding CSS directly in PHP:
register_block_style(
'core/image',
array(
'name' => 'rounded',
'label' => __( 'Rounded', 'your-text-domain' ),
'style_handle' => 'custom-block-styles'
)
);3. Registering block variations
Block variations let you create predefined versions of a block with custom settings, making it easier for users to apply consistent designs with a single click. Instead of modifying a block’s settings manually each time, a variation allows you to insert a block that already has the right attributes, styles, or configurations applied.
Example: Testimonial block with existing core blocks
While WordPress doesn’t have a dedicated Testimonial block, the Quote block (core/quote) can be adapted to serve that purpose. Instead of making users manually add an image, align the text, and format everything, we can define a Testimonial variation of the Quote block.
registerBlockVariation() in JavaScript
Since block variations are handled on the client side, we need to enqueue a JavaScript file that registers our custom Testimonial variation.
To implement this, create a JavaScript file (like custom-block-variations.js) that defines the Testimonial variation of the Quote block. You can create this file in your theme’s assets/js/ directory and add the following code:
wp.domReady(() => {
wp.blocks.registerBlockVariation(
'core/quote',
{
name: 'testimonial',
title: 'Testimonial',
description: 'A variation of the Quote block for testimonials.',
category: 'text',
attributes: {
className: 'is-style-testimonial',
},
innerBlocks: [
['core/image', { align: 'center', width: 100, height: 100 }],
['core/quote'],
['core/paragraph', { placeholder: 'Name', align: 'center', fontSize: 'medium', className: 'testimonial-name' }],
['core/paragraph', { placeholder: 'Company / Role', align: 'center', fontSize: 'small', className: 'testimonial-company' }]
],
scope: ['inserter'],
}
);
// Inject inline styles for the editor preview
const style = document.createElement('style');
style.innerHTML = `
.wp-block-quote.is-style-testimonial {
background-color: #f9f9f9;
padding: 24px;
border: none !important;
border-radius: 8px;
text-align: center;
font-size: 1.2em;
font-style: normal;
color: #333;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center;
}
.wp-block-quote.is-style-testimonial p {
margin-bottom: 12px;
font-size: 1.1em;
}
.wp-block-quote.is-style-testimonial cite {
font-weight: bold;
display: block;
margin-top: 10px;
color: #0073aa;
}
.wp-block-quote.is-style-testimonial .wp-block-image {
display: flex;
justify-content: center;
margin: 0 auto 12px;
}
.wp-block-quote.is-style-testimonial .wp-block-image img {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 12px;
}
.wp-block-quote.is-style-testimonial .testimonial-name {
font-weight: bold;
font-size: 1.2em;
margin-top: 12px;
color: #222;
}
.wp-block-quote.is-style-testimonial .testimonial-company {
font-size: 0.9em;
color: #555;
}
`;
document.head.appendChild(style);
});In the code above, registerBlockVariation() defines the Testimonial variation of the Quote block, preloading an Image block, a Quote block, and two Paragraph blocks for the person’s name and company. The Image block is centered at 100×100 pixels for uniform profile pictures, while the Quote block remains unchanged as the testimonial text.
A custom class (is-style-testimonial) is applied for styling, giving the block a light background, subtle shadow, and centered text. The default left border is removed, and the image keeps its aspect ratio with slightly rounded corners for a polished look.
Enqueue it in the block editor
Next, since the JavaScript file needs to load inside the block editor, we must enqueue it in functions.php. This ensures the Testimonial block variation appears inside the block editor.
function enqueue_custom_block_variations() {
wp_enqueue_script(
'custom-block-variations',
get_template_directory_uri() . '/assets/js/custom-block-variations.js',
array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ),
filemtime( get_template_directory() . '/assets/js/custom-block-variations.js' ),
true
);
}
add_action( 'enqueue_block_editor_assets', 'enqueue_custom_block_variations' );
While the JavaScript code ensures the block looks correct in the editor, we also need to apply the styles on the frontend so testimonials display correctly when published. Add the following code to functions.php:
function register_testimonial_block_style() {
register_block_style(
'core/quote',
array(
'name' => 'testimonial',
'label' => __( 'Testimonial', 'your-text-domain' ),
'inline_style' => '
.wp-block-quote.is-style-testimonial {
background-color: #f9f9f9;
padding: 24px;
border: none !important;
border-radius: 8px;
text-align: center;
font-size: 1.2em;
font-style: normal;
color: #333;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center;
}
.wp-block-quote.is-style-testimonial .wp-block-image img {
width: 100px;
height: 100px;
object-fit: cover;
border-radius: 12px;
}
.wp-block-quote.is-style-testimonial .testimonial-name {
font-weight: bold;
font-size: 1.2em;
margin-top: 12px;
color: #222;
}
.wp-block-quote.is-style-testimonial .testimonial-company {
font-size: 0.9em;
color: #555;
}
',
)
);
}
add_action( 'init', 'register_testimonial_block_style' );Now, whenever a user inserts a Testimonial block, it already includes the image, quote, name, and company fields, all preformatted and styled correctly. This eliminates the need for manual adjustments, ensuring every testimonial follows the same clean and professional structure.
4. Use block supports API and block styles API together
Let’s consider a real-world scenario. A company wants all buttons on its site to follow strict brand guidelines. They don’t want users picking random colors, changing padding, or applying funky typography. However, they do want flexibility — so users should be able to choose between two pre-approved button styles:
- Primary Button — The main call-to-action button, with a solid background and bold styling.
- Secondary Button — A more subtle, outlined button typically used for secondary actions.
To achieve this, we need to:
- Use the Styles API to define the two button styles.
- Use the Supports API to remove unnecessary settings, ensuring users don’t manually override branding by changing colors, spacing, or typography.
Define custom button styles
Start by adding the following code to the functions.php file:
function register_custom_button_styles() {
register_block_style(
'core/button',
array(
'name' => 'primary-button',
'label' => __( 'Primary Button', 'your-text-domain' ),
'inline_style' => '
.wp-block-button.is-style-primary-button .wp-block-button__link {
background-color: #4D4D4D;
color: #ffffff;
padding: 12px 24px;
border-radius: 4px;
font-size: 1em;
font-weight: 500;
text-transform: none;
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.1);
}
',
)
);
register_block_style(
'core/button',
array(
'name' => 'secondary-button',
'label' => __( 'Secondary Button', 'your-text-domain' ),
'inline_style' => '
.wp-block-button.is-style-secondary-button .wp-block-button__link {
background-color: transparent;
color: #4D4D4D;
padding: 12px 24px;
border: 1px solid #4D4D4D;
border-radius: 4px;
font-size: 1em;
font-weight: 500;
text-transform: none;
box-shadow: none;
}
',
)
);
}
add_action( 'init', 'register_custom_button_styles' );Restricting Button Customization
While the button styles are now predefined, users could still manually override them using WordPress’s block editor settings. If they change the colors, padding, or typography, the buttons may no longer match the brand guidelines.
We can use the Supports API to disable these customization options, preventing users from making unintended changes. Add this to functions.php:
function restrict_button_customization($args, $block_type) {
if ($block_type === 'core/button') {
// Disable specific color settings (text, background, link)
$args['supports']['color'] = [
'text' => false,
'background' => false,
'link' => false,
];
// Disable typography settings (font size, font weight, line height)
$args['supports']['typography'] = false;
// Disable spacing settings (padding, margin)
$args['supports']['spacing'] = false;
}
return $args;
}
add_filter('register_block_type_args', 'restrict_button_customization', 10, 2);