Chargement d’articles avec AJAX et WordPress

Je vous propose aujourd’hui de charger les articles de WordPress sans avoir à recharger la page pour une navigation plus intuitive et rapide, comme le montre la vidéo ci-dessous. (Il n’y a pas de css, on va se concentrer sur l’aspect technique avec un thème très épuré) :

Nous allons donc avoir un lien qui va demander à WordPress de nous donner la suite des articles puis les afficher. Nous utiliserons jQuery pour les requêtes AJAX, pour plus de facilité et de rapidité dans le développement. Nous n’aurons besoin que de cinq fichiers pour notre thème WordPress : functions.php, index.php, script.js, jquery.js et style.css (qui ne servira à rien).

Architecture Theme

Architecture Theme

index.php contiendra seulement le strict minimum :

PHP

<?php wp_head(); ?>
 
<?php if(have_posts()) : while(have_posts()) : the_post(); ?>
   <article id="<?php echo get_the_ID(); ?>">
        <h2><?php the_title(); ?></h2>
        <?php the_excerpt(); ?>
    </article>
<?php endwhile; endif; ?>
 
<a id="load" href="#">Chargez d'autres posts</a>
 
<script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/jquery.js"></script>
<?php wp_footer(); ?>

Nous n’y toucherons plus par la suite. Pour commencer le PHP, nous allons inclure le fichier JavaScript qui nous servira à faire la requête AJAX par la suite.

JS

$(document).ready(function(){
    var compteur = 1;
    var load = $('#load');
 
    load.click(function(e){
        $.ajax({
            url: ajax_var.url,
            data: {
                action: 'posts',
                compteur: compteur
            },
            complete: function(xhr){
                if($.parseJSON(xhr.responseText)['post_count'] > 0){
                    var posts = $.parseJSON(xhr.responseText)['posts'];
                        for (variable in posts){
                            $('<article><h2><a href="' + posts[variable]['guid'] + '">' + posts[variable]['post_title'] + '</a></h2><p>+ posts[variable]['post_content'] + '</p></article>').insertAfter($('article').last());
                            console.log( posts[variable]);
                        }
                } else {
                   $('Plus de posts à charger').insertAfter(load);
                   $(load).hide();
                }
            }
        });
 
        compteur++;
        e.preventDefault();
    });
});

C’est ici que rentre en jeu le paramètre action que l’on a passé dans data action: 'posts'. On rajoute en fait à 'wp_ajax' la valeur de action, puis on fait appel à la fonction : add_action( 'wp_ajax_posts', 'ajax_load_posts' ); A la première ligne, la variable $numberposts récupère le nombre d’article affichés (déterminé dans l’admin Réglages -> Lecture) :

Nombres d'articles

Nombres d’articles

La seconde ligne de la fonction instancie crée une requête WordPress qui va chercher les articles ('type' => 'posts'), à partir du nombre d’articles à afficher multiplié par le nombre de clic de l’utilisateur ('offset' => $numberposts * $_GET['compteur']) et qui en récupère seulement 2 'posts_per_page' => '2' Les deux dernières lignes permettent de renvoyer la requête au JS en disant que l’on renvoie du JSON : header("Content-Type: text/json");. C’est un choix totalement arbitraire de prendre du JSON, c’est juste que j’aime bien ce format. La réponse peut très bien aussi être renvoyé en XML ou HTML. die(json_encode($wp_query)); termine la requête en encodant en JSON notre variable $wp_query qui contient (entre autre) nos articles. Retour ensuite au JavaScript, où il va falloir traiter les données reçus :

JS

if($.parseJSON(xhr.responseText)['post_count'] > 0){
    var posts = $.parseJSON(xhr.responseText)['posts'];
    
    for (variable in posts){
        $('<article><h2><a href="' + posts[variable]['guid'] + '">' + posts[variable]['post_title'] + '</a></h2>' + posts[variable]['post_content'] + '</article>').insertAfter($('article').last());
        console.log( posts[variable]);
    }
} else {
    $('<p>Plus de posts à charger</p>').insertAfter(load);
    $(load).hide();
}

Décomposons ce code. Déjà, xhr correspond à la réponse de notre requête nous l’avons définie pour : complete: function(xhr){. Les articles se trouvent dans $.parseJSON(xhr.responseText)['posts']. Je le sais car je teste toujours les variables que je reçois avec des console.log();.

Liste posts

Liste posts

Je fais une boucle qui va parcourir chaque index du tableau contenant les articles. Pour chaque article, j’insère le HTML après le dernier article.

Article

Article

Pour finir , le code à l’intérieur de else est utilisé lorsqu’il n’y a plus d’article à charger. Voici le lien vers le repo Github J’espère que cet article vous a plu, n’hésitez pas à commenter pour dire que vous avez apprécié, mal compris, ou s’il faut que je revienne sur certains points pas très clair !