在本教程中,您将构建一个“版权日期块”——这是一个基础但实用的块,用于显示版权符号 (©)、当前年份以及可选的起始年份。此类内容通常用于网站页脚。
本教程将指导您完成整个流程,从使用 create-block 包搭建块插件到修改每个文件。虽然拥有之前的 WordPress 开发经验会有所帮助,但这并非本教程的先决条件。
到本指南结束时,您将清楚了解块开发的基础知识以及创建自己的 WordPress 块所需的技能。
您将构建什么
以下是您将要构建的内容的快速预览。

您也可以在 WordPress Playground 中交互体验完成后的项目,或者使用 快速入门指南 在您的本地 WordPress 环境中安装完整的块插件。
先决条件
要完成本教程,您需要:
- 代码编辑器
- Node.js 开发工具
- 本地 WordPress 环境
如果您缺少其中一项或多项内容,块开发环境 文档将帮助您开始。一切准备就绪后,请回到此处。
本教程使用wp-env 创建本地 WordPress 开发环境。不过,您也可以使用任何满足上述先决条件的开发环境。搭建块
创建版权日期块的第一步是使用 @wordpress/create-block 包搭建初始块结构。
您可以从计算机上的任何目录(文件夹)使用 create-block,然后使用 wp-env 创建本地 WordPress 开发环境,其中包含已安装并激活的新块插件。
因此,请选择一个目录来放置块插件,或者可选地创建一个名为“块教程”的新文件夹。打开您的终端并使用 cd 进入该目录。然后运行以下命令。
wp-env,则相反请使用终端导航到本地 WordPress 安装中的 plugins/ 文件夹并运行以下命令。npx @wordpress/create-block@latest copyright-date-block --variant=dynamic
cd copyright-date-block
执行此命令后,您将在 plugins 文件夹中找到一个名为 copyright-date-block 的新目录。该目录包含所有用于开始自定义块的初始文件。
此命令还设置了块的基本结构,其 slug 为 copyright-date-block。此 slug 在 WordPress 中唯一标识您的块。
--variant=dynamic 标志。这告诉 create-block 您希望搭建一个动态渲染的块。在本教程稍后,您将了解动态和静态渲染,并为该块添加静态渲染。导航到 WordPress 管理中的插件页面并确认插件已激活。然后,创建一个新的页面或文章,并确保您可以插入版权日期块。插入后它应该看起来像这样。

审查文件
在我们开始修改搭建的块之前,重要的是要审查插件的文件结构。在代码编辑器中打开插件文件夹。

接下来,查看 块的文件结构 文档以详细了解每个文件的作用。如果现在感到不知所措也没关系。您将在本教程中学习如何使用每个文件。
由于您搭建了一个动态块,因此您将看不到save.js 文件。在教程稍后,您将添加此文件到插件中以启用静态渲染,敬请期待。初始设置
让我们从创建最简单的版权日期块开始,这将是一个动态渲染的块,仅显示版权符号 (©) 和当前年份。我们还将添加一些控件,允许用户修改字体大小和文本颜色。
在进行以下步骤之前,请在插件目录内的终端中运行 npm run start。此命令将监视 /src 文件夹中的每个文件的变化。每次保存文件时,块的构建文件都将更新。
查看 在块编辑器中使用 JavaScript 文档以了解更多内容。
更新 block.json
打开 /src 文件夹中的 block.json 文件。
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"example": {},
"supports": {
"html": false
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php",
"viewScript": "file:./view.js"
}
查阅 block.json 文档以了解此文件的介绍。由于此搭建过程创建了该文件,因此需要对其进行一些更新以适应版权日期块的需求。
修改块的标识
首先删除图标并添加更合适的描述。您稍后将添加自定义图标。
- 删除
icon的行 - 将描述更新为“显示您站点的版权日期。”
- 保存文件
刷新编辑器后,您应该看到块不再带有笑脸图标,并且其描述已更新。

添加块支持
接下来,让我们添加一些 块支持,以便用户可以控制块的字体大小和文本颜色。
您应该始终尝试使用原生块支持,然后再构建自定义功能。这种方法可为用户提供一致的编辑体验,并且您的块只需几行代码即可受益于核心功能。更新 block.json 文件中的 supports 部分,使其如下所示。
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},
请注意,当您使用 "text": true 启用文本颜色支持时,背景颜色默认也会启用。您可以保留它处于启用状态,但这对本教程并非必需,因此您可以手动设置 "background": false。
保存文件并在编辑器中选择该块。您现在将在设置面板中看到颜色和排版面板。尝试修改设置并查看会发生什么。

删除不必要的代码
为了简单起见,版权日期块的样式将完全由颜色和排版块支持控制。该块也没有任何前端 JavaScript。因此,您不需要在 block.json 文件中指定样式表或 viewScript。
- 删除
editorStyle的行 - 删除
style的行 - 删除
viewScript的行 - 保存文件
刷新编辑器,您将看到块的样式现在与当前主题匹配。

整合所有内容
您最终的 block.json 文件应如下所示:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "Display your site's copyright date.",
"example": {},
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php"
}
更新 index.js
在开始构建块本身的功能之前,让我们先进行一些清理工作并为块添加自定义图标。
打开 index.js 文件。这是块的 main JavaScript 文件,用于在客户端注册该块。您可以在 Registration of a block 文档中了解有关客户端和服务器端注册的更多信息。
首先查看 registerBlockType 函数。该函数接受块的名称(我们从导入的 block.json 文件中获取)和块配置对象。
import Edit from './edit';
import metadata from './block.json';
registerBlockType( metadata.name, {
edit: Edit,
} );
默认情况下,该对象仅包含 edit 属性,但您可以添加更多属性,包括 icon。虽然这些属性的大部分已在 block.json 中定义,但您需要在此处指定图标以使用自定义 SVG。
添加自定义图标
使用来自 Gutenberg Storybook 的日历图标,像这样将 SVG 添加到函数中:
const calendarIcon = (
<svg
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
focusable="false"
>
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm.5 16c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5V7h15v12zM9 10H7v2h2v-2zm0 4H7v2h2v-2zm4-4h-2v2h2v-2zm4 0h-2v2h2v-2zm-4 4h-2v2h2v-2zm4 0h-2v2h2v-2z"></path>
</svg>
);
registerBlockType( metadata.name, {
icon: calendarIcon,
edit: Edit
} );
所有块图标都应为 24 像素正方形。注意上面的 viewBox 参数。保存 index.js 文件并刷新编辑器。您现在将看到日历图标而不是默认图标。

此时,块的图标和描述已正确设置,且块支持允许您更改字体大小和文本颜色。现在,是时候转向块的实际功能了。
更新 edit.js
edit.js 文件控制块在编辑器中的功能和外观。目前,用户看到的是“Copyright Date Block – hello from the editor!”消息。让我们更改它。
打开该文件,您将看到 Edit() 函数返回一个带有默认消息的段落标签。
export default function Edit() {
return (
<p { ...useBlockProps() }>
{ __(
'Copyright Date Block – hello from the editor!',
'copyright-date-block-demo'
) }
</p>
);
}
这看起来比实际更复杂。
useBlockProps()在 块的包装器 中输出编辑器所需的所有必要 CSS 类和样式,其中包括您之前添加的块支持提供的样式__()用于文本字符串的国际化
作为提醒,此块的主要目的是显示版权符号 (©) 和当前年份。因此,您首先需要以字符串形式获取当前年份,这可以通过以下代码完成。
const currentYear = new Date().getFullYear().toString();
接下来,更新函数以显示正确的信息。
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<p { ...useBlockProps() }>© { currentYear }</p>
);
}
保存 edit.js 文件并刷新编辑器。您现在将看到版权符号 (©) 后跟当前年份。

