[一钩定乾坤:区块分类的多种玩法]
你可能已经注意到WordPress区块是按分类组织的。但你知道吗?你并非必须接受这些默认分类。你可以调整它们,让它们为你所用。
你可以重命名它们。重新排序它们。添加全新的分类,包括为你的自定义区块创建新分类。甚至可能做到你我尚未想到的事情。
而这一切,你都可以通过一个钩子实现:block_categories_all
这个钩子是一个多功能工具,允许开发者自定义区块分类的组织方式。在本文中,你将学习如何使用这个钩子,并构建函数来添加、重新排序和重命名单个或多个区块分类。
在深入之前,需要注意的是,每个函数都接受一个参数,该参数应为现有区块分类的数组。在本文中,它被定义为 $categories。
添加分类
如果你构建自定义区块,可能希望将它们放入一些自定义分类中。自定义分类也可能有其他用途——也许你正在构建一些具有自定义样式的区块。无论出于何种原因,这里有三种方法:
创建新分类
以下是如何使用 array_merge 将一个名为“自定义区块”的新分类添加到现有分类数组的末尾。
add_filter( 'block_categories_all', 'add_block_category', 10, 2 );
function add_block_category( $categories ) {
$custom_category = array(
array(
'slug' => 'custom-blocks',
'title' => __( 'Custom Blocks', 'your-text-domain' ),
'icon' => null,
),
);
return array_merge( $categories, $custom_category );
}
首先创建一个接受单个参数的函数——记住,它期望的是现有 $categories 列表。在函数内部,创建一个名为 $custom_category 的变量,并分配一个包含以下键值对的数组:
slug— 分类的唯一标识符title— 分类的显示名称icon— 一个Dashicon或自定义SVG
注意:据我所知,我们目前没有在任何地方使用或显示 icon,因此在此示例中,你可以将其设置为 null。
然后,你将使用 array_merge 函数将 $custom_category 与现有的 $categories 列表合并。你可以根据将每个变量传递给 array_merge 的顺序,将新分类放在 $categories 之前或之后。

定位新分类
以下是如何使用 array_splice 将一个名为“自定义区块”的新分类添加到 $categories 的第二个位置(索引 1)。
add_filter( 'block_categories_all', 'add_order_block_category', 10, 2 );
function add_order_block_category( $categories ) {
$custom_category = array(
'slug' => 'custom-blocks',
'title' => __( 'Custom Blocks', 'your-text-domain' ),
'icon' => null,
'position' => 1,
);
// 从自定义分类数组中提取位置。
$position = $custom_category['position'];
// 从自定义分类数组中移除位置。
unset( $custom_category['position'] );
// 在期望的位置插入自定义分类。
array_splice( $categories, $position, 0, array( $custom_category ) );
return $categories;
}
首先创建一个函数和一个新的分类数组,类似于上一个示例。但这次你将添加一个 position 键,其值指定你希望新分类在 $categories 中的位置。
然后,你将提取 position 并将其设置为一个变量,以便在 array_splice 中使用,但在此之前,使用 unset 将位置从数组中移除——你不需要它。
最后,使用 array_splice 函数,它接受 4 个参数:
- 数组: 你想要修改的数组
- 偏移量: 你希望插入的位置
- 长度: 指定在偏移量之后要移除的项目数量
- 替换: 要在指定位置添加的元素数组
在你的 array_splice 中,传入 $categories、你在新分类数组中指定的位置、长度(在本例中为 0,因为我们不想移除任何内容),然后是你的新分类数组。

添加并定位多个新分类
现在让我们一次性添加并定位一些分类。以下是如何将两个自定义分类插入到 $categories 的第二和第四位置。
add_filter( 'block_categories_all', 'add_order_multiple_block_categories', 10, 2 );
function add_order_multiple_block_categories( $categories ) {
$custom_categories = array(
array(
'slug' => 'custom-category-1',
'title' => __( 'Custom Category 1', 'your-text-domain' ),
'icon' => null,
'position' => 1,
),
array(
'slug' => 'custom-category-2',
'title' => __( 'Custom Category 2', 'your-text-domain' ),
'icon' => null,
'position' => 3,
),
);
$added_categories = array();
// 准备一个以位置为键的关联数组。
foreach ( $custom_categories as $custom_category ) {
$position = $custom_category['position'];
unset( $custom_category['position'] );
$added_categories[ $position ] = $custom_category;
}
// 按位置/键对要插入的分类进行排序。
ksort( $added_categories );
// 将排序后的分类插入到现有分类数组中。
foreach ( $added_categories as $position => $custom_category ) {
array_splice( $categories, $position, 0, array( $custom_category ) );
}
return $categories;
}
创建一个函数。在内部,创建一个名为 $custom_categories 的新分类数组,包括每个项目的期望位置。创建一个空数组以在下一步存储数据,将其命名为 $added_categories。
接下来,遍历 $custom_categories 以提取并移除位置,并将其存储在 $added_categories 中,以新位置作为其键。然后添加一个 ksort 函数,以确保存储在 $added_categories 中的分类按其键排序。
最后添加 foreach 并遍历 $added_categories,使用 array_splice 将每个分类插入到期望的位置。最后,使用 array_values 重新索引分类,以确保新分类列表中的顺序正确。

