Masonry et Infinite Scroll sous WordPress sans plugin

Masonry et Infinite Scroll sont 2 scripts jQuery qui permettent respectivement de gérer des hauteurs de contenus différentes –  pour une disposition en colonnes de vos articles, et d’afficher les pages suivantes sans rechargement de page – au clic sur un bouton ou par simple défilement à la manière de Facebook ou encore Twitter. Face à l’absence de tutoriel complet sur l’intégration de ces 2 scripts jQuery sous WordPress, je vous ai concocté un tutoriel complet – ou presque, sur le sujet.

N.B : ce tutoriel est réservé à des utilisateurs avancés.

Démonstration du résultat final

J’ai appliqué l’ensemble des technique énoncées ci-après pour l’affichage de toutes les pages d’archives de WordPress Channel : accueil, catégories, recherche… toutes je vous dis !

Un autre exemple intéressant et pertinent sur le site Prévention Santé de la collègue Déborah Donnier.

N’hésitez pas non plus à redimensionner la fenêtre du navigateur et admirer l’animation qui replace les éléments avec fluidité.

Chargement des prochains articles sans rafraichissement de page
Chargement des prochains articles sans rafraichissement de page
Un affichage en colonnes via Masonry
Un affichage en colonnes via Masonry

Étape n°1 – Ajout des scripts jQuery

Dans votre thème et plus précisément dans le fichier functions.php – ou celui qui charge l’ensemble de vos scripts, collez les lignes de code suivantes.

function wpc_styles() {
	wp_register_script( 'infinite-scroll', get_template_directory_uri().'/inc/js/jquery.infinitescroll.min.js', 'jquery', '2.0', true );
	wp_enqueue_script( 'jquery-masonry' );
	wp_enqueue_script( 'infinite-scroll' );
add_action('wp_enqueue_scripts', 'wpc_styles');

Vous noterez que Masonry n’a pas besoin d’être présent dans le dossier de votre thème et que nous pouvons le charger directement. WordPress l’intègre de base dans les scripts disponibles alors profitez-en !

Il vous faudra néanmoins télécharger Infinite Scroll et l’envoyer dans un dossier /inc/js de votre thème. Notez que le chemin dépend directement de la façon dont vous avez structuré votre thème. A vous, ensuite, d’adapter le code en fonction.

Infinite Scroll

Script JS de défilement continu sans rechargement de page.

Taille : 21,0 KiB  •  Date : 27 juillet 2014 •  Hits : 1 795

Étape n°2 – Ajout des styles CSS

La prise en charge des effets énoncés dépend directement des styles CSS que vous devez ajouter dans le fichier style.css.

Voici le code utilisé que vous serez libre d’adapter selon votre charte graphique :

/* Masonry */
.grid {
	list-style: none;
	margin: 0 auto;
	padding: 0;
}
.grid h2 {
    font-size: 17px;
	margin-top: 0;
}
.grid article {
    background-color: #FFFFFF;
    border: 2px solid #C3C0AB;
    display: block;
    float: left;
    margin: 10px;
    width: 23%;
}


/* Infinite Scroll */
.load-more-manual #page-nav {
	display:block !important; 
}
#page-nav {
	display:none; 
	text-align:center; 
}
.load-more-manual #page-nav a {
	margin:20px auto 10px auto;
	display:inline-block;
	width:auto;
}
.load-more-manual #page-nav a {
    font-weight: bold;
    display: inline-block;
    font-size: 15px;
    position: relative;
    transition-duration: 150ms;
    text-decoration: none;
}
#infscr-loading { 
	text-align: center;
	z-index: 100;
	position: fixed;
	left: 50%;
	bottom: 40px;
	width: 200px;
	margin-left:-100px;
	padding: 10px;
	background: #000; 
	opacity: 0.8;
	color: #FFF;
	-webkit-border-radius: 10px;
	 -moz-border-radius: 10px;
	      border-radius: 10px;
}
.more { 
	width: 300px;
}

Prenez garde à la propriété width: 23% pour .grid article car elle détermine la largeur de vos colonnes. Faites appel aux outils de développement intégrés dans votre navigateur favori.

Étape n°3 – Ajout du JavaScript

