如何禁用和锁定古腾堡区块

如何禁用和锁定古腾堡区块

Gutenberg 可让您轻松使用区块创建内容,但有时您需要控制哪些区块可用。也许你正在为一个客户网站工作,想阻止他们使用某些区块。或者,您想通过删除不必要的选项来简化编辑体验。

在本指南中,我们将探讨禁用 Gutenberg 区块的不同方法,包括:

  • 使用 WordPress 用户界面(UI)隐藏插入器中的区块
  • 锁定区块以防止其被移动或删除
  • 使用 PHP 强化区块限制,包括基于角色的访问权限

也就是说,我们不会讨论区块的可见性(根据条件显示/隐藏内容)或禁用特定的区块设置(如文本或背景颜色),这些在 theme.json 中处理。不过,我们将讨论区块锁定,因为它与禁用区块密切相关。

本指南中的所有方法都无需插件即可使用,并且适用于任何基于区块的主题

使用PHP禁用区块

允许或阻止在 WordPress 中使用区块有两种截然不同的基本方法。您可以根据自己的需要,选择允许或拒绝在插入器中使用区块。

这两种方法都可以使用 PHP 或 JavaScript 来实现,各有利弊。在允许列出区块时,PHP 通常更简单,而在拒绝列出区块时,JavaScript 通常更有效。

我们将在所有示例中使用 PHP 来演示各种用例。

允许列出区块

要在插入器中只允许特定的区块,请使用以下过滤器。这将确保所有用户只能使用指定的区块:

add_filter('allowed_block_types_all', 'allowed_block_types_all_users', 10, 2 );
function allowed_block_types_all_users( $allowed_blocks, $block_editor_context ) {
return array(
'core/paragraph',
'core/heading',
'core/image',
'core/cover',
'core/list',
'core/list-item'
);
}

应将此代码添加到子主题functions.php文件中,以防止更新主题时丢失更改。

使用此方法时,请确保包含所有必要的子代码区块。例如,如果允许使用 core/list 区块,则必须同时包含 core/list-item 以防止出错。

允许列表区块

允许列表区块

allowed_block_types_all 过滤器可让开发人员控制插入器中可用的区块。它接受两个参数:

  • $allowed_block_types – 一个数组或布尔值,用于定义允许插入的区块(默认值:true)。
  • $block_editor_context – 提供有关当前区块编辑器状态的信息,包括正在编辑的文章。

允许贡献者和作者使用特定区块

以下代码限制了不具备 publish_pages 功能的用户(贡献者和作者)的可用区块:

add_filter('allowed_block_types_all', 'allowed_block_types_for_non_admins', 10, 2);
function allowed_block_types_for_non_admins($allowed_blocks, $block_editor_context) {
// Apply restrictions if the user does not have the 'publish_pages' capability
if (!current_user_can('publish_pages')) {
// Define the allowed blocks for users without 'publish_pages' capability
$allowed_blocks = array(
'core/paragraph',
'core/heading',
'core/image',
'core/cover',
'core/list',
'core/list-item'
);
}
return $allowed_blocks;
}

在上例中,投稿人和作者只能使用段落、标题、图片、封面和列表区块。

允许特定文章类型和用户使用区块

以下代码在编辑页面时将 Shortcode 区块添加到插入器中,但其他文章类型则无法使用:

add_filter('allowed_block_types_all', 'allowed_block_types', 25, 2);
function allowed_block_types($allowed_blocks, $editor_context) {
$allowed_blocks = array(
'core/paragraph',   
'core/heading',    
'core/image',      
'core/cover',      
'core/list',       
'core/list-item'
);
// Check if the editor context has a post object and if its type is 'page'
if (!empty($editor_context->post) && 'page' === $editor_context->post->post_type) {
$allowed_blocks[] = 'core/shortcode';
}
return $allowed_blocks;
}

请记住,由于撰稿人添加作者不能创建或修改页面,因此结果只会出现在文章中。

所有用户将只看到六个区块,但管理员和编辑也将看到仅适用于页面的简码区块。

简码区块

该简码区块仅适用于页面的管理员和编辑

在我们的示例中,这对贡献者和作者的影响是无效的,因为默认情况下,他们不能添加新页面。不过,使用角色管理器插件可以改变这一功能。

允许基于文章ID的区块

