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
)
ParameterTypeDescription
$pattern_slugstringSlug of the pattern containing the target block
$block_typestringBlock type name (e.g. 'core/heading')
$occurrenceintZero-indexed position of the block within the pattern
$textstringNew 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,
    ]
)
ParameterTypeDescription
$pattern_slugstringSlug of the pattern containing the target block
$block_typestringBlock type name
$occurrenceintZero-indexed position of the block within the pattern
$attrsarrayAttributes 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.

ParameterTypeDescription
$pattern_slugstringSlug of the pattern containing the target block
$block_typestringBlock type name
$occurrenceintZero-indexed position of the block within the pattern
$htmlstringComplete 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
)
ParameterTypeDescription
$pattern_slugstringSlug of the pattern containing the target block
$block_typestringBlock type name
$occurrenceintZero-indexed position of the block within the pattern
$searchstringString to search for
$replacestringReplacement 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;
    }
)
ParameterTypeDescription
$pattern_slugstringSlug of the pattern containing the target block
$block_typestringBlock type name
$callbackcallableCallback 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
)
ParameterTypeDescription
$pattern_slugstringSlug of the pattern containing the target block
$block_typestringBlock type name
$occurrenceintZero-indexed position of the block
$valuemixedIf 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 )
)
ParameterTypeDescription
$pattern_slugstringSlug of the pattern containing the target block
$block_typestringBlock type name
$occurrenceintZero-indexed position of the block
$conditioncallableCallback 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
)
ParameterTypeDescription
$placeholder_namestringThe metadata.name value of the placeholder block
$content_blocksarrayArray 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.

ParameterTypeDescription
$pattern_slugstringThe pattern reference to convert (must appear as wp:pattern in the template)
$keystringUnique identifier for this synced pattern instance — used for lookup on subsequent runs
$titlestringDisplay 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.

Next: Helper Namespaces →