本文承接上一篇关于“在WordPress区块前端渲染外部API数据”的文章。上一篇文章中,我们学习了如何获取外部API并将它与一个区块集成,该区块在WordPress网站的前端渲染获取的数据。
问题在于,我们实现的方式阻止了我们在WordPress区块编辑器中看到数据。换句话说,我们可以将区块插入页面,但看不到它的预览。只有发布后才能看到区块。
让我们回顾一下上一篇文章中创建的示例区块插件。这次,我们将利用WordPress的JavaScript和React生态系统,在后端区块编辑器中获取和渲染数据。
开始之前,这里有一个我们在上一篇文章中完成的演示,您可以参考。您可能已经注意到,我在上一篇文章中使用了render_callback
方法,以便能够在PHP文件中使用属性并渲染内容。
这在您可能需要使用一些原生WordPress或PHP函数来创建动态区块的情况下很有用。但是,如果您只想使用WordPress的JavaScript和React(特别是JSX)生态系统来渲染静态HTML以及存储在数据库中的属性,您只需要关注区块插件的Edit
和Save
函数。
Save
函数是我们今天要讨论的重点。我们可以在前端创建交互式组件,但为此我们需要像在上一篇文章中那样,在一个文件中手动包含和访问它们。
因此,我将介绍我们在上一篇文章中所做的相同内容,但这次您可以在发布到前端之前在区块编辑器中看到预览。
我故意在上一篇文章中省略了关于edit
函数属性的任何解释,因为这会分散对主要内容(渲染)的注意力。
如果您有React背景,您可能会理解我所说的内容,但如果您是新手,我建议您查看React文档中的组件和属性。
如果我们将props
对象记录到控制台,它将返回与我们的区块相关的WordPress函数和变量列表:
我们只需要attributes
对象和setAttributes
函数,我将在我的代码中从props
对象解构它们。在上一篇文章中,我修改了RapidAPI的代码,以便可以通过setAttributes()
存储API数据。Props
是只读的,因此我们无法直接修改它们。
区块属性类似于React中的状态变量和setState
,但React在客户端运行,而setAttributes()
用于在保存帖子后将属性永久存储在WordPress数据库中。因此,我们需要做的是将它们保存到attributes.data
,然后将其作为useState()
变量的初始值调用。
我将复制粘贴我们在上一篇文章的football-rankings.php
中使用的HTML代码,并对其进行一些编辑以转向JavaScript背景。还记得我们在上一篇文章中为前端样式和脚本创建了两个附加文件吗?按照我们今天的方法,无需创建这些文件。相反,我们可以将所有内容移动到Edit
函数中。
完整代码
```javascript
import { useState } from "@wordpress/element";
export default function Edit(props) {
const { attributes, setAttributes } = props;
const [apiData, setApiData] = useState(attributes.data); // 使用 attributes.data 作为初始值
function fetchData() { const options = { method: "GET", headers: { "X-RapidAPI-Key": "Your Rapid API key", "X-RapidAPI-Host": "api-football-v1.p.rapidapi.com", }, }; fetch( "https://www.php.cn/link/a2a750ff64f34c66249d0f7d3dd42004", options ) .then((response) => response.json()) .then((response) => { let newData = { ...response }; // 深度克隆响应数据 setAttributes({ data: newData }); // 将数据存储在WordPress属性中 setApiData(newData); // 使用新数据修改状态 }) .catch((err) => console.error(err)); }
return (
我已经从
@wordpress/element中包含了React钩子
useState(),而不是从React库中使用它。这是因为如果我以常规方式加载,它会为我使用的每个区块下载React。但是,如果我使用
@wordpress/element`,它会从单个来源加载,即React之上的WordPress层。
这次,我没有将代码包装在useEffect()
中,而是包装在一个仅在点击按钮时调用的函数中,以便我们可以实时预览获取的数据。我已经使用了一个名为apiData
的状态变量来有条件地渲染联赛表。因此,一旦点击按钮并获取数据,我将apiData
设置为fetchData()
中的新数据,并且会使用可用的足球排名表HTML进行重新渲染。
您会注意到,一旦保存帖子并刷新页面,联赛表就会消失。这是因为我们使用空状态(null)作为apiData
的初始值。当帖子保存时,属性将保存到attributes.data
对象中,我们将其作为useState()
变量的初始值调用,如下所示:
const [apiData, setApiData] = useState(attributes.data);
我们将对save
函数做几乎完全相同的事情,但要稍作修改。例如,前端不需要“获取数据”按钮,apiData
状态变量也不需要,因为我们已经在edit
函数中检查它了。但是我们需要一个随机的apiData
变量来检查attributes.data
,以有条件地渲染JSX,否则它会抛出未定义的错误,并且区块编辑器UI将变为空白。
完整代码
```javascript
export default function save(props) {
const { attributes } = props;
const apiData = attributes.data; // 直接使用 attributes.data
return ( apiData && ( // 只在 apiData 可用时渲染
如果您在区块已存在于区块编辑器中后修改
save`函数,它会显示如下错误:
这是因为保存的内容中的标记与我们新的save
函数中的标记不同。由于我们处于开发模式,因此更容易从当前页面删除区块并将其重新插入为新区块——这样,将使用更新的代码,并且一切都会恢复同步。
如果我们使用了render_callback
方法,则可以避免这种情况,因为输出是动态的,由PHP而不是save
函数控制。因此,每种方法都有其自身的优点和缺点。
Tom Nowell 在这个Stack Overflow答案中对save
函数中不应该做什么进行了详尽的解释。
关于样式,它将与我们在上一篇文章中看到的几乎相同,但有一些小的更改,我已经在注释中解释了。我只是在这里提供完整的样式,因为这只是一个概念验证,而不是您想要复制粘贴的内容(除非您确实需要一个像这样样式的显示足球排名的区块)。请注意,我仍在使用在构建时编译为CSS的SCSS。
编辑器样式
css /* 目标所有带有 data-title="Football Rankings" 的区块 */ .block-editor-block-list__layout .block-editor-block-list__block.wp-block[data-title="Football Rankings"] { /* 默认情况下,区块被限制在 650px 最大宽度加上其他设计特定代码 */ max-width: unset; /* ... 其他样式 ... */ }
前端样式
```css
/ 前端区块样式 /
.wp-block-post-content .wp-block-football-rankings-league-table {
/ ... 样式 ... /
}
/ ... 样式 ... /
}
``<code>我们将此添加到
我们将此添加到src/style.scss`中,它负责编辑器和前端的样式。我无法分享演示URL,因为它需要编辑器访问权限,但我录制了一个视频供您观看演示:
查看演示 很整洁,对吧?现在我们有一个功能齐全的区块,它不仅在前端渲染,而且还在区块编辑器中获取API数据并进行渲染——还有一个刷新按钮!
但是,如果我们想充分利用WordPress区块编辑器,我们应该考虑将一些区块的UI元素映射到区块控件,例如设置颜色、排版和间距。这是区块开发学习之旅中一个不错的下一步。
以上是在后端的WordPress块中渲染外部API数据的详细内容。更多信息请关注PHP中文网其他相关文章!