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 una respuesta

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

× ¿Puedo ayudarte?