Scroll infinito con WordPress REST API y jQuery

En este artículo voy a explicar una técnica muy simple para poder hacer scroll infinito de nuestros posts utilizando solamente el plugin REST API de WordPress y jQuery. Seguramente se preguntarán por qué no utilizo los 15.000 plugins que ya existen para realizar esta funcionalidad, por el simple hecho de que el código es muy simple y se ejecuta solo cuándo, dónde y cómo lo necesito. Veamos primero a grande rasgos cuáles son los pasos a seguir y luego nos meteremos en los detalles de cada uno de ellos.

Pasos generales

  • Guardar en un objeto javascript la consulta de base de datos de WordPress ($wp_query).
  • Escuchar cuando el usuario hace scroll hasta un determinado porcentaje de la p√°gina para llamar los nuevos posts.
  • Hacer una llamada GET a la API REST de WordPress para recolectar post utilizando los argumentos previamente guardados.
  • Renderizar los datos en el frontend.
  • Resetear las variables p√°gina para que la p√°gina siga escuchando por nuevos scrolls.

Guardando las variables de b√ļsqueda $wp_query

Cada p√°gina que solicitamos a WordPress genera una consulta principal a base de datos con las condiciones necesarias para obtener los posts adecuados y la almacena en una variable global llamada $wp_query. Esta consulta puede ser los √ļltimos posts, una p√°gina en particular o el archive de un post personalizado ordenado por T√≠tulo en forma descendente. Estas condiciones debemos guardarla en un objeto javascript para luego reutilizarlas en nuestras llamadas AJAX. Para ello usaremos la funci√≥n wp_localize_script de WordPress que nos permite guardar valores de servidor en un objeto Javascript.

<?php

function site_scripts() {
	// Variables
    global $wp_query;

	// Registro los javascripts
	wp_register_script('handlebars', get_bloginfo('template_url') . '/js/libs/handlebars.js', array('jQuery'),false,true);
	wp_register_script('script', get_bloginfo('template_url') . '/js/script.js', array('jQuery','handlebars'),false,true);

	// Agrego al javascript 'script' el objeto con la consulta $wp_query de WordPress
	wp_localize_script( 'script', 'phpVariables', array(
		'home'      => get_home_url(),
	    'query_vars'=> $wp_query->query_vars
	));

	// Encolo los javascripts
	wp_enqueue_script('handlebars');
	wp_enqueue_script('script');
}
add_action( 'wp_enqueue_scripts', 'site_scripts' );

Escuchar por el evento Scroll

Nuestra web tiene que ser capaz de escuchar el evento scroll y lanzar la petición de posts cuando el usuario haya llegado a un porcentaje dado de la página.

jQuery(document).ready(function($){
	'use strict';
	// Variables
	var porcentajeScroll 	= 0.7;
	var procesando			= false;
	var args;				

	
	$(document).scroll(function(e){
		/* 	Cancelo el evento si se est√°n procesando nuevos posts 
		*	o si se ha llegado al final de los mismos. */
		if(procesando) return false;


		if ($(window).scrollTop() >= ( $(document).height() - $(window).height() ) * porcentajeScroll ){
			/*
			* 	El usuario ha llegado hasta el porcentaje de altura de la p√°gina.
			*	Cambio el valor de la variable `procesando` para evitar m√ļtiples llamadas
			*/
        	procesando = true;

	        //Llamar a la función para obtener nuevos posts
	        obtenerNuevosPosts()
		}	

	});
});

La variable porcentajeScroll es la que nos indica hasta qu√© punto el usuario har√° scroll en la p√°gina antes de lanzar la petici√≥n. En el ejemplo hemos indicado un 70% de la altura del documento. La variable procesando es un booleano que evitar√° m√ļltiples llamadas una vez lanzada la petici√≥n. Y por √ļltimo, en la variable args guardaremos las condiciones de b√ļsqueda de posts que generamos en el punto anterior.

Conseguir los nuevos posts

Una vez que el usuario llegó hasta un porcentaje de la página realizamos la llamada a través de AJAX para conseguir los nuevos posts.

