0

Fresh/clean install of WordPress 6.1.1 (no 3rd party plugins/themes)- PHP 8.0.x

Using the following code in functions.php of twentytwentytwo theme.

function wrm_testblock() {
  register_block_type('wrm/testblock', array(
    'attributes' => array(
      'title' => array(
        'type' => 'string',
        'default' => 'TEST',
      ),
      'imageUrl' => array(
        'type' => 'string',
        'default' => '',
      ),
      'linkUrl' => array(
        'type' => 'string',
        'default' => '',
      ),
    ),
  ));
}
add_action('init', 'wrm_testblock');

According to any documentation I have read, I would expect to see the new block available in the blocks panel in the editor. But that's not the case. The new block is nowhere. If I do intentionally a mistake -e.g. type the block name with capitals, WP will let me know about my mistake, which means that the function gets called.

I might be missing something obvious that I am not able to see.

Does the block need to have any other attributes in order to become available in the blocks panel? Or do I need anything else to make this work?

All the docs I read and many examples show that I can register a block only by its name and that it should appear as block option in the panel.

Any idea?

2 Answers 2

2

The PHP code you shared registers the block on the server side, and this information is passed to the block editor via the REST API.

However, no information about how to display or edit the block is included with this, there is no edit component, no save component, and no JS file referenced. So there is no way to show your block in the block editor with just what you've told it. Using this method still requires that the block be registered in javascript too

It is possible to specify a JS file when using register_block_type but you would then need to register the block in that file and pass it the necessary save and edit parameters. Not only that but the title, icon, block category, are all missing.

The easiest method is probably to use register_block_type_from_metadata and provide it the folder/path of a block.json file. This is a more modern version of what you've used, and it will process relative file paths to load edit and save component JS in the same folder.

This is what the WP Scripts block scaffolding will do. It also auto-generates some PHP that can be used to enqueue the needed scripts for the block automagically, and it sets up React etc and commands/docs to build and do live in browser rebuild/refresh.

8
  • Has not WP added support for block.json in register_block_type recently? At first place my question is about being able to see the block as available in the blocks panel, even if it's not capable of showing, saving, editing anything. Shouldn't the block be available there?
    – FFrewin
    Commented Dec 21, 2022 at 14:37
  • no, why would it? It has no name, description, icon, no edit or save component, so there's no way to insert it, no way to display it, even listing it requires information you haven't provided. I'm not entirely sure what you expect you would see in the block inserter if it did try to display your block, as far as the block editor is concerned, it is aware there is something named wrm/testblock that takes specific attributes, but it knows nothing more than that, and has no idea how to display/save/edit/insert it. Registering the block only in JS with just that info would have the same result
    – Tom J Nowell
    Commented Dec 21, 2022 at 15:06
  • likewise, if you programmatically created that block and tried to insert it, the editor would show it as a crashed block, though it may break at a higher level with messages in the console
    – Tom J Nowell
    Commented Dec 21, 2022 at 15:11
  • Thanks for your input so far. I will check further, try to validate your directions, and should be back with my findings at some point.
    – FFrewin
    Commented Dec 21, 2022 at 16:55
  • OK @Tom - I managed to gather all the pieces together - my misconception is cleared now. Thanks for the time you put and the information you provided. Best wishes.
    – FFrewin
    Commented Dec 22, 2022 at 10:39
0

Sadly, WP doesn't have this automated yet. So to actually display the block in the editor, you have to register it using JS.

Luckily, this can be done without any JS/react building, using just pure PHP&JS:

add_action('admin_head', function () {
    ?>
    <script>
        if (typeof window.wp.blockEditor !== 'undefined') {
            ( function ( blocks, element, blockEditor, editor ) {
                const el = element.createElement;
                const InnerBlocks = blockEditor.InnerBlocks;
                const useBlockProps = blockEditor.useBlockProps;

                blocks.registerBlockType('wrm/testblock', {
                    edit: function (props) {
                        return el(
                            editor.ServerSideRender,
                            {
                                block: "wrm/testblock",
                                attributes: props.attributes
                            }
                        );
                    },

                    save: () => null,
                });
            } )( window.wp.blocks, window.wp.element, window.wp.blockEditor, window.wp.editor );
        }
    </script>
    <?php
});

What this does is basically telling the editor that you want to use this block in the editor and that for its rendering you want to use the render.php you have defined in your block.json e.g. like

"render": "file:./render.php",

This is just a basic example for a HTML static block.

In case you want parts of the block to be editable - again you have to tell it to editor "I want to have this input and when it changes I want to update this attribute/prop" - example adding block setting text input to the sidebar of block settings - note that it will still leverage the server-side rendering in both editor and frontend view 😉:

edit: function (props) {
    return [
        el(
            editor.ServerSideRender,
            {
                block: "wrm/testblock",
                attributes: props.attributes
            }
        ),
        el(
            editor.InspectorControls,
            {},
            el(
                wp.components.TextControl,
                {
                    label: 'Title',
                    value: props.attributes.title,
                    onChange: (title) => props.setAttributes({ title: title }),
                }
            )
        )
    ];
},

Then in your render.php you can do something like

<h3><?php echo esc_html($block->attributes['title']); ?></h3>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.