本文内容主要参考 海拔科技 以及 Gutenberg 开发API ,介绍并解读新版WordPress所采用的 Gutenberg 编辑器 _( Block Editor/块编辑器 )_如何创建自定义编辑块,包括块的样式以及扩展工具栏等。

本文适用于WordPress 5.22。关于WordPress Gutenberg自定义系列目录如下:
1、WordPress之Gutenberg(古腾堡)自定义块(一)
2、WordPress之Gutenberg(古腾堡)自定义块(二)
3、WordPress之Gutenberg(古腾堡)自定义块扩展栏
4、WordPress之Gutenberg(古腾堡)自定义块工具栏

本文内容来自海拔科技: https://www.haibakeji.com/archives/582.html ,详细介绍各个属性可阅读本文WordPress之Gutenberg(古腾堡)自定义块(一)。

Block介绍

新的编辑器采用Block块的方式插入文章,把内容分成各种块,方便内容的调整和修改,同时也大大的扩展了编辑器的功能。

目前相关的中文内容还是很少,需要了解更多内容可以参考官方介绍:

效果截图

wp_block1

wp_block2

如图所示,通过创建自定义块可以更方便的调整文章内容功能和效果,在此我以实现上图的两个自定义块为例,一步一步的创建。

详细教程

创建自定义的过程大致分为三步,只要按照我的教程一步一步的来,还是很简单的

  1. 在function中注册相关的脚本文件
  2. 编辑块Block的JS文件
  3. 编辑块的css外观

注册 Gutenberg Block块

找到你主题的 function.php 文件,在最下方添加以下代码:

function.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 古腾堡编辑器扩展
function duxq_block() {
wp_register_script( //引入核心js文件
'duxq_block',
get_stylesheet_directory_uri().'/js/gb_block.js',
array( 'wp-blocks', 'wp-element' )
);

wp_register_style( //引入css外观样式文件
'duxq_block',
get_stylesheet_directory_uri().'/css/editor-style.css',
array( 'wp-edit-blocks' )
);

register_block_type( 'duxq/block', array(
'editor_script' => 'duxq_block',
'editor_style' => 'duxq_block',
) );
}
if (function_exists('register_block_type')) { //判断是否使用古腾堡编辑器
add_action( 'init', 'duxq_block' );
}

语法解释:

  • wp_register_script() 引入核心的js文件
  • wp_register_style() 引入css外观样式文件
  • 最后我们检测一下是否使用古腾堡,然后排队注册

编辑Block块JS内容

块是的核心就是JS文件控制的,要实现的所有功能也是靠这个就是文件。

按照我们上面引入的js文件,我们打开编辑这个文件。

/js/gb_block.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
(function(blocks, editor, element, components, _) {
var el = element.createElement;
var RichText = editor.RichText;
var AlignmentToolbar = editor.AlignmentToolbar;
var BlockControls = editor.BlockControls;
var Fragment = element.Fragment;

/*---------创建第一个自定义块---------*/
blocks.registerBlockType('reilve/quote', {
title: 'DUXQ引言',
category: 'layout',
icon: {
src: 'format-quote',
foreground: '#f85253'
},
description: '几种不同的引言框',
attributes: { //设定自定义属性
content: {
type: 'array',
source: 'children',
selector: 'span',
},
typeClass: {
source: 'attribute',
selector: '.quote_q',
attribute: 'class',
}
},
edit: function(props) { //编辑器函数
var content = props.attributes.content,
typeClass = props.attributes.typeClass 'quote_q qe_wzk_lan',
isSelected = props.isSelected;
function onChangeContent(newContent) {
props.setAttributes({
content: newContent
})
}
function changeType(event) {
var type = event.target.className;
props.setAttributes({
typeClass: 'quote_q ' + type
})
}
var richText = el(RichText, { //内容输入框
tagName: 'p',
onChange: onChangeContent,
value: content,
isSelected: props.isSelected,
placeholder: '请输入...'
});
var outerHtml = el('div', {
className: typeClass
},
richText);
var selector = el('div', {
className: 'duxq anz'
},
//在此添加4个可点击的按钮
[el('button', {className: 'qe_wzk_lan',onClick: changeType}),
el('button', {className: 'qe_wzk_lv',onClick: changeType}),
el('button', {className: 'qe_wzk_hui',onClick: changeType}),
el('button', {className: 'qe_wzk_hong',onClick: changeType})]
);
return el('div', {},[outerHtml, isSelected && selector])},
save: function(props) { //保存的函数
var content = props.attributes.content,
typeClass = props.attributes.typeClass 'quote_q qe_wzk_lan';
var outerHtml = el('div', {
className: typeClass
},
el('i', {
className: 'fa fa-quote-left '
}), el('span', {},
content));
return el('div', {},
outerHtml)
},
});

/*---------创建第二个自定义块---------*/
blocks.registerBlockType('aduxq/button', {
title: 'UDXQ 按钮',
category: 'layout',
icon: {
src: 'marker',
foreground: '#f85253'
},
attributes: {
content: {
type: 'array',
source: 'children',
selector: 'span',
},
alignment: {
type: 'string',
},
typeClass: {
source: 'attribute',
selector: '.an_q',
attribute: 'class',
}
},
edit: function(props) {
var content = props.attributes.content,
typeClass = props.attributes.typeClass 'qe_fxan b1',
alignment = props.attributes.alignment,
isSelected = props.isSelected;
function onChangeContent(newContent) {
props.setAttributes({
content: newContent
})
}
function changeType(event) {
var type = event.target.className;
props.setAttributes({
typeClass: 'an_q ' + type
})
}
function onChangeAlignment(newAlignment) {
props.setAttributes({
alignment: newAlignment
})
}
var richText = el(RichText, {
tagName: 'span',
onChange: onChangeContent,
value: content,
isSelected: props.isSelected,
placeholder: '按钮'
});
var outerHtml1 = el('div', {
className: typeClass
},
richText);
var outerHtml = (el(element.Fragment, null, el(BlockControls, null, el(AlignmentToolbar, {
value: alignment,
onChange: onChangeAlignment,
})), outerHtml1));
var selector = el('div', {
className: 'duxq anz'
},
[el('button', {
className: 'qe_fxan b1',
onClick: changeType
},
''), el('button', {
className: 'qe_fxan b2',
onClick: changeType
},
''), el('button', {
className: 'qe_fxan b3',
onClick: changeType
},
''), el('button', {
className: 'qe_fxan b4',
onClick: changeType
},
''), el('button', {
className: 'qe_fxan b5',
onClick: changeType
},
''), ]);
return el('div', {
style: {
textAlign: alignment
}
},
[outerHtml, isSelected && selector])
},
save: function(props) {
var content = props.attributes.content,
alignment = props.attributes.alignment,
typeClass = props.attributes.typeClass 'qe_fxan b1';
if (alignment) {
var outerHtml = el('div', {
style: {
textAlign: alignment
}
},
el('span', {
className: typeClass
},
content))
} else {
var outerHtml = el('span', {
className: typeClass
},
content)
}
return outerHtml
},
})
})(window.wp.blocks, window.wp.editor, window.wp.element, window.wp.components, window._, );

