本文内容参考 倾微博客 ,但是原文有几处错误导致不能使用于最新的WordPress,本博主进行了修改调整达到了无错可用。以下内容在WordPress5.0.4测试通过。
写在前面
Gutenberg(古腾堡)是一个新的 WordPress 编辑器。它以 Johannes Gutenberg 命名,他在 500 多年前发明了一种可移动式印刷机。当前的可视化编辑器需要我们很多人利用短代码和 HTML 来使事情发挥作用。他们的目标是让这更容易,特别是那些刚刚开始使用 WordPress 的人。他们正在拥抱“ block ”,翻译过来就是“块”的意思,并希望添加更多高级布局选项。并且 WordPress 5.0 将 Gutenberg 编辑器命名为了“Block Editor/块编辑器”。
Block介绍
新的编辑器采用Block块的方式插入文章,把内容分成各种块,方便内容的调整和修改,同时也大大的扩展了编辑器的功能。
目前相关的中文内容还是很少,需要了解更多内容可以参考官方介绍
效果截图
如图所示,通过创建自定义块可以更方便的调整文章内容功能和效果,在此我以实现上图的两个自定义块为例,一步一步的创建。
详细教程
创建自定义的过程大致分为三步,只要按照我的教程一步一步的来,还是很简单的
- 在function中注册相关的脚本文件
- 编辑块Block的JS文件
- 编辑块的css外观
注册 Gutenberg Block块
找到你主题的 function.php文件,在最下方添加以下代码:
// 古腾堡编辑器扩展
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文件,我们打开编辑这个文件(此处本站进行了错误修复,修复了几个错误提示以便正常使用)。
(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 了,那我们添加一些样式,就可以看到效果了!
.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样式可能还需要根据你的主题做一些优先级调整,才能显示正确的效果,这里就不再详细赘述了!
提示:
代码添加完可在添加区块-布局元素中找到刚才添加的区块,同时你也可以给根据需要将自定义块添加到其他分组或新建分组。
参考
倾微博客 :http://blog.qiwe.ink/?p=2391
WordPress官方文档、Google等