Using WordPress ‘pre_render_block’ PHP filter

The ‘pre_render_block’ WordPress PHP  filter enables you to short-circuit the render_block() function by returning a non-null value.

This can be useful for modifying or replacing block content before it’s rendered.

Usage

add_filter( 'pre_render_block', 'your_function_name', 10, 3 );

Parameters

  • $pre_render (string|null): The pre-rendered content. Default null.
  • $parsed_block (array): The block being rendered.
  • $parent_block (WP_Block|null): If this is a nested block, a reference to the parent block.

Examples

Add a CSS class to a specific block

function add_css_class_to_block( $pre_render, $parsed_block, $parent_block ) {
    if ( $parsed_block['blockName'] === 'core/paragraph' ) {
        $parsed_block['attrs']['class'] .= ' custom-class';
        return render_block( $parsed_block );
    }
    return $pre_render;
}
add_filter( 'pre_render_block', 'add_css_class_to_block', 10, 3 );

This code adds the custom-class CSS class to all paragraph blocks. It checks if the block being rendered is a paragraph block and then appends the class to the block’s attributes. Finally, it re-renders the block with the added class.

Replace an image block with a custom image

function replace_image_block( $pre_render, $parsed_block, $parent_block ) {
    if ( $parsed_block['blockName'] === 'core/image' ) {
        $custom_image_url = 'https://example.com/custom-image.jpg';
        $parsed_block['attrs']['url'] = $custom_image_url;
        return render_block( $parsed_block );
    }
    return $pre_render;
}
add_filter( 'pre_render_block', 'replace_image_block', 10, 3 );

This code replaces the default image in all image blocks with a custom image. It checks if the block being rendered is an image block, and then replaces the image URL with a custom URL. The block is then re-rendered with the updated image URL.

Remove heading blocks in nested blocks

function remove_heading_in_nested_blocks( $pre_render, $parsed_block, $parent_block ) {
    if ( $parsed_block['blockName'] === 'core/heading' && $parent_block !== null ) {
        return '';
    }
    return $pre_render;
}
add_filter( 'pre_render_block', 'remove_heading_in_nested_blocks', 10, 3 );

This code removes all heading blocks that are nested within another block. It checks if the block being rendered is a heading block and if it has a parent block. If both conditions are true, the heading block is removed by returning an empty string.

Wrap quotes in a custom container

function wrap_quotes_in_container( $pre_render, $parsed_block, $parent_block ) {
    if ( $parsed_block['blockName'] === 'core/quote' ) {
        $quote_content = render_block( $parsed_block );
        return '<div class="custom-quote-container">' . $quote_content . '</div>';
    }
    return $pre_render;
}
add_filter( 'pre_render_block', 'wrap_quotes_in_container', 10, 3 );

This code wraps all quote blocks in a custom container with the class custom-quote-container. It checks if the block being rendered is a quote block, then renders the quote content and wraps it inside a custom <div>. Finally, the wrapped quote is returned.

Display a message for empty paragraph blocks

function display_message_for_empty_paragraph( $pre_render, $parsed_block, $parent_block ) {
    if ( $parsed_block['blockName'] === 'core/paragraph' && empty( trim( $parsed_block['innerHTML'] ) ) ) {
        return '<p class="empty-paragraph">This paragraph is empty.</p>';
    }
    return $pre_render;
}
add_filter( 'pre_render_block', 'display_message_for_empty_paragraph', 10, 3 );

This code displays a message for empty paragraph blocks. It checks if the block being rendered is a paragraph block and if its innerHTML is empty (trimmed). If both conditions are true, it returns a paragraph with the message “This paragraph is empty” and a class empty-paragraph.

Tagged in

2 comments on “Using WordPress ‘pre_render_block’ PHP filter

  1. I came across your post while looking for some solution ideas, but I don’t think your ‘Add a CSS class’ or ‘replace an image’ solutions will work.

    When you try to use render_block inside of pre_render_block, you end up with an infinite loop, as pre_render_block is actually a sub-filter of the parent render_block function.

    1. I was actually looking for comments section to write this! I did through removing the filter before calling render_block then adding it again after I saved the render_block return into a variable.

Leave a Comment

Your email address will not be published. Required fields are marked *