如果在某些情况下,您希望只允许某些文章使用一组区块,可以通过以下方法实现:

add_filter('allowed_block_types_all', 'allowed_block_types', 10, 2);
function allowed_block_types($allowed_blocks, $editor_context) {
// Check if the editor context has a post object
if (!empty($editor_context->post)) {
$post_id = $editor_context->post->ID;
// Define allowed blocks for specific post IDs
$allowed_blocks_by_post = array(
2 => array('core/paragraph', 'core/heading', 'core/image'),
3 => array('core/paragraph', 'core/heading', 'core/image')
);
// Check if the current post ID has a defined allowed blocks array
if (array_key_exists($post_id, $allowed_blocks_by_post)) {
return $allowed_blocks_by_post[$post_id];
}
}
return $allowed_blocks;
}

在本例中,只有段落、标题和图像区块可用于文章 ID 2 和 3。

这三个区块仅适用于两个 ID

这三个区块仅适用于两个 ID

这对一小部分文章 ID 来说没有问题。但如果您需要不断添加页面或文章的动态情况,则应考虑对分类标准和自定义字段进行过滤。

拒绝列出区块

允许列表是拒绝列表的一种形式,因为不可用的区块会被拒绝。不过,如果你想允许除少数区块外的大多数区块,也可以采取相反的方法。在本例中,标题和封面区块不再对任何用户开放。

add_filter('allowed_block_types_all', 'deny_blocks');
function deny_blocks($allowed_blocks) {
// Get all registered blocks
$blocks = WP_Block_Type_Registry::get_instance()->get_all_registered();
// Disable two specific blocks
unset($blocks['core/heading']);
unset($blocks['core/cover']);
return array_keys($blocks);
}

基本上,我们会找到所有已注册的区块,然后删除标题和封面区块。

如果你认为可以用这种方法取消设置任何区块,那就要小心了。如果某个区块(核心区块或其他区块)已通过 JavaScript 注册,则必须通过 JavaScript 取消注册。

拒绝列出整个区块类别

如果您想移除整个区块类别,例如小部件、嵌入或主题区块,请使用此方法:

add_filter('allowed_block_types_all', 'disable_blocks_by_categories', 10, 2);
function disable_blocks_by_categories($allowed_blocks, $editor_context) {
// Get all registered blocks
$registered_blocks = WP_Block_Type_Registry::get_instance()->get_all_registered();
// Specify the categories to disable
$categories_to_disable = array('widgets', 'embed', 'theme');
// Initialize an array to hold allowed block names
$allowed_block_names = array();
// Loop through registered blocks
foreach ($registered_blocks as $block_name => $block_type) {
// Check if the block has categories defined
if (isset($block_type->category)) {
// If the block's category is NOT in the disabled list, allow it
if (!in_array($block_type->category, $categories_to_disable, true)) {
$allowed_block_names[] = $block_name;
}
} else {
// If the block has no category defined, allow it by default
$allowed_block_names[] = $block_name;
}
}
return $allowed_block_names;
}

这种方法可以过滤掉整个类别的区块,简化图区块编辑器的使用体验。

删除了小工具、嵌入式和主题区块类别

删除了小工具、嵌入式和主题区块类别。

使用WordPress用户界面禁用区块

移除不必要的区块有助于简化编辑体验,并可略微提高后台性能,因为禁用的区块不会加载到内存中。

任何用户都可以通过区块编辑器中的首选项菜单禁用区块。点击右上角的三点设置(⋮)菜单,编辑器首选项就会打开。然后,在“区块”选项卡下,用户可以取消选中任何区块,将其从区块插入器中移除。

例如,只需取消选中“Quote区块的复选框,就可以禁用该区块,如下图所示。

“Quote”区块已被禁用

区块首选项模式视图显示,“Quote”区块已被禁用。

如果想更进一步,可以禁用整个区块类别。例如,取消选中“文本”类别将从插入器中移除所有与文本相关的区块,确保它们不再可用。这有助于简化编辑器,防止用户访问不必要的区块。

区块首选项模式视图显示文本类别已被禁用

区块首选项模式视图显示文本类别已被禁用

注:这同时适用于“文章编辑器”和“网站编辑器”。此外,禁用区块不会影响现有内容,这意味着之前添加到文章或页面中的任何区块实例都将保持不变。

