掌握 WordPress Gutenberg 块编辑器的完整开发指南及进阶实战技巧

3 分钟阅读时间
2026-03-17
2026-06-04
2,423
通过下方链接进行购物时,您无需支付额外费用,我就能获得佣金。.

WordPress 的古騰堡區塊編輯器(Gutenberg Block Editor)徹底改變了內容建立的方式,將頁面構建的靈活性和控制權直接交到了編輯者手中。對於開發者而言,這意味著一個全新的、以 React 和現代 JavaScript 為核心的開發正規化。本文將深入探討如何從零開始建立自定義區塊,並進階到開發動態區塊、應用區塊變體等高階主題,旨在為你提供一份全面的實戰開發指南。

理解區塊編輯器的核心架構

古騰堡編輯器並非一個單一的整體應用,而是一個由多個獨立包(Packages)組成的生態系統。理解其架構是進行有效開發的基礎。

編輯器與資料層的分離

編輯器介面本身與 WordPress 的資料層是分離的。核心的 @wordpress/editor 包提供了編輯器的 UI 元件,而 @wordpress/data 包則實現了類似 Redux 的狀態管理。這種分離使得開發者可以專注於區塊的檢視和互動邏輯,而資料持久化則由 WordPress 的核心機制自動處理。

推荐阅读 掌握 WordPress 自定义文章类型:从创建到发布的完整实践指南

區塊的註冊與生命週期

每個區塊都需要透過 registerBlockType 函式進行註冊。這個函式接受兩個引數:區塊的唯一名稱(如 my-plugin/my-custom-block)和一個包含區塊所有配置資訊的物件。
註冊後,區塊會經歷初始化、渲染、編輯、儲存等生命週期。開發者主要透過定義 edit 以及 save 兩個關鍵函式來控制區塊在編輯器中和在前端的表現。

UltaHost WordPress 主機
30天退款保證,無限頻寬與資料庫,免費的 DDoS 防護,購買3年優惠50%

從零開始建立你的第一個自定義區塊

我們將建立一個簡單的“高亮提示”區塊,它允許使用者新增一個帶有背景色和標題的提示框。

設定開發環境與基礎檔案

首先,確保你的開發環境已準備好。你需要 Node.js 和 npm 環境。在外掛目錄下建立一個新外掛資料夾,例如 my-custom-blocks。在該資料夾中,建立以下核心檔案:
- my-custom-blocks.php (外掛主檔案)
- package.json (用於管理 Node 依賴和構建指令碼)
- src/ 目錄 (用於存放原始碼)
- build/ 目錄 (構建工具輸出目錄,由 WordPress 讀取)

关于 package.json 中,配置構建指令碼並引入 @wordpress/scripts 包,它可以極大地簡化 Webpack、Babel 等工具的配置。

{
  "name": "my-custom-blocks",
  "scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start"
  },
  "devDependencies": {
    "@wordpress/scripts": "^26.0.0"
  }
}

在外掛主檔案 my-custom-blocks.php 中,你需要使用 register_block_type 函式來告知 WordPress 從 build 目錄載入區塊的資產。

推荐阅读 WordPress 主题开发指南:从零开始构建高性能自定义主题

<?php
/**
 * Plugin Name: My Custom Blocks
 */
function my_custom_blocks_register_block() {
    register_block_type( __DIR__ . '/build/highlight-box' );
}
add_action( 'init', 'my_custom_blocks_register_block' );

編寫區塊的 JavaScript 原始碼

关于 src 目錄下建立 highlight-box/index.js 檔案。這是區塊的主入口檔案。

import { registerBlockType } from '@wordpress/blocks';
import { RichText, useBlockProps, InspectorControls, ColorPalette } from '@wordpress/block-editor';
import { PanelBody, PanelRow } from '@wordpress/components';

