Cómo hacer peticiones AJAX con JavaScript, desde cualquier frontend, al backend de WordPress

2020-08-02 - Categorías: JavaScript / PHP / WordPress

Una persona me ha hecho una pregunta sobre WordPress. Curioseando para responder al comentario, inspeccionando las llamadas con el Monitor de Red, me he dado cuenta de una funcionalidad muy interesante que nos brinda WordPress. Resulta que tenemos disponible otra forma de desacoplar el frontend de una instalación WordPress, pero seguir disfrutando del backend de WordPress. Podemos programar con esto en mente, para trabajar la información usando llamadas AJAX que ataquen al CMS.

Rizando el rizo un poco, estas llamadas AJAX, incluso se podrían hacer desde otro tipo de programas que no fueran webs..

Es decir, tenemos un ‘endpoint’ con la ruta wp-admin/admin-ajax.php al que podemos atacar. Y a partir de este punto de entrada podemos crear plugins o themes, con lo que podemos programarle lo que queramos en la parte de backend. Por otro lado, en la parte de frontend, al atacar este endpoint podríamos así desacoplar más todo el frontend, y usar cualquier tecnología de frontend como podría ser Angular, React, Vue, etc.. o incluso otro tipo de programas de escritorio o aplicaciones nativas de móviles.

Testing frontend call with JavaScript to WordPress backend with a plugin..
Testing frontend call with JavaScript to WordPress backend with a plugin..

Resumiendo, hoy traigo un codekata o howto sobre WordPress y el desarrollo de plugins o themes. Se trata de un pequeño desarrollo de un plugin para procesar peticiones AJAX dentro de WordPress en la parte de back, y devolver una respuesta al frontend desde el que se ha llamado para pintar luego los resultados recibidos.

Un poco de historia sobre AJAX

En el origen de los tiempos, todas las páginas web se creaban en el servidor, y se devolvía la respuesta completa al navegador para pintar al visitante la información de una vez. No había programadores frontend y backend, porque todo se programaba en el servidor. Esta era la forma original y más sencilla. Todo programado en el backend, con lenguajes de servidor, que luego se mezclaban con las salidas HTML y CSS.

Con el desarrollo de la web, y tras la aparición de JavaScript, nació la división entre programación backend y frontend (temas aparte dejo a los applets, flash.. y tecnologías de este estilo). Se hizo cada vez más habitual la carga, o recarga, de partes de las webs. Se hacía una carga inicial, y luego ciertas partes se llenaban mediante AJAX. Este AJAX significa Asynchronous JavaScript And XML.

Con esta tecnología, se crearon frameworks para el uso intensivo frontend, como Angular, React, Vue.. o el gran jQuery. En éstas webs, el frontend se puede llegar a cargar casi por completo en una única petición inicial, y luego se van recargando lo que haga falta. Este uso intensivo del JavaScript cada vez es más habitual, sólo pidiendo al servidor las partes de la aplicación web necesarias, menos tráfico entre navegador y servidor, mejor experiencia de usuario, aplicaciones web más interactivas, etc..

La parte de frontend

Vamos con el caso del post. Un HTML para consumir el admin-ajax.php de WordPress podría ser:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Testing frontend call to WordPress plugin with AJAX</title>
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <link rel="stylesheet" href="ajax.css">
</head>

<body>
    <h1>Testing frontend call to WordPress plugin with AJAX</h1>

    <button onclick="pureJavascriptDoSomethingAJAX()">Send AJAX request to the server with pure Javascript</button>
    <button onclick="jQueryDoSomethingAJAX()">Send AJAX request to the server with jQuery</button>

    <div id="txt-for-request-content"></div>

    <script src="ajax.js"></script>
</body>

</html>

Una hoja de estilo CSS relacionada podría ser como el siguiente fichero ajax.css que se llama desde el HTML:

body {
    padding: 0px;
    margin: 0px;
    background-color: #808080;
    text-align: center;
}

h1 {
    background-color: #606060;
    color: white;
    margin: 0px 0px 30px 0px;
    padding: 20px;
    text-align: center;
    text-shadow: 5px 5px 5px black;
    box-shadow: 5px 5px 5px black;
}

button {
    margin: 20px;
    border-radius: 20px;
    padding: 20px;
    font-size: 20px;
    border: 2px solid black;
}

button:hover {
    box-shadow: 5px 5px 5px black;
    transition: box-shadow 1s;
}

button:active {
    box-shadow: 0px 0px 0px black;
    transition: box-shadow 0s;
}

#txt-for-request-content {
    border: 2px dashed black;
}

Y un JavaScript relacionado que hiciera toda la carga AJAX, llamando mediante JavaScript asíncronamente a WordPress podría ser como el siguiente fichero ajax.js que se llama desde el HTML anterior:

"use strict";

