Vamos a hacer un bloque dinámico que muestre un listado de contenidos extraídos de un servicio externo. En este caso volveremos a traernos los últimos posts del blog de WordPress.org y en otro ejemplo mostraremos un listado de libros haciendo una solicitud a una API pública externa.
En WordPress para realizar solicitudes HTTP disponemos de la API HTTP. Son un conjunto de funciones que nos permitirán acceder, consular y manipular de forma remota servicios de API de terceros, recursos externos o consultar la propia REST API de WordPress entre otras funcionalidades.
En este tutorial vamos a repasar las distintas funciones que trae esta API para obtener un resultado de recursos perfecto combinándolas entre ellas.
¿Qué podemos hacer con la API HTTP?
- Integración de APIs de terceros para plugin, themes o desarrollos Headless.
- Obtener datos de un servicio web externo como: Meteorología, resultados deportivos, precio de criptomonedas…
- Descargar archivos en remoto como imágenes o PDFs.
- Integración con servicios de almacenamiento en la nube.
- Actualización de datos actuando directamente sobre la base de datos de WordPress.
- Sincronización con servicios externos con un CRM como puede ser: Ofertas de empleo, inmuebles, conciertos…
Con la API HTTP de WordPress se simplifica la realización de solicitudes remotas. También nos permite alterar la información que nos devuelve.
Funciones solicitantes:
- wp_remote_get($url, $args); Utiliza el método GET para recuperar un recurso incluyendo el contenido principal del cuerpo (body).
- wp_remote_post($url, $args); Utiliza el método POST para enviar y guardar datos en la base de datos.
- wp_remote_head($url, $args); Es similar a una solicitud GET, pero sin obtener el contenido principal del cuerpo (body).
- wp_remote_request($url, $args); Es la función genérica que nos permite realizar todos los métodos de solicitudes HTTP (POST, GET, PUT, DELETE, PATCH, TRACE, OPTIONS, HEAD).
Estas cuatro funciones nos permiten poner dos argumentos ($url, $args(OPCIONAL)). Podemos incluir alguno de los siguientes argumentos para dar instrucciones a la solicitud:
$response = wp_remote_request($url, array(
'method' => 'GET', // Método de la solicitud: GET, POST, PUT, DELETE, etc.
'timeout' => 10, // Tiempo máximo de espera para la respuesta antes de que se anule la solicitud (en segundos).
'redirection' => 5, // Número máximo de redirecciones permitidas antes de que se detenga la solicitud.
'httpversion' => '1.0', // Versión de HTTP a utilizar en la solicitud.
'headers' => array(
'Content-Type' => 'application/json', // Encabezados adicionales para incluir en la solicitud.
),
'user-agent' => 'wordpress/6.4; https://israelescuer.com/', // Agregar un encabezado "User-Agent" para identificar el cliente que realiza la solicitud.
'reject_unsafe_urls' => $url, // Rechazar URL potencialmente peligrosas para evitar ataques de seguridad.
'blocking' => true, // Indicar si el script debe esperar a que se complete la solicitud antes de continuar la ejecución.
'body' => null, // Datos adicionales para enviar con la solicitud, utilizados principalmente en métodos POST y PUT.
'cookies' => array(), // Cookies adicionales para incluir en la solicitud si es necesario.
'compress' => false, // Deshabilitar la compresión de la solicitud para evitar problemas de compatibilidad con algunos servidores.
'decompress' => true, // Habilitar la descompresión de la respuesta para procesar la respuesta de forma adecuada.
'sslverify' => true, // Verificar el certificado SSL del servidor remoto para garantizar la seguridad de la conexión.
'sslcertificates' => ABSPATH . WPINC . '/certificates/ca-bundle.crt', // Especificar la ruta del archivo de certificados SSL para la verificación.
'stream' => false, // Indicar si se debe usar un flujo de datos para la solicitud en lugar de cargarla en la memoria.
'filename' => NULL, // Nombre del archivo donde se almacenará la respuesta si se desea guardar en disco.
'limit_response_size' => NULL // Limitar el tamaño máximo de la respuesta para evitar consumir demasiada memoria.
));
Para que se entiendas mejor, se puede obtener el mismo resultado utilizando una de las funciones específicas o utilizando la función genérica.
//Obtenies el mismo resultado GET de la siguiente form
$get_results = wp_remote_get($url, $args);
$get_results = wp_remote_request($url, array( 'method' => 'GET' ));
//Obtenies el mismo resultado POST de la siguiente forma
$post_results = wp_remote_post($url, $args);
$post_results = wp_remote_request($url, array( 'method' => 'POST' ));
//Obtenies el mismo resultado HEAD de la siguiente forma
$head_results = wp_remote_head($url, $args);
$head_results = wp_remote_request($url, array( 'method' => 'HEAD' ));
Funciones para entender las respuestas:
- wp_error(); y is_wp_error(); Se utilizan comúnmente para manejar errores dentro de WordPress y personalizar el manejo de errores para determinadas situaciones.
- wp_remote_retrieve_response_code(); Recuperar el código de estado HTTP de la respuesta. Devuelve el código de estado HTTP como un entero.
- wp_remote_retrieve_response_message(); Recuperar el mensaje de estado HTTP de la respuesta de una solicitud HTTP. Devuelve el mensaje de estado HTTP como una cadena.
- wp_remote_retrieve_header(); Recuperar el valor de un encabezado HTTP específico de la respuesta de una solicitud HTTP. Devuelve el valor del encabezado como una cadena o
false
si no se encuentra. - wp_remote_retrieve_headers(); Recuperar todos los encabezados HTTP de la respuesta de una solicitud HTTP. Devuelve los encabezados como un array.
- wp_remote_retrieve_body(); Recuperar el cuerpo de la respuesta de una solicitud HTTP. Devuelve el cuerpo de la respuesta como una cadena.
- json_decode(); Esta función se utiliza para decodificar una cadena JSON y convertirla en un objeto o un array en PHP. Es útil para manipular datos JSON recibidos desde una API o servicio web en PHP.
*IMPORTANTE No todas las APIs son públicas, en ocasiones necesitarás una clave de autenticación para obtener su contenido. En tal caso habrá que meter las credenciales necesarias en las cabeceras (headers).
$args = array(
'headers' => array(
'Accept' => 'application/json',
'Authorization' => 'token 3f4f654ab31c2f15e839c74c952e5de2f562f1ee'
)
);
Hago desarrollos a medida con WordPress para agencias
Domino la programación a medida con WordPress, creando soluciones personalizadas, escalables, con buen rendimiento y seguras. Proyectos como CRMs, Intranet, Tiendas Online o WordPress Headless entre otros.
Empezamos…
Una vez entiendes bien estas funciones, podrás preparar fragmentos de código avanzados controlando al detalle las solicitudes y todo tipo de respuestas obtenidas.
El primer ejercicio hará una llamada a la REST API del blog de WordPress.org, como argumentos le voy a decir que si tarda mas de 10 segundos que se anule la petición y le paso un filtro indicando que debería obtener una respuesta en formato JSON.
Compruebo que la solicitud esta OK y si me devuelve un código 200, seguidamente transformo el contenido del JSON en un formato que pueda manipular con PHP. Utilizando json_decode().
El resultado lo itero con PHP y la función foreach() para recorrer cada uno de los post y obtener su información en este caso el título de cada post que es lo que le estoy indicando.
Todo lo envuelvo en una función que crea un shortcode el cual puedo reutilizar en distintos sitios de mi web y por supuesto no me olvido de ponerle un buffer de salida para que el PHP se ejecute siempre al finalizar la función.
function remote_ultimas_entradas_blog() {
// Iniciar el almacenamiento en el buffer de salida
ob_start();
// Realizar la solicitud para obtener los títulos de los posts
$response = wp_remote_get('https://es.wordpress.org/wp-json/wp/v2/posts/', array(
'timeout' => 10,
'headers' => array(
'Content-Type' => 'application/json',
)
));
// Verificar si la solicitud fue exitosa
if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
// Decodificar la respuesta JSON
$posts_data = json_decode(wp_remote_retrieve_body($response), true);
// Preparar los datos para los títulos de los posts
$post_titles = '';
foreach ($posts_data as $post) {
$title = isset($post['title']['rendered']) ? esc_html($post['title']['rendered']) : '';
// Agregar cada título como un elemento <li> a la lista
$post_titles .= '<li>' . $title . '</li>';
}
// Mostrar los títulos de los posts
echo '<ul>' . $post_titles . '</ul>';
} else {
// En caso de error en la solicitud
echo 'No se pudo obtener los títulos de los posts.';
}
// Capturar y limpiar el contenido del buffer de salida
$content = ob_get_clean();
// Devolver el contenido generado por el shortcode
return $content;
}
add_shortcode('remote-ultimas-entradas-blog', 'remote_ultimas_entradas_blog');
Resultado del bloque dinámico de posts
- Meetup y WordCamp en España – Enero 2025
- Cómo configurar la identificación en dos pasos (2FA) en WordPress
- Meetup y WordCamp en España – Diciembre 2024
- Publicación de recomendaciones para mejorar la inclusividad en los eventos
- WordPress 6.7.1 – Actualización de mantenimiento
- WordCamp Griñón 2024: Hambre de negocio (y de coliflores)
- WordCamp Sevilla 2024, un evento para contribuir con la comunidad
- WordPress 6.7 «Rollins»
- Meetup y WordCamp en España – Noviembre 2024
- WordTributor Day Sevilla 2024: Elige tu Propia Aventura
Bloque en tiempo real con los títulos de posts
De igual forma, comparto otro ejemplo extrayendo contenido de una API externa de libros. Utilizo prácticamente el mismo código a excepción de la iteración de libros. Lo primero que hay que hacer es examinar el JSON que te devuelve la solicitud y ajustar el código con los campos que necesites. En este caso hay que entrar en «results» y únicamente extraer el «title».
* Esto es distinto en todas las APIs. ¡Por favor! tomate un tiempo para analizar sus respuesta y ajusta bien los datos que vas a extraer. Utiliza una herramienta como Postman para enviar y recibir solicitudes.
function remote_books() {
ob_start();
$response = wp_remote_get('https://gutendex.com/books/?languages=es', array(
'timeout' => 10,
'headers' => array(
'Content-Type' => 'application/json',
)
));
if (is_wp_error($response)) {
return 'Error en la solicitud remota: ' . $response->get_error_message();
}
$posts_data = json_decode(wp_remote_retrieve_body($response), true);
// Verificar si se pudo decodificar el JSON correctamente
if ($posts_data === null) {
return 'Error al decodificar la respuesta JSON.';
}
// Verificar si la propiedad "results" existe en $posts_data
if (!isset($posts_data['results'])) {
return 'No se encontraron resultados en la respuesta JSON.';
}
$post_titles = '';
foreach ($posts_data['results'] as $post) {
$title = isset($post['title']) ? esc_html($post['title']) : '';
$post_titles .= '<li>' . $title . '</li>';
}
echo '<ul>' . $post_titles . '</ul>';
$content = ob_get_clean();
// Devolver el contenido generado por el shortcode
return $content;
}
add_shortcode('remote-books', 'remote_books');
Resultado del listado de libros en Español
- Don Quijote
- Mi Ultimo Adiós
- Doctrina Christiana: The first book printed in the Philippines, Manila, 1593.
- La Odisea
- El paraíso perdido
- La Divina Comedia
- Spanish Tales for Beginners
- El libro de las mil noches y una noche; t. 1
- Diccionario Ingles-Español-Tagalog: Con partes de la oracion y pronunciacion figurada
- El crimen y el castigo
- Cuentos de Amor de Locura y de Muerte
- El Hombre Mediocre: Ensayo de psicologia y moral
- A First Spanish Reader
- Niebla (Nivola)
- El árbol de la ciencia: novela
- Doña Perfecta
- El arte de amar
- El libro de las tierras vírgenes
- An Elementary Spanish Reader
- Las cien mejores poesías (líricas) de la lengua castellana
- Noli me tángere: Novela Tagala, Edición completa con notas de R. Sempau
- La isla del tesoro
- Cecilia Valdés o la Loma del Ángel
- La Ilíada
- Las Fábulas de Esopo, Vol. 01
- Cuentos escogidos
- Vida de Jesús
- Zumalacárregui
- Novelas Cortas
- Edipo rey; Edipo en Colona; Antígona
- Legends, Tales and Poems
- Platero y yo
Bloque en tiempo real con los títulos de una API externa de libros
Muchas gracias por llegar hasta el final del artículo, espero que te sirva de ayuda para gestionar solicitudes de APIs externas y consigas hacer desarrollos web muchas mas complejos y profesionales.