L'implementazione di un sistema di paginazione AJAX in WordPress si ottiene solitamente recuperando il contenuto HTML di ogni pagina collegata dagli elementi di impaginazione. Questo è il modo sbagliato per implementare questa funzione. Invece, possiamo ottenere risultati migliori usando le API AJAX di WordPress.
Abbiamo solo bisogno del numero di pagina di ciascun link. A tale scopo, possiamo creare la nostra azione AJAX personalizzata in functions.php:
function my_get_posts_for_pagination() {
$paged = $_GET['page'];
$html = '';
$pag = 0;
if( filter_var( intval( $paged ), FILTER_VALIDATE_INT ) ) {
$pag = $paged;
$args = array(
'paged' => $pag,
'posts_per_page' => 10
);
$loop = new WP_Query( $args );
if( $loop->have_posts() ) {
while( $loop->have_posts() ) {
$loop->the_post();
// Costruire la stringa HTML
}
wp_reset_postdata();
}
}
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' );
Abbiamo bisogno di un indicatore di caricamento visivo per mostrare che un'azione è in corso. Un semplice caricatore CSS può essere implementato come segue:
#pagination-loader {
width: 40px;
height: 40px;
margin: 1.5em auto;
background: #ccc;
border-radius: 50%;
animation: pulse 1s infinite alternate; display: none;
}
@keyframes pulse {
from { opacity: 1; width: 40px; height: 40px; }
to { opacity: 0.5; width: 35px; height: 35px; }
}
In jQuery dobbiamo ottenere il numero di pagina del link corrente. Questo può essere fatto con espressioni regolari. Una volta che i post vengono recuperati tramite AJAX, dobbiamo contrassegnare il link corrente per evitare l'inserimento di post duplicati.
La nostra azione AJAX invia due parametri attraverso la richiesta GET: il nome dell'azione WordPress e il numero di pagina corrente.
(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+/ ),
pageNumber = page[0],
data = {
action: options.action,
page: pageNumber
};
if( !$a.hasClass( "clicked" ) ) {
$loader.show();
$.get( options.ajaxURL, data, function( html ) {
$loader.hide();
$loader.before( html );
$a.addClass( "clicked" );
});
}
});
}
};
return this.each(function() {
var element = this;
var pagination = new WPPagination( element );
});
};
})( jQuery );
Possiamo usare il codice sopra riportato come segue:
(function( $ ) {
$(function() {
if( $( "#pagination" ).length ) {
$( "#pagination" ).wpPagination();
}
});
})( jQuery );