如何構建古騰堡外掛以增強區塊編輯器功能

如何構建古騰堡外掛以增強區塊編輯器功能

多年來,我們從多個角度對古騰堡進行了探索。我們剖析了編輯器的功能,與其他頁面構建工具進行了比較,構建了靜態動態自定義區塊,等等。

在最新版本的 WordPress 中,新功能和新工具通過豐富和增強區塊編輯器的功能,讓您可以更輕鬆地建立複雜的佈局,而無需構建自定義區塊。

由於引入了區塊樣板和開發者工具(如區塊繫結 API),自定義區塊的用例越來越少。現在,您可以建立複雜的區塊結構,在內容中注入後設資料值,並在不離開編輯器介面的情況下自動執行大部分工作流程。簡而言之,WordPress讓您可以像以前一樣,只需點選幾下就能建立複雜的網站。

在編輯器中新增自定義控制元件和工具可以讓內容建立過程更加順暢。例如,您可能需要在 “文章” 側邊欄中新增一個面板來增加功能,或者建立一個自定義側邊欄來管理多個元欄位。

如何在不建立自定義區塊的情況下建立區塊編輯器外掛

WordPress 提供了一個方便的命令列工具,允許您安裝一個本地 Node.js 開發環境,其中包含建立自定義區塊所需的所有檔案和依賴項。只需在命令列工具中鍵入 npx @wordpress/create-block,等待幾秒鐘,就大功告成了。

不過,當你只需要新增一個側邊欄或一個簡單的設定面板時,就沒有必要為自定義區塊搭建腳手架了。在這種情況下,您需要建立一個古騰堡外掛。

WordPress 沒有提供自動建立 Gutenberg 外掛的工具,因此您需要手動建立。不過不用太擔心。這個過程相對簡單,我們將引導您完成。具體步驟如下:

1. 下載並安裝本地開發環境

先做第一件事: 雖然您可以在遠端環境中開發 Gutenberg 外掛,但在本地安裝一個開發 WordPress 網站可能更方便。您可以使用任何基於 PHP 和 MySQL 的環境。在眾多替代方案中,我們推薦MAMP。它功能齊全、易於使用。

設定好開發網站後,您就可以建立 Gutenberg 區塊編輯器外掛了。

2. 下載並安裝 Node.js 和 npm

nodejs.org 下載 Node.js 並安裝到您的電腦上。這還將安裝 Node 軟體包管理器 npm。

安裝完成後,啟動命令列工具並執行 node -vnpm -v 。您將看到 Node.js 和 npm 的安裝版本。

檢查 node 和 npm 版本

檢查 node 和 npm 版本

3. 建立外掛資料夾

wp-content/plugins 下新建一個資料夾,並將其重新命名為 my-sidebar-plugin 或類似名稱。記住,這個名稱應反映你的外掛名稱。

開啟終端,導航到外掛資料夾,然後使用以下命令初始化一個 npm 專案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm init -y
npm init -y
npm init -y

這將建立一個基本的 package.json 檔案。

建立基本 package.json 檔案

建立基本 package.json 檔案

4. 安裝依賴項

在命令列工具中鍵入以下命令:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install @wordpress/plugins @wordpress/scripts --save-dev
npm install @wordpress/plugins @wordpress/scripts --save-dev
npm install @wordpress/plugins @wordpress/scripts --save-dev
  • @wordpress/plugins安裝WordPress 的 plugins 模組
  • @wordpress/scripts安裝用於 WordPress 開發的可重用指令碼集合。

一個新的 node_modules 資料夾應該已經新增到你的專案中。

現在,開啟 package.json,更新 scripts 如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"name": "my-sidebar-plugin",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@wordpress/plugins": "^7.14.0",
"@wordpress/scripts": "^30.7.0"
}
}
{ "name": "my-sidebar-plugin", "version": "1.0.0", "main": "index.js", "scripts": { "build": "wp-scripts build", "start": "wp-scripts start" }, "keywords": [], "author": "", "license": "ISC", "description": "", "devDependencies": { "@wordpress/plugins": "^7.14.0", "@wordpress/scripts": "^30.7.0" } }
{
"name": "my-sidebar-plugin",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@wordpress/plugins": "^7.14.0",
"@wordpress/scripts": "^30.7.0"
}
}

現在可以檢查外掛資料夾了:

Visual Studio Code 中的外掛專案

Visual Studio Code 中的外掛專案

