我在WordPress中尝试写了一篇关于如何创建自定义区块的文章
首先
WordPress 5.0 以后,采用了名为 Gutenberg 的区块编辑器作为默认编辑器。因此,预计未来将会有更多的开发基于这个区块编辑器进行。
在我个人看来,我并没有对以往的所见即所得编辑器感到不满意,但随着出现了块编辑器这个选择,我觉得我们能够做的事情变得更多了。
在本文中,我将介绍如何创建这个块编辑器的新块(以下称为自定义块)。
什么是区块编辑器?
块编辑器是一个根据其名称而命名的编辑器,它将HTML堆叠起来以创建HTML。

请参考以下内容以获取更详细的信息。
作为区块编辑器的一个特点,上述链接页面中也提到了,即编辑器将以实际网站的形式显示。 接下来所描述的自定义区块也将以实际网站的形式创建并显示。
此外,WordPress的区块编辑器可以创建两种不同类型的自定义区块。
-
- 動的ブロック ・・・ 最新の投稿を表示するブロック等の動的にブロックの内容が変化するブロック
- 静的ブロック ・・・ 動的とは反対で、画像アップロードやテキストフィールド等のブロックの内容が変化しないブロック
现在开始创建自定义静态块。(动态块将在其他部分描述)
制作自定义的代码块
创建一个可以从侧边导航中选择背景色的自定义块,以编写以下类似的文本。我们将创建两种样本块,一种是在编辑器和屏幕显示(以下称为前端)应用CSS的块,另一种是仅在编辑器应用CSS的块。