使用WordPress用户界面锁定区块

锁定区块可以防止其被移动或删除,同时仍允许内容编辑。任何用户都可以随时使用区块工具栏上的锁定选项锁定或解锁区块。

要锁定或解锁一个区块,请单击区块上的三点设置 (⋮),单击锁定,然后选择锁定全部选项,就会自动启用防止移动防止删除,但这些选项也可以单独应用。

锁定模式会显示单个区块的可用选项

锁定模式会显示单个区块的可用选项

需要注意的是,即使区块被锁定,用户仍可更改其内容和样式,除非应用了进一步的限制。

仅通过锁定功能无法防止样式更改。要限制区块样式,必须修改 theme.json 文件。

对于包含嵌套元素的区块,还可以选择只锁定父区块或锁定所有内部区块。这可以确保分组元素保持结构化,同时允许在其中进行受控编辑。

锁定模式会显示父区块的可用选项

锁定模式会显示父区块的可用选项

使用PHP锁定区块

虽然 WordPress 用户界面提供了基本的区块锁定功能,但它并不能在整个网站范围内实施限制。任何有编辑器访问权限的用户都可以解锁区块,从而轻松覆盖锁定的内容。要永久限制区块锁定,PHP 是最好的解决方案。

使用 PHP,你可以完全取消锁定和解锁区块的功能,确保任何用户都无法绕过限制。在 WordPress 5.9 版本推出区块锁定之前,WordPress 就是这样运行的。

区块锁定在很多情况下都很有用,尤其是在维护结构化内容时。通过使用 PHP 执行区块限制,您可以

  • 防止用户修改关键代码区块,从而保持设计的完整性。
  • 防止可能破坏布局的意外编辑。
  • 通过减少不必要的选项来简化内容创建。
  • 确保模式和模板的一致性,尤其是客户项目。

为所有用户移除区块锁定功能

以下 PHP 代码段可完全禁用区块锁定功能,防止任何用户锁定或解锁区块:

add_filter('block_editor_settings_all', 'example_disable_block_locking', 10, 2);
function example_disable_block_locking($settings, $context) {
$settings['canLockBlocks'] = false; 
return $settings;
}

使用此功能后,区块编辑器中的区块锁定功能将被完全移除。用户将看不到锁定选项,而且无论谁都无法锁定或解锁区块。

根据用户角色限制区块锁定

您可能想限制谁可以锁定和解锁区块,而不是完全删除区块锁定。下面的 PHP 代码段只允许管理员和编辑修改区块锁,而作者和贡献者则不能解锁管理员或编辑设置的任何区块。

add_filter('block_editor_settings_all', 'example_disable_block', 10, 2);
function example_disable_block ($settings, $context ) {
if (
isset( $context->post ) &&
'post' === $context->post->post_type &&
! current_user_can( 'edit_theme_options' )
) {
$settings['canLockBlocks'] = false; 
$settings['codeEditingEnabled'] = false;   
}
return $settings;
}

这种方法将区块控制权限制在具有 edit_theme_options 功能的用户,通常是管理员和编辑。作者和贡献者将无法解锁上级用户设置的区块。

此外,代码编辑器的访问权限也被禁用,用户无法通过手动修改区块标记来绕过限制。这样可以确保锁定的区块保持不变,即使具有编码知识的用户也无法更改。

注:除了 PHP 和 JavaScript 之外,你可能还想知道是否存在其他禁用区块的方法。

目前,theme.json不支持锁定、解锁或禁用区块,这意味着你无法使用它来执行区块限制。

那么 WP-CLI 呢?由于 WP-CLI 操作的是服务器端数据,因此不包括启用或禁用特定区块的命令。

目前,PHP 和 JavaScript 仍是 WordPress 中管理区块可用性的唯一可靠方法。

小结

选择允许还是禁用区块(或两者结合)取决于您的具体需求。您可能希望限制某些区块,以获得更简洁的编辑体验,强制执行设计一致性,或根据用户角色控制访问权限。

说到用户角色,可以通过修改功能来进一步定制块的管理方式。这为我们提供了更多的可能性。

请记住,WordPress 会随着时间不断发展。未来的更新可能会引入新的区块管理方式或修改现有功能,因此与 WordPress 开发保持同步对于确保您的方法始终有效非常重要。

评论留言