WP Rest API: detalhes da postagem mais recente, incluindo o URL da mídia em destaque em uma solicitação?

15

Estou usando a API wp-rest para obter informações sobre postagens. Também uso itens de filtro wp rest api para filtrar campos e resumir o resultado:

Quando eu ligo http://example.com/wp-json/wp/v2/posts?items=id,title,featured_media, retorna resultados como este:

[

    {
        "id": 407,
        "title": {
            "rendered": "Title 1"
        },
        "featured_media": 399
    },
    {
        "id": 403,
        "title": {
            "rendered": "Title 2"
        },
        "featured_media": 401
    }

]

A questão é como posso gerar um URL de mídia em destaque usando esse ID? Por padrão, a chamada http://example.com/wp-json/wp/v2/media/401retorna um novo json que possui todos os detalhes sobre URLs de diferentes tamanhos de imagem de origem:

{

    "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"
            }
        ]
    }

}

Mas considere o caso em que quero obter a lista de postagens e suas miniaturas. Uma vez que devo ligar http://example.com/wp-json/wp/v2/posts?items=id,title,featured_media, devo ligar http://example.com/wp-json/wp/v2/media/id10 vezes para cada ID de mídia, analisar os resultados e obter o URL final da miniatura da mídia. Portanto, ele precisa de 11 solicitações para obter detalhes de 10 postagens (uma para lista e 10 para miniaturas). É possível obter esses resultados em uma solicitação?

VSB
fonte
11
Você registrou um novo campo para sua resposta com register_rest_field?
Benoti
@Benoti Vou verificar sua documentação. Se houvesse mais coisas para perguntar eu vou voltar para você :)
VSB
É verdade, você não tem a data da imagem na solicitação de postagem, apenas o ID da mídia em destaque e uma nova solicitação é necessária no padrão da API do WP.
bueltge
Se você adicionar o _embedparâmetro, o objeto de postagem retornado incluirá todos os detalhes sobre a mídia em destaque e todos os seus tamanhos disponíveis. Verifique minha resposta para um exemplo.
Jesús Franco

Respostas:

18

Ah, eu só tive esse problema! E embora _embedseja ótimo, na minha experiência, é muito lento, e o objetivo do JSON é ser rápido: D

Eu tenho o seguinte código em um plug-in (usado para adicionar tipos de postagem personalizados), mas imagino que você possa colocá-lo no function.phparquivo do seu tema .

php

add_action( 'rest_api_init', 'add_thumbnail_to_JSON' );
function add_thumbnail_to_JSON() {
//Add featured image
register_rest_field( 
    'post', // Where to add the field (Here, blog posts. Could be an array)
    'featured_image_src', // Name of new field (You can call this anything)
    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'], // Image attachment ID
    'thumbnail',  // Size.  Ex. "thumbnail", "large", "full", etc..
    true // Whether the image should be treated as an icon.
  );
  return $feat_img_array[0];
}

Agora, na sua resposta JSON, você verá um novo campo chamado "featured_image_src":contendo uma URL para a miniatura.

Leia mais sobre a modificação de respostas aqui:
http://v2.wp-api.org/extending/modifying/

E aqui estão mais informações sobre as funções register_rest_fielde 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/

** Nota: Não esqueça as <?php ?>tags se este for um novo arquivo php!

StephanieQ
fonte
2
Isso funciona muito bem e ajuda que o _embed não precise ser usado, pois eu quero apenas a imagem em tamanho real. Eu tive que alterá-lo para: ($object['featured_media'], 'fullsize', false);para não me dar o URL da miniatura, mas funciona perfeitamente via functions.php --Obrigado!
Jordan
11
Todo esse malabarismo com o terminal da API RES me lembra por que gosto do GraphQL e que devo terminar os wrappers da API REST e dos novos resolvedores personalizados ;-) De qualquer forma, é uma solução inteligente e, na verdade, utilizo terminais personalizados na produção para obter os dados Eu preciso (e exatamente isso).
Jesús Franco
O novo plug-in possui, http://mahditajik.ir/wp-json/wp/v2/media/<id>mas possui muitos dados extras que tornam a resposta lenta, de modo que eu possa personalizar a API REST do DEST?
Mahdi
11
Muito obrigado, isso me ajudou a concluir meu recurso de conteúdo em destaque! : D
Atem18
11
Eu só queria que você soubesse que isso diminuiu 2s do meu tempo de carregamento! Muito obrigado e pela sua bibliografia cuidadosamente selecionada!
GuiHarrison 12/02/19
7

Basta adicionar o _embedargumento de consulta ao seu URL solicitando as postagens, e todo objeto de postagem incluirá o _embedded.[wp:featuredmedia]objeto, que inclui todas as imagens, assim como o /media/$idrecurso. Se você deseja um tamanho específico, basta acessá-lo pelo nome da propriedade, ou seja, _embedded[wp:featuredmedia][0].media_details.sizes.full.source_urlpela miniatura:_embedded[wp:featuredmedia][0].media_details.sizes.thumbnail.source_url

Ou seja, o objeto incorporado wp: featuredmedia inclui todos os URLs e detalhes para todos os tamanhos disponíveis para sua postagem, mas se você quiser apenas a imagem em destaque original, poderá usar o valor nesta chave: post._embedded["wp:featuredmedia"][0].source_url

Eu o uso em um site com algo assim (use seu próprio domínio, é claro):

$.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);
    });
});

Vejo? Não há necessidade de duas consultas, basta adicionar _embedcomo argumento de consulta e você terá todas as informações necessárias para usar o melhor tamanho para sua exibição.

Jesús Franco
fonte