博客

超越基础块:创建自定义 Gutenberg 块以增强 WordPress 功能

通过学习创建自己的自定义 Gutenberg 块,充分释放 WordPress 块编辑器的全部潜力。本指南提供了实用的步骤、代码示例和最佳实践,用于扩展您网站的功能和设计。

摘要

WordPress 块编辑器 Gutenberg 凭借其模块化块系统彻底改变了内容创建。虽然核心块提供了通用性,但自定义块对于独特的网站功能和品牌推广至关重要。本文将指导您完成开发自己的 Gutenberg 块的过程,涵盖块注册、属性和渲染等基本概念。我们将探讨实际示例,讨论代码组织和安全性的最佳实践,并重点介绍自定义块如何与 WordPress 的架构和钩子集成。通过掌握自定义块开发,您可以显著增强 WordPress 网站的功能和用户体验。

超越基础块:创建自定义 Gutenberg 块以增强 WordPress 功能

Gutenberg 块编辑器在 WordPress 5.0 中的推出标志着内容创建和管理方式的重大转变。Gutenberg 摒弃了经典编辑器线性方法,引入了一种模块化系统,内容通过离散的“块”构建。虽然默认块集涵盖了广泛的常见需求,但许多网站需要独特的功能、特定的设计元素或超出可用范围的集成。这就是自定义 Gutenberg 块开发发挥作用的地方,它提供了一种强大的方式来扩展 WordPress 的功能,并精确地满足您项目的需求。

开发自定义块可让您创建可重用组件,从而简化内容创建者(编辑器)的工作流程,确保品牌一致性,并在编辑器界面内直接实现复杂功能。本指南将引导您完成整个过程,从理解基本概念到实施健壮且可维护的自定义块的最佳实践。

理解块编辑器的架构

在深入开发之前,掌握 Gutenberg 及其块在 WordPress 生态系统中的功能至关重要。WordPress 本身建立在模块化的 PHP 和 MySQL 架构之上。主题控制演示,插件添加功能。Gutenberg 作为 WordPress 的核心功能,无缝集成到此结构中。它利用 JavaScript(主要是 React)来实现动态的浏览器内编辑体验,而 PHP 则处理服务器端注册和渲染。

自定义块本质上是注册到 WordPress 的 JavaScript 组件。当用户将自定义块添加到帖子或页面时,Gutenberg 会在数据库中存储其配置(属性)。在前端渲染帖子时,WordPress 使用 PHP 来解释此配置并输出适当的 HTML,通常会利用相同的 JavaScript 组件或单独的 PHP 模板。

自定义块的核心组件

每个自定义 Gutenberg 块的核心都包含几个关键部分:

  1. 注册: 这是告知 WordPress 新块的过程。它涉及定义其名称、标题、图标和其他元数据。这主要使用 JavaScript 的 registerBlockType 函数完成。
  2. 属性: 这些是与块关联的数据字段。将它们视为用户可以为块的特定实例修改的设置或属性(例如,文本内容、图像 URL、颜色选择)。属性在块的 JavaScript 注册中定义。
  3. 编辑函数: 此 JavaScript 函数定义块在 Gutenberg 编辑器中的外观和行为。在这里,您可以构建内容创建者将用于配置块的交互式 UI。
  4. 保存函数: 此 JavaScript 函数定义将保存到数据库并在网站前端渲染的静态 HTML 标记。它应反映块属性的当前状态。

分步操作:创建您的第一个自定义块

让我们创建一个简单的自定义块,用于显示带有标题和按钮的“号召性用语”(CTA)。本示例将重点介绍块注册和编辑的基本 JavaScript 方面,并假定已设置了基本的 WordPress 开发环境。

先决条件:

  • 本地 WordPress 开发环境。
  • JavaScript、React 和 PHP 的基本理解。
  • 已安装 Node.js 和 npm(或 yarn)用于资源编译。

1. 项目设置:

自定义块通常作为插件的一部分进行开发。创建一个新的插件文件(例如,my-custom-blocks/my-custom-blocks.php)和用于块的 JavaScript 文件(例如,src/index.js)。您还需要一个构建过程来编译 JavaScript。一种常见的方法是使用 @wordpress/scripts,它提供了一种方便的方式来处理编译。

