WP Rest API: получение данных последнего поста включая URL изображения в одном запросе?
Я использую wp-rest api для получения информации о постах. Также я использую фильтрацию элементов wp rest api для фильтрации полей и суммирования результата:
Когда я вызываю http://example.com/wp-json/wp/v2/posts?items=id,title,featured_media
, он возвращает результаты такого вида:
[
{
"id": 407,
"title": {
"rendered": "Заголовок 1"
},
"featured_media": 399
},
{
"id": 403,
"title": {
"rendered": "Заголовок 2"
},
"featured_media": 401
}
]
Вопрос в том, как сгенерировать URL изображения используя этот id? По умолчанию вызов http://example.com/wp-json/wp/v2/media/401
возвращает новый json, который содержит все детали об URL различных размеров исходного изображения:
{
"id": 401,
"date": "2016-06-03T17:29:09",
"date_gmt": "2016-06-03T17:29:09",
"guid": {
"rendered": "http://example.com/wp-content/uploads/my-image-name.png"
},
"modified": "2016-06-03T17:29:09",
"modified_gmt": "2016-06-03T17:29:09",
"slug": "my-image-name",
"type": "attachment",
"link": "http://example.com/my-post-url",
"title": {
"rendered": "my-image-name"
},
"author": 1,
"comment_status": "open",
"ping_status": "closed",
"alt_text": "",
"caption": "",
"description": "",
"media_type": "image",
"mime_type": "image/png",
"media_details": {
"width": 550,
"height": 250,
"file": "my-image-name.png",
"sizes": {
"thumbnail": {
"file": "my-image-name-150x150.png",
"width": 150,
"height": 150,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name-150x150.png"
},
"medium": {
"file": "my-image-name-300x136.png",
"width": 300,
"height": 136,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name-300x136.png"
},
"one-paze-port-thumb": {
"file": "my-image-name-363x250.png",
"width": 363,
"height": 250,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name-363x250.png"
},
"one-paze-blog-thumb": {
"file": "my-image-name-270x127.png",
"width": 270,
"height": 127,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name-270x127.png"
},
"one-paze-team-thumb": {
"file": "my-image-name-175x175.png",
"width": 175,
"height": 175,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name-175x175.png"
},
"one-paze-testimonial-thumb": {
"file": "my-image-name-79x79.png",
"width": 79,
"height": 79,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name-79x79.png"
},
"one-paze-blog-medium-image": {
"file": "my-image-name-380x250.png",
"width": 380,
"height": 250,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name-380x250.png"
},
"full": {
"file": "my-image-name.png",
"width": 550,
"height": 250,
"mime_type": "image/png",
"source_url": "http://example.com/wp-content/uploads/my-image-name.png"
}
},
"image_meta": {
"aperture": "0",
"credit": "",
"camera": "",
"caption": "",
"created_timestamp": "0",
"copyright": "",
"focal_length": "0",
"iso": "0",
"shutter_speed": "0",
"title": "",
"orientation": "0",
"keywords": [ ]
}
},
"post": 284,
"source_url": "http://example.com/wp-content/uploads/my-image-name.png",
"_links": {
"self": [
{
"href": "http://example.com/wp-json/wp/v2/media/401"
}
],
"collection": [
{
"href": "http://example.com/wp-json/wp/v2/media"
}
],
"about": [
{
"href": "http://example.com/wp-json/wp/v2/types/attachment"
}
],
"author": [
{
"embeddable": true,
"href": "http://example.com/wp-json/wp/v2/users/1"
}
],
"replies": [
{
"embeddable": true,
"href": "http://example.com/wp-json/wp/v2/comments?post=401"
}
]
}
}
Но рассмотрим случай, когда я хочу получить список постов и их миниатюр. Сначала мне нужно вызвать http://example.com/wp-json/wp/v2/posts?items=id,title,featured_media
, затем вызвать http://example.com/wp-json/wp/v2/media/id
10 раз для каждого media id, а затем разобрать результаты и получить конечный URL миниатюры. Таким образом, требуется 11 запросов для получения деталей 10 постов (один для списка, 10 для миниатюр).
Возможно ли получить эти результаты в одном запросе?
Ах, у меня была такая же проблема! И хотя _embed
хорош, по моему опыту он очень медленный, а цель JSON — быть быстрым :D
У меня есть следующий код в плагине (используется для добавления пользовательских типов записей), но я думаю, вы могли бы поместить его в файл function.php
вашей темы.
php
add_action( 'rest_api_init', 'add_thumbnail_to_JSON' );
function add_thumbnail_to_JSON() {
//Добавляем изображение записи
register_rest_field(
'post', // Где добавить поле (здесь — записи блога. Можно указать массив)
'featured_image_src', // Название нового поля (можете назвать как угодно)
array(
'get_callback' => 'get_image_src',
'update_callback' => null,
'schema' => null,
)
);
}
function get_image_src( $object, $field_name, $request ) {
$feat_img_array = wp_get_attachment_image_src(
$object['featured_media'], // ID вложения изображения
'thumbnail', // Размер. Например: "thumbnail", "large", "full" и т.д.
true // Следует ли обрабатывать изображение как иконку.
);
return $feat_img_array[0];
}
Теперь в вашем JSON-ответе должно появиться новое поле "featured_image_src":
, содержащее URL миниатюры.
Подробнее о модификации ответов здесь:
http://v2.wp-api.org/extending/modifying/
А здесь больше информации о функциях register_rest_field
и wp_get_attachment_image_src()
:
1.) https://developer.wordpress.org/reference/functions/register_rest_field/
2.) https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/
**Примечание: Не забудьте теги <?php ?>
, если это новый PHP-файл!