在以上代码中我们创建了两个自定义块,分别是DUXQ标题和DUXQ按钮,点击块就会出现上面图片中的块,包含了文字内容输入,和几个按钮,按下按钮会切换内容的css Class,以实现外观样式的改变!

语法解释:

  • blocks , editor , i18n , element , components等均是官方的API接口,实现数据传递
  • blocks.registerBlockType() 创建Block的函数接口
  • registerBlockType 的几个参数:title(标题)、icon(图标)、category(分组)、attributes(自定义属性)
  • 两个核心函数:edit 和 save ,分别定义了编辑时候的函数和保存的函数
  • 上面我们增加了几个按钮,传递 onClick 事件,实现点击切换不同的 className

css外观样式

通过创建了自定义块,能实现加载不同的css className 了,那我们添加一些样式,就可以看到效果了!

/css/editor-style.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
.duxq.anz button {
margin: 10px;
padding: .5em 1em;
min-width: 33px;
min-height: 33px;
cursor: pointer
}
.duxq.anz button:hover {
box-shadow: 0 0 10px #ddd;
opacity: .8
}
.qe_wzk_hong {
margin: 10px 0;
padding: .6em 1em;
border: 1px solid #f1d3d3;
border-radius: 4px;
background: #fff7f7;
color: #dc3f3f
}
.qe_wzk_lan {
margin: 10px 0;
padding: .6em 1em;
border: 1px solid #b3daf1;
border-radius: 4px;
background: #f7fcff;
color: #197cb1
}
.qe_wzk_hui {
margin: 10px 0;
padding: .6em 1em;
border: 1px solid #d4d4d4;
background: #f5f5f5;
color: #757575
}
.qe_wzk_lv {
margin: 10px 0;
padding: .6em 1em;
border: 1px solid #b4e6b1;
border-radius: 4px;
background: #f7fff9;
color: #1d9c24
}
.quote_q:before {
content: "“";
position: absolute;
color: #ccc;
font-size: 120px;
top: -60px;
left: 0
}
.qe_fxan {
display: inline-block;
margin: .5em;
padding: .6em .8em;
min-width: 80px;
border: none;
border-radius: 60px;
box-shadow: -1px 4px 10px rgba(0,0,0,.2);
color: #fff;
text-align: center;
transition: all .2s ease
}
.qe_fxan a,.qe_fxan a:hover {
color: #fff
}
.qe_fxan.b1 {
background-image: linear-gradient(135deg,#f58852 10%,#e43e2f 100%)
}
.qe_fxan.b2 {
background-image: linear-gradient(135deg,#59b7fb 10%,#036bff 100%)
}
.qe_fxan.b3 {
background-image: linear-gradient(135deg,#CE9FFC 10%,#7367F0 100%)
}
.qe_fxan.b4 {
background-image: linear-gradient(135deg,#FCCF31 10%,#f77f2d 100%)
}
.qe_fxan.b5 {
background-image: linear-gradient(135deg,#54ea98 10%,#0db757 100%)
}

以上css内容除了要添加到刚刚引入的css文件中,还需要添加到主题的相关css文件中,才能实现文章页中也显示相同效果!同时css样式可能还需要根据你的主题做一些优先级调整,才能显示正确的效果,这里就不再详细赘述了!

代码添加完可在添加区块-布局元素中找到刚才添加的区块,同时你也可以给根据需要将自定义块添加到其他分组或新建分组。

本文简单介绍了怎样构建自定义块,下一文《WordPress之Gutenberg(古腾堡)自定义块(二)》将会详细解读构建过程以及个属性值。

WordPress Gutenberg其他相关自定义系列文章:
1、WordPress之Gutenberg(古腾堡)自定义块(二)
2、WordPress之Gutenberg(古腾堡)自定义块扩展栏
3、WordPress之Gutenberg(古腾堡)自定义块工具栏