更新 render.php
虽然块在编辑器中正常工作,但前端仍显示默认块消息。要修复此问题,请打开 render.php 文件,您将看到以下内容。
<?php
...
?>
<p <?php echo get_block_wrapper_attributes(); ?>>
<?php esc_html_e( 'Copyright Date Block – hello from a dynamic block!', 'copyright-date-block' ); ?>
</p>
类似于编辑器中的 useBlockProps() 函数,get_block_wrapper_attributes() 在 块的包装器 中输出所有必要的 CSS 类和样式。只需更新内容即可。
您可以使用 date( "Y" ) 在 PHP 中获取当前年份,您的 render.php 应如下所示。
<?php
...
?>
<p <?php echo get_block_wrapper_attributes(); ?>>© <?php echo date( "Y" ); ?></p>
保存文件并确认块在编辑器和前端中正确显示。
清理工作
当您使用 create-block 包创建块时,它可能包含您不需要的文件。在本教程的情况下,块不使用样式表或前端 JavaScript。通过以下操作清理插件的 src/ 文件夹。
- 在
edit.js文件中,删除导入editor.scss的行 - 在
index.js文件中,删除导入style.scss的行 - 删除 editor.scss、style.scss 和 view.js 文件
最后,确保没有未保存的更改,然后终止 npm run start 命令。运行 npm run build 以优化您的代码并使其准备好用于生产。
您已经构建了一个功能完整的 WordPress 块,但让我们不要就此止步。在接下来的部分中,我们将添加功能并启用静态渲染。
添加块属性
您构建的 Copyright Date Block 显示当前年份,但如果您想同时显示起始年份怎么办?

此功能需要用户在块上的某个位置输入起始年份。他们还应该能够切换开启或关闭该选项。
您可以通过不同的方式实现这一点,但所有方法都需要 块属性。属性允许您为块存储自定义数据,然后可用于修改块的标记。
要启用此起始年份功能,您需要一个属性来存储起始年份,另一个属性将用于告诉 WordPress 是否应显示起始年份。
更新 block.json
块属性通常指定在 block.json 文件中。因此,打开该文件并在 example 属性之后添加以下部分。
"example": {},
"attributes": {
"showStartingYear": {
"type": "boolean"
},
"startingYear": {
"type": "string"
}
},
在定义属性时,您必须指定其 type。在这种情况下,showStartingYear 应为 true 或 false,因此将其设置为 boolean。startingYear 只是一个字符串。
保存文件后,您就可以继续操作编辑器了。
更新 edit.js
打开 edit.js 文件。您需要完成两项任务。
- 添加一个用户界面,允许用户输入起始年份、切换功能的开启或关闭状态,并将这些设置存储为属性。
- 更新块以根据定义的属性显示正确的内容。
添加用户界面
在本教程的早期部分,您添加了块支持功能,从而在块的设置侧边栏中自动创建了“颜色”和“排版”面板。您可以使用 InspectorControls 组件创建自己的自定义面板。
检查器控件
InspectorControls 属于 @wordpress/block-editor 包,因此您可以通过在第 14 行添加组件名称将其导入到 edit.js 文件中。结果应如下所示。
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
接下来,更新 Edit 函数以返回当前块内容和包含文本“Testing”的 InspectorControls 组件。您可以将所有内容包裹在 Fragment(<></>)中,以确保正确的 JSX 语法。结果应如下所示。
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
Testing
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
保存文件并刷新编辑器。选择块时,您应该在设置侧边栏中看到“Testing”消息。

组件和面板
现在,让我们使用几个核心组件来添加自定义面板和起始年份功能的用户界面。您应该从 @wordpress/components 包中导入 PanelBody、TextControl 和 ToggleControl。
在 edit.js 文件中的其他导入语句下方添加以下行。
import { PanelBody, TextControl, ToggleControl } from '@wordpress/components';
然后将“Testing”消息包裹在 PanelBody 组件中,并将 title 参数设置为“Settings”。有关其他参数选项,请参阅 组件文档。
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
Testing
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
保存文件并刷新编辑器。您现在应该能看到新的“设置”面板。