Это отлично работает и помогает избежать использования _embed, так как мне нужен только полноразмерный featured image. Мне пришлось изменить на: ($object['featured_media'], 'fullsize', false);
чтобы не получать URL миниатюры, но через functions.php работает идеально. Спасибо!

Все эти манипуляции с конечной точкой REST API напоминают мне, почему мне нравится GraphQL и что мне стоит завершить обёртки для REST API и новые кастомные резолверы ;-) В любом случае, это умное решение, и я на самом деле использую кастомные конечные точки в продакшене, чтобы получать только нужные данные (и ничего лишнего).

Новый плагин имеет http://mahditajik.ir/wp-json/wp/v2/media/<id>
, но он содержит много лишних данных, которые замедляют ответ. Как я могу кастомизировать ответ REST API?

Большое спасибо, это помогло мне завершить функционал избранного контента! :D

Просто добавьте параметр запроса _embed
к вашему URL при запросе постов, и каждый объект поста будет включать объект _embedded.[wp:featuredmedia]
, который содержит все изображения, аналогично ресурсу /media/$id
. Если вам нужен конкретный размер изображения, просто обратитесь к нему по имени свойства, например: _embedded[wp:featuredmedia][0].media_details.sizes.full.source_url
или для миниатюры: _embedded[wp:featuredmedia][0].media_details.sizes.thumbnail.source_url
.
То есть, встроенный объект wp:featuredmedia включает все URL-адреса и детали для каждого доступного размера изображения вашего поста. Но если вам нужно только оригинальное изображение записи, вы можете использовать значение из этого ключа: post._embedded["wp:featuredmedia"][0].source_url
.
Я использую это на сайте примерно так (используйте свой домен, конечно):
$.get('https://example.com/wp-json/wp/v2/posts/?categories=3&_embed',
function(posts) {
var elems = '';
posts.forEach(function(post){
var link = post.link;
var title = post.title.rendered;
var pic = post._embedded["wp:featuredmedia"][0].source_url);
elems += '<div class="this_week"><a href="' + link + '" target="_blank">';
elems += '<img src="' + pic + '" title="' + title + '"/><span class="title">';
elems += title + '</span></a></div>';
});
$('#blockbusters').html(elems);
});
});
Видите? Нет необходимости в двух запросах, просто добавьте _embed
как параметр запроса, и у вас будет вся необходимая информация для использования оптимального размера изображения в вашем представлении.