registerBlockType('my-custom-blocks/highlight-box', {
    title: '高亮提示框',
    icon: 'warning', // 從 Dashicons 中選擇
    category: 'design',
    attributes: {
        title: {
            type: 'string',
            source: 'html',
            selector: '.highlight-title',
        },
        content: {
            type: 'string',
            source: 'html',
            selector: '.highlight-content',
        },
        backgroundColor: {
            type: 'string',
            default: '#fff3cd',
        },
    },
    edit: ({ attributes, setAttributes }) =&gt; {
        const blockProps = useBlockProps();
        const { title, content, backgroundColor } = attributes;

const onChangeTitle = (newTitle) =&gt; {
            setAttributes({ title: newTitle });
        };
        const onChangeContent = (newContent) =&gt; {
            setAttributes({ content: newContent });
        };
        const onChangeBackgroundColor = (newColor) =&gt; {
            setAttributes({ backgroundColor: newColor });
        };

return (
            <>
                <inspectorcontrols>
                    <panelbody title="颜色设置">
                        <panelrow>
                            <colorpalette
                                value="{backgroundColor}"
                                onchange="{onChangeBackgroundColor}"
                            />
                        </panelrow>
                    </panelbody>
                </inspectorcontrols>
                <div {...blockprops} style="{{" backgroundcolor, padding: '20px', borderradius: '5px' }}>
                    <richtext
                        tagname="h3"
                        classname="highlight-title"
                        onchange="{onChangeTitle}"
                        value="{title}"
                        placeholder="输入标题..."
                    />
                    <richtext
                        tagname="p"
                        classname="highlight-content"
                        onchange="{onChangeContent}"
                        value="{content}"
                        placeholder="输入提示内容..."
                    />
                </div>
            </>
        );
    },
    save: ({ attributes }) =&gt; {
        const blockProps = useBlockProps.save();
        const { title, content, backgroundColor } = attributes;
        return (
            <div {...blockprops} style="{{" backgroundcolor, padding: '20px', borderradius: '5px' }}>
                <RichText.Content tagName="h3" className="highlight-title" value={title} />
                <RichText.Content tagName="p" className="highlight-content" value={content} />
            </div>
        );
    },
});

执行 npm start 開始開發模式(監聽檔案變化)或 npm run build 進行生產構建。之後在 WordPress 編輯器中,你就能在“設計”分類下找到並使用這個“高亮提示框”區塊了。

進階開發:動態區塊與伺服器端渲染

靜態區塊的內容被直接儲存在文章內容中。但對於需要實時資料(如最新文章列表、使用者資訊)的區塊,我們需要建立動態區塊。動態區塊在儲存時只儲存一些屬性(如文章數量),前端顯示時透過 PHP 模板動態生成內容。

hostng.com 共享主机
高效能,配备 AMD EPYC CPU、NVMe SSD 存储和 LiteSpeed,全天候 24 小时专业内部支持,先进的安全措施包括 SSL、暴力破解、恶意软件和 DDoS 防护,节省高达 731 TB/月的带宽成本。

將靜態區塊轉換為動態區塊

首先,修改區塊的註冊配置,將 save 函式改為返回 null,並新增一個 render_callback 属性。

// 在 registerBlockType 的配置对象中
save: () => {
    return null; // 动态区块不在内容中保存 HTML
},

然後,在 PHP 端更新註冊程式碼,指定渲染回撥函式。

function my_custom_blocks_register_dynamic_block() {
    register_block_type( __DIR__ . '/build/latest-posts', [
        'render_callback' =&gt; 'my_custom_blocks_render_latest_posts'
    ] );
}
add_action( 'init', 'my_custom_blocks_register_dynamic_block' );

function my_custom_blocks_render_latest_posts( $attributes ) {
    $posts = get_posts( [
        'posts_per_page' =&gt; $attributes['numberOfPosts'] ?? 5,
    ] );

if ( empty( $posts ) ) {
        return '<p>暂无文章。</p>';
    }

$output = '<ul class="wp-block-my-custom-blocks-latest-posts">';
    foreach ( $posts as $post ) {
        $output .= sprintf(
            '<li><a href="/zh-tw/%s/">%s</a></li>',
            esc_url( get_permalink( $post ) ),
            esc_html( get_the_title( $post ) )
        );
    }
    $output .= '</ul>';

return $output;
}

使用區塊模板檔案進行渲染

對於更復雜的動態區塊,推薦使用模板檔案。在外掛目錄建立 templates/latest-posts.php,將上面的渲染邏輯移入該檔案。然後在 render_callback 请将下文翻译成中文,并详细说明翻译过程: ob_get_clean 以及 include 來載入模板,這使 PHP 和 HTML 邏輯更清晰、易於維護。

