How to Limit Editor Blocks Without Wrecking the Site Editor

Got a call last week from a client in a full-blown panic. Their marketing team was complaining that the block editor was stripped bare—they could only add paragraphs and headings. At the same time, their lead designer was seeing a completely broken Site Editor. Templates wouldn’t load, layout blocks were gone… total mess. The designer was blaming the marketers, the marketers were blaming the designer. And me? I had a hunch it was a dev fix gone wrong.

Turns out, a junior dev was asked to limit allowed blocks for the content team to keep the blog post layouts consistent. A reasonable request. Their solution? The allowed_block_types_all filter. On the surface, it makes perfect sense. But they applied it globally, and in modern WordPress, that’s a landmine.

Why a Global Filter Breaks the Site Editor

Here’s the deal. The Site Editor isn’t just editing a post or a page. It’s working with special post types: wp_template and wp_template_part. It needs access to every single layout block—groups, rows, stacks, query loops, you name it—to function. When you slap a global filter on allowed_block_types_all, you’re telling WordPress, “These are the only blocks anyone gets to use, anywhere.” The Site Editor tries to load a template, finds that the necessary blocks are banned, and just… breaks.

My first thought years ago would have been the same—just use the filter. And before the Site Editor existed, that was fine. But it’s a classic example of how a solution from one era becomes a problem in the next. You can’t use a sledgehammer when you need a scalpel.

The Right Way: Check the Context

Here’s the kicker: that filter isn’t as dumb as it looks. It passes a second argument, $context, which is an absolute lifesaver. This object tells you exactly where the filter is being called. Is it the post editor? A widget? Or the Site Editor? By checking that context, you can apply the rules selectively.

add_filter( 'allowed_block_types_all', 'allowed_blocks', 10, 2 );

function allowed_blocks( $allowed, $context ) {
    // Site Editor usually edits these post types.
    if ( isset( $context->post ) && $context->post ) {
        $post_type = $context->post->post_type;

        // Allow all blocks in the Site Editor.
        if ( in_array( $post_type, array( 'wp_template', 'wp_template_part' ), true ) ) {
            return true;
        }

        // Restrict blocks for regular content.
        if ( in_array( $post_type, array( 'post', 'page' ), true ) ) {
            return array(
                'core/paragraph',
                'core/heading',
                'core/image',
            );
        }
    }

    // Fallback: detect the Site Editor screen directly if available.
    if ( function_exists( 'get_current_screen' ) ) {
        $screen = get_current_screen();
        if ( $screen && 'site-editor' === $screen->id ) {
            return true;
        }
    }

    // Another fallback: some contexts expose a name like 'core/edit-site'.
    if ( isset( $context->name ) && 'core/edit-site' === $context->name ) {
        return true;
    }

    return $allowed;
}

So, What’s the Point?

The real lesson here isn’t just about this one filter. It’s about paying attention to the context WordPress gives you. A lot of modern hooks and filters include that extra parameter for a reason. The code I used is a slightly more robust version of a great snippet from the official WordPress Developer News. Trust me on this, checking the context first saves hours of debugging.

  • Leave the Site Editor alone: The code first checks if we’re in a wp_template or wp_template_part context. If so, it returns true, which tells WordPress to allow all blocks. Hands off.
  • Restrict for content editors: Next, it checks if the post type is a standard post or page. If it is, then we return our short, clean list of approved blocks.
  • Add fallbacks: The checks for get_current_screen() and $context->name are there just in case the post object isn’t available, making the function work consistently across different WordPress versions.

Look, this stuff gets complicated fast. If you’re tired of debugging someone else’s mess and just want your site to work, drop my team a line. We’ve probably seen it before.

Leave a Reply

Your email address will not be published. Required fields are marked *