Bidouille: imposer la catégorie par défaut pour les permaliens Wordpress
Ce n’est pas le genre de bidouille (hack de code) dont je puisse être fier. Mais si je me résigné à le faire, c’est que je devenais fou à cause des liens permanents (permalink) qui changent au gré des catégories ajoutées ou retirées à un billet.
Vous aurez peut-être également envie de figer les catégories des permaliens dans 2 cas:
- Vous souhaitez rassembler vos billets dans des catégories « majeures ».
- Vous ne souhaitez pas que, lors de l’ajout d’une catégorie à un billet existant, cela modifie l’url de ce billet!
Vous vous demandez peut-être comment la catégorie « principale » (celle utilisée pour construire le permalien) est choisie par Wordpress lorsque votre billet est attaché à plus d’une catégorie. Et bien c’est simple: c’est la catégorie qui a le plus petit identifiant dans la base de données (et c’est relativement logique). Cependant, si vous ajoutez une très vielle catégorie à un billet existant, cela a pour effet de modifier le permalien du billet, puisque la catégorie ajoutée a un identifiant plus ancien (vous suivez?).
Et si, comme moi, vous utilisez wordpressMu, vous allez découvrir qu’une catégorie ajoutée dans un blog peut avoir un identifiant très petit, pour peu qu’il ait déjà été utilisé dans un autre blog…
La grosse bidouille
Encore une fois, je n’en suis pas particulièrement fier. Mais comme c’est un problème que je ne suis pas forcément le seul à avoir, j’ai préféré la partager.
Pour ne pas prendre de risque, je vous conseille de conserver ce « hack » dans un fichier à part (plus facile à retirer), et de l’inclure, par exemple, dans le fichier functions.php du thème du blog (un moyen de limiter les dégats à un thème…)
Pour modifier le contenu du permalien, je n’ai rien trouvé de mieux que d’ajouter un filtre sur « the_permalink »:
add_filter('the_permalink', 'custom_cat_order');
S’ensuit la fonction qui filtre tout ça:
// ordonne par cat_order, ou à défaut par ordre alphabétique, en supposant qu'il s'agit un permalien de billet (sale!) function custom_cat_order( $content ) { global $post; // si id du billet pas trouvé, ne rien faire if ( @empty($post->ID) ) return $content; // sinon, on suppose que le filtre traite le billet courant (sale!) // Definition en dur de l'ordre imposé des categories (sale!) $cat_order = array("directory", "bonus", "blog"); // et ajouter toutes les categories existantes (avec doublons, sale!) $all_cats = get_categories(); // Creer un tableau avec les slugs des categories foreach( $all_cats as $cat) $cat_order[] = $cat->slug; $cats = get_the_category($post->ID); if ( $cats ) { // Creer un tableau avec les slugs des categories du post foreach( $cats as $cat) $post_cats[] = $cat->slug; $the_cats = array_intersect($cat_order, $post_cats); usort($cats, '_usort_terms_by_ID'); // order by ID $category0 = $cats[0]->slug; $the_cat = array_shift($the_cats); // On suppose que la categorie est entre 'slash' (sale!) $content = str_replace("/".$category0."/", "/".$the_cat."/", $content); } return $content; }
Donc, pour résumer, je défini les catégories prioritaires dans le tableau $cat_order
, et remplace à la fin le slug de l’ancienne catégorie par celui de la catégorie imposée.
Comme vous avez pu le voir, c’est une méthode assez sale… même si cela semble fonctionner. Si vous trouvez une approche plus « propre », faites-le moi savoir!
Just thought you should know, there’s now a plugin that seems to do this quite well: http://wordpress.org/extend/plugins/hikari-category-permalink
Thanks Ash, sounds very good !