4

This has been asked but I do not think it has been answered properly.

There are two approaches to get all registered block-types, using PHP server-side and JS on client-side. The PHP wouldn't always catch any new blocks registered by the client.

I know how to do both but I still see Block options in the Post Editor that are not on any of these lists - anyone know why, and more importantly, how to catch those?

My ultimate goal is to have a whitelist of blocks and remove/unregister anything that does not match.

This code works for me in PHP and returns about 91 block names:

<?php
require 'wp-load.php';
$block_types = WP_Block_Type_Registry::get_instance()->get_all_registered();
$keys = array();
foreach($block_types as $key) {
    $keys[] = $key->name;
}
print_r($keys);

This JavaScript, copy/pasted into developer console on a Post editor page gives me about 90 block names:

wp.blocks.getBlockTypes();

However when I go to create a new Post and look at the list of allowable blocks I see more than what is featured in this list, like Stack, Group, Row and others./

How do I catch these?

4
  • 1
    They are there in the JS output, but hidden under variations — for example, look in the core/group object's variations and you'll see group, group-row, group-stack… it's all new to me but I guess the block editor will also show variations in the add block panel. Sep 25, 2022 at 21:48
  • Thanks @NabhaCosley but I'm afraid not sure the helps - unless you know a way to list all variations, and then thoughts on how to unregister them?
    – donohoe
    Sep 28, 2022 at 21:41
  • 1
    Hmm @donohoe if you unregistered the main block, I'm sure it would also take the variations with it. (I'd be doubtful about unregistering individual variations.) But listing the variations is easy since they are in the JS output — you'd just have to dig into the block information that you get with wp.blocks.getBlockTypes() and grab that. Sep 28, 2022 at 22:51
  • If you want to get block names, run this: wp.blocks.getBlockTypes().map(b => b.name);
    – Anh Tran
    Aug 15, 2023 at 9:22

1 Answer 1

1

The Basics

I realize this is older, but recently had to do exactly the same thing (whitelist certain blocks). Your code does work, but you have to be sure it runs after all blocks are registered. Secret to that is in the filter where you run the code - as long as the priority is higher than blocks being registered, it'll work. It's possible to register a block inside the 'allowed_block_types_all' filter, so ensuring your priority is higher than any code that potential does that, you'll get a comprehensive list of blocks. Here's my code:

        add_filter('allowed_block_types_all', function($enabled_blocks) {
            $enabled_blocks = array_map(function($block) {
                return $block->name;
            }, WP_Block_Type_Registry::get_instance()->get_all_registered());
            
            // do something with the list of block names, then return

            return $enabled_blocks;       
        }, INF, 1);

Note: the value of the $enabled_blocks parameter is simply true by default, meaning all block types are allowed. But a boolean or an array of registered block names can be returned.

Also Note: I have the priority set to INF so it is always the highest priority. I personally do this, but I don't recommended it in almost any circumstance since this locks even yourself out of running a higher-priority function if you ever want to. A sufficiently high integer like 1000 I'm sure would be fine. I do INF because I know for a fact I will never want anything to run after my function.

Variations

Blocks can have variations, but if you filter out the block, the variations go with it. A variation is not in itself a block - so is not in your list of registered blocks. This is why your server-side and client-side lists don't match. If you want to whitelist/blacklist blocks, this doesn't really matter. If you want to whitelist/blacklist specific variations of blocks, that's a different question altogether, and a fair bit more involved.


The Whitelist

I'm using the roots/acorn package, and have a custom config where I can list the blocks I want to support. I then handle my whitelist like so:

        add_filter('allowed_block_types_all', function($enabled_blocks) {
            // get all enabled blocks
            $enabled_blocks = collect(WP_Block_Type_Registry::get_instance()->get_all_registered())
                ->map(fn($block) => $block->name);

            // get all allowed core/third-party blocks from my config
            $allowed_blocks = collect(config('gutenberg.supported'));

            // get all my custom theme blocks (not listed in my supported array)
            $custom_blocks = collect(config('gutenberg.blocks'))
                ->map(fn(Block $block) => $block::blockname());

            // remove blocks that are not supported
            $final_blocks = $enabled_blocks
                ->intersect($allowed_blocks);

            // add the custom theme blocks back in
            $final_blocks = $final_blocks
                ->merge($custom_blocks);

            // return the final list of block names
            return $final_blocks->toArray();
        }, INF, 1);

My custom config (read in by the roots/acorn package):

// config/gutenberg.php
return [
  // list of custom theme blocks (abstracted into classes that follow an interface.
  'blocks' => [],

  // list of supported third-party/core block names
  'supported' => [
  ],
];

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.