plugin development – How do you render_callback for register_block_type to a method in another class?


I’m writing a new plugin, and one of the things it does is create a new dynamic block. I generally write my plugins based off of WPPB, which does things in an object-oriented way, and semantically separates admin functionality from public functionality.

I have the admin class successfully creating the edit side of the block. But for the “save” side, for a dynamic block, it makes semantic sense for the render function to be in the public class … but (I think) it needs to get registered in the admin class (actually, now that I’m writing this, is there any harm to calling register_block_type more than once?).

I’m thinking there’s more than one way to skin this cat, and I’m trying to figure out the “best”, where “best” is making optimal use of both PHP OOP and WordPress builtin functionality, to maximize speed, minimize size, and provide clean, readable code.

Option 1: make sure the main plugin class instantiates the public class first, and then passes it to the admin class:

class My_Plugin {
        $my_public = new My_Public();
        $my_admin = new My_Admin($my_public);
}

class My_Admin {
        public function __construct($my_public) {
                $this->my_public = $my_public;
        }

        register_block_type( 'my-plugin/my-block',
                    array(
                        'editor_script' => 'my_editor_function',
                        'render_callback' => array($this->my_public, 'my_save_function')
        ) );
}

class My_Public {
        public function my_save_function() {
                //do stuff to render the public side of the block
        }
}

Option 2: do something with WordPress Actions and Hooks:

class My_Admin {
        register_block_type( 'my-plugin/my-block',
                    array(
                        'editor_script' => 'my-editor-function',
                        'render_callback' => 'render_front_end')
        ) );

        public function render_front_end() {
                do_action('my_plugin_render_action');
        }
}

class My_Public {
        public function my_save_function() {
                //do stuff to render the public side of the block
        }
        add_action('my_plugin_render_action', 'my_save_function', 10);
}

Or, hypothetically, Option 3: if there’s no problem calling the register function more than once:

class My_Admin {
        register_block_type( 'my-plugin/my-block',
                    array(
                        'editor_script' => 'my-editor-function',
        ) );
}

class My_Public {
        register_block_type( 'my-plugin/my-block',
                    array(
                        'render_callback' => 'my_save_function'
        ) );

        public function my_save_function() {
                //do stuff to render the public side of the block
        }
}

Is one of these preferable? Do all of these work? Is there a better way to do this?