// Función con JavaScript puro,,
function pureJavascriptDoSomethingAJAX() {
    var xhr = new XMLHttpRequest();

    // Enganchamos el evento cambio de estado de la conexión
    // para pintar la respuesta en el frontend..
    xhr.onreadystatechange = function (response) {
        if (xhr.readyState === 4) {
            console.log(response);
            console.log(xhr);
            document.getElementById('txt-for-request-content').innerHTML =
                'AJAX response with pure Javascript:<br>' + xhr.responseText;
        }
    };

    // Otra forma de preparar los parámetros de la petición AJAX,,
    /* var data = new FormData();
    data.append('action', 'jnjtest');
    //data.append('var1', 'value1');
    //data.append('var2', 'value2');*/

    // Aquí la ruta al endpoint que queremos atacar,,
    xhr.open('POST', 'http://localhost:18000/wp-admin/admin-ajax.php');
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    xhr.send('action=jnjtest');
    //xhr.send(data);
}

// Lo mismo que lo anterior pero con jQuery..
function jQueryDoSomethingAJAX() {
    // Preparamos los parámetros para la petición..
    var data = {
        'action': 'jnjtest',
        //'var1': 'value1',
        //'var2': 'value2',
    };

    // Hacemos la petición al endpoint de WordPress..
    jQuery.post("http://localhost:18000/wp-admin/admin-ajax.php", data, function (response) {
        // Contenido de la función de callback, que se lanza cuando tenemos la respuesta..
        console.log(response);
        document.getElementById('txt-for-request-content').innerHTML =
            'AJAX response with jQuery:<br>' + response;
    });
}

El contenido de este fichero ajax.js también podríamos haberlo puesto en el HTML usando las etiquetas <script>, pero la idea era separar la vista de la parte de control..

Si lo cargamos en el navegador, se tiene que ver como en la imagen del principio. Y al apretar a uno u otro de los botones se tienen que hacer unas llamadas al servidor, sin que recargue la página por completo. Inspeccionando con el Monitor de Red del Navegador se tienen que ver peticiones como la siguiente:

AJAX call testing network monitor..

Es principal ser conscientes de que para programar en la parte de backend de WordPress la respuesta, tendremos que elegir los action que queramos. He dejado comentados en JavaScript parámetros extra, que también se pueden definir para recibir en el backend, y cambiar los tipos de acciones.

La parte de backend

Lo siguiente es crear las acciones en WordPress programándolas para construir entonces las respuestas que queremos enviarles al frontend. Esto se puede hacer de dos formas: mediante un plugin, o mediante un theme.

He elegido para hacer este post un plugin. Así que un plugin de ejemplo podría ser como el siguiente:

<?php
/**
 * Plugin Name: Test plugin for AJAX
 * Plugin URI: https://jnjsite.com/
 * Description: For testing purpuoses only
 * Version: 1.0
 * Author: Jnj
 * Author URI: https://jnjsite.com/.
 */
add_action('wp_ajax_jnjtest', 'jnj_mi_funcion');
add_action('wp_ajax_nopriv_jnjtest', 'jnj_mi_funcion');

// Esta función tiene que devolver los resultados al frontend
// en el formato que queramos..
function jnj_mi_funcion()
{
    echo 'A response sent to the frontend, requested by the AJAX request done with JavaScript:<br>';
    echo 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt'
        .' ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation'
        .' ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in'
        .' reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur'
        .' sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id'
        .' est laborum.<br>';
    wp_die();
}
// ..y claro, podremos definir tantas funciones como queramos. Además de que podemos
// parametrizar cada función y leer los valores pasados mediante JavaScript, leyéndolos con $_POST..

Este plugin podemos ponerlo en un fichero nombrado /wp-content/plugins/jnj-ajax.php por ejemplo. Después de ponerlo el contenido en el fichero, entonces tendremos que ir al panel de control de WordPress, a la zona de administración de plugins, para activarlo.

Mira que el kit de la cuestión son los actions. Se utilizan dos en este caso porque es una llamada AJAX que quiero usar desde el frontend, sin ningún requisito de seguridad, y accesible para todo el mundo. Entonces hay que engancharlo a los siguientes actions:

  • wp_ajax_jnjtest
  • wp_ajax_nopriv_jnjtest

Lo que marco en negrita es porque es personalizable, podemos poner el texto que queramos. Y en la función a la que engancha también, podemos nombrarla como queramos. Lo que no es opción es la parte donde pone wp_ajax_ que es para llamadas AJAX para el panel de control de WordPress, y donde pone wp_ajax_nopriv_ es para definir las llamadas AJAX para usar desde cualquier frontend.

Terminando

Para terminar sólo me quede remitirte a la documentación oficial de WordPress que está muy bien, para el que quiera continuar extendiendo ésta funcionalidad:
https://codex.wordpress.org/AJAX_in_Plugins

Otro día más 😉 ¡Un saludo!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

 

© 2020 JnjSite.com - MIT license

Sitio hecho con WordPress, diseño y programación del tema por Jnj.