环境的准备
前提是已经安装了以下内容。
-
- PHP: 7.1以上
-
- Node: v10.x
- Yarn: v1.9.4
WordPress的区块编辑器是使用React创建的。
将来要创建的自定义区块也将使用React的组件进行开发。
然而,我们将使用WordPress提供的React,而不是通常的React。因此,不需要安装React。
接下来是安装库的步骤。
需要准备 package.json 文件。
创建一个类似以下的package.json文件。
{
"name": "sample-block",
"version": "1.0.0",
"description": "Sample Block",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Kodak",
"license": "GPL-2.0"
}
准备[任意]webpack
以下是可选的。
如果您想通过Webpack构建JavaScript,请安装以下内容。
由于我们将在接下来使用@wordpress/scripts进行构建,所以不需要安装它。
yarn add -D webpack webpack-cli
需要准备[BABEL]
我将安装以下内容:
由于我希望使用JSX编写自定义代码块,因此还会安装@babel/preset-react。
yarn add -D @babel/core babel-loader @babel/preset-env @babel/preset-react
@babel/core ・・・ BABEL本体
babel-loader ・・・ webpackからBABELを通すためのライブラリ
@babel/preset-env ・・・ 特定の環境(ブラウザ)に合わせた変換をしてくれるライブラリ
@babel/preset-react ・・・ JSXのコンパイル可能にするライブラリ
准备一个库来支持[SASS]的任意选择。
这是可选的。
这次我们想要支持SASS,所以我们会安装以下内容。
yarn add -D node-sass css-loader sass-loader
node-sass ・・・ SASS(SCSS)をCSSに変換するライブラリ
sass-loader ・・・ webpackからSASS(SCSS)をCSSに変換するライブラリ
css-loader ・・・ CSSをJavaScriptにバンドルするライブラリ
准备一个用于扩展CSS的库。
这是任意的,但最好安装它。
它会将供应商前缀和CSS作为单独的文件输出。
yarn add -D postcss-loader autoprefixer mini-css-extract-plugin optimize-css-assets-webpack-plugin terser-webpack-plugin
postcss-loader ・・・ ベンダープレフィックスをCSSに追加するため&ネストしたCSSを解析してくれるライブラリ
autoprefixer ・・・ ベンダープレフィックスをCSSに追加(postcss-loaderのプラグイン)
mini-css-extract-plugin ・・・ CSSを別ファイルとして出力するためのライブラリ
optimize-css-assets-webpack-plugin ・・・ 作成するCSSを圧縮するためのライブラリ
terser-webpack-plugin ・・・ CSSを圧縮する際、さらにCSSを縮小してくれる(邪魔なコメントやscourceMapを削除してくれる)ライブラリ
为了确保不在建立文件夹时留下垃圾文件,需准备一个库。
为了避免在构建文件夹中留下垃圾文件,请安装这个。
yarn add -D clean-webpack-plugin
clean-webpack-plugin ・・・ ビルドする度に、ビルドフォルダーを削除するライブラリ
需要准备一个能够创建自定义代码块的库。
这是用于创建自定义块的库。
yarn add -D @wordpress/browserslist-config @wordpress/scripts @wordpress/blocks @wordpress/dependency-extraction-webpack-plugin
@wordpress/browserslist-config ・・・ WordPressのブロックエディターが動くブラウザリストのライブラリ
@wordpress/scripts ・・・ WordPressのブロックエディター用のwebpackが詰め込まれたライブラリ。これを使用しない場合は、webpackを別途インストールする必要がある。
@wordpress/blocks ・・・ WordPressでカスタムブロックを作るためのライブラリ。
@wordpress/dependency-extraction-webpack-plugin ・・・ ライブラリの依存関係を自動で解決するassets.phpファイルを生成してくれるライブラリ
根据创建的自定义积木块准备相应的库。
根据要创建的自定义区块安装相应的库。
这次我们将使用@wordpress/block-editor和@wordpress/components。
yarn add -D @wordpress/block-editor @wordpress/components
请参阅官方网站以获取各个库的详细信息。
事前准备
“name”: “sample-block”,
“version”: “1.0.0”,
“description”: “样例区块”,
“main”: “index.js”,
“scripts”: {
“test”: “echo \”错误:未指定测试\” && exit 1″,
“start”: “wp-scripts build –mode=development –config webpack.config.js –watch”,
“build”: “wp-scripts build –mode=production –config webpack.config.js”
},
“author”: “Kodak”,
“license”: “GPL-2.0”,
“devDependencies”: {
“@babel/core”: “^7.8.7”,
“@babel/preset-env”: “^7.8.7”,
“@babel/preset-react”: “^7.8.3”,
“@wordpress/block-editor”: “^3.7.5”,
“@wordpress/blocks”: “^6.12.1”,
“@wordpress/browserslist-config”: “^2.6.0”,
“@wordpress/components”: “^9.2.4”,
“@wordpress/dependency-extraction-webpack-plugin”: “^2.4.0”,
“@wordpress/scripts”: “^7.1.3”,
“autoprefixer”: “^9.7.4”,
“babel-loader”: “^8.0.6”,
“clean-webpack-plugin”: “^3.0.0”,
“css-loader”: “^3.4.2”,
“mini-css-extract-plugin”: “0.6.0”,
“node-sass”: “^4.13.1”,
“optimize-css-assets-webpack-plugin”: “^5.0.3”,
“postcss-loader”: “^3.0.0”,
“sass-loader”: “^8.0.2”,
“terser-webpack-plugin”: “^2.3.5”
},
“browserslist”: [
“extends @wordpress/browserslist-config”
]
}
为了使用webpack(wp-scripts)来构建WordPress,可以按如下定义:
"scripts": {
"start": "wp-scripts build --mode=development --config webpack.config.js --watch",
"build": "wp-scripts build --mode=production --config webpack.config.js"
},
浏览器列表通过使用extends进行加载。
"browserslist": [
"extends @wordpress/browserslist-config"
]
注意:由于在使用chunkFilename时遇到了错误,mini-css-extract-plugin的版本已更改为0.6.0。
function isDevelopment() {
return argv.mode === ‘development’
}var config = {
entry: {
editor: ‘./src/editor.js’,
script: ‘./src/script.js’,
},
output: {
filename: “[name].js”
},
optimization: {
minimizer: [
new TerserWebpackPlugin({
sourceMap: isDevelopment()
}),
new OptimizeCSSAssetsWebpackPlugin(
{
cssProcessorOptions: {
map: {
inline: false,
annotation: true
}
}
}
)
]
},
plugins: [
new DependencyExtractionWebpackPlugin(),
new CleanWebpackPlugin(),
new MiniCSSExtractPlugin({
chunkFilename: “[id].css”,
filename: chunkData => {
return chunkData.chunk.name === “script” ? ‘style.css’ : ‘[name].css’;
}
})
],
devtool: ‘source-map’,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: ‘babel-loader’,
options: {
presets: [
‘@babel/preset-env’,
[
‘@babel/preset-react’,
{
“pragma”: “wp.element.createElement”,
“pragmaFrag”: “wp.element.Fragment”,
“development”: isDevelopment()
}
]
]
}
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCSSExtractPlugin.loader,
‘css-loader’,
{
loader: ‘postcss-loader’,
options: {
plugins: [
autoprefixer()
]
}
},
‘sass-loader’
]
}
]
},
};
return config;
}
将用于React的函数进行BABEL转译。
通常情况下,我们会写”React.createElement.xxxx”,但是WordPress的区块编辑器需要使用WordPress专用的React,所以我们会按照以下方式进行编写。
'@babel/preset-react',
{
"pragma": "wp.element.createElement",
"pragmaFrag": "wp.element.Fragment",
}
请注意,如果您不使用WordPress的构建工具(例如wp-scripts和dependency-extraction-webpack-plugin),需要使用webpack来解决WordPress的依赖关系,请参考以下描述。
以下是原文的中文翻译:请参考https://developer.wordpress.org/block-editor/packages/packages-dependency-extraction-webpack-plugin/。
externals: {
"@wordpress/blocks": ["wp", "blocks"],
"@wordpress/editor": ["wp", "editor"],
"@wordpress/components": ["wp", "components"],
"@wordpress/element": ["wp", "element"],
}
开发自定义模块作为插件。
如果要将自定义块的创建过程绘制成图表,感觉大致如下。

