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 );