Вопрос или проблема
Обычно нахожу здесь то, что мне нужно, не задавая вопросов, но, похоже, столкнулся с чем-то новым, извините, если это уже было отвечено в другом месте. Я создаю сайт на WordPress, который не является моей обычной CMS, но кажется достаточно простым. Я пытаюсь получить данные публикации с помощью API, обращаясь к данным на /wp-json/wp/v2/pages/24, что прекрасно, пока мы не дойдем до самого содержимого. Контент блока/страницы приходит только в полностью отрендеренном формате с HTML. Я пробовал использовать разный контекст, но это, похоже, либо ничего не делает, либо вызывает ошибку разрешений.
Я ищу что-то подобное приведенному ниже, но, кажется, не могу этого нигде найти. Это просто недоступно или я упускаю суть этого API? Любая помощь была бы замечательной!
"content": {
"blocks": {
"cover": {
"classes": "wp-block-cover has-background-dim",
"background-image": "https:\/\/localhost.local:8890\/wp-content\/uploads\/2020\/07\/92977310_Preview.jpeg",
"content": "Our Range Title"
},
"image": {
"classes": "wp-block-image",
"image": "https:\/\/localhost.local:8890\/wp-content\/uploads\/2020\/07\/976545678.jpeg",
"alt": "This is the alt for the image"
},
"layout": {
"classes": "background-green",
"columns": 2,
"content": [
{
"image": {
"classes": "wp-block-image",
"image": "https:\/\/localhost.local:8890\/wp-content\/uploads\/2020\/07\/976545678.jpeg",
"alt": "This is the alt for the image"
},
"paragraph": {
"classes": "",
"content": "This is the <strong>paragraph for</strong> the left column."
}
},
{
"image": {
"classes": "wp-block-image",
"image": "https:\/\/localhost.local:8890\/wp-content\/uploads\/2020\/07\/976545678.jpeg",
"alt": "This is the alt for the image"
},
"paragraph": {
"classes": "",
"content": "This is the <strong>paragraph for</strong> the right column."
}
}
]
}
},
"protected": false
}
Очень старый вопрос, но если кто-то блуждает по API Rest API WordPress, как я, вот краткий фрагмент кода, который можно добавить в файл functions.php вашей темы, чтобы добавить поле blocks
к возвращаемым данным поста/страницы.
add_action(
'rest_api_init',
function () {
if ( ! function_exists( 'use_block_editor_for_post_type' ) ) {
require ABSPATH . 'wp-admin/includes/post.php';
}
// Отобразить все блоки Гутенберга в REST API WordPress
$post_types = get_post_types_by_support( [ 'editor' ] );
foreach ( $post_types as $post_type ) {
if ( use_block_editor_for_post_type( $post_type ) ) {
register_rest_field(
$post_type,
'blocks',
[
'get_callback' => function ( array $post ) {
return parse_blocks( $post['content']['raw'] );
},
]
);
}
}
}
);
В результате будет возвращаться следующий JSON, полученный из запроса одного поста:
"blocks": [
{
"blockName": "core\/paragraph",
"attrs": [],
"innerBlocks": [],
"innerHTML": "\n<p>Here is the story content for section 1.<\/p>\n",
"innerContent": [
"\n<p>Here is the story content for section 1.<\/p>\n"
]
},...
Тоже самое здесь, хотя это и старое, но полезное, поэтому вот еще один ответ:
add_action('rest_api_init', function () {
if (!function_exists('use_block_editor_for_post_type')) {
require ABSPATH . 'wp-admin/includes/post.php';
}
// Получить все типы записей, поддерживающие редактор блоков
$post_types = get_post_types_by_support(['editor']);
foreach ($post_types as $post_type) {
if (use_block_editor_for_post_type($post_type)) {
register_rest_field(
$post_type,
'blocks',
[
'get_callback' => function (array $post) {
return parse_blocks($post['content']['raw']);
},
'update_callback' => function ($blocks, $post) {
return update_post_blocks($post['ID'], $blocks);
},
'schema' => [
'description' => 'Блоки Гутенберга в виде JSON',
'type' => 'array',
],
]
);
}
}
});
/**
* Обновляет пост WordPress новыми блоками Гутенберга.
*
* @param int $post_id Идентификатор поста для обновления.
* @param array $blocks Новые блоки для вставки.
* @return bool|WP_Error True при успешном выполнении, WP_Error при ошибке.
*/
function update_post_blocks($post_id, $blocks)
{
if (!current_user_can('edit_post', $post_id)) {
return new WP_Error('rest_forbidden', __('У вас нет прав на редактирование этого поста.'), ['status' => 403]);
}
if (!is_array($blocks)) {
return new WP_Error('rest_invalid_param', __('Блоки должны быть массивом.'), ['status' => 400]);
}
// Преобразовать блоки обратно в сериализованный post_content
$content = serialize_blocks($blocks);
// Обновить пост
$result = wp_update_post([
'ID' => $post_id,
'post_content' => $content,
], true);
if (is_wp_error($result)) {
return $result;
}
return true;
}
Ответ или решение
Для многих разработчиков, которые начинают работать с WordPress, задача получения данных блоков поста в формате JSON через WordPress API может показаться сложной. Дело в том, что API по умолчанию предоставляет содержимое поста в виде отрендеренного HTML, что не всегда удобно, если вам нужно более структурированное представление данных, особенно когда вы работаете с современными темами и блоками редактора Гутенберг.
Теория
WordPress имеет мощный REST API, который позволяет разработчикам взаимодействовать с данными сайта программным способом. Однако, стандартно содержимое постов возвращается как HTML. Это происходит потому, что WordPress заточен под традиционные веб-сайты, для которых основная задача — это визуальное отображение контента. Однако, для некоторых приложений, таких как headless CMS или более сложные SPA (Single Page Applications), такая реализация может быть не очень удобной.
Пример
Предположим, вы разработали сайт на WordPress, который использует нативные блоки редактора Гутенберг для создания контента страницы. Вы хотите, чтобы API возвращал данные в более структурированном виде, предоставляя доступ к каждому блоку с его атрибутами, внутренним содержимым и другими метаданными. Такой подход облегчает разработку сторонних приложений, которые могут использовать полученные данные в различных контекстах — например, для создания мобильных приложений или других веб-интерфейсов.
В приведенном выше коде, добавление нового REST поля решает эту задачу. Мы регистрируем дополнительное поле blocks
для всех типов постов, поддерживающих редактор. Это поле заполняется, используя функцию parse_blocks()
, которая разбирает сырое содержимое (raw content
) поста и возвращает структуру блоков в виде массива.
Применение
-
Добавление функции в
functions.php
: Вам нужно добавить приведенные примеры кода в файлfunctions.php
вашей темы или в плагин. Это обеспечит регистрацию нового REST поля, которое будет доступно для всех поддерживаемых типов постов.add_action( 'rest_api_init', function () { if (!function_exists('use_block_editor_for_post_type')) { require ABSPATH . 'wp-admin/includes/post.php'; } // Получение всех типов постов, поддерживающих блоковый редактор $post_types = get_post_types_by_support(['editor']); foreach ($post_types as $post_type) { if (use_block_editor_for_post_type($post_type)) { register_rest_field( $post_type, 'blocks', [ 'get_callback' => function (array $post) { return parse_blocks($post['content']['raw']); }, ] ); } } } );
-
Тестирование и использование: Теперь, при запросе поста через API (например,
/wp-json/wp/v2/posts/{id}
), в ответе JSON-документа появится новое полеblocks
. Это поле содержит массив, где каждый элемент предоставляет информацию о соответствующем Gutenberg-блоке, включая его имя (blockName
), атрибуты и внутреннее содержимое (innerHTML
иinnerContent
). -
Обработка данных: В зависимости от ваших нужд, вы можете парсить полученные JSON данные в клиентской части вашего приложения (например, на JavaScript), отображая их соответствующим образом в пользовательском интерфейсе или же используя их в других целях (например, для аналитики или генерации отчетов).
Таким образом, подход, предложенный в коде, позволяет вывести взаимодействие с WordPress на новый уровень, предоставляя разработчикам гибкие инструменты для работы с данными контента. Это особенно актуально в эпоху headless CMS и все более широкого использования WordPress в качестве бэкенд-решения для разнообразных приложений.