這是一篇手把手教你開發(fā)WordPress Gutenberg Sidebar的文章。雖然之前也寫了很多關(guān)于Gutenberg的開發(fā)心得,不過都直接忽略了環(huán)境的安裝和配置,以至于很多新手對于ES Next的編譯仍然無法下手。因此本文在寫Gutenberg Sidebar開發(fā)心得的時候,加上了環(huán)境配置的部分。
安裝Node
從Node官方網(wǎng)站下載符合你系統(tǒng)版本的Node進行安裝,過程就是下一步下一步完成一類的。App安裝過程省略。
準(zhǔn)備開發(fā)環(huán)境
1、在主題內(nèi)新建一個文件夾,這個文件夾可以放置到任何位置,例如我在pandastudio_plugins目錄下新建了一個sample_gutenberg_sidebar
2、打開這個文件夾,按住Shift右鍵單擊空百處,選擇打開Powershell(Win10以前的系統(tǒng)應(yīng)該是命令行)。Mac系統(tǒng)手動打開系統(tǒng)自帶Shell,輸入cd空格,將文件夾拖入到Shell窗口回車即可
3、輸入npm?init來創(chuàng)建一個項目,回車后,會讓你輸入包名稱、項目名稱、版本號等,全部按回車即可。大致效果如下:
PS D:\apps\xampp\htdocs\wordpress\wp-content\themes\reVival\pandastudio_plugins\sample_gutenberg_sidebar> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (sample_gutenberg_sidebar)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\apps\xampp\htdocs\wordpress\wp-content\themes\reVival\pandastudio_plugins\sample_gutenberg_sidebar\package.json:
{
"name": "sample_gutenberg_sidebar",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes)
PS D:\apps\xampp\htdocs\wordpress\wp-content\themes\reVival\pandastudio_plugins\sample_gutenberg_sidebar>
4、可以看到,目錄下已經(jīng)出現(xiàn)了一個package.json文件。現(xiàn)在先不管它,我們繼續(xù)在這個目錄安裝開發(fā)需要的?@wordpress/scripts 依賴,繼續(xù)在剛才的命令行中輸入
npm install @wordpress/scripts -D
5、根據(jù)網(wǎng)絡(luò)情況,可能需要下載一段時間,然后自動安裝。此過程中可以看到一個進度條以及下載的包名稱,效果如下
[ ................] \ fetchMetadata: sill XXXXXXX
如果安裝一次等了很久屏幕都沒有動靜,可以連續(xù)按下幾次Ctrl+C來終止,然后繼續(xù)輸入前面的命令來重新安裝
6、安裝完依賴之后,在剛才的文件夾下新建src文件夾,然后在里面新建index.js文件作為未編譯的原始文件
7、打開package.json,將scripts里面的內(nèi)容修改為下面的內(nèi)容, 保存后關(guān)閉
"scripts": {
"dev": "wp-scripts start",
"build": "wp-scripts build"
},
8、在剛才的PowerShell命令行中輸入下面的命令來開始開發(fā):
npm run dev
9、命令運行后,將監(jiān)聽src/index.js文件的變化來自動編譯,大致效果如下:
PS D:\apps\xampp\htdocs\wordpress\wp-content\themes\reVival\pandastudio_plugins\sample_gutenberg_sidebar> npm run dev
> sample_gutenberg_sidebar@1.0.0 dev D:\apps\xampp\htdocs\wordpress\wp-content\themes\reVival\pandastudio_plugins\sample_gutenberg_sidebar
> wp-scripts start
webpack is watching the files…
Live Reload listening on port 35729
Hash: f06cbcda0a4aad106cd6
Version: webpack 4.8.3
Time: 1495ms
Built at: 2019-08-16 09:41:56
Asset Size Chunks Chunk Names
index.js 2.79 KiB index [emitted] index
index.js.map 2.52 KiB index [emitted] index
index.deps.json 15 bytes index [emitted] index
Entrypoint index = index.js index.js.map index.deps.json
[./src/index.js] 0 bytes {index} [built]
10、此時可以看到在原來的文件夾下生成了一個build的文件夾,里面的index.js就是編譯后的腳本了。這樣,一個Gutenberg的腳本開發(fā)環(huán)境就搭建好了。
PHP引入腳本
1、PHP引入腳本的方法都是一樣的:使用鉤子來進行引入。在主題的function.php文件中添加一個enqueue_block_editor_assets的動作,然后在執(zhí)行此動作的時候注冊和引入腳本即可
<?php
add_action( 'enqueue_block_editor_assets', function(){
wp_register_script(
'sample_gutenberg_sidebar',
get_stylesheet_directory_uri()."/pandastudio_plugins/sample_gutenberg_sidebar/build/index.js",
array( 'wp-plugins', 'wp-edit-post', 'wp-element' )
);
wp_enqueue_script( 'sample_gutenberg_sidebar' );
});
2、要驗證是否成功引入了,可以在src/index.js里面輸入下面的內(nèi)容來測試(保證在開發(fā)狀態(tài),已經(jīng)運行了npm?run?dev)
alert('已成功引入!');
3、接下來在開發(fā)環(huán)境中用瀏覽器打開Gutenberg編輯器,刷新后即可看到“已成功引入”的彈窗。下面就可以開始正式編寫Gutenberg的邊欄腳本了。
開始編寫Gutenberg邊欄
注冊Meta元數(shù)據(jù)
1、我們的邊欄數(shù)據(jù)都是存儲在Post的Meta里面的,因此需要先注冊Meta然后才可以使用,假設(shè)現(xiàn)在需要注冊一個叫做sample_meta1的字符串?dāng)?shù)據(jù),我們在function.php里面這樣寫
register_post_meta( 'post', 'sample_meta1', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string'
));
2、在src/index.js里面編寫邊欄的前端部分
//引入需要的模塊
const {
registerPlugin
} = wp.plugins;
const {
PluginSidebar,
PluginSidebarMoreMenuItem
} = wp.editPost;
const {
withSelect,
withDispatch
} = wp.data;
const {
Fragment
} = wp.element;
const {
TextControl,
} = wp.components;
//注冊邊欄
registerPlugin( 'sample-gutenberg-sidebar', {
render() {
return (
<Fragment>
<PluginSidebar
name="sample-gutenberg-sidebar"
icon="admin-post"
title="邊欄示例"
>
示例內(nèi)容
</PluginSidebar>
</Fragment>
)
},
} );
打開編輯器,看到效果如下