Il nous faut déclencher Masonry et Infinite Scroll en plaçant le bout de JavaScript suivant dans votre footer.php ou de façon plus propre dans un fichier scripts.js par exemple – n’oubliez pas de le charger comme les autres scripts (cf. étape n°1). L’exemple ci-dessous se base sur l’utilisation d’un fichier JS dans lequel je place mes différents scripts :

jQuery( document ).ready( function( $ ) {
    /* Masonry + Infinite Scroll */	
    var $container = $('#grid-container');
    $container.imagesLoaded(function () {
        $container.masonry({
            itemSelector: '.post'
        });
    });
    $('#grid-container').masonry({
        itemSelector: '.post',
        columnWidth: 258
    });
    $container.infinitescroll({
        navSelector: '#page-nav',
        nextSelector: '#page-nav a',
        itemSelector: '.post',
        loading: {
            msgText: 'Chargement des contenus...',
            finishedMsg: 'Aucun contenu à charger.',
            img: 'http://i.imgur.com/6RMhx.gif'
        }
    }, function (newElements) {
        var $newElems = $(newElements).css({
            opacity: 0
        });
        $newElems.imagesLoaded(function () {
            $newElems.animate({
                opacity: 1
            });
            $container.masonry('appended', $newElems, true);
        });
    });
    $(window).unbind('.infscr');
    jQuery("#page-nav a").click(function () {
        jQuery('#grid-container').infinitescroll('retrieve');
        return false;
    });
    $(document).ajaxError(function (e, xhr, opt) {
        if (xhr.status == 404) $('#page-nav a').remove();
    });    
});

Quelques notes importantes :

  • La propriété columnWidth est à définir en pixels et correspond à la largeur d’une colonne ;
  • Les différents textes de la propriété loading peuvent être modifiés au besoin ;
  • Insérez l’URL du gif animé ou enregistrez celle de l’exemple dans le thème WordPress pour la propriété img;

Étape n°4 – Structure HTML

A présent nous disposons de tous les éléments : scripts jQuery, CSS et JavaScript. Il nous faut donc passer à la structure HTML.

D’ordinaire, on commence par l’inverse mais j’ai préféré procéder comme tel afin de vous amener à comprendre les liens avec le code HTML. Simple question de méthode pédagogique je dirais.

Comme vous pouvez le voir dans le code ci-dessous, nous utilisons des identifiants et des classes CSS spécifiques qui correspondent directement aux étapes précédentes. Il ne faut pas les supprimer.

<section id="grid-container" class="transitions-enabled fluid masonry js-masonry grid">
	<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<?php get_template_part('content', get_post_format()); ?>
	<?php endwhile; ?>
</section>
<div class="load-more-manual">
	<nav id="page-nav" role="navigation"><?php next_posts_link( __( '<span class="more btn btn-primary btn-lg btn-block">Load more posts</span>', 'wpc' ) ); ?></nav>
</div>
<?php else: ?>
	<?php get_template_part('content', 'none'); ?>
<?php endif; ?>

Remarque de taille : la boucle utilisée ici fait appel à un fichier content.php dans sa version la plus simple (si on exclut l’usage des posts formats). Il est impératif de rajouter une classe CSS dans chaque article que nous nommerons post pour que les scripts fonctionnent.

Les lignes 6 à 8 quand à elles permettent l’affichage du bouton pour charger plus d’éléments. Là encore, amusez-vous à le personnaliser via le CSS (cf. étape n°2).

Pour ce faire, modifiez le fichier correspondant et veillez à éditez cette ligne :

<article id="post-<?php the_ID(); ?>" <?php post_class('post'); ?>>

A propos du bouton load-more

Les plus attentifs d’entre vous auront noté que le chargement d’une page 3, 4 ou plus ne modifiait pas l’URL. Cela empêche donc le partage d’une URL en particulier comme me l’a fait remarqué Geoffrey Crofte :

Malheureusement, je n’ai à ce jour aucune solution technique à proposer. Si une âme charitable se sent l’envie de mes communiquer ses compléments, j’éditerai le tutoriel en conséquence avec mes remerciements les plus sincères cela va de soi.

Tous les sites ne se prêtent pas à un usage Masonry + Infinite Scroll mais dans le cas d’un blog ou d’un magazine avec du contenu régulier, j’y trouve personnellement beaucoup d’avantages. Quel est votre avis sur la question ?

Crédits photo : Leo Prieto