5. 建立外掛檔案

在外掛目錄下新建一個 .php 檔案,檔名與資料夾相同。在我們的例子中,檔名是 my-sidebar-plugin.php

開啟檔案並貼上以下程式碼,以便在伺服器上註冊外掛:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/**
* Plugin Name: My Sidebar Plugin
*/
function my_sidebar_plugin_register_script() {
wp_enqueue_script(
'my_sidebar_plugin_script',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-plugins', 'wp-edit-post' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
);
}
add_action( 'enqueue_block_editor_assets', 'my_sidebar_plugin_register_script' );
<?php /** * Plugin Name: My Sidebar Plugin */ function my_sidebar_plugin_register_script() { wp_enqueue_script( 'my_sidebar_plugin_script', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-plugins', 'wp-edit-post' ), filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' ) ); } add_action( 'enqueue_block_editor_assets', 'my_sidebar_plugin_register_script' );
<?php
/**
* Plugin Name: My Sidebar Plugin
*/
function my_sidebar_plugin_register_script() {
wp_enqueue_script(
'my_sidebar_plugin_script',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-plugins', 'wp-edit-post' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
);
}
add_action( 'enqueue_block_editor_assets', 'my_sidebar_plugin_register_script' );

接下來,在外掛目錄下建立一個 src 資料夾。在其中建立一個新的 index.js 檔案,程式碼如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { registerPlugin } from '@wordpress/plugins';
import { PluginSidebar } from '@wordpress/edit-post';
const MyPluginSidebar = () => (
<PluginSidebar
name="my-sidebar-plugin"
title="My Sidebar Plugin"
>
<div>
Hello my friends!
</div>
</PluginSidebar>
);
registerPlugin( 'my-sidebar-plugin', {
render: MyPluginSidebar,
} );
import { registerPlugin } from '@wordpress/plugins'; import { PluginSidebar } from '@wordpress/edit-post'; const MyPluginSidebar = () => ( <PluginSidebar name="my-sidebar-plugin" title="My Sidebar Plugin" > <div> Hello my friends! </div> </PluginSidebar> ); registerPlugin( 'my-sidebar-plugin', { render: MyPluginSidebar, } );
import { registerPlugin } from '@wordpress/plugins';
import { PluginSidebar } from '@wordpress/edit-post';
const MyPluginSidebar = () => (
<PluginSidebar
name="my-sidebar-plugin"
title="My Sidebar Plugin"
>
<div>
Hello my friends!
</div>
</PluginSidebar>
);
registerPlugin( 'my-sidebar-plugin', {
render: MyPluginSidebar,
} );

6. 編譯程式碼

現在就差編譯了。返回命令列並執行以下命令:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm run build
npm run build
npm run build

這會建立一個包含專案壓縮檔案的 build 資料夾。

VSC 中的外掛專案資料夾

VSC 中的外掛專案資料夾

完成後,導航到 WordPress 面板中的外掛介面,啟用外掛。建立一個新的文章或頁面,點選右上角的外掛圖示,顯示自定義側邊欄。

文章編輯器中的自定義側邊欄

文章編輯器中的自定義側邊欄

7. 開發和構建

我們將 index.js 檔案放在 src 資料夾中。在 WordPress 外掛和主題開發中,使用 src 資料夾是一種常見的慣例,這樣可以讓其他開發人員更容易理解您的程式碼。

將 JS 程式碼放在 src 資料夾後,您就可以使用 npm start 或 npm run start 命令啟動開發環境,該環境會監控指令碼並在必要時自動重新編譯程式碼。開發完成後,使用 npm build 或 npm run build 命令會將 JavaScript 程式碼編譯到 build 資料夾中,其中將包含為生產而優化的程式碼。

現在,讓我們學以致用,修改上一節中建立的外掛,在文章編輯器側邊欄中新增一個新面板,用於管理自定義欄位。

如何建立附加側邊欄來管理文章元欄位

我們的目標是建立一個自定義側邊欄,其中包含一個面板和一個文字欄位,用於新增和編輯自定義元欄位。

在開始之前,我們應該提到,我們可以使用自定義元欄來實現同樣的效果。在 WordPress 6.7 中,元方框得到了升級,現在可以與區塊編輯器完全相容,所以你可能會問,為什麼要用自定義側邊欄而不是元方框來管理元欄位。原因是側邊欄允許你利用內建元件。這可以幫助你建立更友好的介面,並提供使用者熟悉的強大控制元件。

下面是建立自定義側邊欄的過程,它允許你在編輯器中管理自定義欄位。

my-sidebar-plugin.php

步驟 1:註冊文章元

首先,您需要註冊元欄位。在外掛主檔案中新增以下程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function my_sidebar_plugin_register_meta() {
register_post_meta(
'post',
'meta_fields_book_title',
array(
'show_in_rest' => true,
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'label' => __( 'Book title', 'my-sidebar-plugin' ),
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
}
)
);
}
add_action( 'init', 'my_sidebar_plugin_register_meta' );
function my_sidebar_plugin_register_meta() { register_post_meta( 'post', 'meta_fields_book_title', array( 'show_in_rest' => true, 'type' => 'string', 'single' => true, 'sanitize_callback' => 'sanitize_text_field', 'label' => __( 'Book title', 'my-sidebar-plugin' ), 'auth_callback' => function() { return current_user_can( 'edit_posts' ); } ) ); } add_action( 'init', 'my_sidebar_plugin_register_meta' );
function my_sidebar_plugin_register_meta() {
register_post_meta(
'post',
'meta_fields_book_title', 
array(
'show_in_rest' => true,
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'label' => __( 'Book title', 'my-sidebar-plugin' ),
'auth_callback' => function() { 
return current_user_can( 'edit_posts' );
}
)
);
}
add_action( 'init', 'my_sidebar_plugin_register_meta' );

register_post_meta 函式接受三個引數:

  • 要註冊元關鍵字的文章型別。如果設定為空字串,就會在所有現有的文章型別中註冊元關鍵字。
  • 要註冊的元鍵。請注意,我們沒有在元鍵開頭使用下劃線。在元鍵前加上下劃線會隱藏自定義欄位,所以你可能想在元框中使用它。不過,隱藏自定義欄位會導致元欄位無法通過區塊繫結 API 在文章內容中使用。
  • 引數陣列。請注意,必須將 show_in_rest 設定為 true。這樣就能將元欄位公開給 Rest API,並允許我們將元欄位繫結到區塊屬性。有關其他屬性,請參閱函式參考

步驟 2:註冊元框

