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.
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.
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
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
Ce tutoriel est plutôt technique et je vous invite à vérifier chaque ligne de code en fonction de votre site au préalable.
@Julio : je pense qu’il y a une coquille sur le foreach non ? Et sinon oui ça fonctionne nickel. 🙂
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é.
Oui très pratique ! Et différentes techniques existent.
P.S : oui oui 😉
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)…
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 :O
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
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 !
auto réponse, il faut lire « is_post_type_archive( $post_type ) » au lieu de « is_home() » et le pastebin du hook ici : http://pastebin.com/Y9ywcCHp
Tout fonctionne au poil ! Merci bien !
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
Justement je me suis aperçu que effectivement ça ne vidait pas le cache… tu mets à jour ton code ?
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 ? ^^