function obtenerNuevosPosts(){
	/* 
	*	Solo la primera vez guardaré los valores de la consulta de WordPress
	*	En las llamadas posteriores reutilizaré la variable.
	*/
	if(!args) {
		/* 
		*	La variable 'phpVariables' es la que configuramos en PHP con los valores
		*	de la consulta $wp_query.
		*
		*	Configuramos la variable 'args' siguiendo la documentación de la REST API de WordPress
		*	para su endpoint 'Posts -> List' => http://v2.wp-api.org/reference/posts/
		*/
        args = {filter: phpVariables.query_vars};
    };

	/*	
	*	Esta instrucción nos indicará qué página de resultados debemos ir a buscar.
	*	En cada llamada se incrementar√° en uno la p√°gina a buscar especificado en
	*	el atributo 'args.filter.paged'.
	*/
    args.filter.paged = (args.filter.paged == 0)?2:args.filter.paged + 1;

    $.ajax({
        data: args,
        dataType: 'json',
        success: function(data, textStatus, jqXHR){
        	/* 
        	*	En el caso de que 'data.lenght' sea igual a cero, esto significa
        	*	que la b√ļsqueda no devuelve m√°s resultados. En este caso no reseteamos
        	*	la variable 'processing' para que no se sigan realizando peticiones en vano.
        	*/
            if(data.length > 0){
            	/* 
            	*	Renderizar los datos obtenidos en el frontend.
            	*	En mi caso utilizo Handlebars como gestor de templates.
            	*	http://handlebarsjs.com/
            	*/
                var source   		= $("#itempost-template").html();
                var theTemplate 	= Handlebars.compile(source);
                var theCompiledHtml = theTemplate(data);
                $('.content').append(theCompiledHtml);
                // ======================================================

                // Reseteo la variable 'procesando' para permitir m√°s llamadas
                procesando = false;
            }
        },
        url: phpVariables.home + '/wp-json/wp/v2/posts' // Endpoint de API REST de WordPress
    });
}

Una vez obtenido los nuevos posts estos se agregan al resto y el proceso vuelve a comenzar. En el caso de que la petición no devuelva más valores, porque no se cumplen las condiciones, no se reactiva la variable para evitar peticiones innecesarias.
Se pueden utilizar los atributos beforeSend y complete de jQuery.ajax() para mostrar alguna animaci√≥n de ¬ęcargando…¬Ľ mientras se realiza el proceso.
En mi caso he utilizado Handlebars para renderizar la información, pero cada uno puede implementar el sistema de template que más le guste.

Ejemplo de plantilla con Handlebars

<?php get_header(); ?>

<?php 
/* 
*    Este primer bloque renderizar√° el primer LOOP con la cantidad
*    de posts especificado en las configuraciones de lectura del 
*    administrador de WordPress.
*/
?>
<div class="content no-visible">
    <?php while(have_posts()): the_post(); ?>
        <article class="itempost">
            <div class="container">
                <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                <?php the_excerpt(); ?>
                <a href="<?php the_permalink(); ?>" role="button"><?php _e('Ver m√°s', 'domain'); ?></a>
            </div>
        </article>
    <?php endwhile; ?>
</div><!-- END .content -->


<?php 
/* 
*    El segundo bloque es el template que utilizamos para 
*    generar los nuevos posts desde la llamada AJAX.
*/
?>
<script id="itempost-template" type="text/x-handlebars-template">
    {{#each this}}
    <article class="itempost">
        <div class="container">
            <h2>{{title.rendered}}</h2>
            {{{excerpt.rendered}}}
            <a href="{{link}}" role="button"><?php _e('Ver m√°s', 'domain'); ?></a>
        </div>
    </article>
    {{/each}}
</script>
<?php get_footer(); ?>

Conclusión

Esta funcionalidad es muy √ļtil para evitar la recarga de toda la p√°gina cuando solo queremos mostrar una nueva lista de resultados. Tambi√©n puede reutilizarse la llamada a nuevos posts pero para nuevos eventos, por ejemplo cuando se pincha un bot√≥n de ¬ęCargar m√°s posts¬Ľ al final de un listado. Por √ļltimo, el c√≥digo Javascript es muy gen√©rico y podemos encapsularlo para utilizarlo en todas las llamadas de posts que necesitemos en nuestra web (siempre y cuando estas llamadas se rijan por las condiciones del $wp_query).

Imagen de cabecera: Juan Salmoral


¬ŅQu√© te pareci√≥ el art√≠culo?
No molaPobreMolaMuy bueno¬°Excelente! (4 votos, promedio: 5,00 de 5)
Cargando…
Mauricio Gelves
Mauricio Gelves es Lic. en Inform√°tica y trabaja como Consultor Web Freelance con su marca personal MauGelves. Se especializ√≥ en WordPress para ofrecer soluciones personalizadas y rentables a medianas y largas empresas. Es N√≥made Digital desde el a√Īo 2015, actividad que combina sus dos principales pasiones: la inform√°tica y los viajes, y refleja sus experiencias a trav√©s de sus hobbies audiovisuales en Instagram y YouTube.
10 Pasos para ser Freelance - eBook Gratuito

10 pasos para convertirte en Freelance

Descarga en forma totalmente gratuita mi eBook en donde explico los 10 pasos que he dado para convertirme en Freelance.

Ingresa tu email y recibe en tu bandeja de correo el enlace para descargarte el eBook.

(Te doy mi palabra que solo enviaré un email al mes con todas mis novedades)


3 thoughts on “Scroll infinito con WordPress REST API y jQuery”

Deja un comentario

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

× ¬ŅPuedo ayudarte?