為確保外掛的向後相容性,您需要註冊一個自定義元框,以便使用者即使使用經典編輯器也能管理自定義欄位。在外掛的 PHP 檔案中新增以下程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* Register meta box
*
* @link https://developer.wordpress.org/reference/functions/add_meta_box/
*
*/
function my_sidebar_plugin_register_meta_box(){
add_meta_box(
'book_meta_box', // Unique ID
__( 'Book details' ), // Box title
'my_sidebar_plugin_meta_box_callback', // Content callback
array( 'post' ), // Post types
'advanced', // context
'default', // priority
array('__back_compat_meta_box' => true) // hide the meta box in Gutenberg
);
}
add_action( 'add_meta_boxes', 'my_sidebar_plugin_register_meta_box' );
/** * Register meta box * * @link https://developer.wordpress.org/reference/functions/add_meta_box/ * */ function my_sidebar_plugin_register_meta_box(){ add_meta_box( 'book_meta_box', // Unique ID __( 'Book details' ), // Box title 'my_sidebar_plugin_meta_box_callback', // Content callback array( 'post' ), // Post types 'advanced', // context 'default', // priority array('__back_compat_meta_box' => true) // hide the meta box in Gutenberg ); } add_action( 'add_meta_boxes', 'my_sidebar_plugin_register_meta_box' );
/**
* Register meta box
* 
* @link https://developer.wordpress.org/reference/functions/add_meta_box/
* 
*/
function my_sidebar_plugin_register_meta_box(){
add_meta_box(
'book_meta_box', // Unique ID
__( 'Book details' ), // Box title
'my_sidebar_plugin_meta_box_callback', // Content callback
array( 'post' ), // Post types
'advanced', // context
'default', // priority
array('__back_compat_meta_box' => true) // hide the meta box in Gutenberg
);
}
add_action( 'add_meta_boxes', 'my_sidebar_plugin_register_meta_box' );

現在宣告構建表單的回撥:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* Build meta box form
*
* @link https://developer.wordpress.org/reference/functions/wp_nonce_field/
* @link https://developer.wordpress.org/reference/functions/get_post_meta/
*
*/
function my_sidebar_plugin_meta_box_callback( $post ){
wp_nonce_field( 'my_sidebar_plugin_save_meta_box_data', 'my_sidebar_plugin_meta_box_nonce' );
$title = get_post_meta( $post->ID, 'meta_fields_book_title', true );
?>
<div class="inside">
<p><strong><?php echo __( 'Book title', 'my-sidebar-plugin' ); ?></strong></p>
<p><input type="text" id="meta_fields_book_title" name="meta_fields_book_title" value="<?php echo esc_attr( $title ); ?>" /></p>
</div>
<?php
}
/** * Build meta box form * * @link https://developer.wordpress.org/reference/functions/wp_nonce_field/ * @link https://developer.wordpress.org/reference/functions/get_post_meta/ * */ function my_sidebar_plugin_meta_box_callback( $post ){ wp_nonce_field( 'my_sidebar_plugin_save_meta_box_data', 'my_sidebar_plugin_meta_box_nonce' ); $title = get_post_meta( $post->ID, 'meta_fields_book_title', true ); ?> <div class="inside"> <p><strong><?php echo __( 'Book title', 'my-sidebar-plugin' ); ?></strong></p> <p><input type="text" id="meta_fields_book_title" name="meta_fields_book_title" value="<?php echo esc_attr( $title ); ?>" /></p> </div> <?php }
/**
* Build meta box form
* 
* @link https://developer.wordpress.org/reference/functions/wp_nonce_field/
* @link https://developer.wordpress.org/reference/functions/get_post_meta/
* 
*/
function my_sidebar_plugin_meta_box_callback( $post ){
wp_nonce_field( 'my_sidebar_plugin_save_meta_box_data', 'my_sidebar_plugin_meta_box_nonce' );
$title = get_post_meta( $post->ID, 'meta_fields_book_title', true );
?>
<div class="inside">
<p><strong><?php echo __( 'Book title', 'my-sidebar-plugin' ); ?></strong></p>
<p><input type="text" id="meta_fields_book_title" name="meta_fields_book_title" value="<?php echo esc_attr( $title ); ?>" /></p>
</div>
<?php
}

接下來,編寫將元欄位儲存到資料庫的函式:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* Save metadata
*
* @link https://developer.wordpress.org/reference/functions/wp_verify_nonce/
* @link https://developer.wordpress.org/reference/functions/current_user_can/
* @link https://developer.wordpress.org/reference/functions/sanitize_text_field/
* @link https://developer.wordpress.org/reference/functions/update_post_meta/
*
*/
function my_sidebar_plugin_save_meta_box_data( $post_id ) {
if ( ! isset( $_POST['my_sidebar_plugin_meta_box_nonce'] ) )
return;
if ( ! wp_verify_nonce( $_POST['my_sidebar_plugin_meta_box_nonce'], 'my_sidebar_plugin_save_meta_box_data' ) )
return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( ! current_user_can( 'edit_post', $post_id ) )
return;
if ( ! isset( $_POST['meta_fields_book_title'] ) )
return;
$title = sanitize_text_field( $_POST['meta_fields_book_title'] );
update_post_meta( $post_id, 'meta_fields_book_title', $title );
}
add_action( 'save_post', 'my_sidebar_plugin_save_meta_box_data' );
/** * Save metadata * * @link https://developer.wordpress.org/reference/functions/wp_verify_nonce/ * @link https://developer.wordpress.org/reference/functions/current_user_can/ * @link https://developer.wordpress.org/reference/functions/sanitize_text_field/ * @link https://developer.wordpress.org/reference/functions/update_post_meta/ * */ function my_sidebar_plugin_save_meta_box_data( $post_id ) { if ( ! isset( $_POST['my_sidebar_plugin_meta_box_nonce'] ) ) return; if ( ! wp_verify_nonce( $_POST['my_sidebar_plugin_meta_box_nonce'], 'my_sidebar_plugin_save_meta_box_data' ) ) return; if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( ! current_user_can( 'edit_post', $post_id ) ) return; if ( ! isset( $_POST['meta_fields_book_title'] ) ) return; $title = sanitize_text_field( $_POST['meta_fields_book_title'] ); update_post_meta( $post_id, 'meta_fields_book_title', $title ); } add_action( 'save_post', 'my_sidebar_plugin_save_meta_box_data' );
/**
* Save metadata
* 
* @link https://developer.wordpress.org/reference/functions/wp_verify_nonce/
* @link https://developer.wordpress.org/reference/functions/current_user_can/
* @link https://developer.wordpress.org/reference/functions/sanitize_text_field/
* @link https://developer.wordpress.org/reference/functions/update_post_meta/
* 
*/
function my_sidebar_plugin_save_meta_box_data( $post_id ) {
if ( ! isset( $_POST['my_sidebar_plugin_meta_box_nonce'] ) )
return;
if ( ! wp_verify_nonce( $_POST['my_sidebar_plugin_meta_box_nonce'], 'my_sidebar_plugin_save_meta_box_data' ) )
return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( ! current_user_can( 'edit_post', $post_id ) )
return;
if ( ! isset( $_POST['meta_fields_book_title'] ) )
return;
$title = sanitize_text_field( $_POST['meta_fields_book_title'] );
update_post_meta( $post_id, 'meta_fields_book_title', $title );
}
add_action( 'save_post', 'my_sidebar_plugin_save_meta_box_data' );

由於超出了本文的討論範圍,我們將不再深入探討這些程式碼,但您可以通過函式標題中的連結找到所需的全部資訊。

最後,我們需要啟動外掛的 index.js 檔案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function my_sidebar_plugin_register_script() {
wp_enqueue_script(
'my_sidebar_plugin_script',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-plugins', 'wp-edit-post' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
);
}
add_action( 'enqueue_block_editor_assets', 'my_sidebar_plugin_register_script' );
function my_sidebar_plugin_register_script() { wp_enqueue_script( 'my_sidebar_plugin_script', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-plugins', 'wp-edit-post' ), filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' ) ); } add_action( 'enqueue_block_editor_assets', 'my_sidebar_plugin_register_script' );
function my_sidebar_plugin_register_script() {
wp_enqueue_script(
'my_sidebar_plugin_script',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-plugins', 'wp-edit-post' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
);
}
add_action( 'enqueue_block_editor_assets', 'my_sidebar_plugin_register_script' );

這就是 PHP 檔案的全部內容。接下來,我們需要編寫 JS 程式碼。

index.js

您的index.js位於src資料夾中,該資料夾是您在開發階段儲存 JS 檔案的地方。

開啟index.js,新增以下 import 宣告

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';
import { PluginSidebar } from '@wordpress/editor';
import { PanelBody, PanelRow, TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { __ } from '@wordpress/i18n'; import { registerPlugin } from '@wordpress/plugins'; import { PluginSidebar } from '@wordpress/editor'; import { PanelBody, PanelRow, TextControl } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { useEntityProp } from '@wordpress/core-data';
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';
import { PluginSidebar } from '@wordpress/editor';
import { PanelBody, PanelRow, TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';

您需要使用這些資源來建立帶有所需控制元件的側邊欄。

接下來,您需要構建側邊欄元件:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const MyPluginSidebar = () => {
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const bookTitle = meta ? meta[ 'meta_fields_book_title' ] : '';
const updateBookTitleMetaValue = ( newValue ) => {
setMeta( { ...meta, meta_fields_book_title: newValue } );
};
if ( postType === 'post' ) {
return (
<PluginSidebar
name="my-sidebar-plugin"
icon="book"
title="My plugin sidebar"
>
<PanelBody title="Book details" initialOpen={ true }>
<PanelRow>
<TextControl
value={ bookTitle }
label={ __( "Book title" ) }
onChange={ updateBookTitleMetaValue }
__nextHasNoMarginBottom
/>
</PanelRow>
</PanelBody>
</PluginSidebar>
);
}
};
registerPlugin( 'my-sidebar-plugin', {
render: MyPluginSidebar,
} );
const MyPluginSidebar = () => { const postType = useSelect( ( select ) => select( 'core/editor' ).getCurrentPostType(), [] ); const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' ); const bookTitle = meta ? meta[ 'meta_fields_book_title' ] : ''; const updateBookTitleMetaValue = ( newValue ) => { setMeta( { ...meta, meta_fields_book_title: newValue } ); }; if ( postType === 'post' ) { return ( <PluginSidebar name="my-sidebar-plugin" icon="book" title="My plugin sidebar" > <PanelBody title="Book details" initialOpen={ true }> <PanelRow> <TextControl value={ bookTitle } label={ __( "Book title" ) } onChange={ updateBookTitleMetaValue } __nextHasNoMarginBottom /> </PanelRow> </PanelBody> </PluginSidebar> ); } }; registerPlugin( 'my-sidebar-plugin', { render: MyPluginSidebar, } );
const MyPluginSidebar = () => {
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const bookTitle = meta ? meta[ 'meta_fields_book_title' ] : '';
const updateBookTitleMetaValue = ( newValue ) => {
setMeta( { ...meta, meta_fields_book_title: newValue } );
};
if ( postType === 'post' ) {
return (
<PluginSidebar
name="my-sidebar-plugin"
icon="book"
title="My plugin sidebar"
>
<PanelBody title="Book details" initialOpen={ true }>
<PanelRow>
<TextControl 
value={ bookTitle }
label={ __( "Book title" ) }
onChange={ updateBookTitleMetaValue }
__nextHasNoMarginBottom
/>
</PanelRow>
</PanelBody>
</PluginSidebar>
);
}
};
registerPlugin( 'my-sidebar-plugin', {
render: MyPluginSidebar,
} );

registerPlugin 函式用於註冊外掛並渲染名為 MyPluginSidebar 的元件。

函式 MyPluginSidebar 宣告瞭幾個常量,並返回元件的 JSX 程式碼。

  • useSelect 是一個自定義鉤子,用於從已註冊的選擇器中獲取道具。我們用它來獲取當前的文章型別。另請參閱 WordPress 開發者部落格中的這篇博文
  • useEntityProp 返回一個元欄位陣列和一個用於設定新元值的 setter 函式。另請參閱線上參考資料
  • updateBookTitleMetaValue 是一個儲存 bookTitle 元欄位值的事件處理程式。

我們使用了一些內建元件來建立側邊欄:

  • PluginSidebar 允許您在“文章”或“網站”編輯器螢幕的工具欄上新增專案。(請參閱該元件的參考資料。)
  • PanelBody 可建立一個可摺疊的容器,並可切換開啟或關閉。(請參閱該元件的參考資料。)
  • PanelRowPanelBody 中行的通用容器。(請參閱該元件的參考資料。)
  • TextControl 是一個單行欄位,可用於自由輸入文字。(請參閱該元件的參考資料。)

現在執行npm run build命令,啟用外掛,然後建立一個新的文章。頂部側邊欄會出現一個新書圖示。點選該圖示即可顯示外掛側邊欄。

帶有元欄位的自定義側邊欄

帶有元欄位的自定義側邊欄

如果您不需要新的側邊欄,但想在內建的文章側邊欄中顯示自定義欄位,該怎麼辦?您只需將 PluginSidebar 替換為 PluginDocumentSettingPanel 即可。這就是你的新 index.js 檔案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { PanelBody, PanelRow, TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
const MyPluginSidebar = () => {
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const bookTitle = meta ? meta[ 'meta_fields_book_title' ] : '';
const updateBookTitleMetaValue = ( newValue ) => {
setMeta( { ...meta, meta_fields_book_title: newValue } );
};
if ( postType === 'post' ) {
return (
<PluginDocumentSettingPanel
name="my-sidebar-plugin"
title="Book details"
className="my-sidebar-plugin"
>
<PanelRow>
<TextControl
value={ bookTitle }
label={ __( "Book title" ) }
onChange={ updateBookTitleMetaValue }
__nextHasNoMarginBottom
/>
</PanelRow>
</PluginDocumentSettingPanel>
);
}
};
registerPlugin( 'my-sidebar-plugin', {
render: MyPluginSidebar,
} );
import { __ } from '@wordpress/i18n'; import { registerPlugin } from '@wordpress/plugins'; import { PluginDocumentSettingPanel } from '@wordpress/edit-post'; import { PanelBody, PanelRow, TextControl } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { useEntityProp } from '@wordpress/core-data'; const MyPluginSidebar = () => { const postType = useSelect( ( select ) => select( 'core/editor' ).getCurrentPostType(), [] ); const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' ); const bookTitle = meta ? meta[ 'meta_fields_book_title' ] : ''; const updateBookTitleMetaValue = ( newValue ) => { setMeta( { ...meta, meta_fields_book_title: newValue } ); }; if ( postType === 'post' ) { return ( <PluginDocumentSettingPanel name="my-sidebar-plugin" title="Book details" className="my-sidebar-plugin" > <PanelRow> <TextControl value={ bookTitle } label={ __( "Book title" ) } onChange={ updateBookTitleMetaValue } __nextHasNoMarginBottom /> </PanelRow> </PluginDocumentSettingPanel> ); } }; registerPlugin( 'my-sidebar-plugin', { render: MyPluginSidebar, } );
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { PanelBody, PanelRow, TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
const MyPluginSidebar = () => {
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const bookTitle = meta ? meta[ 'meta_fields_book_title' ] : '';
const updateBookTitleMetaValue = ( newValue ) => {
setMeta( { ...meta, meta_fields_book_title: newValue } );
};
if ( postType === 'post' ) {
return (
<PluginDocumentSettingPanel 
name="my-sidebar-plugin"
title="Book details" 
className="my-sidebar-plugin"
>
<PanelRow>
<TextControl 
value={ bookTitle }
label={ __( "Book title" ) }
onChange={ updateBookTitleMetaValue }
__nextHasNoMarginBottom
/>
</PanelRow>
</PluginDocumentSettingPanel>
);
}
};
registerPlugin( 'my-sidebar-plugin', {
render: MyPluginSidebar,
} );

下圖顯示了結果。

文章側邊欄中的自定義設定面板

文章側邊欄中的自定義設定面板

例項:區塊樣板覆蓋,實現工作流程自動化

現在,您可以為自定義欄位新增一個值,該值可通過區塊繫結 API 與區塊屬性一起使用。例如,您可以在內容中新增一個段落區塊,並將自定義欄位繫結到段落的 content 屬性上。

將元欄位繫結到區塊屬性

將元欄位繫結到區塊屬性

您可以自由更改自定義欄位的值,這些更改將自動應用到您的段落內容中。

如果您想知道自定義欄位和區塊繫結是否還有其他功能,答案是肯定的!通過區塊樣板和區塊繫結 API,您可以自動完成整個內容建立過程。

要獲得線索,至少要建立一個包含標題或段落的樣板。在本例中,我們建立的區塊樣板包含一個欄目區塊、一個影象、一個標題和幾個行區塊,每個行區塊包含兩個段落。

帶有一個圖片、一個標題和兩行的欄目區塊

帶有一個圖片、一個標題和兩行的欄目區塊

對佈局滿意後,選擇包裝元素並建立同步樣板。

建立樣板

建立樣板

為區塊樣板新增名稱和類別,並確保同步。

新增新樣板

新增新樣板

下一步,如果您在“文章”編輯器中建立了樣板,請選擇該樣板並單擊區塊工具欄中的“編輯原始”。您也可以導航到網站編輯器的樣板部分,在我的樣板下或您之前設定的樣板類別中找到該樣板。

開啟程式碼編輯器,找到要繫結到自定義欄位的區塊。在區塊分隔符中新增以下程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!-- wp:heading {
"metadata":{
"bindings":{
"content":{
"source":"core/post-meta",
"args":{
"key":"meta_fields_book_title"
}
}
}
}
} -->
<!-- wp:heading { "metadata":{ "bindings":{ "content":{ "source":"core/post-meta", "args":{ "key":"meta_fields_book_title" } } } } } -->
<!-- wp:heading {
"metadata":{
"bindings":{
"content":{
"source":"core/post-meta",
"args":{
"key":"meta_fields_book_title"
}
}
}
}
} -->

程式碼編輯器中的區塊樣板

程式碼編輯器中的區塊樣板

儲存樣板並建立新文章。將樣板新增到內容中,併為自定義欄位設定一個值。您會看到該值自動應用到您的樣板中。

同步樣板中的繫結標題

同步樣板中的繫結標題

現在,你可以玩轉這個外掛了。藉助自定義欄位和區塊繫結 API,您可以新增更多的欄位和控制元件來自動填充佈局。

小結

開發自定義區塊可能很有挑戰性。但是,如果使用區塊樣板可以做得更多,還需要構建區塊嗎?

隨著區塊樣板的發展和強大的開發人員功能(如區塊繫結 API)的引入,建立自定義區塊來構建複雜而實用的網站已不再必要。一個簡單的外掛和一個區塊樣板就能有效地自動完成大部分工作流程。

本教學演示瞭如何通過外掛為 WordPress 文章編輯器新增功能。然而,我們在這篇文章中介紹的只是WordPress目前提供的強大功能的皮毛。

您是否已經探索過這些功能併為 WordPress 編輯器新增了功能?如果是,請在下面的評論區分享您的經驗和見解。

評論留言