推荐阅读 WooCommerce 插件使用教程:从安装配置到店铺运营的完整指南

高階主題與最佳實踐

掌握了基礎與動態區塊後,以下主題能讓你開發出更強大、更專業的區塊。

實現區塊的變體功能

區塊變體(Block Variations)允許你基於一個基礎區塊建立多個預設樣式或配置。例如,為“高亮提示框”建立“成功”、“警告”、“錯誤”等變體。

InterServer 共享主机
虚拟主机的月费为1TB+5TB,价格为2.50美元。首月优惠价为1TB+5TB,价格为0.1美元。优惠码为"tryinterserver"。平台提供461个云应用脚本,一键安装便捷。
import { registerBlockVariation } from '@wordpress/blocks';

registerBlockVariation('my-custom-blocks/highlight-box', [
    {
        name: 'success',
        title: '成功提示',
        icon: 'yes-alt',
        attributes: {
            title: '操作成功',
            backgroundColor: '#d4edda',
        },
        isDefault: false,
    },
    {
        name: 'error',
        title: '错误警告',
        icon: 'dismiss',
        attributes: {
            title: '发生错误',
            backgroundColor: '#f8d7da',
        },
    },
]);

利用區塊樣式與編輯器樣式

使用 (注:此处"使用"指的是某种产品或服务的使用情况) registerBlockStyle 函式可以為區塊新增不同的視覺樣式,使用者可以在側邊欄切換。同時,使用 add_editor_style 可以確保編輯器內的預覽與前端樣式保持一致,提供所見即所得的體驗。

效能最佳化與程式碼分割

隨著區塊增多,將所有 JavaScript 打包到一個檔案中會影響載入效能。可以利用 @wordpress/dependency-extraction-webpack-plugin(已包含在 @wordpress/scripts 中)確保正確宣告對 WordPress 包的外部依賴。對於大型外掛,可以考慮按需載入或程式碼分割技術。

总结

古騰堡區塊編輯器的開發是一個融合了現代前端技術(React, JSX, Webpack)和傳統 WordPress PHP 知識的過程。從理解其架構開始,透過建立靜態區塊掌握核心 API,再進階到動態區塊處理動態資料,最後透過區塊變體、樣式等高階功能提升使用者體驗和開發效率。遵循最佳實踐,如清晰的程式碼組織、效能最佳化和充分的國際化準備,你將能構建出強大、可維護且使用者友好的自定義區塊,充分釋放古騰堡編輯器的潛力。

常见问题解答(FAQ)

開發古騰堡區塊必須使用 React 嗎?

是的,目前古騰堡編輯器的官方開發方式完全基於 React。雖然理論上可以使用其他框架,但 WordPress 核心提供的所有元件、鉤子和工具都圍繞 React 生態構建,使用其他框架會帶來極大的複雜性和相容性問題。

如何為我的區塊新增自定義側邊欄控制元件?

您可以使用 <code>InspectorControls</code> 元件。在區塊的 edit 函式中,將其與主預覽內容一同返回。在 <code>InspectorControls</code> 內部,你可以使用 <code>PanelBody</code>、<code>TextControl</code>、<code>SelectControl</code>、<code>RangeControl</code></code> 等来自 @wordpress/components` 包的元件來構建豐富的設定介面。

動態區塊和靜態區塊在效能上有什麼區別?

靜態區塊的 HTML 內容直接儲存在資料庫的帖子內容中,因此前端載入速度很快,但無法包含動態資料。動態區塊在渲染時需要執行 PHP 程式碼查詢資料庫,因此會有輕微的效能開銷,但能提供實時資料。對於不常變化的內容,可以考慮使用靜態區塊結合定期快取策略;對於需要高度實時性的內容,則必須使用動態區塊。

我可以在傳統的小工具區域或文章元框中使用區塊嗎?

可以,這被稱為“區塊小工具”和“區塊元框”。從 WordPress 5.8 開始,小工具區域也完全由古騰堡區塊編輯器驅動。你也可以使用 register_block_type 嗯,我想我可能需要去趟洗手间。 widget_types 引數(或相關 API)來讓區塊在小工具編輯器中可用。對於文章元框,可以使用 `register_post_meta API 並結合區塊來建立更直觀的元資料編輯介面。