WordPress: paginazione AJAX con jQuery

WordPress: paginazione AJAX con jQuery

L'implementazione di un sistema di paginazione AJAX in WordPress è solitamente realizzata reperendo il contenuto di ciascuna pagina collegata ai link della paginazione. Questa implementazione non è corretta. Dobbiamo invece usare le API AJAX di WordPress.

Abbiamo solo bisogno del numero di pagina. Registriamo un'action AJAX in functions.php:


function my_get_posts_for_pagination() {
	$paged = $_GET['page']; // Numero di pagina
	$html = '';
	$pag = 0;
	if( filter_var( intval( $paged ), FILTER_VALIDATE_INT ) ) { // Validazione
		$pag = $paged;
		$args = array(
			'paged' => $pag, // Usiamo il numero di pagina fornito da AJAX
			'posts_per_page' => 2 // Numero di post per pagina
		);
		$loop = new WP_Query( $args );
			
		if( $loop->have_posts() ) {
			while( $loop->have_posts() ) {
				$loop->the_post();
				// Costruiamo la struttura dei post come stringa HTML
			}
				
			wp_reset_query();
		}
	}
		
	echo $html;
	exit();

}

add_action( 'wp_ajax_my_pagination', 'my_get_posts_for_pagination' );
add_action( 'wp_ajax_nopriv_my_pagination', 'my_get_posts_for_pagination' );

Implementiamo con i CSS un indicatore di caricamento animato:


#pagination-loader {
	width: 40px;
	height: 40px;
	margin: 1.5em auto;
	background: #ccc;
	border-radius: 50%;
	-webkit-animation: pulse 1s infinite alternate;
	animation: pulse 1s infinite alternate;
	display: none;
}

@-webkit-keyframes pulse {
	from {
		opacity: 1;
		width: 40px;
		height: 40px;
	}
	
	to {
		opacity: 0.5;
		width: 35px;
		height: 35px;
	}
}

@keyframes pulse {
	from {
		opacity: 1;
		width: 40px;
		height: 40px;
	}
	
	to {
		opacity: 0.5;
		width: 35px;
		height: 35px;
	}
}

jQuery invierà via AJAX due parametri GET: il nome della action AJAX e il numero di pagina estratto dall'URL dei link. Quindi marcherà il link appena cliccato per evitare duplicati.


(function( $ ) {
	
	$.fn.wpPagination = function( options ) {
		options = $.extend({
			links: "a",
			action: "my_pagination",
			ajaxURL: "http://" + location.host + "/wp-admin/admin-ajax.php",
			next: ".next",
			previous: ".previous",
			disablePreviousNext: true
		}, options);
		
		function WPPagination( element ) {
			this.$el = $( element );
			this.init();
		}
		
		WPPagination.prototype = {
			init: function() {
				this.createLoader();
				this.handlePreviousNextLinks();
				this.handleLinks();
			},
			createLoader: function() {
				var self = this;
				self.$el.before( "<div id='pagination-loader'></div>" );
			},
			handlePreviousNextLinks: function() {
				var self = this;
				var $previous = $( options.previous, self.$el );
				var $next = $( options.next, self.$el );
				
				if( options.disablePreviousNext ) {
					$previous.remove();
					$next.remove();
				} else {
					$previous.addClass( "clicked" );
					$next.addClass( "clicked" );
				}
			},
			handleLinks: function() {
				var self = this,
					$links = $( options.links, self.$el ),
					$loader = $( "#pagination-loader" );
					
					$links.click(function( e ) {
						e.preventDefault();
						var $a = $( this ),
							url = $a.attr( "href" ),
							page = url.match( /\d+/ ), // Reperisce il numero di pagina
							pageNumber = page[0],
							data = {
								action: options.action, // Parametri AJAX
								page: pageNumber
							};
							
						  if( !$a.hasClass( "clicked" ) ) { // Non vogliamo duplicati
							
							$loader.show(); // Mostra l'indicatore di caricamento
							
							$.get( options.ajaxURL, data, function( html ) {
								$loader.hide(); // Nasconde l'indicatore di caricamento
								$loader.before( html ); // Inserisce i post
								$a.addClass( "clicked" ); // Marca il link corrente come cliccato
							});
							
						   }
					});
			}
		};
		
		return this.each(function() {
			var element = this;
			var pagination = new WPPagination( element );
		});
	};
	
	
})( jQuery );

Esempio d'uso:


(function( $ ) {
	$(function() {
		if( $( "#pagination" ).length ) {
			$( "#pagination" ).wpPagination();
		}
	});
	
})( jQuery );

Demo

Torna su