在插件的根目录中,创建一个 package.json 文件:

{
  "name": "my-custom-blocks",
  "version": "1.0.0",
  "description": "A plugin for custom Gutenberg blocks.",
  "main": "index.js",
  "scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start"
  },
  "keywords": ["wordpress", "gutenberg", "block"],
  "author": "Your Name",
  "license": "GPL-2.0-or-later",
  "devDependencies": {
    "@wordpress/scripts": "^26.0.0" 
  }
}

安装依赖项:npm install

2. 注册块(JavaScript):

src/index.js 文件中,您将使用 @wordpress/blocks 包中的 registerBlockType

import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';

// Import components for the editor
import { Edit } from './edit';
import { Save } from './save';

registerBlockType( 'my-custom-blocks/cta', {
    title: __( 'Call to Action', 'my-custom-blocks' ),
    icon: 'megaphone',
    category: 'widgets',
    attributes: {
        headline: {
            type: 'string',
            default: '',
        },
        buttonText: {
            type: 'string',
            default: 'Learn More',
        },
        buttonUrl: {
            type: 'string',
            default: '#',
        },
    },
    edit: Edit,
    save: Save,
} );

3. 定义编辑器界面(src/edit.js):

此组件处理块在编辑器中的外观和功能。

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, TextControl } from '@wordpress/components';

export const Edit = ( { attributes, setAttributes } ) => {
    const blockProps = useBlockProps();

    const onChangeHeadline = ( newHeadline ) => {
        setAttributes( { headline: newHeadline } );
    };

    const onChangeButtonText = ( newButtonText ) => {
        setAttributes( { buttonText: newButtonText } );
    };

    const onChangeButtonUrl = ( newButtonUrl ) => {
        setAttributes( { buttonUrl: newButtonUrl } );
    };

    return (
        <>
            <InspectorControls>
                <PanelBody title={ __( 'Button Settings', 'my-custom-blocks' ) }>
                    <TextControl
                        label={ __( 'Button Text', 'my-custom-blocks' ) }
                        value={ attributes.buttonText }
                        onChange={ onChangeButtonText }
                    />
                    <TextControl
                        label={ __( 'Button URL', 'my-custom-blocks' ) }
                        value={ attributes.buttonUrl }
                        onChange={ onChangeButtonUrl }
                    />
                </PanelBody>
            </InspectorControls>
            <div { ...blockProps }>
                <RichText
                    tagName="h3"
                    placeholder={ __( 'Enter your headline here...', 'my-custom-blocks' ) }
                    value={ attributes.headline }
                    onChange={ onChangeHeadline }
                    allowedFormats={ [ 'core/bold', 'core/italic' ] }
                />
                <a href={ attributes.buttonUrl } className="wp-element-button">
                    { attributes.buttonText }
                </a>
            </div>
        </>
    );
};

4. 定义保存函数(src/save.js):

此函数确定前端的 HTML 输出。

import { useBlockProps, RichText } from '@wordpress/block-editor';

export const Save = ( { attributes } ) => {
    const blockProps = useBlockProps.save();

    return (
        <div { ...blockProps }>
            <RichText.Content
                tagName="h3"
                value={ attributes.headline }
            />
            <a href={ attributes.buttonUrl } className="wp-element-button">
                { attributes.buttonText }
            </a>
        </div>
    );
};

5. 排队块脚本(PHP):

在主插件文件(my-custom-blocks.php)中,您需要注册并排队您的编译后的 JavaScript 文件。

<?php
/**
 * Plugin Name: My Custom Blocks
 * Description: Adds custom Gutenberg blocks.
 * Version: 1.0
 * Author: Your Name
 */

function my_custom_blocks_register_block() {
    // Automatically loads the block.json file and enqueues the script.
    register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'my_custom_blocks_register_block' );
?>

6. 构建资源:

在插件目录中运行 npm run build。这将把您的 JavaScript 编译到 build 文件夹中。

现在,在 WordPress 中激活该插件。您应该会在编辑器中看到您的“号召性用语”块!

自定义块开发的最佳实践

