Support » Plugin: Genesis Custom Blocks » Block render called twice when editing a page/post

  • Resolved Martin Taylor

    (@docdunning)


    When I edit a post/page containing a GCB block, my “block.php” rendering code is called twice as the editor page loads.

    This is somewhat annoying – my block uses another plugin’s template function to display some content. When “block.php” is first called, it seems that the other plugin hasn’t yet been activated, so the function call fails and I get a fatal error / white screen of death from WordPress.

    OK, there’s a workaround, which is to use if (function_exists(... in “block.php”, before rendering the output. I guess that’s a sensible precaution anyway, but like I say, it’s a little annoying.

    I can’t understand why “block.php” would be called twice, and this may not be a GCB plugin issue but it would be good to know if there’s a way of avoiding it.

    Here’s a debug backtrace, showing the two calls to “block.php”. The first one is the one that happens very early on, and which causes the fatal error if it references any other plugin’s functions.

    Any thoughts? Is this just one of those things that WP does that we can’t avoid?

    In block.php – first time
    #0 require() called at [D:\webpages\test\wp-includes\template.php:732]
    #1 load_template() called at [D:\webpages\test\wp-content\plugins\genesis-custom-blocks\php\Blocks\Loader.php:475]
    #2 Genesis\CustomBlocks\Blocks\Loader->block_template() called at [D:\webpages\test\wp-content\plugins\genesis-custom-blocks\php\Blocks\Loader.php:374]
    #3 Genesis\CustomBlocks\Blocks\Loader->render_block_template() called at [D:\webpages\test\wp-content\plugins\genesis-custom-blocks\php\Blocks\Loader.php:202]
    #4 Genesis\CustomBlocks\Blocks\Loader->Genesis\CustomBlocks\Blocks\{closure}() called at [D:\webpages\test\wp-includes\class-wp-block.php:221]
    #5 WP_Block->render() called at [D:\webpages\test\wp-includes\blocks.php:799]
    #6 render_block() called at [D:\webpages\test\wp-includes\blocks.php:837]
    #7 do_blocks() called at [D:\webpages\test\wp-includes\class-wp-hook.php:292]
    #8 WP_Hook->apply_filters() called at [D:\webpages\test\wp-includes\plugin.php:212]
    #9 apply_filters() called at [D:\webpages\test\wp-includes\rest-api\endpoints\class-wp-rest-posts-controller.php:1721]
    #10 WP_REST_Posts_Controller->prepare_item_for_response() called at [D:\webpages\test\wp-includes\rest-api\endpoints\class-wp-rest-posts-controller.php:504]
    #11 WP_REST_Posts_Controller->get_item() called at [D:\webpages\test\wp-includes\rest-api\class-wp-rest-server.php:1139]
    #12 WP_REST_Server->respond_to_request() called at [D:\webpages\test\wp-includes\rest-api\class-wp-rest-server.php:985]
    #13 WP_REST_Server->dispatch() called at [D:\webpages\test\wp-includes\rest-api.php:479]
    #14 rest_do_request() called at [D:\webpages\test\wp-includes\rest-api.php:2810]
    #15 rest_preload_api_request()
    #16 array_reduce() called at [D:\webpages\test\wp-admin\edit-form-blocks.php:82]
    #17 require(D:\webpages\test\wp-admin\edit-form-blocks.php) called at [D:\webpages\test\wp-admin\post.php:187]
    ——
    In block.php – second time
    #0 require() called at [D:\webpages\test\wp-includes\template.php:732]
    #1 load_template() called at [D:\webpages\test\wp-content\plugins\genesis-custom-blocks\php\Blocks\Loader.php:475]
    #2 Genesis\CustomBlocks\Blocks\Loader->block_template() called at [D:\webpages\test\wp-content\plugins\genesis-custom-blocks\php\Blocks\Loader.php:374]
    #3 Genesis\CustomBlocks\Blocks\Loader->render_block_template() called at [D:\webpages\test\wp-content\plugins\genesis-custom-blocks\php\Blocks\Loader.php:202]
    #4 Genesis\CustomBlocks\Blocks\Loader->Genesis\CustomBlocks\Blocks\{closure}() called at [D:\webpages\test\wp-includes\class-wp-block.php:221]
    #5 WP_Block->render() called at [D:\webpages\test\wp-includes\blocks.php:799]
    #6 render_block() called at [D:\webpages\test\wp-includes\rest-api\endpoints\class-wp-rest-block-renderer-controller.php:186]
    #7 WP_REST_Block_Renderer_Controller->get_item() called at [D:\webpages\test\wp-includes\rest-api\class-wp-rest-server.php:1139]
    #8 WP_REST_Server->respond_to_request() called at [D:\webpages\test\wp-includes\rest-api\class-wp-rest-server.php:985]
    #9 WP_REST_Server->dispatch() called at [D:\webpages\test\wp-includes\rest-api\class-wp-rest-server.php:412]
    #10 WP_REST_Server->serve_request() called at [D:\webpages\test\wp-includes\rest-api.php:354]
    #11 rest_api_loaded() called at [D:\webpages\test\wp-includes\class-wp-hook.php:292]
    #12 WP_Hook->apply_filters() called at [D:\webpages\test\wp-includes\class-wp-hook.php:316]
    #13 WP_Hook->do_action() called at [D:\webpages\test\wp-includes\plugin.php:551]
    #14 do_action_ref_array() called at [D:\webpages\test\wp-includes\class-wp.php:388]
    #15 WP->parse_request() called at [D:\webpages\test\wp-includes\class-wp.php:750]
    #16 WP->main() called at [D:\webpages\test\wp-includes\functions.php:1291]
    #17 wp() called at [D:\webpages\test\wp-blog-header.php:16]
    #18 require(D:\webpages\test\wp-blog-header.php) called at [D:\webpages\bssc\index.php:19]
    ——

Viewing 3 replies - 1 through 3 (of 3 total)
  • Plugin Contributor Ryan Kienstra

    (@ryankienstra)

    Hi @docdunning,
    Thanks for your stack trace.

    Hm, I’m not really sure how that could happen.

    This is somewhat annoying – my block uses another plugin’s template function to display some content.

    What’s the other plugin, and could you please paste the block.php file here? I’ll see if I can reproduce this.

    Thread Starter Martin Taylor

    (@docdunning)

    Hi @ryankienstra

    I’ve worked out that this is mainly an issue with the other plugin (TablePress). The author Tobias is usually pretty helpful when I’ve asked for support, and I will ask him for his view.

    So – here’s the block I’m using:

    <?php
    $tableid = filter_var(block_value('table-id'),FILTER_SANITIZE_STRING);
    $showname = filter_var(block_value('show-name'),FILTER_VALIDATE_BOOLEAN);
    // if (function_exists('tablepress_print_table')) {
            $f = fopen($_SERVER['DOCUMENT_ROOT'].'/blockdebug.txt','a');
            fputs ($f, 'Debugging block at '.date('H:i:s'));
            fclose ($f);
            echo '<div class="blocktable">';
            tablepress_print_table( array( 'id' => $tableid, 'use_datatables' => false, 'print_name' => $showname ));
            echo '</div>';
    // }

    As it stands, this crashes WordPress. What I’ve found is that tablepress_print_table() is only enabled “on the front end”. Here’s Tobias’s code:

    if ( is_admin() ) {
    	$controller = 'admin';
    	if ( wp_doing_ajax() ) {
    		$controller .= '_ajax';
    	}
    } else {
    	$controller = 'frontend';
    }
    self::$controller = self::load_controller( $controller );
    

    The function is only enabled as a result of that last ‘frontend’ condition.

    What’s still a mystery to me though is why WP invokes the block twice. On the first pass, the function isn’t available, but on the second pass it is. So when I reinstate the if (function_exists condition, it works OK – and it displays the function’s output in the editor.

    And that’s the obvious workaround – check for the function’s availability before invoking it, but it’s still odd.

    Plugin Contributor Ryan Kienstra

    (@ryankienstra)

    Hi @docdunning,
    Thanks, good to hear you narrowed it down.

    Yeah, that’s pretty strange. The render_callback must somehow be running twice:
    https://github.com/WordPress/wordpress-develop/blob/1446948f95fcb4c8fa05cb3c7ac6c22ba5f6fb52/src/wp-includes/class-wp-block-type.php#L250

    It means a lot to me that you joined us on Genesis Custom Blocks from Block Lab.

    Have a great weekend!

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Block render called twice when editing a page/post’ is closed to new replies.