Skip to content

Instantly share code, notes, and snippets.

@mattheu
Last active July 13, 2018 14:16
Show Gist options
  • Save mattheu/e1872b00684498e2d15ad9e345bf2c83 to your computer and use it in GitHub Desktop.
Save mattheu/e1872b00684498e2d15ad9e345bf2c83 to your computer and use it in GitHub Desktop.
Gutenberg Bug - dynamic block with loop in render_callback.

If you have a dynamic gutenberg block, and in the PHP render_callback, your code includes a custom query and loop, then it will break the editor.

This test plugin demonstrates the issue.

  • Create a new page.
  • Add the 'Demo Dynamic Post Block' block
  • Add one or more image IDs. Comma separated (e.g. 12, 523 )
  • Save a draft.
  • If you preview the page - this will work as expected. You will see the image titles and IDs.
  • If you reload the page in the editor, the page will break with the following JS error:

Unhandled promise rejection TypeError: "r.content is undefined"

Notes

  • this works fine if I roll back to v3.0.1. It is broken in versions v3.1.0 and newer.
  • If you query for post type post instead of image, then the content of the editor is replaced with the content of the post queried in the render_callback.
( function( blocks, element ) {
var el = element.createElement;
blocks.registerBlockType( 'humanmade/test-block', {
title: 'Demo Dynamic Post Block',
icon: 'format-aside',
category: 'common',
attributes: {
attachmentIds: {
type: 'array',
default: [],
},
},
edit: function ( props ) {
var attachmentIds = props.attributes.postIds || [];
var label = el( 'label', {
key: 'label',
style: { display: 'block' },
}, 'Enter some Image IDs. Comma separated.' );
var input = el( 'input', {
type: 'text',
value: attachmentIds.join( ', ' ),
key: 'input',
onChange: function( e ) {
const idArray = e.target.value.split(',')
.map( function( id ) { return id.trim(); } )
.map( function( id ) { return parseInt( id, 10 ); } );
props.setAttributes( { attachmentIds: idArray } );
},
} );
return el( 'div', {}, [ label, input ] );
},
save: function () {
return null
}
} );
} )(
window.wp.blocks,
window.wp.element
);
<?php
function test_gutenberg_block() {
wp_register_script( 'test-gutenberg-block', plugins_url( 'test.js', __FILE__ ), array( 'wp-blocks', 'wp-element' ) );
register_block_type( 'humanmade/test-block', array(
'editor_script' => 'test-gutenberg-block',
'attributes' => [
'attachmentIds' => [
'type' => 'array',
'default' => []
],
],
'render_callback' => 'test_render_block_section_services',
) );
}
add_action( 'init', 'test_gutenberg_block' );
/**
* Render Callback.
* Note that this includes a custom query, and it loops over the results and outputs some code.
* This is captured by an output buffer and returned.
*/
function test_render_block_section_services( $attributes ) {
$my_query = new WP_Query([
'post__in' => $attributes['attachmentIds'],
'post_type' => 'attachment',
'post_status' => 'any',
]);
ob_start();
while ( $my_query->have_posts() ) {
$my_query->the_post();
echo '<p>' . get_the_title() . ': ' . get_the_ID() . '</p>';
wp_reset_postdata();
}
$r = ob_get_clean();
return $r;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment