En el post anterior veíamos cómo hacer una petición AJAX en WordPress de una manera tradicional. Ahora veremos cómo resolver el mismo ejemplo de la entrada anterior de una manera más moderna y elegante.
Cuando digo moderna y elegante, no me refiero a otra cosa que utilizar la REST API de WordPress y la Fetch API de JavaScript.
Recordamos que lo que buscamos es que cuando pulsemos un botón se muestren los últimos 10 post de un Custom Post Type «evento«, que tenga el custom field «destacado» igual a true. Para ello necesitaremos crear nuestro propio endpoint que nos devuelva esta información
Generando nuestro REST API Endpoint personalizado
Aunque para obtener los eventos destacados podríamos utiliza el filtro rest_{$post_type_name}_query y añadir el soporte a nuestro campo personalizado, para este ejemplo vamos a crear un endpoint nuevo específico para esta consulta que queremos hacer.
<?php
function events_endpoint() {
register_rest_route( 'eventos/', 'destacados', array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'get_events',
) );
}
add_action( 'rest_api_init', 'events_endpoint' );
function get_events( $request ) {
$args = array(
'post_type' => 'evento',
'meta_query' => array(
array(
'key' => 'destacado',
'value' => 1,
'compare' => '=',
),
),
);
$query = new WP_Query( $args );
return $query->posts;
}
Como vemos, utilizamos el método register_rest_route para registrar nuestro nuevo endpoint. Ahora cuando llamemos a https://mi-dominio.com/wp-json/eventos/destacados obtendremos un json con los datos que buscamos.
Esos datos salen del método callback get_events que ejecuta nuestro endpoint. Allí simplemente hacemos una consulta para que nos devuelva todos los posts de nuestro CPT evento, que tengan el campo personalizado destacado=1.
Utilizando la Fetch API de Javascript
Antes de nada, carguemos nuestro archivo eventos.js, al que pasaremos la variable url y nonce.
<?php
function my_load_scripts() {
wp_enqueue_script( 'my_js', get_theme_file_uri( 'js/eventos.js' ), array( 'jquery' ) );
wp_localize_script( 'my_js', 'ajax_var', array(
'url' => rest_url( '/eventos/destacados' ),
'nonce' => wp_create_nonce( 'wp_rest' ),
) );
}
add_action( 'wp_enqueue_scripts', 'my_load_scripts' );
En este ejemplo, al URL no será una llamada a admin-ajax.php como en el ejemplo anterior. Haremos la petición directamente al endpoint que hemos creado. También usaremos el nonce específico para la REST API (wp_rest), que se comprobará de manera automática.
En nuestro archivo JS tendremos lo siguiente:
jQuery(document).ready(function ($) {
$("#boton").on("click", function ($e) {
$e.preventDefault();
const headers = new Headers({
'Content-Type': 'application/json',
'X-WP-Nonce': ajax_var.nonce
});
fetch(ajax_var.url, {
method: 'get',
headers: headers,
credentials: 'same-origin'
})
.then(response => {
return response.ok ? response.json() : 'Not Found...';
}).then(json_response => {
let html;
if (typeof json_response === 'object') {
html = '<ul>';
json_response.forEach((element, index, data) => {
html += '<li>' + element.post_title + '</li>';
});
html += '</ul>';
} else {
html = json_response;
}
$('#eventos').html(html);
});
});
});
Como puede observarse, creamos una constante headers, donde establecemos que el Content-Type es de tipo JSON, y una cabecera X-WP-Nonce para enviar nuestro nonce.
Lo siguiente es hacer una petición fetch a nuestro endpoint. Establecemos como GET como method (aunque es así por defecto), y le pasamos las cabeceras. Una petición fetch nos devuelve una promesa con el resultado.
Preguntaremos si la respuesta tiene ok a true. En caso afirmativo enviaremos la respuesta en formato json a otra promesa. Es aquí donde comprobaremos si json_response es un objeto, y si es así lo recorremos e iremos pintando nuestro HTML.
En la siguiente entrada analizaré desde el punto de vista del performance, las dos maneras de hacer AJAX en WordPress.