Template API
The Template class is the primary interface for pattern-based content transformation. It provides a fluent (chainable) API for loading a pattern, declaring transformations, and serializing the result.
use HM\Rehydrator\Template;
$transformer = new Template( 'theme/template-article' );
The constructor takes a pattern slug. The pattern is not loaded immediately — it’s resolved lazily when you call get_content() or get_blocks(), so all transformations can be registered before resolution begins.
Text and attribute transformations
replace_text()
Replace the text content of a specific block, preserving its HTML structure (tag name, attributes, classes).
->replace_text(
pattern_slug: 'theme/hero',
block_type: 'core/heading',
occurrence: 0,
text: $title
)
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | Slug of the pattern containing the target block |
$block_type | string | Block type name (e.g. 'core/heading') |
$occurrence | int | Zero-indexed position of the block within the pattern |
$text | string | New text content |
replace_attributes()
Merge new attributes into a specific block, preserving any existing attributes not included in $attrs.
->replace_attributes(
pattern_slug: 'theme/hero',
block_type: 'core/image',
occurrence: 0,
attrs: [
'id' => $image_id,
'url' => $image_url,
'alt' => $alt_text,
]
)
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | Slug of the pattern containing the target block |
$block_type | string | Block type name |
$occurrence | int | Zero-indexed position of the block within the pattern |
$attrs | array | Attributes to merge into the block |
replace_html()
Replace the full innerHTML of a specific block. Use this when you need to control the complete HTML output, not just the text content.
->replace_html(
pattern_slug: 'theme/byline',
block_type: 'core/paragraph',
occurrence: 0,
html: '<p>By <a href="' . $author_url . '">' . $author_name . '</a></p>'
)
Note that the replacement HTML is not escaped or sanitized - you must handle data sanitization yourself.
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | Slug of the pattern containing the target block |
$block_type | string | Block type name |
$occurrence | int | Zero-indexed position of the block within the pattern |
$html | string | Complete replacement innerHTML |
search_replace()
Search and replace a string within a specific block’s innerHTML.
->search_replace(
pattern_slug: 'theme/hero',
block_type: 'core/paragraph',
occurrence: 0,
search: '',
replace: $value
)
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | Slug of the pattern containing the target block |
$block_type | string | Block type name |
$occurrence | int | Zero-indexed position of the block within the pattern |
$search | string | String to search for |
$replace | string | Replacement string |
Custom transformations
transform_callback()
Apply an arbitrary callback to every block of a given type within a pattern. The callback receives the block array and must return the modified block array.
->transform_callback(
pattern_slug: 'theme/stats',
block_type: 'core/columns',
callback: function( array $block ) use ( $stats ) : array {
// Modify $block['innerBlocks'] based on $stats...
return $block;
}
)
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | Slug of the pattern containing the target block |
$block_type | string | Block type name |
$callback | callable | Callback receiving the block array and returning a modified block array |
Unlike the targeted methods above, transform_callback does not take an $occurrence parameter — it applies to all blocks of that type within the pattern.
Block removal
remove_block()
Remove a specific block occurrence from the output.
->remove_block(
pattern_slug: 'theme/hero',
block_type: 'core/paragraph',
occurrence: 1
)
remove_if_empty()
Remove a block only if the provided value is empty. A convenient shorthand for conditionally stripping optional fields.
->remove_if_empty(
pattern_slug: 'theme/hero',
block_type: 'core/paragraph',
occurrence: 1,
value: $subtitle // Block is removed if $subtitle is empty
)
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | Slug of the pattern containing the target block |
$block_type | string | Block type name |
$occurrence | int | Zero-indexed position of the block |
$value | mixed | If empty(), the block is removed |
remove_if()
Remove a block based on an arbitrary condition callback.
->remove_if(
pattern_slug: 'theme/video',
block_type: 'core/group',
occurrence: 0,
condition: fn() => empty( $video_url )
)
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | Slug of the pattern containing the target block |
$block_type | string | Block type name |
$occurrence | int | Zero-indexed position of the block |
$condition | callable | Callback returning true if the block should be removed |
Content insertion
replace_placeholder()
Replace a named placeholder block with an array of blocks. The placeholder is any block with metadata.name set to the given name.
In your pattern file:
<!-- wp:paragraph {"metadata":{"name":"content-placeholder"}} -->
<p></p>
<!-- /wp:paragraph -->
In your migration script:
->replace_placeholder(
placeholder_name: 'content-placeholder',
content_blocks: $body_blocks
)
| Parameter | Type | Description |
|---|---|---|
$placeholder_name | string | The metadata.name value of the placeholder block |
$content_blocks | array | Array of block arrays to insert in place of the placeholder |
The placeholder block is replaced entirely by the provided blocks. If $content_blocks is an empty array, the placeholder is removed.
Synced patterns
replace_with_synced_pattern()
Convert a pattern reference in the template to a synced pattern (formerly “reusable block”) instead of resolving it inline.
Use this for sections that should stay shared and editable across multiple posts — sidebars, footer CTAs, resource sections, etc.
->replace_with_synced_pattern(
pattern_slug: 'theme/footer-cta',
key: 'site-footer-cta',
title: 'Footer CTA'
)
If a synced pattern with the given key already exists in the database, it’s reused. If not, a new wp_block post is created from the pattern’s content.
| Parameter | Type | Description |
|---|---|---|
$pattern_slug | string | The pattern reference to convert (must appear as wp:pattern in the template) |
$key | string | Unique identifier for this synced pattern instance — used for lookup on subsequent runs |
$title | string | Display title shown in the editor’s synced patterns list |
Getting results
get_content()
Apply all pending transformations and return the serialized block markup, ready to write to post_content.
$content = $transformer->get_content();
if ( ! is_wp_error( $content ) ) {
wp_update_post( [
'ID' => $post_id,
'post_content' => $content,
] );
}
Returns string on success, or a WP_Error if the pattern could not be found.
get_blocks()
Apply all pending transformations and return the block array instead of serialized markup. Useful for inspecting the output structure or applying further processing before serialization.
$blocks = $transformer->get_blocks();
Returns array.
has_error() and get_error()
Check for errors after processing, for example if the pattern slug wasn’t found.
if ( $transformer->has_error() ) {
$error = $transformer->get_error(); // WP_Error
WP_CLI::warning( $error->get_error_message() );
}
Combining transformations
Multiple transformation methods can be chained on the same block. They are applied in the order they’re registered:
$transformer
// Replace text and attributes on the same block in theme/hero
->replace_text( 'theme/hero', 'core/heading', occurrence: 0, text: $title )
->replace_attributes( 'theme/hero', 'core/image', occurrence: 0, attrs: [ 'url' => $image_url ] )
// Conditionally clean up optional blocks
->remove_if_empty( 'theme/hero', 'core/paragraph', occurrence: 1, value: $subtitle )
// Handle the body content
->replace_placeholder( 'content-placeholder', $body_blocks )
// Keep the footer CTA as a shared synced pattern
->replace_with_synced_pattern( 'theme/footer-cta', key: 'site-footer-cta', title: 'Footer CTA' );
Error handling
If the initial pattern slug isn’t found in the WordPress pattern registry, all transformation methods still return $this safely. The error is stored and returned by get_content() as a WP_Error. Check has_error() after the call if you need to handle failures gracefully.