文本控件
下一步是用允许用户设置 startingYear 属性的 TextControl 组件替换“Testing”消息。但是,在这样做之前,您必须在 Edit() 函数中包含两个参数。
attributes是一个包含块所有属性的对象setAttributes是一个允许您更新属性值的函数
包含这些参数后,您可以获取 showStartingYear 和 startingYear 属性。
将 Edit() 函数的顶部更新为如下所示。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
...
要查看与版权日期块关联的所有属性,请在 Edit() 函数的顶部添加 console.log( attributes );。这在构建和测试自定义块时非常有用。现在,您可以删除“Testing”消息并添加一个 TextControl。它应该包括:
- 将
label属性设置为“起始年份” - 将
value属性设置为属性startingYear - 一个
onChange属性,每当值更改时更新startingYear属性
将所有内容放在一起后,Edit() 函数应如下所示。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
<TextControl
label={ __(
'Starting year',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
您可能注意到 value 属性的值为 startingYear || ''。符号 || 称为 逻辑或(逻辑析取)运算符。这可以防止在 startingYear 为空时出现 React 警告。有关详细信息,请参阅 受控和非受控组件。保存文件并刷新编辑器。确认设置面板中现在存在一个文本字段。添加一个起始年份,并确认当您更新页面时,该值已保存。

切换控件
接下来,让我们添加一个切换开关以开启或关闭起始年份功能。您可以使用 ToggleControl 组件来实现这一点,该组件设置 showStartingYear 属性。它应该包括:
- 将
label属性设置为“显示起始年份” - 将
checked属性设置为属性showStartingYear - 一个
onChange属性,每当切换开关被选中或取消选中时更新showStartingYear属性
您还可以更新“起始年份”文本输入框,使其仅在 showStartingYear 为 true 时显示,这可以使用 && 逻辑运算符来实现。
Edit() 函数应如下所示。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
<PanelBody title={ __( '设置', 'copyright-date-block' ) }>
<ToggleControl
checked={ !! showStartingYear }
label={ __(
'显示起始年份',
'copyright-date-block'
) }
onChange={ () =>
setAttributes( {
showStartingYear: ! showStartingYear,
} )
}
/>
{ showStartingYear && (
<TextControl
label={ __(
'起始年份',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
) }
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
保存文件并刷新编辑器。确认点击切换开关会显示文本输入框,并且当你更新页面时,该切换开关保持激活状态。

更新块内容
到目前为止,你已经创建了添加起始年份并更新相关块属性的用户界面。现在你需要在编辑器中实际更新块内容。
让我们创建一个名为 displayDate 的新变量。当 showStartingYear 为 true 且用户提供了 startingYear 时,displayDate 应包含由长破折号分隔的 startingYear 和 currentYear。否则,仅显示 currentYear。
代码应该大致如下所示。
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}
当你使用 let 声明变量时,意味着该变量稍后可能会被重新赋值。使用 const 声明变量意味着该变量永远不会改变。你可以使用 const 重写这段代码。这仅仅是个人偏好的问题。接下来,你只需要更新块内容以使用 displayDate 而不是 currentYear 变量。
Edit() 函数应如下所示。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}
return (
<>
<InspectorControls>
<PanelBody title={ __( '设置', 'copyright-date-block' ) }>
<ToggleControl
checked={ !! showStartingYear }
label={ __(
'显示起始年份',
'copyright-date-block'
) }
onChange={ () =>
setAttributes( {
showStartingYear: ! showStartingYear,
} )
}
/>
{ showStartingYear && (
<TextControl
label={ __(
'起始年份',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
) }
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { displayDate }</p>
</>
);
}
保存文件并刷新编辑器。确认当你在设置面板中进行更改时,块内容能正确更新。

更新 render.php
虽然编辑器看起来很棒,但起始年份功能尚未添加到前端。让我们通过更新 render.php 文件来修复这个问题。
首先添加一个名为 $display_date 的变量,并复制你在上面的 Edit() 函数中执行的操作。
该变量应显示 startingYear 属性值和 $current_year 变量的值,两者之间用长破折号分隔;或者如果 showStartingYear 属性为 false,则仅显示 $current_year。
render.php 中暴露了三个变量,你可以使用它们来自定义块的输出:$attributes(数组): 块属性。$content(字符串): 块的默认内容。$block(WP_Block): 块实例。
代码应该大致如下所示。
if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
$display_date = $attributes['startingYear'] . '–' . $current_year;
} else {
$display_date = $current_year;
}
接下来,你只需要更新块内容以使用 $display_date 而不是 $current_year 变量。
你最终的 render.php 文件应如下所示。
<?php
$current_year = date( "Y" );
if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
$display_date = $attributes['startingYear'] . '–' . $current_year;
} else {
$display_date = $current_year;
}
?>
<p <?php echo get_block_wrapper_attributes(); ?>>
© <?php echo esc_html( $display_date ); ?>
</p>
保存文件并确认正确的块内容现在已出现在网站的前端。
你现在已成功构建了一个动态渲染的自定义块,它利用了块支持、核心 WordPress 组件和自定义属性。在许多情况下,对于显示版权日期并具有一些额外功能的块来说,这已经足够了。
然而,在下一节中,你将为块添加静态渲染。此练习将说明块数据如何存储在 WordPress 中,并提供一种后备方案,以防该插件被意外禁用。
添加静态渲染
块可以使用动态渲染、静态渲染或两者兼用。到目前为止你构建的块是动态渲染的。其块标记和相关属性存储在数据库中,但其 HTML 输出并未存储。
静态渲染的块将始终在数据库中存储块标记、属性和输出。块也可以在数据库中存储静态输出,同时在前端通过动态方式进一步增强,即两种方法的组合。
如果你从编辑器中切换到代码编辑器,你会看到以下内容。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} /-->
将其与静态渲染的块(如段落块)进行比较。
<!-- wp:paragraph -->
<p>这是一个测试。</p>
<!-- /wp:paragraph -->
段落的 HTML 存储在帖子内容中并保存在数据库中。
你可以在 基础文档 中了解更多有关动态和静态渲染的信息。虽然大多数块要么是动态渲染,要么是静态渲染,但你可以构建一个同时利用这两种方法的块。
为什么要添加静态渲染?
当你为动态渲染的块添加静态渲染时,render.php 文件仍将控制前端的输出,但块的 HTML 内容将保存在数据库中。这意味着即使插件从网站中移除,内容也会保留。对于此版权日期块来说,内容将还原为一个自定义 HTML 块,你可以轻松将其转换为段落块。

