Add PHP block template to content using wp_insert_post

I have created a block template so that every new post starts with a certain collection of blocks.

In the below reduced example, let’s say that the block template contains just a heading block and a paragraph block (in reality, the block template is much more complex):

function register_custom_block_template() {
    $post_type_object = get_post_type_object( 'post' );
    $post_type_object->template = array(
        array( 'core/heading', array(
            'placeholder' => 'Post Heading',
        ) ),
        array( 'core/paragraph', array(
            'placeholder' => 'Post Paragraph',
        ) ),
    );
}
add_action( 'init', 'register_custom_block_template' );

Sometimes, based on a certain action, I want to programatically add a post using wp_insert_post() that will use the same or similar block template. However, in order to add the same blocks inside the “post_content” key of the wp_insert_post array, I have to manually rewrite all of the PHP arrays of the block template into the HTML/Comments format used by the block editor:

// Programatically insert new post
wp_insert_post(
    array(
        'post_title'    => 'Test Post',

        'post_content'  => '
        <!-- wp:heading {"placeholder":"Post Heading"} -->
        <h2></h2>
        <!-- /wp:heading -->

        <!-- wp:paragraph {"placeholder":"Post Paragraph"} -->
        <p></p>
        <!-- /wp:paragraph -->',

        'post_status'   => 'publish',
        'post_author'   => 1,
    )
);

How do I reuse the PHP arrays of the block template inside wp_insert_post() i.e by adding the arrays to a common variable. WordPress is supposedly doing this conversion as when a new post is created the block template will be converted from PHP/arrays to HTML/comments in the new post, so there must be some sort of a function in core?

What I essentially need is something like this:

// Block Template
$block_template = array(
    array( 'core/heading', array(
        'placeholder' => 'Post Heading',
    ) ),
    array( 'core/paragraph', array(
        'placeholder' => 'Post Paragraph',
    ) ),
);

// Post Template (for newly created posts)
function register_custom_block_template() {
    $post_type_object = get_post_type_object( 'post' );

    $post_type_object->template = $block_template;
}
add_action( 'init', 'register_custom_block_template' );

// Programatically insert new post
wp_insert_post(
    array(
        'post_title'    => 'Test Post',

        'post_content'  => $block_template,

        'post_status'   => 'publish',
        'post_author'   => 1,
    )
);

1 Answer
1

I’ve modified serialize_block a bit:

function serialize_block_template( $block ) {
    $block_content="";

    if (isset($block[2])) {
        $index = 0;
        foreach ( $block[2] as $chunk ) {
            $block_content .= is_string( $chunk ) ? $chunk : serialize_block_template( $block[2][ $index++ ] );
        }
    }

    return get_comment_delimited_block_content(
        $block[0],
        $block[1],
        $block_content
    );
}

Disclaimer: could have some bugs, only tested it for one simple use case.

Leave a Comment