各位观众老爷,晚上好!今天咱们不聊风花雪月,来点硬核的:扒一扒 WordPress 区块编辑器的底裤,啊不,源码。具体来说,就是那个神秘的 get_block_editor_settings()
函数,看看它到底是怎么把区块编辑器的配置一股脑儿塞给你的。
准备好了吗?系好安全带,发车了!
第一节:开胃小菜 – get_block_editor_settings()
是个啥?
简单来说,get_block_editor_settings()
是 WordPress 用来获取区块编辑器(也就是古腾堡编辑器)配置信息的函数。它返回一个包含各种设置的大数组,这些设置控制了编辑器如何工作,包括允许哪些区块、编辑器样式、各种面板设置等等。
想象一下,你开了一家装修公司,get_block_editor_settings()
就像你的配置清单,上面详细列出了:
- 允许使用的建材(区块)
- 装修风格(编辑器样式)
- 各种工具(面板设置)
有了这份清单,你的设计师(区块编辑器)才能按照你的要求进行装修。
第二节:追根溯源 – 源码在哪里?
get_block_editor_settings()
的源码位于 wp-admin/includes/template.php
文件中。打开这个文件,你就能看到它的真面目。
第三节:庖丁解牛 – 源码分析
接下来,咱们一点一点地剖析 get_block_editor_settings()
的源码。
function get_block_editor_settings( $settings = array() ) {
global $post, $pagenow;
$post_id = 0;
if ( isset( $post ) ) {
$post_id = $post->ID;
}
$available_block_types = WP_Block_Type_Registry::get_instance()->get_all_registered();
$default_block_categories = array(
array(
'slug' => 'common',
'title' => _x( 'Common blocks', 'block category' ),
),
array(
'slug' => 'formatting',
'title' => _x( 'Formatting', 'block category' ),
),
array(
'slug' => 'layout',
'title' => _x( 'Layout elements', 'block category' ),
),
array(
'slug' => 'widgets',
'title' => _x( 'Widgets', 'block category' ),
),
array(
'slug' => 'theme',
'title' => _x( 'Theme', 'block category' ),
),
array(
'slug' => 'embed',
'title' => _x( 'Embeds', 'block category' ),
),
array(
'slug' => 'reusable',
'title' => __( 'Reusable blocks' ),
),
);
/**
* Filters the default block categories.
*
* @since 5.0.0
*
* @param array[] $default_block_categories Array of block categories.
*/
$block_categories = apply_filters( 'block_categories', $default_block_categories, $post );
$settings = array_merge(
array(
'available_block_types' => array_keys( $available_block_types ),
'allowedBlockTypes' => true, // Allows all block types by default.
'block_categories' => $block_categories,
'disableCustomColors' => get_theme_support( 'disable-custom-colors' ),
'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ),
'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ),
'enableCustomLineHeight' => get_theme_support( 'custom-line-height' ),
'enableCustomSpacing' => get_theme_support( 'custom-spacing' ),
'enableCustomUnits' => get_theme_support( 'custom-units' ),
'enableCustomFontSize' => get_theme_support( 'custom-font-size' ),
'isRTL' => is_rtl(),
'l10n' => array(
'insert' => __( 'Add block' ),
'inserter' => __( 'Add a block' ),
'inserterMedia' => __( 'Add media' ),
'inserterText' => __( 'Add text' ),
'multiBlockSelected' => _n( '%d block selected', '%d blocks selected', 1 ),
'noBlocksFound' => __( 'No blocks found.' ),
'noResultsFound' => __( 'No results found.' ),
'tryAgain' => __( 'Try again.' ),
'update' => __( 'Update' ),
'saved' => __( 'Saved' ),
'saving' => __( 'Saving…' ),
'default' => __( 'Default' ),
'ariaLabelMedia' => __( 'Add media' ),
'ariaLabelText' => __( 'Add text' ),
'block' => __( 'Block' ),
'categories' => __( 'Categories' ),
'close' => __( 'Close' ),
'confirmCancel' => __( 'Are you sure you want to discard your changes?' ),
'contentSelectedText' => __( '%d item selected' ),
'copyAllBlocks' => __( 'Copy all blocks' ),
'createBlock' => __( 'Create block' ),
'createReusableBlock' => __( 'Create reusable block' ),
'defaultBlock' => __( 'Default block' ),
'describeBlock' => __( 'Describe block' ),
'edit' => __( 'Edit' ),
'expandAll' => __( 'Expand all' ),
'finishDescription' => __( 'Finish description' ),
'focusBlock' => __( 'Focus block' ),
'insertBlock' => __( 'Insert block' ),
'inserterMenu' => __( 'Add block' ),
'leaveBlank' => __( 'Leave blank' ),
'mediaLibrary' => __( 'Media Library' ),
'moveDown' => __( 'Move down' ),
'moveUp' => __( 'Move up' ),
'navigation' => __( 'Navigation' ),
'noTitle' => __( 'No title' ),
'ok' => __( 'OK' ),
'options' => __( 'Options' ),
'ordinals' => array(
__( 'First' ),
__( 'Second' ),
__( 'Third' ),
__( 'Fourth' ),
__( 'Fifth' ),
__( 'Sixth' ),
__( 'Seventh' ),
__( 'Eighth' ),
__( 'Ninth' ),
__( 'Tenth' ),
),
'patterns' => __( 'Patterns' ),
'reusableBlocks' => __( 'Reusable blocks' ),
'reusableBlockSaved' => __( 'Reusable block saved.' ),
'save' => __( 'Save' ),
'savedBlocks' => __( 'Saved blocks' ),
'search' => __( 'Search' ),
'selectAllBlocks' => __( 'Select all blocks' ),
'selectBlock' => __( 'Select block' ),
'settings' => __( 'Settings' ),
'showMoreSettings' => __( 'Show more settings' ),
'styles' => __( 'Styles' ),
'switchToHTML' => __( 'Switch to HTML editor' ),
'switchToVisual' => __( 'Switch to the visual editor' ),
'toolsPanelMore' => __( 'Tools & options' ),
'transformTo' => __( 'Transform to' ),
'tryBlockSearch' => __( 'Try searching for a block' ),
'updateBlock' => __( 'Update block' ),
'useReusableBlock' => __( 'Use reusable block' ),
'viewCode' => __( 'View code' ),
'visualEditor' => __( 'Visual editor' ),
),
'maxUploadFileSize' => wp_max_upload_size(),
'post' => get_default_post_to_edit( get_post_type(), true ),
'styles' => array(),
'template' => isset( $post->ID ) ? get_page_template_slug( $post->ID ) : '',
'templateLock' => isset( $post->ID ) ? get_post_meta( $post->ID, '_wp_template_lock', true ) : '',
'__experimentalBlockPatterns' => WP_Block_Patterns_Registry::get_instance()->get_all_registered(),
'__experimentalBlockPatternCategories' => WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(),
),
$settings
);
$editor_styles = array();
if ( ! empty( $settings['styles'] ) ) {
$editor_styles = $settings['styles'];
}
if ( current_theme_supports( 'editor-styles' ) ) {
$editor_styles = array_merge( $editor_styles, get_editor_stylesheets() );
}
/**
* Filters the editor styles.
*
* @since 5.0.0
*
* @param string[] $editor_styles Array of editor styles.
*/
$editor_styles = apply_filters( 'editor_styles', $editor_styles );
$settings['styles'] = $editor_styles;
/**
* Filters the settings passed to the block editor.
*
* @since 5.0.0
*
* @param array $settings Array of settings for the block editor.
* @param WP_Post $post Post being edited.
*/
return apply_filters( 'block_editor_settings', $settings, $post );
}
代码有点长,咱们分段解读:
- 初始化
function get_block_editor_settings( $settings = array() ) {
global $post, $pagenow;
$post_id = 0;
if ( isset( $post ) ) {
$post_id = $post->ID;
}
$available_block_types = WP_Block_Type_Registry::get_instance()->get_all_registered();
- 函数接收一个可选的
$settings
数组作为参数,允许你传入自定义设置。 - 获取全局变量
$post
(当前编辑的文章/页面) 和$pagenow
(当前管理页面)。 - 获取当前文章/页面的 ID。
- 通过
WP_Block_Type_Registry
获取所有已注册的区块类型。WP_Block_Type_Registry
是一个单例类,负责管理区块类型的注册和检索。get_all_registered()
返回一个包含所有已注册区块类型对象的数组。
- 默认区块分类
$default_block_categories = array(
array(
'slug' => 'common',
'title' => _x( 'Common blocks', 'block category' ),
),
array(
'slug' => 'formatting',
'title' => _x( 'Formatting', 'block category' ),
),
array(
'slug' => 'layout',
'title' => _x( 'Layout elements', 'block category' ),
),
array(
'slug' => 'widgets',
'title' => _x( 'Widgets', 'block category' ),
),
array(
'slug' => 'theme',
'title' => _x( 'Theme', 'block category' ),
),
array(
'slug' => 'embed',
'title' => _x( 'Embeds', 'block category' ),
),
array(
'slug' => 'reusable',
'title' => __( 'Reusable blocks' ),
),
);
/**
* Filters the default block categories.
*
* @since 5.0.0
*
* @param array[] $default_block_categories Array of block categories.
*/
$block_categories = apply_filters( 'block_categories', $default_block_categories, $post );
- 定义了一组默认的区块分类,例如 "Common blocks", "Formatting" 等。
- 使用
apply_filters( 'block_categories', $default_block_categories, $post )
允许开发者通过block_categories
过滤器修改这些分类。 这是 WordPress 强大的扩展机制之一,你可以通过这个过滤器添加、删除或修改区块分类,从而定制区块编辑器的界面。
- 构建设置数组
$settings = array_merge(
array(
'available_block_types' => array_keys( $available_block_types ),
'allowedBlockTypes' => true, // Allows all block types by default.
'block_categories' => $block_categories,
'disableCustomColors' => get_theme_support( 'disable-custom-colors' ),
'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ),
'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ),
'enableCustomLineHeight' => get_theme_support( 'custom-line-height' ),
'enableCustomSpacing' => get_theme_support( 'custom-spacing' ),
'enableCustomUnits' => get_theme_support( 'custom-units' ),
'enableCustomFontSize' => get_theme_support( 'custom-font-size' ),
'isRTL' => is_rtl(),
'l10n' => array(
'insert' => __( 'Add block' ),
'inserter' => __( 'Add a block' ),
// ...省略大量本地化字符串...
),
'maxUploadFileSize' => wp_max_upload_size(),
'post' => get_default_post_to_edit( get_post_type(), true ),
'styles' => array(),
'template' => isset( $post->ID ) ? get_page_template_slug( $post->ID ) : '',
'templateLock' => isset( $post->ID ) ? get_post_meta( $post->ID, '_wp_template_lock', true ) : '',
'__experimentalBlockPatterns' => WP_Block_Patterns_Registry::get_instance()->get_all_registered(),
'__experimentalBlockPatternCategories' => WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(),
),
$settings
);
- 这是一个核心步骤,它构建了一个包含各种设置的数组。
available_block_types
: 所有可用区块类型的键名数组。allowedBlockTypes
: 默认值为true
,表示允许所有区块类型。你可以将其设置为一个区块类型名称数组,只允许特定的区块类型。block_categories
: 前面获取的区块分类数组。disableCustomColors
,disableCustomFontSizes
,disableCustomGradients
,enableCustomLineHeight
,enableCustomSpacing
,enableCustomUnits
,enableCustomFontSize
: 这些选项控制了是否允许用户自定义颜色、字体大小、渐变、行高、间距和单位。它们的值取决于主题是否支持这些特性 (通过add_theme_support()
函数声明)。isRTL
: 判断当前语言是否为从右向左书写。l10n
: 包含大量本地化字符串,用于区块编辑器的界面显示。maxUploadFileSize
: 允许上传的最大文件大小。post
: 当前文章/页面的默认数据,通过get_default_post_to_edit()
获取。styles
: 编辑器样式表数组,稍后会进行处理。template
: 当前文章/页面使用的页面模板。templateLock
: 模板锁定设置,防止用户修改模板结构。__experimentalBlockPatterns
: 所有已注册的区块模式。__experimentalBlockPatternCategories
: 所有已注册的区块模式分类。array_merge()
: 将默认设置与传入的$settings
数组合并。如果$settings
中有相同的键,则$settings
中的值会覆盖默认值。
- 处理编辑器样式
$editor_styles = array();
if ( ! empty( $settings['styles'] ) ) {
$editor_styles = $settings['styles'];
}
if ( current_theme_supports( 'editor-styles' ) ) {
$editor_styles = array_merge( $editor_styles, get_editor_stylesheets() );
}
/**
* Filters the editor styles.
*
* @since 5.0.0
*
* @param string[] $editor_styles Array of editor styles.
*/
$editor_styles = apply_filters( 'editor_styles', $editor_styles );
$settings['styles'] = $editor_styles;
- 首先,将
$settings['styles']
中的样式表复制到$editor_styles
数组中。 - 如果主题支持
editor-styles
特性 (通过add_theme_support( 'editor-styles' )
声明),则通过get_editor_stylesheets()
获取主题的编辑器样式表,并将其合并到$editor_styles
数组中。 - 使用
apply_filters( 'editor_styles', $editor_styles )
允许开发者通过editor_styles
过滤器修改编辑器样式表。 - 最后,将处理后的
$editor_styles
数组赋值给$settings['styles']
。
- 最终过滤和返回
/**
* Filters the settings passed to the block editor.
*
* @since 5.0.0
*
* @param array $settings Array of settings for the block editor.
* @param WP_Post $post Post being edited.
*/
return apply_filters( 'block_editor_settings', $settings, $post );
}
- 使用
apply_filters( 'block_editor_settings', $settings, $post )
允许开发者通过block_editor_settings
过滤器修改最终的设置数组。 这是最后一个机会修改区块编辑器的配置,你可以通过这个过滤器添加、删除或修改任何设置。 - 返回最终的设置数组。
第四节:深入细节 – 几个关键设置项
咱们来重点看看几个比较重要的设置项:
设置项 | 描述 | 示例 |
---|---|---|
available_block_types |
一个包含所有已注册区块类型名称的数组。 | array( 'core/paragraph', 'core/image', 'core/heading' ) |
allowedBlockTypes |
控制允许使用的区块类型。可以设置为 true (允许所有区块类型),也可以设置为一个包含允许的区块类型名称的数组。 |
true (允许所有区块), array( 'core/paragraph', 'core/image' ) (只允许段落和图片区块) |
block_categories |
一个包含区块分类信息的数组。每个分类包含 slug (分类的唯一标识符) 和 title (分类的显示名称)。 |
php array( array( 'slug' => 'common', 'title' => __( 'Common blocks' ) ), array( 'slug' => 'formatting', 'title' => __( 'Formatting' ) ) ) |
disableCustomColors |
如果设置为 true ,则禁用用户自定义颜色。主题可以通过 add_theme_support( 'disable-custom-colors' ) 来控制这个选项。 |
true (禁用自定义颜色), false (允许自定义颜色) |
styles |
一个包含编辑器样式表 URL 的数组。这些样式表会被加载到区块编辑器中,用于提供与主题风格一致的视觉效果。 | array( 'https://example.com/wp-content/themes/my-theme/editor-style.css' ) |
template |
当前文章/页面使用的页面模板。 | page-templates/my-custom-template.php |
templateLock |
模板锁定设置。可以设置为 'all' (锁定所有区块) 或 'insert' (只允许插入新区块,不允许移动或删除现有区块)。 |
'all' , 'insert' |
__experimentalBlockPatterns |
一个包含所有已注册区块模式的数组。 | 数组,每个元素代表一个区块模式 |
第五节:实战演练 – 如何修改区块编辑器配置
现在,咱们来演示一下如何通过过滤器修改区块编辑器的配置。
场景 1:只允许使用段落和图片区块
add_filter( 'block_editor_settings', 'my_custom_block_editor_settings' );
function my_custom_block_editor_settings( $settings ) {
$settings['allowedBlockTypes'] = array( 'core/paragraph', 'core/image' );
return $settings;
}
这段代码使用了 block_editor_settings
过滤器,将 allowedBlockTypes
设置为一个包含 core/paragraph
和 core/image
的数组。这样,在区块编辑器中就只允许使用段落和图片区块了。
场景 2:添加自定义区块分类
add_filter( 'block_categories', 'my_custom_block_categories', 10, 2 );
function my_custom_block_categories( $categories, $post ) {
return array_merge(
$categories,
array(
array(
'slug' => 'my-custom-category',
'title' => __( 'My Custom Category', 'my-theme' ),
'icon' => 'star-filled', // 可选,添加分类图标
),
)
);
}
这段代码使用了 block_categories
过滤器,添加了一个名为 "My Custom Category" 的自定义区块分类。icon
参数是可选的,你可以通过它为分类添加一个图标。
场景 3:添加自定义编辑器样式
add_filter( 'editor_styles', 'my_custom_editor_styles' );
function my_custom_editor_styles( $styles ) {
$styles[] = 'https://example.com/wp-content/themes/my-theme/custom-editor-style.css';
return $styles;
}
这段代码使用了 editor_styles
过滤器,添加了一个自定义编辑器样式表。
第六节:注意事项
- 缓存: 修改区块编辑器配置后,可能需要清除浏览器缓存才能看到效果。
- 主题支持: 一些设置项 (例如
disableCustomColors
,disableCustomFontSizes
) 取决于主题是否支持相应的特性。 - 插件冲突: 其他插件可能会修改区块编辑器的配置,导致冲突。 调试时需要注意插件的加载顺序和代码逻辑。
- 实验性特性: 以
__experimental
开头的设置项是实验性的,可能会在未来的 WordPress 版本中发生变化。
第七节:总结
get_block_editor_settings()
函数是 WordPress 区块编辑器的核心,它负责获取并传递各种配置信息。 通过理解它的源码,你可以更好地定制区块编辑器的行为,使其更符合你的需求。 而通过使用 WordPress 提供的各种过滤器,你可以轻松地修改区块编辑器的配置,而无需修改 WordPress 核心代码。
今天的讲座就到这里,希望大家有所收获!下次有机会,咱们再来聊聊其他 WordPress 的黑科技。