WP Rest API: получение данных последнего поста включая URL изображения в одном запросе?

2 окт. 2016 г., 16:29:58
Просмотры: 33.4K
Голосов: 19

Я использую 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 для миниатюр). Возможно ли получить эти результаты в одном запросе?

4
Комментарии

Вы зарегистрировали новое поле для вашего ответа с помощью register_rest_field?

Benoti Benoti
2 окт. 2016 г. 17:34:12

@Benoti Я проверю документацию. Если у меня будут еще вопросы, я вернусь к вам :)

VSB VSB
2 окт. 2016 г. 19:44:28

Это верно, у вас нет даты изображения в POST-запросе, только ID медиа-файла и требуется новый запрос к стандартному API WordPress.

bueltge bueltge
3 окт. 2016 г. 12:18:09

Если добавить параметр _embed, возвращаемый объект записи включает все детали об избранном медиафайле и всех доступных размерах. Посмотрите мой ответ для примера.

Jesús Franco Jesús Franco
3 окт. 2016 г. 23:53:45
Все ответы на вопрос 3
5
29

Ах, у меня была такая же проблема! И хотя _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-файл!

19 дек. 2016 г. 22:17:55
Комментарии

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

Jordan Jordan
4 дек. 2017 г. 02:41:00

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

Jesús Franco Jesús Franco
4 дек. 2017 г. 18:20:23

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

Mahdi Mahdi
11 апр. 2018 г. 18:19:41

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

Atem18 Atem18
27 июн. 2018 г. 20:17:51

Хочу сообщить, что это сократило время загрузки на 2 секунды! Огромное спасибо за вашу тщательно подобранную библиографию!

GuiHarrison GuiHarrison
12 февр. 2019 г. 21:53:26
0
11

Просто добавьте параметр запроса _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 как параметр запроса, и у вас будет вся необходимая информация для использования оптимального размера изображения в вашем представлении.

3 окт. 2016 г. 23:49:40
0

Добавление &_embed к вашему URL добавит wp:featuremedia в ваш JSON, даже если у вас есть пользовательские записи.

Пример:

https://example.com/wp-json/wp/v2/posts?search=НазваниеЗаписи&_embed&order=asc
4 нояб. 2020 г. 15:42:03