48 commentaires

  1. Julio Potier Ⓦ (@BoiteAWeb)

    Hello
    J’ai fait dans le même genre sur boiteaweb, mais je gère effectivement le changement d’URL.
    Aussi j’utilise ma technique du template spécial ajax qui réduit le poids des données reçues. Je l’ai calculé pour le site de Déborah et tu passerais de 39.7ko à 12.9ko. Le tuto est ici (et dans id4d ^^) http://boiteaweb.fr/la-navigation-avec-ajax-7743.html
    Pour les pages dans l’URLs, un c/c ici https://gist.github.com/BoiteAWeb/1207324668fc59255dee (à adapter pour toi surement), le principal étant le window.history.pushState().
    Comme vous avez WP Rocket (merci) il faut donc ajouter ?nocache=1 pour éviter de puiser dans le cache qui renvoi tout.
    Si tu veux mettre ça dans le cache, il faut alors le gérer autrement mais là c’est carrément un autre tuto :p
    Bye !

  2. Thomas Benlevi

    Merci beaucoup, je vais tester, je me suis cassé les dents sur un étrange problème très récemment en tentant de réaliser le même principe. Je n’atteignais jamais les derniers articles, le script rechargeait les articles les plus récents après les plus anciens…

    1. Thomas Benlevi

      Je me réponds à moi-même, en fait j’ai exactement le même problème, lorsque j’atteins le dernier article, je recharge les premiers, ça boucle. Sûrement un problème de pagination… Je sèche un peu.

  3. alan

    Mais comment savoir si le Templates intégrè déjà ce script ? Et la mise à jour futur si il y a conservera les modifs oui ou non . .dans tous les cas , il doit être bon de faire une sauvegarde avant toutes modif je pense aussi .

  4. Grunjo

    Bonjour ! Merci pour ce tuto car c’est exactement ce que je cherchais depuis plusieurs jours.
    Je suis entrain de créer mon thème et pour l’instant je souhaite mettre en place proprement Masonry et Infinite Scroll. L’adaptation graphique viendra ensuite. Cependant, je bute. Un message d’erreur apparaît:

    « function wpc_styles() { wp_register_script( ‘infinite-scroll’, get_template_directory_uri().’/wp-includes/js/jquery.infinitescroll.js’, ‘jquery’, ‘2.0’, true ); wp_enqueue_script( ‘jquery-masonry’ ); wp_enqueue_script( ‘infinite-scroll’ ); add_action(‘wp_enqueue_scripts’, ‘wpc_styles’);
    ( ! ) Parse error: syntax error, unexpected ‘endwhile’ (T_ENDWHILE) in C:\wamp\www\ophelie\wp-content\themes\bambi\index.php on line 37 »

    J’ai bien lu que ce tuto était destiné aux utilisateurs avancés, ce qui n’est pas mon cas. Mais j’adore cet effet et je souhaite vraiment qu’il soit partie prenante de mon site en devenir. Pouvez-vous m’aider ?

    Merci d’avance !

    Grunjo

    1. maknaouimohamed

      Bonjour Grunjo

      pour la fonction il faut ajouter un « } » à la fin de « wp_enqueue_script( ‘infinite-scroll’ ); ».
      votre code sera comme ça :

      function wpc_styles() { wp_register_script( ‘infinite-scroll’, get_template_directory_uri().’/wp-includes/js/jquery.infinitescroll.js’, ‘jquery’, ‘2.0’, true ); wp_enqueue_script( ‘jquery-masonry’ ); wp_enqueue_script( ‘infinite-scroll’ );}
      add_action(‘wp_enqueue_scripts’, ‘wpc_styles’);

      j’espère que ça vous aidera

  5. loic

    Bonjour,
    jai un problème pour gérer les margin: bottom des différents posts.
    Ainsi j’ai des posts qui se chevauchent légèrement.
    Comment faire ?
    Toute aide serait la bienvenue.
    A plus,
    loic

  6. loic

    Bonjour,
    Pour répondre à moi-même, j’ai utilisé les padding pour jouer sur les espacements entre les posts.
    Par contre, le bouton load more fonctionne comme un lien et m’emmène sur la page 2 (et ne fonctionne pas comme un scroll).

    1. christophe

      Hello Loic.
      Si tu repasses par là, j’ai le même souci que toi mais malheureusement pas le même flaire… Moi aussi, le bouton load more fonctionne comme un lien et pas comme un scroll. si tu peux donner ta solution…

      1. Cyrille

        J’avais exactement le même problème également, et je viens de trouver la solution

        Pour moi, l’erreur était causée parce que le fichier « functions.js » est inclu avant les plugins masonry et ImagesLoaded (que j’ai rajouté, je ne sais pas si c’est nécessaire mais il me semble que ce dernier était inclu avec masonry, mais que ce n’est désormais plus le cas).

        Du coup j’ai simplement du déplacer la partie :

        function wpc_styles() {
        wp_register_script( ‘infinite-scroll’, get_template_directory_uri().’/inc/js/jquery.infinitescroll.min.js’, ‘jquery’, ‘2.0’, true );
        wp_enqueue_script( ‘jquery-masonry’ );
        wp_enqueue_script( ‘infinite-scroll’ );
        add_action(‘wp_enqueue_scripts’, ‘wpc_styles’);

        au dessus de

        function twentyfifteen_scripts() { […] }

        dans le fichier function.php

        Je suppose que ce doit être a peu près pareil pour les autres thèmes par défaut de WordPress (il m’a suffit de rechercher « functions.js » dans le document pour trouver.

        Bref, je n’ai plus d’erreur et le bouton « charger plus de contenu » fonctionne très bien maintenant.

        1. christophe

          Salut Cyrille. Merci pour ta réponse. Malheureusement ça ne le fait pas dans mon cas. Je ne suis pas parti du même thème que toi, c’est sans doute pour ça. J’ai bien essayé d’inverser la déclaration des scripts, mais ça ne change rien.

          1. Cyrille

            Ah dommage, j’espérais que ton problème soit résolu.

            Du coup je ne peux pas trop aider plus mais juste au cas où, essaye juste de vérifier via firebug (ou équivalents) que tes différents fichiers js sont appelés dans le bon ordre (avec les balises ):

            – masonry
            – infinite-scroll
            – le fichier contenant le code js de ce tutoriel (dans mon cas, c’était functions.js)

            J’avais aussi rajouté imagesLoaded (avant masonry), mais je viens de le retirer et ça fonctionne toujours correctement.

            Si ça peut laisser une piste…

  7. christophe

    Ok, c’est bon, j’ai trouvé. Merci encore pour ton aide Cyrille. Même si nos problèmes étaient similaires qu’en apparence, ça m’a encouragé à ne pas lâcher…

    En fait je ne cherchais pas du tout dans la bonne direction.
    J’avais simplement oublié d’ajouter l’argument à la fonction post_class() comme c’est pourtant bien précisé dans la 4ème partie du tutorial.

    Comme quoi il faut bien lire les tutoriels jusqu’ au bout. C’est la leçon du jour…

  8. 1way

    Salut, déjà merci pour le tuto j’ai réussi à l’installer sur quelques sites ca marche top.. ! Jusqu’au jour ou je tombe sur mon propre thème perso et là .. petit bug C’est lié à mon CSS je le sais.. mais impossible de trouver pourquoi.

    Je bosse en local.. donc difficile de donner un lien, si jamais on ne trouve pas la solution ensemble je le mettrais en ligne mais bon. En fait le problème est que :

    – mon élément SECTION est mal reconnu par le JS, il ne compte que 63 px de hauteur pour ce div du coup quand je charge la suite.. ca me la charge a 63px de hauteur du SECTION.. et du coup tout les nouveaux postent passent dessus les anciens, je n’arrive pas a faire en sorte qu’au load de la page, sans scroll, mon section soit bien calculé en height.

    Je ne sais pas si tu vois ce que je veux dire ? Merci pour ton aide en tout cas..

    1. 1way

      J’ai oublié de préciser que je fais ça sur woocommerce, que j’ai 4 colonnes, et que les produits sont bien en float:left, j’ai aussi bien les ID produits etc en classe et en ID sur mes éléments, le chargement se fait bien etc, juste un problème de hauteur de contenant qui fait tout péter je pense

  9. Jean-Claude

    Bonjour,

    Merci beaucoup pour votre tutoriel que j’ai parfaitement réussi à intégrer à mon propre thème.
    Cependant, je souhaiterai faire fonctionner l’infinite scroll en simple défilement et non en clic.
    Pouvez-vous me préciser quelle étape je dois modifier ?

    Merci par avance,
    Jean-Claude

  10. CaptainBescherelle

    Les différents texte de la propriété loading peuvent être modifié au besoin ; => Les différents texteS de la propriété loading peuvent être modifiéS au besoin ;

  11. Le Petit SEO

    Vraiment super ! j’étais à la recherche du tel tuto.
    J’ai cherché un moment avant de tomber sur cette article, c’est ce qu’il me fallait.
    Par contre sur mon site, depuis quelques temps, le script marchait parfaitement jusqu’à la mise à jour vers la dernière version WP. Depuis, le script ne s’arrête plus lorsque le dernier article est atteint. Une boucle est faite et repart sur le premier article.

  12. e-maug

    Bonjour,

    par avance désolé pour mon commentaire lourdingue, mais mieux vaut demander vu que je n’avance pas dans ma recherche:

    en clair : je n’ai rien compris au tuto ah ah

    à quoi correspond le fichier content.php ?

    ou se trouve l’article sur lequel ajouter la class post? habituellement je le place directement dans ma boucle

    tout ce que je veux faire apparaitre dans l’article
    </article

    à quoi correspond cette ligne à modifier :

    <article id="post- » >

    ??

    je ne sais pas si mon cerveau ne tourne plus à l’endroit à force de brasser des pages de recherche

    par avance merci pour ton aide.

    1. Aurélien Denis auteur de l’article

      Oula beaucoup de questions… il est évident que l’article requiert de bonnes compétences en développement Web.

      En résumé, le fichier content.php est utilisé pour afficher la boucle uniquement. Il n’est pas obligatoire dans un thème mais permet d’éviter les codes qui se répètent.

      Je ne saisis pas la question sur la balise article…

  13. emaug

    et bien cela répond à la question sur la balise article. (je viens de voir dans le post que ma ligne de code a été bouffée)
    si la boucle est intégrée dans le content.php, la balise article se trouvera dans le content.php

    j’ai avancé depuis ma question, j’ai intégré l’infinite scroll, mais la boucle se fait toujours sur les mêmes articles (4 8 12 selon ce qui est configuré, au lieu de passer à la page deux) apparement problème de compatibilité entre le système de pagination wordpress et les custom query.

    il y a cent cinquante mille forums qui en parlent mais aucune solution ne fonctionne.

  14. annapseudo

    Bonjour Aurélien,
    J’ai réussi à appliquer ton tuto, et je te remercie !!
    Seul truc : quand je diminue la largeur de ma page en réduisant la fenêtre du navigateur, les images diminuent bien, mais le rendu pour smartphone par exemple est trop petit ; en effet les 3 colonnes restent en 3 colonnes, que l’on soit sur grand ou petit écran, ce qui fait des images minuscules.
    Aurais-tu une suggestion ?
    merci !

  15. Christophe

    Bonjour,

    Merci pour le tuto.
    Mais je n’arrive pas à faire fonctionner le tout avec un thème enfant.

    Si je bidouille le thème parent en y incluant tous les scripts, ça fonctionne bien.
    Mais si je fait un thème enfant (sans altérer le parent ce qui est l’intérêt même du thème enfant ) le chargement et/ou l’activation des scripts infinitescroll et masonry ne se produit pas.

    Je travaille à partir du thème pictorico. Est-ce qu’il y a une incompatibilité avec ce thème ?

  16. christophe

    bonjour.
    Bon je suis reparti de zéro et ça fonctionne bien. j’avais du toucher à un truc qu’il ne fallait pas sans m’en rendre compte. Désolé pour le dérangement…
    Sinon, petite question. Pour changer le petit gif de loading, est-ce qu’on doit nécessairement mettre un chemin absolu ? J’ai essayé un chemin relatif au thème mais ça ne marche pas.

  17. Dgedge

    Bonjour, tout d’abord merci pour ce tuto. Je suis en train d’essayer de mettre infinite scrooll sur un petit site d’image. Cela fonctionne mais il faut cliquer sur le bouton more post pour afficher les posts suivant alors que j’aimerais qu’ils se chargent au scroll. J’ai bien essayé de remplacer click par scroll sur la ligne 34 (comme indiquer ci dessus) mais cela ne fonctionne pas et je n’arrive pas a avancer. Merci de me venir en aide

Laisser un commentaire