<?php
add_filter( 'allowed_block_types_all', function( $allowed, $context ) {
/**
* 1) Never restrict the Site Editor (templates need access to layout blocks).
* This mirrors WordPress Dev Blog guidance to avoid breaking the Site Editor.
*/
if ( isset( $context->post ) && $context->post ) {
$post_type = $context->post->post_type;
// Site Editor post types.
if ( in_array( $post_type, array( 'wp_template', 'wp_template_part' ), true ) ) {
return true;
}
// 2) Only restrict blocks on blog posts.
if ( 'post' !== $post_type ) {
return $allowed;
}
} else {
// Fallback detection for Site Editor screens.
if ( function_exists( 'get_current_screen' ) ) {
$screen = get_current_screen();
if ( $screen && 'site-editor' === $screen->id ) {
return true;
}
}
if ( isset( $context->name ) && 'core/edit-site' === $context->name ) {
return true;
}
// If we don't know what we're editing, don't be aggressive.
return $allowed;
}
/**
* 3) Essential core blocks for writing blog posts.
* (Keep paragraph — Gutenberg expects it as a default appender in many flows.)
*/
$essential_core_blocks = array(
'core/paragraph',
'core/heading',
'core/list',
'core/list-item', // inner block for list
'core/quote',
'core/pullquote',
'core/image',
'core/gallery',
'core/video',
'core/audio',
'core/file',
'core/table',
'core/code',
'core/preformatted',
'core/html',
'core/shortcode',
'core/buttons',
'core/button', // inner block for buttons
// Embeds (variations hang off this in modern WP)
'core/embed',
// Reusable block / synced pattern block (optional, but handy):
'core/block',
);
/**
* 4) Collect Etch blocks.
* We try to detect them without you needing to know the namespace:
* - common namespaces like etch/ or etchwp/
* - category containing "etch"
* - render callback class/function containing "etch"
* - script/style handles containing "etch"
*/
$registry = WP_Block_Type_Registry::get_instance();
$types = $registry->get_all_registered();
$etch_blocks = array();
$maybe_etch_namespaces = array( 'etch', 'etchwp' ); // add more if needed
foreach ( $types as $name => $type ) {
$is_etch = false;
// Namespace check.
foreach ( $maybe_etch_namespaces as $ns ) {
if ( 0 === strpos( $name, $ns . '/' ) ) {
$is_etch = true;
break;
}
}
// Category check.
if ( ! $is_etch && isset( $type->category ) && is_string( $type->category ) ) {
if ( false !== stripos( $type->category, 'etch' ) ) {
$is_etch = true;
}
}
// Render callback check.
if ( ! $is_etch && isset( $type->render_callback ) && $type->render_callback ) {
$cb = $type->render_callback;
if ( is_string( $cb ) && false !== stripos( $cb, 'etch' ) ) {
$is_etch = true;
} elseif ( is_array( $cb ) && ! empty( $cb[0] ) ) {
$class = is_object( $cb[0] ) ? get_class( $cb[0] ) : ( is_string( $cb[0] ) ? $cb[0] : '' );
if ( $class && false !== stripos( $class, 'etch' ) ) {
$is_etch = true;
}
}
}
// Script/style handle check (WP 6.1+ uses *_handles, older props are deprecated but may exist).
if ( ! $is_etch ) {
$handle_props = array(
'editor_script_handles',
'script_handles',
'view_script_handles',
'editor_style_handles',
'style_handles',
'view_style_handles',
// Deprecated props (still sometimes populated depending on registration).
'editor_script',
'script',
'view_script',
'editor_style',
'style',
'view_style',
);
foreach ( $handle_props as $prop ) {
if ( empty( $type->$prop ) ) {
continue;
}
foreach ( (array) $type->$prop as $h ) {
if ( is_string( $h ) && false !== stripos( $h, 'etch' ) ) {
$is_etch = true;
break 2;
}
}
}
}
if ( $is_etch ) {
$etch_blocks[] = $name;
}
}
$etch_blocks = array_values( array_unique( $etch_blocks ) );
/**
* 5) Fallback:
* If we didn’t detect any Etch blocks (detection failed, or nothing registered yet),
* allow all NON-core blocks so you don’t lose Etch blocks.
* (This is safer than accidentally locking yourself out.)
*/
if ( empty( $etch_blocks ) ) {
$non_core = array();
foreach ( array_keys( $types ) as $block_name ) {
if ( 0 !== strpos( $block_name, 'core/' ) ) {
$non_core[] = $block_name;
}
}
$etch_blocks = $non_core;
}
return array_values( array_unique( array_merge( $essential_core_blocks, $etch_blocks ) ) );
}, 10, 2 );