Créer des pages d’archive pour vos custom post type

Comment créer des pages d’archives customisées pour vos custom post type ?

Dans cet article, nous allons voir comment outrepasser le fonctionnement par défaut de wordpress concernant les custom post type. Normalement, à la création de votre custom post type, si l’on donne comme argument « has_archive » =>’true‘ à notre CPT, wordpress va automatiquement créer une page d’archive qui affichera tous nos custom post type.

Le problème

Le problème c’est que cette page n’est pas générée dans le dossier wordpress, on ne peut donc pas la modifier par le code. Dans le cas de l’utilisation d’un page builder, Elementor ou autre, vous ne pourrez pas éditer la page.

La solution

Si vous utilisez un page builder et que vous avez besoin de modifier la page ou la rendre administrable pour l’utilisateur final, il faut donc impérativement trouver une solution. Celle-ci consiste en fait à créer un modèle de page d’archive pour notre custom post type.

La création du custom post type

Voici le code de création d’un custom post type. Ici, notre custom post type s’appelle « formation »

function cc_formation_cpt() {
/* Formation */
$labels = array(
'name' => _x('Formations', 'Post Type General Name', 'text_domain'),
'singular_name' => _x('Formation', 'Post Type Singular Name', 'text_domain'),
'menu_name' => _x('Formations', 'text_domain'),
'name_admin_bar' => _x('Formations', 'text_domain'),
'all_items' => _x('Toutes les formations', 'text_domain'),
'add_new_item' => _x('Ajouter une nouvelle formation', 'text_domain'),
'add_new' => _x('Ajouter', 'text_domain'),
'new_item' => _x('Nouvelle formation', 'text_domain' ),
'edit_item' => _x('Editer la formation', 'text_domain'),
'update_item' => _x('Mettre à jour la formation', 'text_domain'),
'view_item' => _x('Voir la formation', 'text_domain'),
'search_items' => _x('Rechercher une formation', 'text_domain'),
'not_found' => _x('Aucune formation trouvée', 'text_domain'),
'not_found_in_trash' => _x('Aucune formation trouvée dans la corbeille', 'text_domain'),
);

$args = array(
'label' => _x('Formation', 'text_domain'),
'description' => _x('Formations', 'text_domain'),
'labels' => $labels,
'supports' => array('title', 'editor', 'thumbnail', 'comments', 'revisions', 'custom-fields'),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'menu_icon' => 'dashicons-admin-home',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => false,
'exclude_from_search' => false,
'publicly_queryable' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'toutes-nos-formations' ),
'capability_type' => 'post',
'show_in_rest' =>'true',
);
register_post_type('formation', $args);
}
add_action('init', 'cc_formation_cpt', 10);

Si on laisse ici « has_archive » = »true » , on peut retrouver un onglet qui s’appelerait « toutes les formations » dans l’onglet Apparence / Menu du backoffice. On aurait donc automatiquement une page avec tous les articles lis à ce custom post type.

Nous on passe ce paramètre « has_archive » à false, et on crée par la même occasion une réécriture d’url :

'rewrite' => array( 'slug' => 'toutes-nos-formations' ),

Cela garantit que WP ne crée pas d’archive réelle et accepte notre modèle de page à la place. La réécriture garantit notamment que les CPT individuels seront publiés de manière à ressembler à des « enfants » de cette page, même s’ils ne le sont pas en réalité !

La création du modèle de page

Template Name: Toutes nos Formations

Tout en haut de notre nouveau fichier php, on signifie à worpdress qu’on est là sur un nouveau modèle de page « Toutes nos formations ». Le nom doit être le même que celui indiqué dans la réécriture d’url. Dans le backoffice de wordpress, on crée ensuite notre nouvelle page « Toutes nos formations » et on lui attribue comme modèle de page « Toutes nos formations ».

Une page administrable

Dans cette page, on va donc pouvoir coder en dur tout ce qu’on veut, cela occupera un espace dans la page en front. On va notamment créer la boucle qui va ramener tous nos custom post type. Il s’agit ici de simuler le comportement d’une page d’archive classique .

<?php 
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'post_type' =>'formation',
'posts_per_page' =>5,
'paged' => $paged

);
$query = new WP_Query( $args ); //Check the WP_Query docs to see how you can limit which posts to display ?>
<?php if ( $query->have_posts() ) : ?>

Pour le reste, on peut appeler le template_tag the_content() normalement, afin que l’utilisateur puisse administrer le reste de la page via l’éditeur de wordpress, Elementor, ou tout autre page builder

<?php		
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_content();
endwhile;
endif;
;?>

Le breadcrumb

Sans modification supplémentaire, le fil d’Ariane va continuer à afficher le nom de la page d’archive générée automatiquement par wordpress. Il va donc falloir le modifier. Si on utilise Yoast SEO, voici un bout de code qui permet de modifier ce fil d’Ariane.

<?php
function cc_filter_yoast_breadcrumbs( $links ) {
// Only affect individual "mycpt" CPTs
if ( is_singular( 'mycpt' ) ) {
// Add "My CPT" breadcrumb
$addedBreadcrumbs = array(
array( 'text' => 'My CPT', 'url' => '/mycpt/', 'allow_html' => 1)
);
// Add the new breadcrumb before the single CPT title
array_splice( $links, 1, 0, $addedBreadcrumbs );
}
// Always return the links, even if we didn't change them
return $links;
}
add_filter( 'wpseo_breadcrumb_links', 'cc_filter_yoast_breadcrumbs' );
?>

Adapté à notre exemple, voici ce que cela donne:

function cc_formation_filter_yoast_breadcrumbs( $links ) {

if ( is_singular( 'formation' ) ) {

$addedBreadcrumbs = array(
array( 'text' => 'Toutes nos formations', 'url' => '/mon site/toutes-nos-formations/', 'allow_html' => 1)
);

array_splice( $links, 1, 0, $addedBreadcrumbs );
}

return $links;
}
add_filter( 'wpseo_breadcrumb_links', 'cc_formation_filter_yoast_breadcrumbs' );

Maintenant, lorsque vous serez dans votre article du custom post type, le fil d’Ariane affichera le nom de votre modèle de page crée précédemment. L’utilisateur ne pourra donc plus tomber sur la page d’archive générée par wordpress.

Sources :

Cette astuce m’a été donnée par WebElaine sur stackoveflow.