skip to Main Content

I’m trying to build a custom Gutenberg Block, which will be rendered dynamically (from PHP).
I’ve spent a significant amount of time searching for different solutions, minimized my code to the absolutely necessary, and still it doesnt work.

My main reference is this page: https://developer.wordpress.org/block-editor/tutorials/block-tutorial/creating-dynamic-blocks/

And here’s my code:
PHP (functions.php):

function register_test_block(){

    wp_register_script('test-block',
        get_template_directory_uri().'/js/test-block.js',
        array('wp-blocks') );

    register_block_type('test/testblock', array(
            'render_callback' => function( $block_attributes, $content ) {
                return '<p>OMG SUCCESS!</p>';
            },
            'editor_script' => 'test-block' )
    );
}

add_action('init', 'register_test_block');

test-block.js:

const { registerBlockType } = wp.blocks;


registerBlockType('test/testblock', {
    title: 'test block',
    edit: props => {
        return (<p>test</p>);
    },
    save: props => {
        return null;
    }
});

i really have no idea why this isn’t working as its supposed to, on the frontend the block is just not rendered at all, not even a comment or anything. Oh and my current WP Version is 5.5.3 with PHP 7.3 if this helps..

Does anyone know why my block isn’t rendering? Thanks!

2

Answers


  1. Chosen as BEST ANSWER

    Really appreciate your help S.Walsh! Cleaning the browsercache or reentering the block didn't really help. Then I rearranged some files, changed some function names, and suddenly it works. Here's my current js (if someone gets the same problem):

    const { registerBlockType } = wp.blocks;
    const { serverSideRender: ServerSideRender } = wp;
    
    const { Fragment } = wp.element;
    
    registerBlockType('abc/dynamicblock', {
        title: 'dynamicblock',
        description: 'dynamicblock',
        icon: (<svg version="1.1" x="0px" y="0px" width="24px" height="24px" viewBox="0 0 24 24"><rect width="24" height="24" style={{fill:'rgb(0,121,200)'}} /></svg>),
        category: 'abc',
        edit: props => {
            return <Fragment>
                <p>serverSideRender should appear here:</p>
                <ServerSideRender
                    block={ "abc/dynamicblock" } />
            </Fragment>;
        },
        save: props => {
            return null; // Nothing to save here..
        }
    });
    

    and this is the php part:

    function register_dynamicblock(){
    
        wp_register_script('dynamicblock',
            get_template_directory_uri().'/js/dynamicblock.js',
            array('wp-blocks', 'wp-element'),
            time() );
    
        $re = register_block_type('abc/dynamicblock', array(
            'render_callback' => 'dynamicblock_renderer',
            'title' => 'dynamicblock',
            'editor_script' => 'dynamicblock'
        ));
    
    }
    add_action('init', 'register_dynamicblock');
    
    function dynamicblock_renderer(){
        return '<div>success!</div>';
    }
    

  2. Your code is on the right path as you do need to register the block both in JavaScript and PHP. The missing link to make it work is that in the JavaScript edit() function, the actual rendering of the PHP callback function is done via <ServerSideRender> component, eg:

    test-block.js:

    const { registerBlockType } = wp.blocks;
    const { serverSideRender: ServerSideRender } = wp;
    
    registerBlockType('test/testblock', {
        title: 'test block',
        edit: () => {
            return (
                <>
                    <ServerSideRender
                        block="test/testblock"
                    />
                </>
            );
        },
        save() {
            return null; // Nothing to save here..
        }
    });
    

    functions.php

    function register_test_block(){
        wp_register_script('test-block', get_template_directory_uri() . '/js/test-block.js', array(
            'wp-blocks',
            'wp'
        ));
    
        register_block_type('test/testblock', array(
            'render_callback' => 'test_testblock_renderer'
            'editor_script' => 'test-block' //re-added, see comment below
        ));
    }
    
    // Optional: Moved render callback to separate function to keep logic clear
    function test_testblock_renderer($block_attributes, $content){
        return '<p>OMG SUCCESS!</p>';
    }
    
    add_action('init', 'register_test_block');
    

    There are many more useful attributes that are part of the ServerSideRender component for building dynamic blocks, however: its a legacy component and if you are building a new data-driven block for Gutenberg, it would be best to see if you are able to achieve your goals via the REST API endpoints where possible.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search