虽然在所有情况下都不需要这样做,但为动态渲染的块添加静态渲染可以提供一个有用的回退方案,以防插件意外被禁用。
此外,考虑一种情况,即块的标记包含在块模式或主题模板中。如果用户在没有安装“版权日期块”的情况下安装该主题或使用该模式,他们将收到通知说该块不可用,但内容仍然会显示。
添加静态渲染也是对 WordPress 中如何存储和渲染块内容的一种很好的探索。
添加保存功能
首先,在 src/ 文件夹中添加一个名为 save.js 的新文件。在此文件中,添加以下内容。
import { useBlockProps } from '@wordpress/block-editor';
export default function save() {
return (
<p { ...useBlockProps.save() }>
{ 'Copyright Date Block – hello from the saved content!' }
</p>
);
}
这应该看起来与原始的 edit.js 文件相似,您可以参考 块包装器 文档以获取更多信息。
接下来,在 index.js 文件中导入此 save() 函数,并在 registerBlockType() 函数中添加一个保存属性。这是更新后文件的简化视图。
import save from './save';
...
registerBlockType( metadata.name, {
icon: calendarIcon,
edit: Edit,
save
} );
在定义对象的属性时,如果属性名和变量名相同,您可以使用简写属性名。这就是上面的代码使用 save 而不是 save: save 的原因。保存 save.js 和 index.js 文件并刷新编辑器。它应该看起来像这样。

