好嘞!各位观众老爷,欢迎来到“区块大爆炸”现场!今天咱们就来扒一扒 WordPress 区块注册的 “葵花宝典” —— register_block_type()。 准备好迎接信息的狂轰滥炸了吗?Let’s go!
开场白:区块的世界,从注册开始
在 WordPress 的世界里,区块就像一个个乐高积木,可以自由组合,搭建出各种炫酷的页面。而 register_block_type() 函数,就是把这些积木“注册”到 WordPress 系统的“户口登记处”,让它们合法存在,可以被 WordPress 编辑器识别和使用。
register_block_type() 的庐山真面目
register_block_type() 函数的基本用法如下:
register_block_type( string $block_name, array|string $settings );
$block_name: 区块的名称,必须是唯一的,通常采用namespace/block-name的格式,比如my-plugin/awesome-block。$settings: 一个数组,包含了区块的所有配置信息,比如属性、渲染回调、编辑器脚本等等。
今天咱们重点就来解剖一下这个 $settings 数组,看看里面都藏着哪些乾坤。
$settings 数组:区块的灵魂所在
$settings 数组是区块定义的核心,它决定了区块的行为和外观。我们来逐个击破它的关键成员:
-
attributes:区块的百变造型attributes定义了区块的属性,属性就像区块的“变量”,可以存储各种数据,比如文本、颜色、图片 URL 等等。用户可以在编辑器中修改这些属性的值,从而改变区块的显示效果。attributes是一个关联数组,键是属性的名称,值是属性的配置信息。每个属性的配置信息又是一个数组,包含以下几个关键字段:type: 属性的类型,可以是string、number、boolean、array、object。default: 属性的默认值。source: 属性值的来源,比如从 HTML 属性、文本内容、内部区块等获取。selector: CSS 选择器,用于从 HTML 中提取属性值。
举个栗子,咱们定义一个简单的标题区块,包含
title和level两个属性:$settings = array( 'attributes' => array( 'title' => array( 'type' => 'string', 'default' => '默认标题', ), 'level' => array( 'type' => 'number', 'default' => 2, ), ), // ... 其他配置 );在这个例子中,
title属性的类型是string,默认值是'默认标题'。level属性的类型是number,默认值是2。source的妙用source字段可以指定属性值的来源。常用的source类型包括:-
attribute: 从 HTML 元素的属性中获取。例如:'imageUrl' => array( 'type' => 'string', 'source' => 'attribute', 'attribute' => 'src', // 从 <img> 元素的 src 属性获取 'selector' => 'img', // 匹配 <img> 元素 ), -
text: 从 HTML 元素的文本内容中获取。例如:'content' => array( 'type' => 'string', 'source' => 'text', 'selector' => 'p', // 匹配 <p> 元素 ), -
html: 从 HTML 元素的内部 HTML 中获取。 例如:'content' => array( 'type' => 'string', 'source' => 'html', 'selector' => '.my-block-content', // 匹配 class 为 my-block-content 的元素 ), -
children: 获取内部区块。例如:'blocks' => array( 'type' => 'array', 'source' => 'children', ), -
query: 获取多个匹配元素的属性。例如:'items' => array( 'type' => 'array', 'source' => 'query', 'selector' => 'li', 'query' => array( 'text' => array( 'type' => 'string', 'source' => 'text', ), ), ),
selector字段用于指定要匹配的 HTML 元素。表格总结:
attributes的核心字段字段 类型 描述 typestring 属性的类型,可以是 string、number、boolean、array、object。defaultmixed 属性的默认值。 sourcestring 属性值的来源,比如 attribute、text、html、children、query。attributestring 当 source为attribute时,指定要获取的 HTML 属性名称。selectorstring CSS 选择器,用于从 HTML 中提取属性值。 queryarray 当 source为query时,指定要获取的多个元素的属性。 -
render_callback:区块的灵魂画师render_callback是一个回调函数,用于生成区块在前端显示的 HTML 代码。它接收一个$attributes数组作为参数,包含了区块的属性值。$settings = array( 'attributes' => array( /* ... */ ), 'render_callback' => 'my_block_render_callback', ); function my_block_render_callback( $attributes ) { $title = isset( $attributes['title'] ) ? $attributes['title'] : '默认标题'; $level = isset( $attributes['level'] ) ? $attributes['level'] : 2; return '<h' . $level . '>' . esc_html( $title ) . '</h' . $level . '>'; }在这个例子中,
my_block_render_callback()函数根据title和level属性的值,生成一个标题 HTML 元素。注意事项:
render_callback必须返回一个字符串,表示区块的 HTML 代码。- 在
render_callback中,一定要对用户输入进行转义,防止 XSS 攻击。可以使用esc_html()、esc_attr()等函数进行转义。 - 如果区块不需要在前端显示,可以不定义
render_callback。
-
editor_script和script:区块的左右护法editor_script: 指定区块在编辑器中使用的 JavaScript 文件。这个文件通常包含区块的编辑逻辑,比如自定义控件、数据验证等等。script: 指定区块在前端使用的 JavaScript 文件。这个文件通常包含区块的交互逻辑,比如动画效果、AJAX 请求等等。
$settings = array( 'attributes' => array( /* ... */ ), 'render_callback' => 'my_block_render_callback', 'editor_script' => 'my-plugin-block-editor-script', 'script' => 'my-plugin-block-script', );在这个例子中,
my-plugin-block-editor-script是编辑器脚本的句柄,my-plugin-block-script是前端脚本的句柄。如何注册脚本?
在使用
editor_script和script之前,需要先使用wp_register_script()函数注册脚本。function my_plugin_register_block() { wp_register_script( 'my-plugin-block-editor-script', plugins_url( 'block-editor.js', __FILE__ ), array( 'wp-blocks', 'wp-element', 'wp-editor' ), filemtime( plugin_dir_path( __FILE__ ) . 'block-editor.js' ) ); wp_register_script( 'my-plugin-block-script', plugins_url( 'block.js', __FILE__ ), array( 'wp-element' ), filemtime( plugin_dir_path( __FILE__ ) . 'block.js' ) ); register_block_type( 'my-plugin/my-block', $settings ); } add_action( 'init', 'my_plugin_register_block' );plugins_url( 'block-editor.js', __FILE__ ): 获取脚本文件的 URL。array( 'wp-blocks', 'wp-element', 'wp-editor' ): 指定脚本的依赖项。filemtime( plugin_dir_path( __FILE__ ) . 'block-editor.js' ): 获取脚本文件的修改时间,用于缓存刷新。
editor_script和script的区别特性 editor_scriptscript加载环境 WordPress 编辑器 前端页面 主要用途 定义区块的编辑界面、自定义控件、数据验证等。 定义区块的交互逻辑、动画效果、AJAX 请求等。 常用依赖项 wp-blocks,wp-element,wp-editor,wp-components等 WordPress 组件。wp-element等 WordPress 组件,以及第三方 JavaScript 库(如 jQuery)。是否必须 不是必须的,如果区块不需要自定义编辑界面,可以不定义。 不是必须的,如果区块不需要交互逻辑,可以不定义。 -
editor_style和style:区块的化妆师editor_style: 指定区块在编辑器中使用的 CSS 样式表。style: 指定区块在前端使用的 CSS 样式表。
$settings = array( 'attributes' => array( /* ... */ ), 'render_callback' => 'my_block_render_callback', 'editor_script' => 'my-plugin-block-editor-script', 'script' => 'my-plugin-block-script', 'editor_style' => 'my-plugin-block-editor-style', 'style' => 'my-plugin-block-style', );如何注册样式表?
与注册脚本类似,需要先使用
wp_register_style()函数注册样式表。function my_plugin_register_block() { wp_register_style( 'my-plugin-block-editor-style', plugins_url( 'block-editor.css', __FILE__ ), array( 'wp-edit-blocks' ), filemtime( plugin_dir_path( __FILE__ ) . 'block-editor.css' ) ); wp_register_style( 'my-plugin-block-style', plugins_url( 'block.css', __FILE__ ), array( 'wp-block-library' ), filemtime( plugin_dir_path( __FILE__ ) . 'block.css' ) ); register_block_type( 'my-plugin/my-block', $settings ); } add_action( 'init', 'my_plugin_register_block' );editor_style和style的区别特性 editor_stylestyle加载环境 WordPress 编辑器 前端页面 主要用途 定义区块在编辑器中的显示样式。 定义区块在前端页面的显示样式。 常用依赖项 wp-edit-blocks等 WordPress 样式表。wp-block-library等 WordPress 样式表。是否必须 不是必须的,如果区块使用主题的默认样式,可以不定义。 不是必须的,如果区块使用主题的默认样式,可以不定义。 -
supports:区块的超能力supports数组用于声明区块支持的特性,比如对齐方式、HTML 锚点、自定义类名等等。$settings = array( 'attributes' => array( /* ... */ ), 'render_callback' => 'my_block_render_callback', 'editor_script' => 'my-plugin-block-editor-script', 'script' => 'my-plugin-block-script', 'supports' => array( 'align' => true, // 支持对齐方式 'anchor' => true, // 支持 HTML 锚点 'className' => false, // 禁用自定义类名 'html' => false, // 禁用 HTML 编辑 ), );常用的
supports选项:选项 类型 描述 alignboolean 是否支持对齐方式。如果设置为 true,用户可以在编辑器中选择区块的对齐方式(左对齐、居中对齐、右对齐、宽对齐、全宽对齐)。anchorboolean 是否支持 HTML 锚点。如果设置为 true,用户可以为区块添加一个唯一的 HTML 锚点,用于页面内部链接。classNameboolean 是否支持自定义 CSS 类名。如果设置为 true,用户可以为区块添加自定义的 CSS 类名。如果设置为false,则禁用自定义类名,只允许使用 WordPress 提供的默认类名。htmlboolean 是否允许用户直接编辑区块的 HTML 代码。如果设置为 false,则禁用 HTML 编辑,只允许通过编辑器界面修改区块的内容。这可以提高安全性,防止用户插入恶意代码。multipleboolean 是否允许在同一篇文章中插入多个相同的区块。如果设置为 false,则只允许插入一个。inserterboolean 控制是否在区块插入器中显示该区块。 默认为 true。 设置为false可以隐藏区块。colorboolean/array 控制区块是否支持颜色设置。 可以设置为 true启用默认颜色设置,或者设置为一个数组来配置具体的颜色选项,例如支持背景色、文本颜色等。spacingarray 控制区块是否支持间距设置,如 padding 和 margin。 你可以配置支持的具体属性和单位。 typographyarray 控制区块是否支持排版设置,如字体大小、字体粗细、行高等。 你可以配置支持的具体属性和单位。 -
parent和provides_context、uses_context: 区块间的亲密关系parent: 指定区块的父区块,用于创建嵌套区块。provides_context: 指定区块提供的上下文信息,供子区块使用。uses_context: 指定区块使用的上下文信息,由父区块提供。
这三个选项用于实现区块之间的通信和数据共享。
例如,我们可以创建一个包含多个子标题的章节区块:
// 注册章节区块 register_block_type( 'my-plugin/chapter', array( 'attributes' => array( 'title' => array( 'type' => 'string', 'default' => '默认章节标题', ), ), 'provides_context' => array( 'my-plugin/chapterTitle' => 'title', // 提供章节标题作为上下文信息 ), 'render_callback' => 'my_chapter_render_callback', ) ); // 注册子标题区块 register_block_type( 'my-plugin/subheading', array( 'attributes' => array( 'content' => array( 'type' => 'string', 'default' => '默认子标题内容', ), ), 'parent' => array( 'my-plugin/chapter' ), // 指定父区块为章节区块 'uses_context' => array( 'my-plugin/chapterTitle' => 'chapterTitle', // 使用章节标题上下文信息 ), 'render_callback' => 'my_subheading_render_callback', ) ); function my_chapter_render_callback( $attributes, $content ) { $title = isset( $attributes['title'] ) ? $attributes['title'] : '默认章节标题'; return '<div class="chapter"><h2>' . esc_html( $title ) . '</h2>' . $content . '</div>'; } function my_subheading_render_callback( $attributes, $content, $block ) { $chapterTitle = $block->context['my-plugin/chapterTitle']; // 获取章节标题上下文信息 $content = isset( $attributes['content'] ) ? $attributes['content'] : '默认子标题内容'; return '<div class="subheading"><h3>' . esc_html( $content ) . ' (章节标题: ' . esc_html( $chapterTitle ) . ')</h3></div>'; }在这个例子中,章节区块提供了
my-plugin/chapterTitle上下文信息,子标题区块使用了这个上下文信息,从而可以在子标题中显示章节标题。
完整示例:一个简单的文本区块
咱们来一个完整的例子,创建一个简单的文本区块,包含一个 content 属性,允许用户编辑文本内容:
function my_plugin_register_block() {
register_block_type( 'my-plugin/text-block', array(
'attributes' => array(
'content' => array(
'type' => 'string',
'default' => '请输入文本内容',
),
),
'editor_script' => 'my-plugin-text-block-editor-script',
'style' => 'my-plugin-text-block-style',
'render_callback' => 'my_text_block_render_callback',
) );
wp_register_script(
'my-plugin-text-block-editor-script',
plugins_url( 'text-block-editor.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-editor' ),
filemtime( plugin_dir_path( __FILE__ ) . 'text-block-editor.js' )
);
wp_register_style(
'my-plugin-text-block-style',
plugins_url( 'text-block.css', __FILE__ ),
array( 'wp-block-library' ),
filemtime( plugin_dir_path( __FILE__ ) . 'text-block.css' )
);
}
add_action( 'init', 'my_plugin_register_block' );
function my_text_block_render_callback( $attributes ) {
$content = isset( $attributes['content'] ) ? $attributes['content'] : '请输入文本内容';
return '<p>' . esc_html( $content ) . '</p>';
}
对应的 text-block-editor.js 文件内容(使用 React):
const { registerBlockType } = wp.blocks;
const { RichText } = wp.editor;
registerBlockType( 'my-plugin/text-block', {
title: '文本区块',
icon: 'edit',
category: 'common',
attributes: {
content: {
type: 'string',
default: '请输入文本内容',
},
},
edit: ( props ) => {
const { attributes, setAttributes } = props;
const { content } = attributes;
function onChangeContent( newContent ) {
setAttributes( { content: newContent } );
}
return (
<RichText
tagName="p"
className={ props.className }
value={ content }
onChange={ onChangeContent }
placeholder="请输入文本内容"
/>
);
},
save: ( props ) => {
return (
<p>
{ props.attributes.content }
</p>
);
},
} );
对应的 text-block.css 文件内容:
.wp-block-my-plugin-text-block p {
font-size: 16px;
line-height: 1.5;
}
总结:掌握 register_block_type(),玩转区块世界
register_block_type() 函数是 WordPress 区块注册的核心。掌握了它的用法,你就可以自定义各种各样的区块,扩展 WordPress 的功能,打造出独一无二的网站。
希望今天的讲座对大家有所帮助!下次再见!