各位同学,早上好!今天咱们聊聊古腾堡,也就是WordPress编辑器里那些神奇的“积木”——区块。更具体地说,我们要扒一扒 register_block_type()
这个函数,看看它是如何把这些“积木”注册到WordPress里的。
开场白:为什么我们要关心这个函数?
想象一下,你是个乐高设计师,register_block_type()
就是你的“乐高零件注册表”。你设计了一个新的零件(区块),要让所有人都知道它,并且能用它来搭建各种模型(页面),你就必须把这个零件的信息登记到这个注册表里。
好,废话不多说,咱们直接上代码!
register_block_type()
的基本结构
register_block_type()
函数接收两个参数:
$block_type
: 区块的名称,字符串类型。这个名字要遵循特定的格式(稍后会详细解释)。$settings
: 一个数组,包含了区块的所有配置信息,比如编辑器里显示的属性、渲染方式等等。
<?php
/**
* Registers a block type.
*
* @since 5.0.0
*
* @param string|WP_Block_Type $block_type Block type name including namespace.
* In general, names should not contain
* uppercase characters or hyphens.
* Allowed characters are lowercase letters, numbers,
* and underscores. Spaces are not allowed.
* @param array $settings Block type settings array.
* @return WP_Block_Type|false The registered block type on success, or false on failure.
*/
function register_block_type( $block_type, $settings = array() ) {
// 代码省略...
}
?>
深入剖析 $block_type
:区块的“身份证”
$block_type
参数是区块的唯一标识符,就像是你的身份证号码一样。它必须遵循一定的命名规范,确保WordPress能正确识别你的区块。
- 格式:
namespace/block-name
namespace
: 通常是你的主题或插件的名称,用于避免和其他区块冲突。block-name
: 区块的具体名称,描述区块的功能。
- 命名规则:
- 只能包含小写字母、数字和下划线。
- 不能包含大写字母或连字符。
- 不能包含空格。
举个栗子:my-theme/fancy-button
、my-plugin/image-slider
都是合法的区块名称。
$settings
:区块的“说明书”
$settings
参数是一个数组,它定义了区块的所有属性和行为。这个数组里的内容非常丰富,我们逐一来看:
属性 | 类型 | 描述 |
---|---|---|
title |
string | 区块的标题,会在编辑器里显示。 |
description |
string | 区块的描述,用于解释区块的用途。 |
icon |
string | 区块的图标,会在编辑器里显示。可以是Dashicons的名称,也可以是自定义的SVG。 |
category |
string | 区块的分类,用于在编辑器里组织区块。常用的分类有common 、formatting 、layout 、widgets 、embed 。 |
attributes |
array | 区块的属性,定义了区块可以接受哪些数据。每个属性都有自己的类型、默认值等。 |
supports |
array | 区块支持的功能,比如对齐方式、HTML锚点等。 |
render_callback |
callable | 一个回调函数,用于在前端渲染区块。这个函数会接收区块的属性作为参数,并返回HTML代码。 |
render |
string | (已弃用,推荐使用render_callback )一个PHP文件路径,用于在前端渲染区块。 |
editor_script |
string | 一个JavaScript文件路径,用于定义区块在编辑器里的行为。 |
editor_style |
string | 一个CSS文件路径,用于定义区块在编辑器里的样式。 |
style |
string | 一个CSS文件路径,用于定义区块在前端的样式。 |
attributes
:区块的“数据仓库”
attributes
属性是区块的核心,它定义了区块可以存储和处理哪些数据。每个属性都有自己的名称、类型和默认值。
'attributes' => array(
'title' => array(
'type' => 'string',
'default' => '默认标题',
),
'content' => array(
'type' => 'string',
),
'imageUrl' => array(
'type' => 'string',
'default' => '',
),
'alignment' => array(
'type' => 'string',
'default' => 'left',
),
)
在这个例子中,我们定义了四个属性:
title
:字符串类型,默认值为“默认标题”。content
:字符串类型,没有默认值。imageUrl
:字符串类型,默认值为空字符串。alignment
:字符串类型,默认值为“left”。
常用的属性类型包括:
string
:字符串number
:数字boolean
:布尔值(true或false)array
:数组object
:对象
render_callback
:区块的“演员”
render_callback
属性是一个回调函数,它负责在前端渲染区块。这个函数会接收区块的属性作为参数,并返回HTML代码。
'render_callback' => 'my_theme_render_fancy_button',
<?php
function my_theme_render_fancy_button( $attributes ) {
$title = isset( $attributes['title'] ) ? $attributes['title'] : '默认标题';
$alignment = isset( $attributes['alignment'] ) ? $attributes['alignment'] : 'left';
$html = '<div class="fancy-button" style="text-align: ' . esc_attr( $alignment ) . ';">';
$html .= '<button>' . esc_html( $title ) . '</button>';
$html .= '</div>';
return $html;
}
?>
在这个例子中,my_theme_render_fancy_button
函数接收一个 $attributes
数组,包含了区块的所有属性。我们从数组中取出 title
和 alignment
属性,并根据这些属性生成HTML代码。
editor_script
和 editor_style
:区块的“化妆师”和“造型师”
editor_script
属性是一个JavaScript文件路径,用于定义区块在编辑器里的行为。你可以在这个文件中编写JavaScript代码,控制区块的编辑界面、处理用户输入等等。
editor_style
属性是一个CSS文件路径,用于定义区块在编辑器里的样式。你可以使用CSS来美化区块在编辑器里的显示效果,让用户更容易识别和操作区块。
一个完整的例子:注册一个简单的文本区块
<?php
add_action( 'init', 'my_theme_register_text_block' );
function my_theme_register_text_block() {
register_block_type(
'my-theme/text-block',
array(
'title' => __( '文本区块', 'my-theme' ),
'description' => __( '一个简单的文本区块', 'my-theme' ),
'icon' => 'edit',
'category' => 'common',
'attributes' => array(
'content' => array(
'type' => 'string',
'default' => '默认文本',
),
'textColor' => array(
'type' => 'string',
'default' => 'black',
),
),
'supports' => array(
'align' => true, // 支持对齐方式
),
'render_callback' => 'my_theme_render_text_block',
'editor_script' => 'my-theme-text-block-editor-script',
'editor_style' => 'my-theme-text-block-editor-style',
'style' => 'my-theme-text-block-style',
)
);
}
function my_theme_render_text_block( $attributes ) {
$content = isset( $attributes['content'] ) ? $attributes['content'] : '默认文本';
$textColor = isset( $attributes['textColor'] ) ? $attributes['textColor'] : 'black';
$alignment = isset( $attributes['align'] ) ? $attributes['align'] : 'left';
$html = '<div class="text-block" style="color: ' . esc_attr( $textColor ) . '; text-align: ' . esc_attr( $alignment ). ';">';
$html .= esc_html( $content );
$html .= '</div>';
return $html;
}
//enqueue scripts and styles
add_action( 'enqueue_block_editor_assets', 'my_theme_enqueue_text_block_editor_assets' );
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_text_block_assets' );
function my_theme_enqueue_text_block_editor_assets() {
wp_enqueue_script(
'my-theme-text-block-editor-script',
get_template_directory_uri() . '/assets/js/text-block-editor.js',
array( 'wp-blocks', 'wp-element', 'wp-editor' ),
filemtime( get_template_directory() . '/assets/js/text-block-editor.js' )
);
wp_enqueue_style(
'my-theme-text-block-editor-style',
get_template_directory_uri() . '/assets/css/text-block-editor.css',
array( 'wp-edit-blocks' ),
filemtime( get_template_directory() . '/assets/css/text-block-editor.css' )
);
}
function my_theme_enqueue_text_block_assets() {
wp_enqueue_style(
'my-theme-text-block-style',
get_template_directory_uri() . '/assets/css/text-block.css',
array(),
filemtime( get_template_directory() . '/assets/css/text-block.css' )
);
}
?>
JavaScript (assets/js/text-block-editor.js):
wp.blocks.registerBlockType('my-theme/text-block', {
edit: function(props) {
const { attributes, setAttributes } = props;
const { content, textColor } = attributes;
function onChangeContent(newValue) {
setAttributes({ content: newValue });
}
function onChangeTextColor(newValue) {
setAttributes({ textColor: newValue });
}
return React.createElement(
'div',
{ className: props.className },
React.createElement('p', null, 'Text Block:'),
React.createElement('input', {
type: 'text',
value: content,
onChange: (event) => onChangeContent(event.target.value),
}),
React.createElement('input', {
type: 'color',
value: textColor,
onChange: (event) => onChangeTextColor(event.target.value),
})
);
},
save: function(props) {
return null; // Rendered server-side using render_callback
},
});
CSS (assets/css/text-block-editor.css):
.wp-block-my-theme-text-block {
border: 1px solid #ccc;
padding: 10px;
}
CSS (assets/css/text-block.css):
.text-block {
margin-bottom: 15px;
}
这个例子注册了一个名为 my-theme/text-block
的区块,它允许用户输入文本内容,并选择文本颜色。
代码解释:
add_action( 'init', 'my_theme_register_text_block' );
: 在 WordPress 初始化时,调用my_theme_register_text_block
函数。register_block_type(...)
: 注册区块,传入区块名称和配置信息。attributes
: 定义了两个属性:content
(文本内容) 和textColor
(文本颜色),都为字符串类型。render_callback
: 指定了my_theme_render_text_block
函数来渲染区块。my_theme_render_text_block(...)
: 接收区块属性,生成包含文本内容的 HTML 代码。enqueue_block_editor_assets
andwp_enqueue_scripts
: Enqueue javascript for the editor and css for the front-end.- JavaScript (text-block-editor.js): Defines the visual editing interface.
- CSS (text-block-editor.css and text-block.css): Provides styles for editor and front-end.
总结:register_block_type()
的工作流程
- 你调用
register_block_type()
函数,传入区块名称和配置信息。 - WordPress 会验证区块名称是否符合规范。
- WordPress 会将区块的配置信息存储到数据库中。
- 当用户在编辑器里使用你的区块时,WordPress 会加载你的 JavaScript 和 CSS 文件,并调用你的
render_callback
函数来渲染区块。
一些补充说明:
- 区块的存储方式: 区块的数据存储在文章的内容里,使用一种叫做“区块语法”的格式。这种格式类似于HTML注释,但包含了区块的名称和属性。
- 动态区块 vs 静态区块: 上面的例子是一个动态区块,因为它的内容是在服务器端动态生成的。你也可以创建静态区块,它的内容完全在客户端生成,不需要服务器端渲染。
- 区块的进阶用法: 你可以使用JavaScript API来创建更复杂的区块,比如包含交互式组件、使用REST API获取数据等等。
结尾:成为古腾堡大师的道路
register_block_type()
函数是古腾堡区块开发的基石。掌握了这个函数,你就可以开始创建自己的区块,扩展WordPress编辑器的功能。当然,这只是一个开始,古腾堡的世界还有很多值得探索的地方。希望今天的讲解能帮助你入门,祝你在古腾堡的道路上越走越远!
今天的讲座就到这里,谢谢大家!有没有什么问题?