别担心,这个错误是预期的。如果您在浏览器中打开检查器,您应该看到以下消息。

此块验证错误发生是因为 save() 函数返回块内容,但由于之前保存的块是动态的,因此块的标记中未存储任何 HTML。请记住,这就是当前标记的样子。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} /-->
随着您在后续步骤中更新 save() 函数,您将看到更多此类错误。只需点击“尝试块恢复”并更新页面即可。
执行块恢复后,打开代码编辑器,您将看到标记现在看起来像这样。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} -->
<p class="wp-block-create-block-copyright-date-block">Copyright Date Block – hello from the saved content!</p>
<!-- /wp:create-block/copyright-date-block -->
在使用静态渲染构建块时,您经常会遇到块验证错误,这是可以的。save() 函数的输出必须与帖子内容中的 HTML 完全匹配,这可能会在您添加功能时不同步。只要您在完全完成块的构建时没有验证错误,您就可以放心了。
更新 save.js
接下来,让我们更新 save() 函数的输出来显示正确的内容。首先复制在 edit.js 中使用的相同方法。
- 向函数添加
attributes参数 - 定义
showStartingYear和startingYear变量 - 定义一个
currentYear变量 - 根据
currentYear、showStartingYear和startingYear的值定义一个displayDate变量
结果应该看起来像这样。
export default function save( { attributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}
return (
<p { ...useBlockProps.save() }>© { displayDate }</p>
);
}
保存文件并刷新编辑器。点击“尝试块恢复”并更新页面。检查代码编辑器,块的标记现在应该看起来像这样。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} -->
<p class="wp-block-create-block-copyright-date-block">© 2017–2023</p>
<!-- /wp:create-block/copyright-date-block -->
此时,您可能看起来已经完成了。块内容现在作为 HTML 保存在数据库中,前端输出是动态渲染的。但是,仍然有一些事情需要解决。
考虑用户于 2023 年将块添加到页面,然后返回编辑页面的情况。前端将按预期更新,但在编辑器中会出现块验证错误。save() 函数知道现在是 2024 年,但数据库中保存的块内容仍然显示为 2023 年。
让我们在下一节中修复这个问题。
处理静态渲染块中的动态内容
通常,您希望避免在静态渲染块中使用动态内容。这也是在使用“动态”一词指代动态渲染时的原因之一。
话虽如此,在本教程中,您将结合这两种渲染方法,并且只需要一些额外的代码即可避免年份更改时出现任何块验证错误。
问题的根源是 currentYear 变量在 save() 函数中动态设置。相反,这应该是函数内的静态变量,可以通过添加一个属性来解决。
添加新属性
打开 block.json 文件并添加一个名为 fallbackCurrentYear 的新属性,类型为 string。文件的 attributes 部分现在应该看起来像这样。
"attributes": {
"fallbackCurrentYear": {
"type": "string"
},
"showStartingYear": {
"type": "boolean"
},
"startingYear": {
"type": "string"
}
},
接下来,打开 save.js 文件并使用新的 fallbackCurrentYear 属性替换 currentYear。您更新的 save() 函数应该看起来像这样。
export default function save( { attributes } ) {
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + fallbackCurrentYear;
} else {
displayDate = fallbackCurrentYear;
}
return (
<p { ...useBlockProps.save() }>© { displayDate }</p>
);
}
现在,如果 fallbackCurrentYear 未定义会发生什么?
在 currentYear 在函数内定义之前,因此即使 showStartingYear 和 startingYear 未定义,save() 函数也始终有内容可返回。
与其仅返回版权符号,不如添加一个条件,如果 fallbackCurrentYear 未设置,则返回 null。通常,在数据库中保存无 HTML 比保存不完整的数据更好。
最终的 save() 函数应该看起来像这样。
export default function save( { attributes } ) {
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;
if ( ! fallbackCurrentYear ) {
return null;
}
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + fallbackCurrentYear;
} else {
displayDate = fallbackCurrentYear;
}
return (
<p { ...useBlockProps.save() }>© { displayDate }</p>
);
}
保存 block.json 和 save.js 文件;您不需要再做任何更改。
在 edit.js 中设置属性
save() 函数现在使用新的 fallbackCurrentYear,因此需要在某个地方设置它。让我们使用 Edit() 函数。
打开 edit.js 文件,首先在与其它属性一起定义 Edit() 函数顶部的 fallbackCurrentYear 变量。接下来,查看函数中发生的事情。
当块在编辑器中加载时,定义了 currentYear 变量。然后该函数使用该变量设置块的内容。
现在,如果属性尚未设置,请在块加载时将 fallbackCurrentYear 属性设置为 currentYear。
if ( currentYear !== fallbackCurrentYear ) {
setAttributes( { fallbackCurrentYear: currentYear } );
}
这可以工作,但可以通过确保此代码仅在块初始化时运行一次来改进。为此,您可以使用 React hook useEffect。有关如何使用此 hook 的更多信息,请参阅 React 文档。
首先,使用以下代码导入 useEffect。
import { useEffect } from 'react';
然后将上面的 setAttribute() 代码包装在 useEffect 中,并将此代码放在 Edit() 函数中的 currentYear 定义之后。结果应如下所示。
export default function Edit( { attributes, setAttributes } ) {
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;
// Get the current year and make sure it's a string.
const currentYear = new Date().getFullYear().toString();
// When the block loads, set the fallbackCurrentYear attribute to the
// current year if it's not already set.
useEffect( () => {
if ( currentYear !== fallbackCurrentYear ) {
setAttributes( { fallbackCurrentYear: currentYear } );
}
}, [ currentYear, fallbackCurrentYear, setAttributes ] );
...
当块在编辑器中初始化时,fallbackCurrentYear 属性将立即设置。此值随后可用于 save() 函数,并且将显示正确的块内容而不会出现块验证错误。
唯一的注意事项是当年份发生变化时。如果 Copyright Date Block 于 2023 年添加到页面中,然后在 2024 年编辑,fallbackCurrentYear 属性将不再等于 currentYear,并且该属性将自动更新为 2024。这将更新 save() 函数返回的 HTML。
您不会收到任何块验证错误,但编辑器会检测到页面已更改并提示您进行更新。
优化 render.php
最后一步是优化 render.php 文件。如果 currentYear 和 fallbackCurrentYear 属性相同,则无需动态创建块内容。它已保存在数据库中,并且可通过 $content 变量在 render.php 文件中可用。
因此,更新文件以在 currentYear 和 fallbackCurrentYear 不匹配时渲染生成的内容。
$current_year = date( "Y" );
// Determine which content to display.
if ( isset( $attributes['fallbackCurrentYear'] ) && $attributes['fallbackCurrentYear'] === $current_year ) {
// The current year is the same as the fallback, so use the block content saved in the database (by the save.js function).
$block_content = $content;
} else {
// The current year is different from the fallback, so render the updated block content.
if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
$display_date = $attributes['startingYear'] . '–' . $current_year;
} else {
$display_date = $current_year;
}
$block_content = '<p ' . get_block_wrapper_attributes() . '>© ' . esc_html( $display_date ) . '</p>';
}
echo wp_kses_post( $block_content );
就是这样!您现在拥有一个利用动态和静态渲染的块。
总结
恭喜完成本教程并构建了自己的 Copyright Date Block。在整个旅程中,您获得了扎实的 WordPress 块开发基础,现在已准备好开始构建自己的块。
作为最终参考,本教程的完整代码可在 GitHub 上的 Block Development Examples 仓库中获取。
现在,无论您是希望磨练技能、应对更高级的项目,还是跟上最新的 WordPress 趋势,以下资源将帮助您提高块开发技能:
- Block Development Environment
- Fundamentals of Block Development
- WordPress Developer Blog
- Block Development Examples | GitHub 仓库
请记住,每位专家曾经都是初学者。继续学习、实验,最重要的是,享受使用 WordPress 构建的乐趣。