Créer une page d'archive d'un type de contenu est relativement simple, il convient de nommer le fichier archive-CPT.php dans le dossier de votre thème. La problématique ici consistait non seulement à lister tous les contenus mais en tenant compte des termes qui leur étaient reliés.

Vous recherchez un développeur WordPress capable de vous créer un thème sur-mesure ? C'est mon métier depuis plus de 8 ans, prenez contact et discutons de votre projet.

Si je devais résumer, voici le résultat souhaité :

  • Terme 1
    • Contenu A
    • Contenu B
    • Contenu C
  • Terme 2
    • Contenu A
    • Contenu B
    • Contenu C
  • Terme 3
    • Contenu A
    • Contenu B
    • Contenu C

Et ainsi de suite jusqu’à ce que tous les contenus aient été listés dans ma page d’archive.

Pour ce faire, j’ai donc commencé par lister les termes à l’aide de la fonction get_terms en spécifiant le nom de la taxonomie reliait à mon type de contenu.

Ensuite, pour chaque terme, une requête WP_Query pour récupérer les contenus qui sont bien associés à ce terme. Une fois dans la boucle, à vous de choisir les éléments que vous souhaitez récupérer : le titre, le permalien, l’image à la une, etc.

Voici l’intégralité du code du tutoriel avec des éléments facultatifs pour bien présenter les choses dont le titre de la page d’archive.

<?php if (! defined('ABSPATH')) die('Restricted Area'); ?>
<?php get_header(); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
	<header class="page-header">
	<h1 class="container"><?php post_type_archive_title(); ?></h1>
	</header>
<?php endwhile; endif; ?>
<div class="content">
	<div class="container">
		<?php
			$taxonomy = 'NOM_TAXONOMIE';

			$term_args = array(
			 'orderby' => 'name',
			 'order' => 'ASC'
			 );

			$terms = get_terms($taxonomy,$term_args);

			if ($terms) { foreach($terms as $term) {
		?>

		<?php 
			$args = array(
			'post_type' => 'NOM_CPT',
			'tax_query' => array(
			array(
				'taxonomy' => 'NOM_TAXONOMIE',
				'terms' => array($term->term_id),
				'include_children' => true,
				'operator' => 'IN'
				)
			)
		);
		$my_query = new WP_Query($args); if ($my_query->have_posts()) { ?>
			<div class="row">
				<h1 class="term-title"><?php echo $term->name; ?></h1>

				<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>
					<div class="col-sm-2">
						<?php if (has_post_thumbnail()) : ?>
							<?php the_post_thumbnail('thumbnail', array('class' => 'img-responsive aligncenter')); ?>
						<?php endif; ?>
						
						<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php _e('Permanent link to ', 'textdomain'); ?><?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
					</div>
				<?php endwhile; ?>
			</div>

		<?php } 
		 } } ?>
		<?php wp_reset_query(); ?>
	</div>
</div>
<?php get_footer(); ?>

Le reste vous l’aurez compris n’est que mise en forme HTML / CSS. Ici, je me base sur le framework CSS de Twitter Bootstrap.

