这里有一些关于 CSS-Tricks 的新教程,用于处理 WordPress 块。 其中之一 是对 WordPress 块开发的介绍,它是了解什么是块并在 WordPress 中注册它们以用于页面和帖子的好地方。
虽然该帖子很好地介绍了块基础知识,但我想更进一步。 你看,在那篇文章中,我们了解了在后端 WordPress 块编辑器中渲染块和在前端主题上渲染它们之间的区别。 该示例是一个简单的 Pullquote Block,它在每一端呈现不同的内容和样式。
让我们更进一步,看看使用 动态内容 在 WordPress 块中。 更具体地说,让我们从外部 API 获取数据,并在将特定块放入块编辑器时将其呈现在前端。
我们将构建一个输出显示足球数据的块(呃, 足球) 排名从 Api-足球.
将 API 与 WordPress 块集成的方法不止一种! 由于关于块基础的文章已经介绍了从头开始制作块的过程,我们将通过使用 @wordpress/create-block
包来引导我们的工作并构建我们的项目。
初始化我们的块插件
首先要做的事情:让我们从命令行启动一个新项目:
npx @wordpress/create-block football-rankings
我通常会通过从头开始制作文件来启动这样的项目,但要感谢 WordPress 核心团队的这个方便的实用程序!
通过命令创建项目文件夹后,从技术上讲,我们将功能齐全的 WordPress 块注册为插件。 所以,让我们继续将项目文件夹放入 wp-content/plugins
安装 WordPress 的目录(最好在本地环境中工作),然后登录 WordPress 管理员并从插件屏幕激活它。
现在我们的块已经初始化、安装和激活,继续从 at 打开项目文件夹 /wp-content/plugins/football-rankings
. 你会想要 cd
也可以从命令行那里,以确保我们可以继续开发。
这些是我们目前需要关注的唯一文件:
edit.js
index.js
football-rankings.php
当然,项目中的其他文件很重要,但此时无关紧要。
查看 API 源
我们已经知道我们正在使用 Api-足球 这是由我们提供的 快速API. 幸运的是,RapidAPI 有一个仪表板,可以自动生成我们需要的脚本来获取 2021 年英超积分榜的 API 数据。
如果您想查看 JSON 结构,可以使用 JSON破解.
edit.js
文件
从 我将把 RapidAPI 代码封装在一个 应对 useEffect()
钩 使用一个空的依赖数组,以便它在页面加载时只运行一次。 这样,我们可以防止 WordPress 在每次块编辑器重新呈现时调用 API。 您可以使用 wp.data.subscribe()
如果你愿意的话。
这是我要导入的代码 useEffect()
,然后将其包裹在 fetch()
RapidAPI 提供的代码:
/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
*
* @return {WPElement} Element to render.
*/
import { useEffect } from "@wordpress/element";
export default function Edit(props) {
const { attributes, setAttributes } = props;
useEffect(() => {
const options = {
method: "GET",
headers: {
"X-RapidAPI-Key": "Your Rapid API key",
"X-RapidAPI-Host": "api-football-v1.p.rapidapi.com",
},
};
fetch("https://api-football-v1.p.rapidapi.com/v3/standings?season=2021&league=39", options)
.then( ( response ) => response.json() )
.then( ( response ) => {
let newData = { ...response };
setAttributes( { data: newData } );
console.log( "Attributes", attributes );
})
.catch((err) => console.error(err));
}, []);
return (
{ __( "Standings loaded on the front end", "external-api-gutenberg" ) }
);
}
请注意,我已离开 return
功能几乎完好无损,但包含一个确认足球排名在前端呈现的注释。 同样,我们将只关注本文中的前端——我们也可以在块编辑器中渲染数据,但我们将把它留给另一篇文章来保持重点。
在 WordPress 中存储 API 数据
现在我们正在获取数据,我们需要将其存储在 WordPress 中的某个位置。 这就是 attributes.data
对象派上用场。 我们正在定义 data.type
作为 object
因为数据被提取并格式化为 JSON。 确保您没有任何其他类型,否则 WordPress 不会保存数据,也不会抛出任何错误供您调试。
我们在我们的 index.js
文件:
registerBlockType( metadata.name, {
edit: Edit,
attributes: {
data: {
type: "object",
},
},
save,
} );
好的,所以 WordPress 现在知道我们正在获取的 RapidAPI 数据是一个对象。 如果我们在 WordPress 块编辑器中打开新的帖子草稿并保存帖子,则数据现在存储在数据库中。 事实上,如果我们能在 wp_posts.post_content
如果我们在 phpMyAdmin、Sequel Pro、Adminer 或您使用的任何工具中打开站点的数据库,则字段。
在前端输出 JSON 数据
前端输出数据的方式有多种。 我将向您展示的方式采用存储在数据库中的属性并将它们作为参数通过 render_callback
在我们的功能 football-rankings.php
文件中。
我喜欢保持关注点分离,所以我这样做的方法是将两个新文件添加到块插件的 build
文件夹: frontend.js
和 frontend.css
(您可以创建一个 frontend.scss
文件中 src
编译成 CSS 的目录 build
目录)。 这样,后端和前端代码是分开的,并且 football-rankings.php
文件更容易阅读。
/explanation 回过头来参考 WordPress 块开发的介绍,有 editor.css
和 style.css
分别用于后端和前端和后端之间共享样式的文件。 通过添加 frontend.scss
(编译为 frontend.css
,我可以隔离仅用于前端的样式。
在我们担心这些新文件之前,这是我们调用它们的方式 football-rankings.php
:
/** * Registers the block using the metadata loaded from the `block.json` file. * Behind the scenes, it registers also all assets so they can be enqueued * through the block editor in the corresponding context. * * @see https://developer.wordpress.org/reference/functions/register_block_type/ */ function create_block_football_rankings_block_init() { register_block_type( __DIR__ . '/build', array( 'render_callback' => 'render_frontend' )); } add_action( 'init', 'create_block_football_rankings_block_init' ); function render_frontend($attributes) { if( !is_admin() ) { wp_enqueue_script( 'football_rankings', plugin_dir_url( __FILE__ ) . '/build/frontend.js'); wp_enqueue_style( 'football_rankings', plugin_dir_url( __FILE__ ) . '/build/frontend.css' ); // HIGHLIGHT 15,16,17,18 } ob_start(); ?>
RankLogoTeam nameGPGWGDGLGFGAPtsLast 5 games
<?php return ob_get_clean();
}由于我正在使用
render_callback()
属性的方法,我将手动处理入队,就像 块编辑器手册建议. 这包含在!is_admin()
条件,并将这两个文件排入队列,以便我们避免在使用编辑器屏幕时将它们排入队列。现在我们有两个要调用的新文件,我们必须确保我们正在告诉
npm
编译它们。 所以,在package.json
在scripts
部分:"scripts": { "build": "wp-scripts build src/index.js src/frontend.js", "format": "wp-scripts format", "lint:css": "wp-scripts lint-style", "lint:js": "wp-scripts lint-js", "packages-update": "wp-scripts packages-update", "plugin-zip": "wp-scripts plugin-zip", "start": "wp-scripts start src/index.js src/frontend.js" },
包含文件的另一种方法是在我们的块元数据中定义它们
block.json
文件, 如前所述 在区块开发简介中:"viewScript": [ "file:./frontend.js", "example-shared-view-script" ], "style": [ "file:./frontend.css", "example-shared-style" ],
我去的唯一原因
package.json
方法是因为我已经在使用render_callback()
方法。呈现 JSON 数据
在渲染部分,我只专注于一个块。 一般来说,您会希望在前端定位多个块。 在这种情况下,您需要使用
document.querySelectorAll()
带有块的特定 ID。我基本上会等待窗口加载并从 JSON 中获取一些关键对象的数据,并将它们应用到一些在前端呈现它们的标记。 我也要转换
attributes
数据到 JSON 对象,以便更容易阅读 JavaScript 并将详细信息从 JSON 设置为 HTML,例如足球联赛徽标、球队徽标和统计数据。“最近 5 场比赛”栏显示球队最近 XNUMX 场比赛的结果。 我必须手动更改它的数据,因为 API 数据是字符串格式。 将其转换为数组有助于在 HTML 中将其用作球队最近五场比赛中每场比赛的单独元素。
import "./frontend.scss"; // Wait for the window to load window.addEventListener( "load", () => { // The code output const dataEl = document.querySelector( ".data pre" ).innerHTML; // The parent rankings element const tableEl = document.querySelector( ".league-table" ); // The table headers const tableHeaderEl = document.querySelector( "#league-standings .header" ); // Parse JSON for the code output const dataJSON = JSON.parse( dataEl ); // Print a little note in the console console.log( "Data from the front end", dataJSON ); // All the teams let teams = dataJSON.data.response[ 0 ].league.standings[ 0 ]; // The league logo let leagueLogoURL = dataJSON.data.response[ 0 ].league.logo; // Apply the league logo as a background image inline style tableHeaderEl.style.backgroundImage = `url( ${ leagueLogoURL } )`; // Loop through the teams teams.forEach( ( team, index ) => { // Make a div for each team const teamDiv = document.createElement( "div" ); // Set up the columns for match results const { played, win, draw, lose, goals } = team.all; // Add a class to the parent rankings element teamDiv.classList.add( "team" ); // Insert the following markup and data in the parent element teamDiv.innerHTML = `
${ index + 1 }${ team.team.name }`; // Stringify the last five match results for a team const form = team.form.split( "" ); // Loop through the match results form.forEach( ( result ) => { // Make a div for each result const resultEl = document.createElement( "div" ); // Add a class to the div resultEl.classList.add( "result" ); // Evaluate the results resultEl.innerText = result; // If the result a win if ( result === "W" ) { resultEl.classList.add( "win" ); // If the result is a draw } else if ( result === "D" ) { resultEl.classList.add( "draw" ); // If the result is a loss } else { resultEl.classList.add( "lost" ); } // Append the results to the column teamDiv.querySelector( ".form-history" ).append( resultEl ); }); tableEl.append( teamDiv ); }); });${ played }${ win }${ draw }${ lose }${ goals.for }${ goals.against }${ team.points }就造型而言,你可以自由地做任何你想做的事! 如果您想使用某些东西,我有一整套样式可供您用作起点。
我在 SCSS 中设置样式
@wordpress/create-block
包支持它开箱即用。 跑npm run start
在命令行中查看 SCSS 文件并在保存时将它们编译为 CSS。 或者,您可以使用npm run build
在每次保存时编译 SCSS 并构建插件包的其余部分。查看 SCSS
body { background: linear-gradient(to right, #8f94fb, #4e54c8); } .data pre { display: none; } .header { display: grid; gap: 1em; padding: 10px; grid-template-columns: 1fr 1fr 3fr 4fr 3fr; align-items: center; color: white; font-size: 16px; font-weight: 600; background-repeat: no-repeat; background-size: contain; background-position: right; } .frontend#league-standings { width: 900px; margin: 60px 0; max-width: unset; font-size: 16px; .header { .stats { display: flex; gap: 15px; & > div { width: 30px; } } } } .league-table { background: white; box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px; padding: 1em; .position { width: 20px; } .team { display: grid; gap: 1em; padding: 10px 0; grid-template-columns: 1fr 1fr 3fr 4fr 3fr; align-items: center; } .team:not(:last-child) { border-bottom: 1px solid lightgray; } .team-logo img { width: 30px; } .stats { display: flex; gap: 15px; } .stats > div { width: 30px; text-align: center; } .form-history { display: flex; gap: 5px; } .form-history > div { width: 25px; height: 25px; text-align: center; border-radius: 3px; font-size: 15px; } .form-history .win { background: #347d39; color: white; } .form-history .draw { background: gray; color: white; } .form-history .lost { background: lightcoral; color: white; } }
这是演示!
检查一下——我们刚刚制作了一个块插件,它可以获取数据并将其呈现在 WordPress 网站的前端。
我们找到了一个 API,
fetch()
-ed 数据,将其保存到 WordPress 数据库,对其进行解析,并将其应用于一些 HTML 标记以显示在前端。 对于单个教程来说还不错,对吧?同样,我们可以做同样的事情,以便排名在块编辑器中呈现,除了主题的前端。 但希望将重点放在前端向您展示如何在 WordPress 块中获取数据,以及如何构建和呈现数据以供显示。