在前端 PlatoBlockchain 数据智能上呈现 WordPress 块中的外部 API 数据。 垂直搜索。 人工智能。

在前端的 WordPress 块中呈现外部 API 数据

这里有一些关于 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 管理员并从插件屏幕激活它。

在前端 PlatoBlockchain 数据智能上呈现 WordPress 块中的外部 API 数据。 垂直搜索。 人工智能。
在前端的 WordPress 块中呈现外部 API 数据

现在我们的块已经初始化、安装和激活,继续从 at 打开项目文件夹 /wp-content/plugins/football-rankings. 你会想要 cd 也可以从命令行那里,以确保我们可以继续开发。

这些是我们目前需要关注的唯一文件:

  • edit.js
  • index.js
  • football-rankings.php

当然,项目中的其他文件很重要,但此时无关紧要。

查看 API 源

我们已经知道我们正在使用 Api-足球 这是由我们提供的 快速API. 幸运的是,RapidAPI 有一个仪表板,可以自动生成我们需要的脚本来获取 2021 年英超积分榜的 API 数据。

一个仪表板界面,三列显示来自 API 源的代码和数据。
RapidAPI 仪表板

如果您想查看 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 输出。
存储在 WordPress 数据库中的 API 输出

在前端输出 JSON 数据

前端输出数据的方式有多种。 我将向您展示的方式采用存储在数据库中的属性并将它们作为参数通过 render_callback 在我们的功能 football-rankings.php 文件中。

我喜欢保持关注点分离,所以我这样做的方法是将两个新文件添加到块插件的 build 文件夹: frontend.jsfrontend.css (您可以创建一个 frontend.scss 文件中 src 编译成 CSS 的目录 build 目录)。 这样,后端和前端代码是分开的,并且 football-rankings.php 文件更容易阅读。

/explanation 回过头来参考 WordPress 块开发的介绍,有 editor.cssstyle.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(); ?>

  
        
      

Rank
Team name
GP
GW
GD
GL
GF
GA
Pts
Last 5 games

<?php return ob_get_clean();
}

由于我正在使用 render_callback() 属性的方法,我将手动处理入队,就像 块编辑器手册建议. 这包含在 !is_admin() 条件,并将这两个文件排入队列,以便我们避免在使用编辑器屏幕时将它们排入队列。

现在我们有两个要调用的新文件,我们必须确保我们正在告诉 npm 编译它们。 所以,在 package.jsonscripts 部分:

"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 }
${ played }
${ win }
${ draw }
${ lose }
${ goals.for }
${ goals.against }
${ team.points }
`; // 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 ); }); });

就造型而言,你可以自由地做任何你想做的事! 如果您想使用某些东西,我有一整套样式可供您用作起点。

我在 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 块中获取数据,以及如何构建和呈现数据以供显示。

时间戳记:

更多来自 CSS技巧