This article follows the previous article about "Rendering external API data on the front end of the WordPress block". In the previous post, we learned how to get an external API and integrate it with a block that renders the retrieved data on the front end of a WordPress website.
The problem is that the way we implement it prevents us from seeing data in the WordPress block editor. In other words, we can insert the block into the page, but we can't see a preview of it. Blocks can only be seen after release.
Let's review the sample block plugin created in the previous post. This time, we will use WordPress's JavaScript and React ecosystem to get and render data in the backend block editor.
Before starting, here is a demo we completed in the previous post, you can refer to. You may have noticed that I used the render_callback
method in my previous post to be able to use properties and render content in a PHP file.
This is useful in situations where you may need to use some native WordPress or PHP functions to create dynamic blocks. However, if you just want to use WordPress's JavaScript and React (particularly JSX) ecosystem to render static HTML and properties stored in the database, you only need to focus on the Edit
and Save
functions of the block plugin.
Save
Functions are the focus of our discussion today. We can create interactive components on the front end, but for this we need to include and access them manually in a file like we did in the previous post.
So I'll cover the same thing we did in the previous post, but this time you can see the preview in the block editor before posting to the frontend .
Block Properties function properties in the previous post because this distracts the main content (rendering). edit
If we record the
object to the console, it will return a list of WordPress functions and variables related to our block: props
We just need the attributes
object and the setAttributes
function, and I will deconstruct them from the props
object in my code. In the previous post, I modified the code of RapidAPI so that the API data can be stored via setAttributes()
. Props
is read-only, so we cannot modify them directly.
block attribute is similar to the state variables and setState
in React, but React runs on the client, while setAttributes()
is used to permanently store the attribute in the WordPress database after saving the post. So what we need to do is save them to attributes.data
and then call them as the initial value of the useState()
variable.
I will copy and paste the HTML code we used in the previous post in football-rankings.php
and do some editing to turn to the JavaScript background. Remember we created two additional files for front-end styles and scripts in the previous post? Follow our approach today, there is no need to create these files. Instead, we can move everything into the Edit
function.
Full code
````javascript
import { useState } from "@wordpress/element";
export default function Edit(props) {
const { attributes, setAttributes } = props;
const [apiData, setApiData] = useState(attributes.data); // Use attributes.data as the initial value
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 }; // Deep cloning response data setAttributes({ data: newData }); // Store data in WordPress attribute setApiData(newData); // Use new data to modify the status }) .catch((err) => console.error(err)); }
return (
我已经从
@wordpress/element中包含了React钩子
useState(),而不是从React库中使用它。这是因为如果我以常规方式加载,它会为我使用的每个区块下载React。但是,如果我使用
@wordpress/element`, which loads from a single source, the WordPress layer above React.
This time, instead of wrapping the code in useEffect()
, I wrapped it in a function that is only called when the button is clicked so that we can preview the retrieved data in real time. I've used a state variable called apiData
to render the league table conditionally. So once the button is clicked and the data is fetched, I set apiData
to new data in fetchData()
and will re-render with the available football ranking table HTML.
You will notice that once the post is saved and the page is refreshed, the league table will disappear. This is because we use the null state (null) as the initial value of apiData
. When a post is saved, the property is saved to the attributes.data
object, which we call as the initial value of the useState()
variable as shown below:
const [apiData, setApiData] = useState(attributes.data);
We will do almost the same thing with the save
function, but with a little modification. For example, the front end does not need the "get data" button, nor does the apiData
state variable, because we have checked it in the edit
function. But we need a random apiData
variable to check attributes.data
to render JSX conditionally, otherwise it throws an undefined error and the block editor UI will become blank.
Full code
````javascript
export default function save(props) {
const { attributes } = props;
const apiData = attributes.data; // Use attributes.data
return ( apiData && ( // Render only when apiData is available
如果您在区块已存在于区块编辑器中后修改
save` function, it will display the following error:
This is because the tags in the saved content are different from those in our new save
function. Since we are in development mode, it is easier to delete blocks from the current page and reinsert them as new blocks – this way, the updated code will be used and everything will be restored to sync.
If we use the render_callback
method, this can be avoided because the output is dynamic and controlled by the PHP rather than the save
function. Therefore, each method has its own advantages and disadvantages.
Tom Nowell provides a detailed explanation of what should not be done in the save
function in this Stack Overflow answer.
Regarding the style, it will be nearly the same as we saw in the previous post, but there are some minor changes that I have explained in the comments. I'm just providing the full style here, because it's just a proof of concept, not what you want to copy and paste (unless you do need a block that shows the football rankings in style like this). Note that I'm still using SCSS that compiles to CSS at build time.
Editor Style
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
/
Front-end block style /
.wp-block-post-content .wp-block-football-rankings-league-table {
/ ... Style ... /
}
... Style ... /
}
``We add this to src/style.scss`, which is responsible for the style of the editor and front-end. I can't share the demo URL as it requires editor access, but I've recorded a video for you to watch the demo:
我们将此添加到
However, if we want to make the most of the WordPress block editor, we should consider mapping some block UI elements to block controls such as setting colors, typography, and spacing. This is a good next step in the Block Development Learning Journey.
The above is the detailed content of Rendering External API Data in WordPress Blocks on the Back End. For more information, please follow other related articles on the PHP Chinese website!