本文承接上一篇關於“在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( "//m.sbmmt.com/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中文網其他相關文章!