Здесь появилось несколько новых руководств по CSS-Tricks для работы с блоками WordPress. Один из них — это введение в разработку блоков WordPress, и это хорошее место, чтобы узнать, что такое блоки, и зарегистрировать их в WordPress для использования на страницах и в сообщениях.
В то время как основы блока хорошо освещены в этом посте, я хочу сделать еще один шаг вперед. Видите ли, в этой статье мы узнали разницу между рендерингом блоков во внутреннем редакторе блоков WordPress и их рендерингом во фронтенд-теме. Примером был простой блок Pullquote, который отображал разное содержимое и стили на каждом конце.
Пойдем дальше и посмотрим на использование динамический контент в блоке WordPress. В частности, давайте будем получать данные из внешнего API и отображать их во внешнем интерфейсе, когда конкретный блок перетаскивается в редактор блоков.
Мы собираемся построить блок, который выводит данные, которые показывают футбол (э-э, футбол) рейтинги взяты из Апи-Футбол.
Существует несколько способов интеграции API с блоком WordPress! Поскольку в статье об основах работы с блоками уже описан процесс создания блока с нуля, мы упростим задачу, используя @wordpress/create-block
package для запуска нашей работы и структурирования нашего проекта.
Инициализация нашего блочного плагина
Перво-наперво: давайте запустим новый проект из командной строки:
npx @wordpress/create-block football-rankings
Обычно я запускаю такой проект, создавая файлы с нуля, но спасибо команде WordPress Core за эту удобную утилиту!
После того, как команда создала папку проекта, технически у нас есть полнофункциональный блок WordPress, зарегистрированный как плагин. Итак, давайте продолжим и поместим папку проекта в wp-content/plugins
каталог, в котором у вас установлен WordPress (вероятно, лучше всего работать в локальной среде), затем войдите в систему администратора WordPress и активируйте его на экране «Плагины».
Теперь, когда наш блок инициализирован, установлен и активирован, откройте папку проекта по адресу /wp-content/plugins/football-rankings
. ты захочешь cd
также из командной строки, чтобы убедиться, что мы можем продолжить разработку.
Это единственные файлы, на которых нам нужно сосредоточиться в данный момент:
edit.js
index.js
football-rankings.php
Другие файлы в проекте, конечно, важны, но на данном этапе они несущественны.
Просмотр исходного кода API
Мы уже знаем, что используем Апи-Футбол который приходит к нам благодаря РапидAPI. К счастью, у RapidAPI есть панель инструментов, которая автоматически генерирует необходимые сценарии, необходимые для получения данных API для турнирной таблицы Премьер-лиги 2021 года.
Если вы хотите взглянуть на структуру JSON, вы можете создать визуальное представление с помощью JSONCrack.
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
функция почти не повреждена, но есть примечание, подтверждающее, что футбольные турнирные таблицы отображаются в интерфейсе. Опять же, в этой статье мы сосредоточимся только на внешнем интерфейсе — мы могли бы отображать данные и в редакторе блоков, но мы оставим это для другой статьи, чтобы сосредоточиться на этом.
Хранение данных API в WordPress
Теперь, когда мы извлекаем данные, нам нужно сохранить их где-нибудь в 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()
с конкретным идентификатором блока.По сути, я подожду, пока окно загрузится и возьмет данные для нескольких ключевых объектов из JSON, и применю их к некоторой разметке, которая отображает их на внешнем интерфейсе. Я тоже собираюсь конвертировать
attributes
данные в объект JSON, чтобы было легче читать JavaScript, и устанавливать детали из JSON в HTML для таких вещей, как логотип футбольной лиги, логотипы команд и статистика.Столбец «Последние 5 игр» показывает результат последних пяти матчей команды. Мне нужно вручную изменить данные для него, так как данные 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()
извлек данные из него, сохранил их в базе данных WordPress, проанализировал и применил к некоторой HTML-разметке для отображения в интерфейсе. Неплохо для одного урока, верно?Опять же, мы можем сделать то же самое, чтобы ранжирование отображалось в редакторе блоков в дополнение к внешнему интерфейсу темы. Но, надеюсь, сосредоточив внимание на внешнем интерфейсе, вы увидите, как работает выборка данных в блоке WordPress и как данные могут быть структурированы и отображены для отображения.