15 commentaires
  1. Julio Potier

    Hello !
    As-tu remarqué que celà ne charge que les X articles pour chaque terme (X=selon les options de lecture de ton WP) ? Tu as oublié de mettre « -1 » en « posts_per_page » !

    Aussi, comme tu es sur une page d’archives, WordPress a déjà une requête qu’il a été faite pour toi, la « main query » et tu ne l’utilises pas !?

    Puis, tu vas faire une WP_Query pour chaque terme ? Omg

    Aussi, n’oublie pas que si tu souhaites afficher TOUS les articles sur une page, c’est assez suicidaire, ça va si tu en a peu sinon … PAF la pastèque.

    Pour en revenir à la main query, je pense qu’il serait mieux de toucher à pre_get_posts, check si on est en is_home pour cette main query, dans ce cas mettre -1 en posts_per_page, ce qui va te permettre d’avoir tous les articles dans la page d’archive.

    Maintenant, plus aucune query à faire, TOUS tes articles sont là, à toit de filtrer l’affichage à base de has_term.
    Et enfin, tout ceci manque de cache, où est le transient ? A chaque reload de chaque visiteur je dois tout re-récup ? wowowow.

    Bon, je viens de tester le code et le faire à ma sauce : http://pastebin.com/fwnMEgYw
    Qu’en dis-tu ? Il prends en charge les transients (je suis passé de 335 reqs à 61), 0 WP_Query, pas de reset query car pas de the_post qui écrase la globale, chacune des fonctions utilisée peut prendre un post ou un ID en param, et ça liste vraiment tout grâce à ce hook à mettre en plugin/mu-plugin/functions.php (au choix).

    (et code commenté ^^)

    Bisous

    1. Aurélien Denis auteur de l’article

      Hey, pour tout te dire je me demandais quand tu allais enfin commenter mon code !

      Je vais tester cela dès demain vu qu’il s’agit d’un projet en cours héhé. Oui le posts_per_page je pensais l’avoir mis mais non…

      Merci l’ami !

      1. Aurélien Denis auteur de l’article

        Tout fonctionne au poil ! Merci bien !

        1. Julio Potier

          Reste un point : vider le transient sinon le cache ne se régen pas. Il faut le faire au save_post, delete_post, save_term, delete_term, etc etc

          1. Aurélien Denis auteur de l’article

            Justement je me suis aperçu que effectivement ça ne vidait pas le cache… tu mets à jour ton code ?

          2. Julio Potier

            Voilà quelques hooks qui devraient faire l’affaire.
            http://pastebin.com/9ABV2ByF
            Aussi, après réflexion, il faut mettre ce transient en cache timé pendant 1 an, le but est qu’il ne soit chargé qu’à la demande et pas non stop (autoload) car il pourrait alors être assez gros et faire grimper la mémoire PHP utilisée pour rien.
            « 365*DAY_IN_SECONDS » pour le timeout

            Pas trop décousue comme réponse ?

  2. Ligo (@SiloweNet)

    Merci les gars!

    @Julien, pourquoi serait suicidaire de mettre tous les articles sur une seule page? (pour exemple, une page dédiée à une liste d’articles d’une catégorie spécifique)…

  3. Grégoire Noyelle

    Merci à Aurélien et à Julio. J’ai eu un casse tête similaire avec des query sur mesure sur les archives des custom taxonomy et c’est le pre_get_posts qui m’a sauvé.

    1. Aurélien Denis auteur de l’article

      Oui très pratique ! Et différentes techniques existent.

      P.S : oui oui

  4. Aurélien Denis auteur de l’article

    @Julio : je pense qu’il y a une coquille sur le foreach non ? Et sinon oui ça fonctionne nickel.

  5. Bonjour,

    J’ai créé une page template comme celle-ci, mais rien ne s’affiche est-ce normal ?

    (a qui puis-je envoyer le lien en MP pour vérification ?)

    Phil

    1. Aurélien Denis auteur de l’article

      Ce tutoriel est plutôt technique et je vous invite à vérifier chaque ligne de code en fonction de votre site au préalable.

  6. Bonjour Aurélien

    Je cherche à faire la même chose mais sur les pages des mots clés ( pages des tags). Pour le moment, wordpress affiche tous les articles qui contiennent chaque mots clés. Moi, je voudrai qu’il m’affiche les articles mais classés par catégorie.

    Exemple :

    Page d’un mot clé :

    Catégorie 1
    Contenu A
    Contenu B
    Contenu C
    Catégorie 2
    Contenu A
    Contenu B
    Contenu C
    Catégorie 3
    Contenu A
    Contenu B
    Contenu C

    De plus, j’aimerais également qu’il ne m’affiche pas les articles provenant des sous-catégories d’une catégorie en particulier. est ce possible de faire ca ?

    Merci pour votre aide

Les commentaires sont fermés.