WordPress: implementazione di un sistema di paginazione in AJAX

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