How to Insert Gutenberg Blocks Using wp_insert_post

It’s 2023, and we still have no simple way to insert Gutenberg blocks into WordPress using wp_insert_post. You’re out of luck if you want to pull content from an API and insert it dynamically with ease. There are methods like parse_blocks and render_blocks but they still require a lot of messing around to work with.

The way Gutenberg blocks work is strange. They’re not stored as an array or structured data in the database. They are stored in the HTML as HTML comments.

For a YouTube embed, it might look like this:

https://www.youtube.com/watch?v=GF423423

You can see how the blocks are handled by viewing the source of your page/post. I can understand why they did it this way for backward compatibility, but it means if you were previously inserting content into your posts, they wouldn’t be Gutenberg blocks by default.

Which is why I ended up creating something that works with the Gutenberg HTML comments. It’s a rather simple function that takes the name, attributes and some content.

function create\_block( $block\_name, $attributes = array(), $content = '' ) {
    $attributes\_string = json\_encode( $attributes );
    $block\_content = '' . $content . '';
    return $block\_content;
}

Going one step further, I also created a wrapper function called create_blocks which allows you to pass in multiple Gutenberg blocks.

function create\_blocks( $blocks = array() ) {
    $block\_contents = '';
    foreach ( $blocks as $block ) {
        $block\_contents .= create\_block( $block['name'], $block['attributes'], $block['content'] );
    }
    return $block\_contents;
}

And here is how you use it.

$blocks = array();
$blocks[] = array(
    'name' => 'paragraph',
    'attributes' => array( 'align' => 'center' ),
    'content' => '

Hello World!

',
);
$blocks[] = array(
    'name' => 'paragraph',
    'attributes' => array( 'align' => 'left' ),
    'content' => '

This is another paragraph.

',
);
$blocks[] = array(
    'name' => 'paragraph',
    'attributes' => array( 'align' => 'right' ),
    'content' => '

And this is yet another paragraph.

',
);
$post\_content = create\_blocks( $blocks );
$post\_id = wp\_insert\_post( array(
    'post\_title'  => 'My post title',
    'post\_content' => $post\_content,
    'post\_status' => 'publish',
    'post\_type'   => 'post',
) );

Is this the best solution you could use? Probably not. Did it work for me? Yes. This saved me the hassle of coming up with a clever solution when all I needed was something that got me out of a pickle.