En esta entrada veremos la forma correcta de implementar Ajax en WordPress y mejorar la usabilidad de nuestra web de una forma sencilla.
¿Qué es Ajax?
AJAX es el acrónimo de Asynchronous Javascript And XML. Es una tecnología asíncrona, es decir, la comunicacion entre el servidor y el navegador se produce en segundo plano sin interferir con la visualización ni el comportamiento de la página
Esta funcionalidad el imprescindible en cualquier web, ya que, mejora mucho la experiencia del usuario. Nos permite mantenerlo informado durante una operación larga, también podemos modificar el contenido visualizado en respuesta a sus acciones, en realidad, podemos implementar cualquier funcionalizad que le ayude a navegar por nuestra web.
Para lograr este efecto debemos hacer lo siguiente:
- Definir las funciones que realizarán las peticiones desde el navegador y gestionarán las respuestas recibidas. Lo habitual es usar JQuery, el cual nos proporciona una encapsulación sencilla de las funciones de Ajax.
- En segundo lufar debemos crear en el servidor las funciones que atenderán las solicitudes del navegador.
Veamos como podemos hacer esto con las herramientas que WordPress pone a nuestra disposición.
Implementando Ajax en WordPress
Implementar Ajax en WordPress es muy sencillo. Al ser una funcionalidad incluida en el núcleo de WordPress está a nuestra disposición en todo momento.
Implementacion en el servidor.
El hook wp_ajax_<funcion_respuesta> nos permite definir las funciones que ejecutará el servidor ante una llamada Ajax. Debemos tener en cuenta que este hook se ejecuta solo para usuarios logueados. Emplearemos wp_ajax_nopriv_<funcion_respuesta> si queremos dar acceso a todos los visitantes.
Por tanto en el functions.php, de nuestro tema hijo incluiremos bloques como el siguiente:
function respuesta_ajax1(){
// Aquí procesamos la petición ...
exit; //Forma correcta de terminar una petición Ajax
}
add_action('wp_ajax_nopriv_respuesta_ajax1', 'respuesta_ajax1'); //usuarios registrados
add_action('wp_ajax_respuesta_ajax1, 'respuesta_ajax1'); //resto de visitantes
Podemos definir tantas funciones como sean necesarias y también ofrecer diferentes respuestas, para usuarios logueados y visitantes.
Implementación en el navegador
Posiblemente la forma más senciila de incluir javascript en nuestras páginas es agregando un bloque como el siguiente a functions.php
function peticion_ajax_php(){ ?>
<script>
ajax_url = "<?php echo admin_url('admin-ajax.php');?>";
function Ajax1() {
jQuery.ajax({
url : ajax_url,
type: "post",
data: {action : "respuesta_ajax1"},
success: funtion(data) {/* petición procesada correctamente */},
error: function(request, status, error_ocurrido) {/* gestion de errores */},
complete: function() {/* codigo adicional a ejecutar siempre */}
);}
};
// Aquí pondremos el codigo que utilizará Ajax1
</scrpti>
<?php
}
add_action('wp_footer', 'peticion_ajax_php');
Con el parámetro action indicamos que función procesará la petición, Es posible utilizar data para enviar parámetros adicionales.
La función admin_url('admin-ajax.php') nos devuelve la url de nuestra instalación de WordPress que procesa las peticiones Ajax. El ejemplo muestra la forma más simple pasar dicha información al navegador.
Si lo hacemos así el código se cargará en todas las páginas. Más correcto es cargarlo solo cuando sea necesario, lo haremos mediante wp_register_script() y wp_enqueue_script(), también usaremos wp_localize_script() para pasar la url de ajax.
Barra de progreso en WordPress
Como hemos visto, implementar Ajax en WordPress es relativamente sencillo. Solo necesitamos definir y registrar un par de funciones. WordPress se encarga de gestionar los detalles del proceso.
Pasemos a un ejemplo práctico: mostraremos una barra de progreso al usuario y lo tendremos informado, mientras el servidor ejecuta una tarea compleja como puede ser la generación de un informe, la carga de contenidos desde un servidor externo, etc.
Implementacion en el servidor
Para llevar cabo esta tarea usaremos dos funciones en el servidor:
- rjc_proceso - realizará el "trabajo duro", aunque en nuestro ejemplo simplemente ejecuta un bucle durante 2 minutos. La segunda tarea de esta función es mantener actualizado la información de estado del proceso. Para ello registra varias opciones y las actualiza en cada iteración. Para evitar lanzar el proceso por duplicado, primero comprobamos si las opciones existen y abortamos si ya lo están.
- rjc_progreso - comprobará las variables de estado y enviará esa información al navegador. Una vez terminado el proceso principal se encargará de relizar el "trabajo de limpieza".
Para implementarlas añadimos las siguientes lineas a nuestro functions.php:
function rjc_proceso() {
$x=0;
$cnt=get_option( 'rjc_cnt',-1 );
if ($cnt>=0) { $x=59;}
CreaOpcion( 'rjc_total',120 );
CreaOpcion( 'rjc_cnt',$x);
CreaOpcion( 'rjc_info','' );
do {
update_option( 'rjc_cnt', $x );
$x++;
update_option( 'rjc_info', 'Procesando elemento '.$x );
sleep(1);
} while ($x<=120);
update_option( 'rjc_info', 'finalizado' );
exit;
}
add_action( 'wp_ajax_rjc_proceso', 'rjc_proceso' );
add_action( 'wp_ajax_nopriv_rjc_proceso', 'rjc_proceso' );
function rjc_progreso() {
$result=get_option( 'rjc_info','' );
$total=get_option( 'rjc_total',0 );
$cnt=get_option( 'rjc_cnt',0 );
$progreso=($total>0) ? round(100*$cnt/$total) : 0;
$otro=$result!=='finalizado' ? 1 : 0 ;
echo '#rol#'.$total.'#rol#'.$cnt.'#rol#'. $progreso .'#rol#'. $otro .'#rol#'. $result .'#rol#';
if ($otro===0) {
delete_option( 'rjc_info' );
delete_option( 'rjc_total' );
delete_option( 'rjc_cnt' );
}
exit;
}
add_action( 'wp_ajax_rjc_progreso', 'rjc_progreso' );
add_action( 'wp_ajax_nopriv_rjc_progreso', 'rjc_progreso' );
function CreaOpcion($option_name,$new_value) {
if ( get_option( $option_name ) !== false ) {update_option( $option_name, $new_value ); }
else {
$deprecated = null;
$autoload = 'no';
add_option( $option_name, $new_value, $deprecated, $autoload );
}
}
Implementacion en el navegador
Insertaremos en nuestrá pagina el código HTML mostrado a continuación.Es simple una barra y un botón para activar el proceso
<h3>Ajax en WordPress - Demo</h3>
<div id="rjc_progreso" style="width: 100%; background-color: #ddd; margin-bottom:20px;">
<div id="rjc_barra" style="width: 0%; height: 30px; background-color: #4CAF50;"></div>
</div>
<div id="resultados" style="width: 100%;"></div>
<div><button id="proceso" style="padding: 5px 10px;">Procesar</button></div>
El código JavaScript lo cargaremos selectivamente mediante wp_enqueue_script. Para ello añadimos a functions.php las siguientes líneas
function rjc_progress() {
if (is_single(3739)) {
$url=get_stylesheet_directory_uri(). '/js/rjc_ajax_progress.js';
wp_register_script('rjc_ajax_progress', $url , array('jquery'), NULL, true);
wp_localize_script('rjc_ajax_progress', 'rjc_vars', array('ajaxurl' => admin_url('admin-ajax.php')));
wp_enqueue_script('rjc_ajax_progress');
}
}
add_action('wp_enqueue_scripts', 'rjc_progress');
El código javaScript que copiaremos en el archivo rjc_ajax_progress.js es el siguiente:
jQuery("#proceso").on("click",function(e){
e.preventDefault();
var elem = document.getElementById("rjc_barra");
if (elem) {
clearTimeout(progreso);
setTimeout(progreso, 1000);
}
jQuery.ajax({
url : rjc_vars.ajaxurl,
type: "post",
data: {action : "rjc_proceso"},
beforeSend: function(){jQuery('#proceso').html("Procesando ...");},
});
});
function progreso() {
var datos=[0,0,0];
jQuery.ajax({
url: rjc_vars.ajaxurl,
type: "post",
data: {action : "rjc_progreso"},
success: function(data) {
datos=data.split("#rol#");
if (datos[1]>0) {
var texto=datos[1]+" elementos ("+datos[2]+" procesados)";
if (datos[4]<=0) texto+="<br>Proceso finalizado"; else texto+="<br>"+datos[5];
jQuery("#resultados").html(texto);
mueve(datos[3]);
}
},
complete: function() {
if (datos[4]>0) setTimeout(progreso, 1000);
else {jQuery("#proceso").html("Procesar"); mueve(0);}
}
});
};
function mueve(width) {
var elem = document.getElementById("rjc_barra");
if (elem) {elem.style.width = width + "%";}
}
Al hacer click en el botón se activa el proceso principal y se va comprobando periódicamente el estado del proceso hasta su finalización.
Ajax en WordPress - Demo
Conclusiones
Como vemos implementar Ajax en WordPress es un proceso realmente sencillo. El código del ejemplo es totlamente funcional y con ligeras modificaciones podemos incorporarlo a nuestros desarrollos para mayor satifacción de nuestros visitantes