重新排序分类
你也可以使用 block_categories_all 钩子来重新排序区块编辑器中的现有分类列表。无论你是想移动单个分类还是重新排列多个分类,这里有一些方法可以让你更好地控制两者。
重新排序单个分类
以下是如何通过移除并重新插入,使用 array_splice PHP 函数将现有数组中的 设计 分类重新排序到第二个位置。
add_filter( 'block_categories_all', 'reorder_design_category', 10, 2 );
function reorder_design_category( $categories ) {
$design_category = null;
$new_position = 1;
// 从现有分类中移除设计分类。
foreach ( $categories as $key => $category ) {
if ( 'design' === $category['slug'] ) {
$design_category = $category;
unset( $categories[ $key ] );
break;
}
}
// 如果设计分类存在,将其插入到新位置。
if ( $design_category ) {
array_splice( $categories, $new_position, 0, array( $design_category ) );
}
// 重新索引数组。
return array_values( $categories );
}
首先在函数内部设置两个变量,一个名为 $design_category 设置为 null,稍后你将用它来存储设计分类(或你希望移动的任何分类),另一个名为 $position,指定你想要移动到的位置。然后,添加一个 foreach,它将遍历现有分类以查找匹配的分类 slug,将其存储在 $design_category 中,并使用 unset 将其从现有列表中移除。
现在检查是否有任何数据存储在你的变量中,并使用 array_splice 将分类插入到期望的位置,就像你在上面的新分类函数中所做的那样。最后,使用 array_values 重新索引分类,以确保顺序正确。

重新排序多个分类
以下是如何通过移除和重新插入,使用 array_splice 将 设计 和 文本 分类重新排序到第一和第四位置。
add_filter( 'block_categories_all', 'reorder_multiple_categories', 10, 2 );
function reorder_multiple_categories( $categories ) {
$reorder_categories = array(
'design' => 0,
'text' => 3,
);
$moved_categories = array();
// 遍历现有分类,添加/移除需要重新排序的分类。
foreach ( $categories as $key => $category ) {
if ( array_key_exists( $category['slug'], $reorder_categories ) ) {
$moved_categories[ $reorder_categories[ $category['slug'] ] ] = $category;
unset( $categories[ $key ] );
}
}
// 按新位置对移动的分类进行排序。
ksort( $moved_categories );
// 将移动的分类插入到它们的新位置。
foreach ( $moved_categories as $position => $category ) {
array_splice( $categories, $position, 0, array( $category ) );
}
// 重新索引数组。
$categories = array_values( $categories );
return $categories;
}
首先在函数内部创建一个名为 $reorder_categories 的关联数组。键可以是你要重新排序的分类,值则是它们的新位置。你还需要创建一个空数组以在下一步存储数据,将其命名为 $moved_categories。
当检查找到匹配项时,函数会将分类添加到 $moved_categories 中,以你指定的位置作为其键。unset 函数会将该分类从 $categories 中移除。
现在添加一个 ksort 函数来按键对分类进行排序。
添加一个 foreach 来遍历 $moved_categories,使用 array_splice 将每个分类插入到其适当的位置。最后,使用 array_values 重新索引分类,以便新的 $categories 列表中的顺序正确。

重命名分类
你也可以使用 block_categories_all 来重命名区块编辑器中的分类列表。想重命名一个分类?想重命名所有分类?这里有一些方法可以让你完全掌控。
重命名一个分类
也许你想将 文本 分类重命名为 文本元素。
add_filter( 'block_categories_all', 'rename_text_category', 10, 2 );
function rename_text_category( $categories ) {
foreach ( $categories as &$category ) {
if ( $category['slug'] === 'text' ) {
$category['title'] = __( 'Text Elements', 'your-text-domain' );
}
}
return $categories;
}
首先使用一个 foreach。遍历 $categories,寻找 slug 等于 text 的分类。如果 text 存在,则将分类标题重命名为 Text Elements。

重命名多个分类
或者,你可能真的想将 文本 和 媒体 分类重命名为 文本元素 和 媒体和文本元素。
add_filter( 'block_categories_all', 'rename_multiple_categories', 10, 2 );
function rename_multiple_categories( $categories ) {
foreach ( $categories as &$category ) {
if ( $category['slug'] === 'text' ) {
$category['title'] = __( 'Text Elements', 'your-text-domain' );
}
if ( $category['slug'] === 'media' ) {
$category['title'] = __( 'Media and Text Elements', 'your-text-domain' );
}
}
return $categories;
}
要在一个函数中重命名多个分类,请遵循与重命名单个分类相同的步骤。只需根据需要添加尽可能多的分类 slug 检查。

整合所有功能
最后。这里你拥有了一切——完全控制现有分类的名称和位置,以及添加新分类的能力。
add_filter( 'block_categories_all', 'modify_block_categories', 10, 2 );
function modify_block_categories( $categories ) {
$new_category_order = array(
array(
'slug' => 'media',
'title' => __( 'Media and Text Elements', 'your-text-domain' ),
'position' => 0,
),
array(
'slug' => 'custom-blocks',
'title' => __( 'Custom Blocks', 'your-text-domain' ),
'position' => 1,
),
array(
'slug' => 'text',
'title' => __( 'Text Elements', 'your-text-domain' ),
'position' => 2,
),
array(
'slug' => 'embed',
'position' => 3,
),
array(
'slug' => 'design',
'position' => 4,
),
);
// 创建一个以slug为键的区块分类关联数组。
$current_block_categories = array_column( $categories, 'title', 'slug' );
// 检查新分类顺序是否设置了标题,否则使用默认标题。
foreach ( $new_category_order as &$new_category ) {
$new_category['title'] = $new_category['title'] ?? $current_block_categories[ $new_category['slug'] ] ?? __( 'Untitled', 'your-text-domain' );
}
// 从新分类顺序创建一个slug数组。
$new_category_slugs = array_column( $new_category_order, 'slug' );
// 过滤掉不在新顺序中的剩余区块分类。
$remaining_categories = array_filter( $categories, function ( $category ) use ( $new_category_slugs ) {
return ! in_array( $category['slug'], $new_category_slugs, true );
} );
// 将新分类顺序与剩余分类合并。
return array_merge( $new_category_order, $remaining_categories );
}
首先定义一个名为 $new_category_order 的分类数组,其中包含你想要添加、重新排序或重命名的分类。现在,slug 是标识每个条目所必需的。根据你想要修改的内容,title 和 position 是可选的。
首先,通过使用 array_column 从 $categories 创建一个名为 $current_block_categories 的关联数组(以分类 slug 为键)来更新任何分类标题。然后使用 foreach 遍历 $new_category_order,检查数组中是否有任何项目设置了新标题,并在必要时更新它们。如果没有设置新的 title,它将根据 slug 从 $current_block_categories 中提取。如果由于某种原因没有找到 slug,则将使用 Untitled。
现在,通过遍历 $new_category_order,检查任何具有新位置的分类,然后将其作为键添加到名为 $moved_categories 的数组中,来构建一个分类的关联数组。
然后使用 ksort 根据位置对 $moved_categories 进行排序。添加一个 foreach 并遍历 $moved_categories,使用 array_splice 将每个分类插入到位置。
现在新的标题和位置已经处理完毕,是时候过滤掉剩余的分类,以便将所有内容重新整合在一起。首先,使用 array_column 从 $new_category_order 创建一个名为 $new_category_slugs 的 slug 数组。然后创建一个名为 $remaining_categories 的变量,它使用 array_filter 从 $categories 中移除那些 slug 不在 $new_category_slugs 中的项目。
最后,使用 array_merge 将新分类顺序与 $remaining_categories 合并,以返回一个完整的修改后的区块分类列表。

结论
block_categories_all 钩子让你可以按照你需要的任何方式让区块分类工作——为你的项目和你的用户,以及他们将创建的所有内容。
而且,说真的,这些函数仅仅是个开始。你将如何使用它们?你还有其他方法吗,或者你能看到它们有创意的变体吗?留下评论吧!