Tuto: un Infinite Scroll pour WordPress from Scratch

Découvrez comment réaliser un infinite scroll pour votre blog WordPress from Scratch. Ce système utilise la puissance de PHP, d’Ajax et évidemment de WP. Il affiche une liste de nouveaux billets sur la page d’accueil, les catégories, les tags et les billets. Le chargement de nouvelles entrées est lancées quand le visiteur atteint le bas de notre page. Notre infinite scroll est composé simplement d’un fichier php, qui a pour mission d’aller chercher les billets demandées par un script présent dans nos pages. Avant de vous lancer vous pouvez observer le résultat ici.

Voici tout d’abord notre fichier php, placé à la racine de notre thème.

<?php
// on inclut wp-load.php pour avoir accès à $wpdb
include("../../../wp-load.php");

$numberOfPost = 10;

$page = $_POST['id'];
$what = $_POST['type'];
$idCat = $_POST['idCat'];
$premierPostLimite = $page * $numberOfPost;

// NOS REQUETES

// single et home
if ($what == "single" || $what == "home") {
    $query = new WP_Query('posts_per_page= ' . $numberOfPost . '&amp;offset=' . $premierPostLimite);
}

// category ou tag
if (($what == "category" || $what == "tag") &amp;&amp; $idCat != "0") {
	if ($what == "category") {
        $query = new WP_Query('cat=' . $idCat . '&amp;posts_per_page= ' . $numberOfPost . '&amp;offset=' . $premierPostLimite);
    }

    if ($what == "tag") {
        $query = new WP_Query('tag_id=' . $idCat . '&amp;posts_per_page= ' . $numberOfPost . '&amp;offset=' . $premierPostLimite);
    }
}

// ON AFFICHE LES RESULTATS

while ($query->have_posts()) {
    $query->next_post();
	?>
    <li>
        <a href="<?php echo get_permalink($query->post->ID); ?>">
            <?php echo attachment_image($query->post->ID, 'thumbnail', 'alt="' . get_the_title($query->post->ID) . '"'); ?>
            <h2><?php echo get_the_title($query->post->ID); ?></h2>
            <p><small><?php echo get_the_time('j/m/Y ', $query->post->ID); ?></small></p>
        </a>
    </li>
    <?php
}
wp_reset_postdata();
?>

Voici maintenant le script présent dans le footer de notre thème. Nous déclenchons une requête Ajax, grâce à JQuery, dès que le visiteur atteint le bas de l’écran.

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
// ....
<script>
$(document).ready(function () {
$("#load").hide();
<?php if (is_single() || is_home() || is_category() || is_tag()) { ?>
    // nombre de chargement de l'infinite scroll
    var count = 1;
    // le script est-il en train de charger
    var isLoading = false;
    // what = single, home, category, tag ?
    var what ="";
    // on passe l'id du tag ou de la catégorie
    var catId = 0;

    // on fixe le nombre maxi de chargements en fonction du type
    <?php 
    if (is_single()) { ?> 
        var maxChargements = 10; what = "single"; 
    <?php }
    if (is_home() || is_category() || is_tag()) { ?>
        var maxChargements = 100000; 
    <?php }
    if (is_home()) { ?> 
        what = "home"; 
    <?php
    }
    if (is_category()) {
        $category = get_the_category();
        $catID = $category[0]->term_id; ?> 
        what = "category"; catId = <?php echo $catID; ?>; 
    <?php }
    if (is_tag()) { ?>
        what = "tag";
        catId = <?php echo get_query_var('tag_id'); ?>;
    <?php } ?>

    // on surveille le scroll
        $(window).scroll(function() {
            // le visiteur est en bas de la page
            if($(window).scrollTop() + window.innerHeight == $(document).height()) {
                // si on n'est pas pendant un chargement
                if(isLoading == false){
                    // si le nombre de chargement est < à maxChargements
                    if(count<maxChargements){
                        // on lance la requete ajax
                        $.ajax({
                            beforeSend: function() {
                                isLoading = true;
                                $("#load").show();
                            },
                            type: "POST",
                            url: "http://monsite.fr/wp-content/themes/montheme/infinitePost.php",
                            data: { id : count, type : what, idCat : catId },
                            success: function(res) {
                            count++;                    
                            $("#listeLastPosts").append(res);
                            $('#listeLastPosts').listview('refresh');
                        }
                        }).done(function() {
                            isLoading = false;
                            $("#load").hide();
                        });
                    }
                }
            }
        });
<?php } ?>

});

Pour pouvoir ajouter les billets récupérés, il faut évidemment que liste des billets affichés au premier chargement ait pour identifiant listeLastPosts (id=listeLastPosts). Une image pour indiquer au visiteur un chargement a quant à elle pour identifiant load (id=load). Elle est cachée au chargement de la page et affichée pendant les requêtes.
* la fonction $(‘#listeLastPosts’).listview(‘refresh’); est utilisée ici pour rafraîchir une liste JQueryMobile.

Amélioration possible et recommandée: il faudrait écrire les résultats en JSON et faire parser ces derniers par le navigateur afin d’économiser de la bande passante. Cette technique est mise en oeuvre dans le billet sur l’autocomplétion.

Publié dans Wordpress

quand j’aurai le temps

  • les filtres wordpress
  • plugin wordpress et enregistrement de données
  • les wordpress custom post type
  • la bdd d'un blog wordpress
  • la balise more de wp
  • personnaliser une galerie wp
  • gérer les longueurs des extraits de wp
  • les animations css3
  • le memento symphony2
  • le squelette d'une page html5
  • liste sur plusieurs colonnes
  • le responsive design
  • exemple d'un jeu basique en html5
  • la réplication des bases de données
  • mettre en place une architecture en silo avec wp
  • parser un fichier xml (donc un rss) avec php5
  • mettre en place lightbox sans plugin
  • améliorer les performances de son wp
  • ajouter un bouton à l'éditeur de texte de wp
  • ...