3

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,
    )
);
4
  • 1
    The logic for generating the HTML for blocks simply doesn't exist in PHP for most blocks. The only way to generate a block is with the block editor, or manually writing valid HTML for that block. This is because the HTML templates and rules for blocks is defined in the JavaScript for that block. WordPress can't know how to generate a block's markup in PHP. – Jacob Peattie Apr 20 '20 at 1:58
  • 2
    @JacobPeattie So if the generation is done in JS, how does WordPress pass the PHP block template to JS to generate the markup when a new post is created? It is obviously done in some way, as when you switch from Visual Editor to Code Editor in a new post that has a PHP block template, the HTML markup is clearly generated in the Code Editor? – senectus Apr 20 '20 at 2:09
  • 2
    The template definition is converted to the HTML for the blocks by the editor, in JavaScript, based on the JS definitions of the blocks. wp_insert_post() does not run the editor, so it can't generate the HTML. – Jacob Peattie Apr 20 '20 at 2:18
  • This answer comes close: wordpress.stackexchange.com/questions/343037/… But it's about serializing actual block arrays. rather than block-template arrays – Jules Aug 8 '20 at 20:34
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.