Dynamic Block not rendering in frontend #65689
-
|
Hi there. I created a dynamic block using the create-block script: In my theme's function my_namespace_blocks_init() {
$directory = __DIR__ . '/assets/blocks';
// get all subfolders inside assets/blocks
$scanned_directory = array_diff( scandir( $directory ), array( '..', '.' ) );
foreach ( $scanned_directory as $dir ) {
register_block_type(
$directory . '/' . $dir,
array(
'render_callback' => 'my_namespace_render',
)
);
}
}
add_action( 'init', 'my_namespace_blocks_init' );My block's render.php file looks like this: <?php
function my_namespace_render( $attr ) {
return '<p>Hello worlds!</p>';
}For testing purposes I left the other files as they were created by the script. In the full site editor the "My Block" block is available and can be added to the page and gets rendered in the backend. But nothing gets rendered in the frontend. I tested if the <p>Hello worlds!</p>This works. I also tried to Is there anything missing to make the render callback function work? Thanks in advance. EDIT: Calling the render callback function inside register_block_type function directly works as well: register_block_type(
$directory . '/' . $dir,
array(
'render_callback' => function() { return "<p>Hi!</p>"; },
)
);
... |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
Okay it seems that the Is it a known bug that you cannot use the callback function inside the |
Beta Was this translation helpful? Give feedback.
-
|
You've actually self-diagnosed it correctly — the reason is in how ob_start();
require $template_path;
return ob_get_clean();So On top of that you're also passing Three clean ways forward, pick one: A. Drop the register_block_type( $directory . '/' . $dir ); // no second arg
<?php
// $attributes, $content, $block are available here.
?>
<p>Hello worlds!</p>B. Keep function my_namespace_render( $attributes, $content, $block ) {
return '<p>Hello worlds!</p>';
}
function my_namespace_blocks_init() {
// … register_block_type with 'render_callback' => 'my_namespace_render'
}
add_action( 'init', 'my_namespace_blocks_init' );C. Anonymous-function variant, which is what worked for you — perfectly fine if all you need is a small piece of render logic and you don't want a separate file. Mixing block.json's |
Beta Was this translation helpful? Give feedback.
You've actually self-diagnosed it correctly — the reason is in how
block.json'srenderfield is implemented in core. Looking atwp-includes/blocks.php, whenregister_block_type_from_metadata()sees arenderfield in block.json, it doesn't call a function — it generates an internalrender_callbackthat does:So
render.phpis expected to output HTML directly (echo / inline markup / function call). It's not a place to define a function — anything just defined there gets loaded at render time and discarded.On top of that you're also passing
'render_callback' => 'my_namespace_render'toregister_block_type()as a string reference. Ati…