无论从哪里开始创作都没有问题,我认为最好先创建自定义块的JS主代码和自定义块的样式代码,然后再创建自定义块的注册代码。
从”@wordpress/blocks”导入{ registerBlockType };
从”@wordpress/editor”导入{ RichText, InspectorControls };
从”@wordpress/components”导入{ PanelBody, ColorPalette };
registerBlockType(‘sample-block/firstblock’, {
标题:’示例块(编辑器)’,
图标:’wordpress-alt’,
类别:’常见’,
示例:{},
属性:{
内容:{
类型:’字符串’,
来源:’html’,
选择器:’p’
},
颜色前缀:{
类型:’字符串’,
默认值:”
}
},
编辑({ className,属性,setAttributes }){
const { content,colorPrefix } =属性;
const changeBackGroundColor =(backGroundColor)=> {
let color_prefix =”;
开关(背景颜色){
案例’蓝色’:
color_prefix =’–蓝色’ ;
打破 ;
案例’红色’:
color_prefix =’–红色’;
打破 ;
案例’绿色’:
color_prefix =’–绿色’;
打破 ;
案例’黄色’:
color_prefix =’–黄色’;
打破 ;
默认:
color_prefix =”;
打破 ;
}
setAttributes({ colorPrefix:color_prefix })
}
返回(
setAttributes( { content: content } ) }
value={ content }
/>
);
},
保存({属性}){
const { content,colorPrefix } =属性;
返回(
)}
);
}
});
&__content {
颜色: 黑色;
背景颜色: 白色;
}
&__content–red {
颜色: 白色;
背景颜色: 红色;
}
&__content–green {
颜色: 白色;
背景颜色: 绿色;
}
&__content–blue {
颜色: 白色;
背景颜色: 蓝色;
}
&__content–yellow {
颜色: 红色;
背景颜色: 黄色;
}
}
编辑函数用于编辑器的显示部分,保存函数用于前端的显示部分。
属性主要定义了从编辑函数传递到保存函数的值,这些值是在编辑器中设置的,比如富文本的数值和选择的颜色类的前缀。
只需将InspectorControls、PanelBody等组合起来,就可以很容易地实现侧边导航。
]
);
// 注册自定义区块.
register_block_type(
‘sample-block/secondblock’,
[
‘script’ => ‘sample-block-script’, // 在编辑器和前台同时加载脚本.
‘style’ => ‘sample-block-style’, // 在编辑器和前台同时加载样式.
]
);
}
add_action( ‘enqueue_block_editor_assets’, ‘sample_block_register’ );
add_action( ‘enqueue_block_assets’, ‘sample_block_register’, 1 );
如果使用WordPress上的webpack(wp-scripts、dependency-extraction-webpack-plugin)进行构建,则会生成脚本文件(xxxx.asset.php)。该文件包含有关库的依赖关系和版本信息,因此可以使用它们来注册JS文件。
自定义块的注册有四种类型:editor_script、editor_style、script和style。这四种类型的区别如下所示。
editor_script ・・・ エディター画面の時のみスクリプトを読み込む
editor_style ・・・ エディター画面の時のみスタイルを読み込む
script ・・・ エディター・フロントの両画面でスクリプトを読み込む
style ・・・ エディター・フロントの両画面でスタイルを読み込む
如果我们从前台预览并从前端查看本文开头展示的方块,显示如下。

上:当使用CSS应用于编辑器和前端使用的块(script、style)时
下:当仅使用CSS应用于编辑器使用的块(editor_script、editor_style)时
可以看到上方,编辑器指定的背景色(红色)应用到了前端。
相反地,可以看到下方,编辑器指定的背景色(绿色)没有反映在前端。
最后提到的是关于Hook,如果要使用editor_script和editor_style,则应使用enqueue_block_editor_assets。
如果要使用script和style,则应使用enqueue_block_assets。
由于为块编辑器准备了适当的Hook,请确保使用正确的Hook。千万不要错误地使用init。
最后
这就是为什么我花了很长时间来编写如何创建自定义块,但是你觉得怎么样呢?
个人而言,我最困扰的是webpack的配置。
作为一个后端工程师,理解webpack的配置方法花费了我很多时间……
自定义块是现代化的设计,很有趣,但是学习成本很高,这是令人痛苦的地方。
我希望这次能够尝试创建动态区块。