AJAX y WordPress, de la manera correcta

Hay múltiples formas de implementar interacciones en AJAX con WordPress… muchas son malas, otras son horribles, algunas profundamente aberrantes y unas pocas son correctas.

En el grupo de las malas, horribles y aberrantes, encontramos todos aquellos métodos que tienen que ver con intentar hacer las cosas de algún modo ingenioso, y no aprovechando las funcionalidades propias de WordPress, por ejemplo: enviando una petición a un archivo en la carpeta de un plugin o tema o capturando parámetros al descubierto.

Los métodos correctos, por otra parte, se integran armoniosamente con WordPress y permiten utilizar sus características propias para facilitar el desarrollo y el funcionamiento de estas interacciones. En este sentido, probablemente la mejor forma de implementar peticiones AJAX es a través de /wp-admin/admin-ajax.php, ya que esto presenta varias ventajas:

  • Podemos utilizar todas las funciones de WordPress, sin necesidad de tener que incluir manualmente archivos
  • Es posible trabajar tanto con peticiones autenticadas como de libre disponibilidad
  • Por convención, se ha adoptado como la forma más recomendada de hacer consultas en AJAX, por lo que puedes estar más seguro de que seguirá funcionando en cualquier actualización de WordPress
  • Por lo mismo, cuando un plugin intenta detectar si se está realizando alguna acción con AJAX, se define con este método en particular

Esto se puede ilustrar con un ejemplo muy básico, por ejemplo, cargar un listado de posts dinámicamente al clickear en un botón.

En primer lugar, debemos generar la petición en AJAX con javascript, lo que puede ser algo como:

https://gist.github.com/felipelavinz/9382151

Aquí lo importante es que el parámetro action debe coincidir con el nombre de la acción en la que luego vamos a engancharnos en WordPress (el uso de este parámetro es una práctica recomendad en WordPress). La petición puede enviada por $_GET o $_POST

Luego, en un plugin o como parte del tema, toca detectar esa petición y devolver los datos que corresponde:

https://gist.github.com/felipelavinz/9381598

En esta parte debemos tener en cuenta que:

  • El nombre de la acción va a ser wp_ajax_{$parámetro_action} si el usuario debe estar logueado o wp_ajax_nopriv_{$parametro_action} en caso que no lo esté. Si es una acción pública, es necesario definir las dos acciones; en caso que sea una acción que sólo debe realizar un usuario autenticado, debes utilizar solamente la primera opción.
  • Recuerda que si vas a capturar parámetros de la petición, debe coincidir con el método en que son enviados o bien puedes utilizar $_REQUEST para capturar parámetros $_GET o $_POST indistintamente.
  • Finalmente, recuerda también que al tratarse de una función que vamos a invocar por AJAX, es necesario agregar un exit(); para finalizar la ejecución de PHP.

Más información en:

14 thoughts on “AJAX y WordPress, de la manera correcta

  1. muy buen repaso, también puede ser necesario señalar (aunque está en tu función de ejemplo) que las funciones de php que se llamen vía ajax tienen que tener un “exit” al final para que funcionen bien.

    1. 😉 estaba en los comentarios del código, pero lo agregué ahora también como parte de las notas… después de este post estoy programando otros más relacionados con la optimización del flujo con compresión de la respuesta, control de caché y más
      Saludos!

    1. Jajaja, excelente, no conocías esas funciones.

      También está http://codex.wordpress.org/Function_Reference/wp_send_json que es más genérica, para mandar cualquier respuesta en JSON

      Por otra parte, desde el punto de vista de un purista REST, no se deberían usar este tipo de respuestas ya que el status debería ser enviado con las cabeceras HTTP (200 = OK; 404 = no encontrado; 500 = error, etc)… en el caso de una API ésta es una buena recomendación, pero para cosas más sencillas las funciones que indicas están muy útiles 🙂

    1. No es que se deban agregar a ese archivo, sino que las peticiones se deben dirigir a esa URL. Luego, en tu plugin o tema, haces la detección de la acción correspondiente y ejecutas el código que necesitas.

  2. Hola, en el javascript, en la línea 8, la variable ajaxurl que valor tiene? Como apunto esa petición al admin-ajax.php ??

    saludos

  3. Y al hacer la petición ajax no tienes que instanciar un objeto en el navegador del usuario?

    1. Claro, pero eso lo haces en el archivo javascript donde vas a estar enviando la petición. En el ejemplo que le envié a Cristian, sólo estoy mostrando la parte en PHP.

      La función wp_localize_script() va a insertar una etiqueta de donde define un objeto “Foo” (el nombre se define a partir del segundo parámetro de la función), que tiene una propiedad “ajaxurl” con la URL completa al archivo admin-ajax.php

  4. Saludos amigo, Necesito hacer una consulta para recibir los valores en otra pagina y procesarlos y luego mostrarlo en un DIV sin refrescar la pagina, este código funciona en PHP y AJAX normal, pero cuando intento implementarlo en WORDPRESS no funciona. agradeciendo cualquier tipo de ayuda.

    function objetoajax(){
    var xmlhttp=false;
    try{
    xmlhttp = new ActiveXObject(“Msxm12.XMLHTTP”);
    } catch(e){
    try{
    xmlhttp= new ActiveXObject(“Microsoft.XMLHTTP”);
    } catch(E){
    xmlhttp=false;
    }
    }
    if (!xmlhttp && typeof XMLHttpRequest!=’undefined’){
    xmlhttp= new XMLHttpRequest();
    }
    return xmlhttp;
    }
    function enviar(){
    jdatefrom = document.getElementById(‘datefrom’).value;
    jdateto = document.getElementById(‘dateto’).value;
    jroomtype = document.getElementById(‘roomtype’).value;
    ajax = objetoajax();
    ajax.open(“POST”,”consulta.php”, true);
    ajax.onreadystatechange=function(){
    if (ajax.readyState==4 && ajax.status==200) {
    document.getElementById(“txtHint”).innerHTML=ajax.responseText;
    }
    }
    ajax.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);
    ajax.send(“sdatefrom=”+jdatefrom+”&sdateto=”+jdateto+”&sroomtype=”+jroomtype+””);
    }

    Aqui recibo los datos para procesarlo

    query($sql);

    //muestra los datos consultados

    while($row = mysqli_fetch_array($resuly)){
    ?>
    Room Type:
    Price per person:
    Price extra pack:
    Price child:

    1. Quizás me falta un poco de contexto, pero me parece que justamente lo que te falta es integrarlo con WordPress, es decir, enviar la petición a admin-ajax.php y asociarlo a una acción mediante add_action …

      También deberías dar preferencia a utilizar $wpdb para interactuar con la base de datos. Así te aseguras que ya tengas la conexión configurada y mayor compatibilidad con WordPress.

    2. Gracias, pero como envio la peticion a admin-ajax.php y como luego lo asocio con el add_action.
      tal vez es mucho pedir pero se lo agradeseria enormemente

Comments are closed.

%d bloggers like this: