WP Rest API: dettagli dell'ultimo post incluso l'URL dei media in evidenza in una singola richiesta?
Sto utilizzando wp-rest api per ottenere informazioni sui post. Uso anche wp rest api filter items per filtrare i campi e sintetizzare il risultato:
Quando chiamo http://example.com/wp-json/wp/v2/posts?items=id,title,featured_media
restituisce risultati come questo:
[
{
"id": 407,
"title": {
"rendered": "Titolo 1"
},
"featured_media": 399
},
{
"id": 403,
"title": {
"rendered": "Titolo 2"
},
"featured_media": 401
}
]
La domanda è come posso generare l'URL dei media in evidenza usando questo ID? Per impostazione predefinita, chiamando http://example.com/wp-json/wp/v2/media/401
restituisce un nuovo json che contiene tutti i dettagli sull'URL delle diverse dimensioni dell'immagine sorgente:
{
"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"
}
]
}
}
Ma consideriamo il caso in cui voglio ottenere l'elenco dei post e le loro miniature. Una volta devo chiamare http://example.com/wp-json/wp/v2/posts?items=id,title,featured_media
poi devo chiamare http://example.com/wp-json/wp/v2/media/id
10 volte per ogni ID dei media e poi analizzare i risultati e ottenere l'URL finale della miniatura dei media. Quindi servono 11 richieste per ottenere i dettagli di 10 post (una per l'elenco, 10 per le miniature).
È possibile ottenere questi risultati in una sola richiesta?
Ah, ho appena avuto questo problema anch'io! E anche se _embed
è ottimo, nella mia esperienza è molto lento, e il punto del JSON è essere veloce :D
Ho il seguente codice in un plugin (usato per aggiungere custom post type), ma immagino che potresti inserirlo nel file function.php
del tuo tema.
php
add_action( 'rest_api_init', 'add_thumbnail_to_JSON' );
function add_thumbnail_to_JSON() {
// Aggiunge l'immagine in evidenza
register_rest_field(
'post', // Dove aggiungere il campo (Qui, articoli del blog. Potrebbe essere un array)
'featured_image_src', // Nome del nuovo campo (Puoi chiamarlo come vuoi)
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 dell'allegato immagine
'thumbnail', // Dimensione. Es. "thumbnail", "large", "full", ecc..
true // Se l'immagine deve essere trattata come un'icona.
);
return $feat_img_array[0];
}
Ora nella tua risposta JSON dovresti vedere un nuovo campo chiamato "featured_image_src":
contenente un URL alla miniatura.
Leggi di più sulla modifica delle risposte qui:
http://v2.wp-api.org/extending/modifying/
E qui ci sono più informazioni sulle funzioni register_rest_field
e 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: Non dimenticare i tag <?php ?>
se questo è un nuovo file php!

Funziona benissimo e aiuta che non sia necessario usare _embed dato che voglio solo l'immagine in evidenza a dimensione intera. Ho dovuto modificarlo in: ($object['featured_media'], 'fullsize', false);
per non ottenere l'URL della miniatura, ma funziona perfettamente tramite functions.php --Grazie!

Tutta questa manipolazione con l'endpoint REST API mi ricorda perché mi piace GraphQL e che dovrei finire i wrapper dell'REST API e i nuovi resolver personalizzati ;-) Comunque, è una soluzione intelligente e in effetti uso endpoint personalizzati in produzione per ottenere i dati di cui ho bisogno (e solo quelli).

Il nuovo plugin ha http://mahditajik.ir/wp-json/wp/v2/media/<id>
ma contiene molti dati extra che rallentano la risposta, quindi come posso personalizzare la risposta dell'API REST?

Grazie mille, mi ha aiutato a completare la mia funzionalità di contenuto in evidenza! :D

Basta aggiungere l'argomento di query _embed
al tuo URL quando richiedi i post, e ogni oggetto post includerà l'oggetto _embedded.[wp:featuredmedia]
, che contiene tutte le immagini, proprio come la risorsa /media/$id
. Se vuoi una dimensione specifica, accedi semplicemente alla sua proprietà, ad esempio: _embedded[wp:featuredmedia][0].media_details.sizes.full.source_url
o per la sua miniatura: _embedded[wp:featuredmedia][0].media_details.sizes.thumbnail.source_url
In altre parole, l'oggetto embedded wp:featuredmedia include tutti gli URL e i dettagli per ogni dimensione disponibile per il tuo post, ma se vuoi solo l'immagine in evidenza originale, puoi usare il valore in questa chiave: post._embedded["wp:featuredmedia"][0].source_url
Lo uso in un sito con qualcosa del genere (usa ovviamente il tuo dominio):
$.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);
});
});
Vedi? Non servono due query, basta aggiungere _embed
come argomento di query, e poi avrai tutte le informazioni necessarie per usare la dimensione migliore per la tua visualizzazione.