3、剛才注冊的邊欄直接取消固定并關(guān)閉(取消星星的填充,然后點擊右側(cè)的叉叉)后,就再也無法打開了,因此需要在Gutenberg的選項中增加一個邊欄的打開菜單,我們在<Fragment>里面增加一個<PluginSidebarMoreMenuItem>并通過target屬性指向到邊欄
<PluginSidebarMoreMenuItem target="sample-gutenberg-sidebar">
邊欄菜單
</PluginSidebarMoreMenuItem>
這樣,哪怕邊欄被取消固定并關(guān)閉后,也可以有再次打開的方法:

4、現(xiàn)在,邊欄的內(nèi)容都是完全空的,我們來增加一個Input輸入框來編輯剛才注冊的sample_meta1數(shù)據(jù)。這一部分的原理在Gutenberg開發(fā)手冊上有詳細(xì)的描述我就不再多說了,主要使用了withSelect和withDispatch來實現(xiàn)數(shù)據(jù)的讀取和更新。考慮到如果注冊的meta字段比較多,這一部分就會重復(fù)寫很多次而且比較繁瑣,因此我將它封裝成了一個構(gòu)建meta模塊的函數(shù),后面的新增meta模塊都用這個方法來進行:
const createMetaBlock = (metaBlockField,metaName) => {
const MetaBlockFieldWithDataAndActions = withDispatch((dispatch) => {
return {
setMetaFieldValue(value) {
let meta = {};
meta[metaName] = value;
dispatch('core/editor').editPost({meta});
}
}
})(withSelect((select) => {
return {
metaFieldValue: select('core/editor').getEditedPostAttribute('meta')[metaName]
}
})(metaBlockField));
return (<MetaBlockFieldWithDataAndActions />);
}
我上面封裝的構(gòu)建模塊方法第一個參數(shù)是Function類型:它接收一個參數(shù)(參數(shù)中包含meta數(shù)據(jù)和設(shè)置meta數(shù)據(jù)的方法),返回需要傳入的組件;第二個參數(shù)是String類型,內(nèi)容是meta字段的名稱。將上面的代碼加入到我們的腳本中后,現(xiàn)在我們用我剛才封裝的方法來添加sample_meta1的編輯框
<PluginSidebar
name="sample-gutenberg-sidebar"
icon="admin-post"
title="邊欄示例"
>
{
createMetaBlock(({metaFieldValue,setMetaFieldValue})=>{return (
<TextControl
label="示例數(shù)據(jù)1"
value={metaFieldValue}
onChange={ (content) => {setMetaFieldValue(content)} }
/>
)},'sample_meta1')
}
</PluginSidebar>
如果有更多的數(shù)據(jù)字段如sample_meta2,只需要在PluginSidebar中添加更多的metaBolck方法即可。編輯器中效果如下:

5、至此,Gutenberg邊欄的編寫就完成了。發(fā)布時,先刪除build文件夾,然后在PowerShell中使用下面的命令來進行代碼打包和代碼壓縮
npm run build
開發(fā)文件夾下的package.json、src、node_modules、package-lock.json都不需要發(fā)布到正式環(huán)境中,只有build文件夾才需要
其他優(yōu)化
- 我們可以看到,上面的樣式不算太好看。因此可以用類似引入腳本的方法,一樣用鉤子去引入樣式。這里我就不再做示例了。發(fā)揮自己的想象去完成它吧
- 根據(jù)實際的需求,可能不止input輸入框一種,因此還可以根據(jù)需要增加更多的組件進去
- 如果不想使用邊欄,也可以將PluginSidebar換成PluginDocumentSettingPanel(具體用法參考Gutenberg開發(fā)文檔),就可以將設(shè)置選項直接集成到文章設(shè)置頁里面了
- 最終,我完成了一個包含“圖片上傳”、“色彩選擇”、“多圖上傳”、“單選”、“下拉”等功能為一體的主題文章設(shè)置工具,如下所示:

總結(jié)
Gutenberg Sidebar 邊欄開發(fā)時都是使用基礎(chǔ)的PluginSidebar組件進行開發(fā),只需掌握使用方法即可。唯一需要注意不要被坑的是要記得添加邊欄菜單的另一個入口,防止被關(guān)閉后無法再次打開。
Meta數(shù)據(jù)的讀取和寫入本身是一個難點,不過在本文中我已經(jīng)將它封裝成一個方便重用的方法了,若需了解詳情,建議參考本文末尾的官方教程學(xué)習(xí)原理即可。
關(guān)于本文的其它說明
本文特色圖在設(shè)計時考慮了Node的Logo外形和Gutenberg的G進行融合,文章頭圖也致敬了Node的顏色和風(fēng)格。頭圖使用了“多邊形”生成工具輔助進行設(shè)計。
參考文獻
- WordPress Gutenberg Handbook 《 Creating a Sidebar for Your Plugin 》
- WordPress Gutenberg Handbook 《 SlotFills Reference 》
注:文本原創(chuàng)出自 http://panda.panda-studio.cn/wordpress-gutenberg-sidebar-development ,轉(zhuǎn)載請注明該出處!