开发自定义块不仅仅是使其功能正常。遵循最佳实践可确保您的块安全、高效、可访问且可维护。

  • 命名空间: 始终为您的块使用唯一的命名空间(例如,my-custom-blocks/cta)。这可以防止与其他块发生冲突。registerBlockType 函数处理此问题。
  • 代码组织: 保持 JavaScript 和 PHP 代码整洁有序。对于复杂的块,请考虑将 JavaScript 分解为更小、可重用的组件。
  • 安全性:
    • 清理: 在将数据保存到数据库(尤其是用户生成的内容)时,请务必对其进行清理。WordPress 提供了 sanitize_text_fieldesc_url 等函数。
    • 转义: 在将数据输出到浏览器时,请务必对其进行转义,以防止跨站脚本(XSS)攻击。使用 esc_htmlesc_attresc_url 等函数。
    • Nonces: 对于与您的块相关的任何 AJAX 请求或表单提交,请使用 nonces 来验证请求是否源自合法的 WordPress 源。
  • 国际化(i18n): 对 JavaScript 中所有面向用户的字符串使用 __()_x() 函数(来自 @wordpress/i18n)。这使得您的块可以翻译。
  • 可访问性: 确保每个人都可以使用您的块。使用语义化 HTML,在必要时提供 ARIA 属性,并使用屏幕阅读器进行测试。
  • 性能:
    • 延迟加载: 对于加载重型资源或复杂数据的块,请考虑实现延迟加载技术。
    • 高效渲染: 优化您的 save 函数和任何服务器端渲染,使其尽可能高效。
    • 资源排队: 仅为您需要的块排队脚本和样式。使用 enqueue_block_styleenqueue_block_script_handle 处理块特定的资源。
  • 模块化和可扩展性: 利用插件中的 WordPress 钩子(操作和过滤器)允许其他插件或主题修改您的块的行为或输出。
  • block.json 对于更复杂的块,请使用 block.json 文件来声明块元数据、依赖项、样式和脚本句柄。这是块开发的现代标准,可简化资源管理。

与 WordPress 架构集成

自定义块不是孤立的实体。它们与 WordPress 的核心架构深度集成:

  • 钩子: 您可以在插件中使用 PHP 操作和过滤器来修改块注册,有条件地添加自定义样式或脚本,甚至更改核心块的渲染输出。例如,您可以使用 block_type_metadata_settings 过滤器来修改已注册块的设置。
  • 主题集成: 基于块的主题和全站点编辑(FSE)在很大程度上依赖于块。自定义块可以设计成与 FSE 模板无缝集成,允许用户使用一致的基于块的工作流程构建整个站点。
  • 插件互操作性: 您的自定义块可以与其他插件进行交互。例如,自定义产品块可以从电子商务插件中提取数据,或者自定义图库块可以与特定的媒体库插件集成。

高级概念和注意事项

  • 服务器端渲染(SSR): 对于需要动态数据或最佳由服务器处理的复杂逻辑的块,您可以实现服务器端渲染。这涉及在注册块时在 PHP 中定义 render_callback 函数。
  • 动态块: 使用 SSR 的块通常称为动态块。它们不会将静态 HTML 保存到数据库;相反,它们仅保存其属性,并且 render_callback 在每次页面加载时生成 HTML。
  • 块样式: 您可以为块定义自定义样式,用户可以在编辑器中选择这些样式。
  • 块变体: 创建基础块的变体,以提供具有不同默认设置或外观的预配置版本。
  • 编辑器与前端差异: 请注意,editsave 函数可能需要处理不同的场景。edit 函数用于交互式编辑器体验,而 save 函数用于静态 HTML 输出。有时,您可能需要一个单独的 render_callback 来进行动态前端渲染。

结论

自定义 Gutenberg 块开发是一项强大的技能,它为 WordPress 网站解锁了更高层次的自定义和功能。通过理解核心组件——注册、属性、编辑和保存函数——并遵循安全、性能和可访问性的最佳实践,您可以创建健壮、可重用且用户友好的块。无论您是为客户构建自定义插件还是增强自己的网站,掌握自定义块都将显著提升您的 WordPress 开发能力,让您超越标准产品,打造真正独特的数字体验。

Sources (5)