Les taxonomies et leurs termes
Le tutoriel ultime

Que celui qui ne s’est jamais pris la tête avec les histoires de catégories, de tags, de taxonomies me jette le premier smartphone… Ok, personne.

J’ai voulu vous faire ici une rétrospective la plus fidèle possible de l’utilisation de ces taxonomies, de A à Z, je compte sur vous pour me corriger, je me donne le droit à l’erreur.

Genèse

D’abord, définissons ce qu’est une taxonomie, ou taxinomie selon votre vocabulaire, car pour l’histoire, le mot « taxonomie » est du vieux français (1813) qui nous a été gentiment piqué en anglais pour donner « taxonomy » (1828), puis comme des amnésiques, nous les français l’avons repris en « taxinomie » afin de ne pas trop l’angliciser. Blasphème, c’est notre mot quoi ! Bref …

Une taxonomie (oui je dis taxonomie moi, je suis vieux) un de ces mots que la plupart des gens n’ont jamais entendu en dehors de WordPress et qui est malheureusement souvent associé à tort en tant que synonyme du mot catégorie.

Fondamentalement, une taxonomie est un moyen de regrouper les choses.

Par exemple, je pourrais avoir un tas de différents types d’animaux. Je peux les regrouper selon diverses caractéristiques, puis attribuer des noms de groupes.

C’est quelque chose que la plupart des gens rencontrent dans les cours de biologie, connu sous le nom de taxonomie linnéenne ou plus simplement classification classique/traditionnelle.

Dans WordPress, une taxonomie est un mécanisme de regroupement pour certains posts.

Je ne vais pas dire article qui est pour moi, un type de post.

Ça va, vous suivez ?

Les noms des différents groupes dans une taxonomie sont appelés termes.

Dans l’utilisation de groupes d’animaux, par exemple, avec la taxonomie « animaux » nous pourrions appeler un groupe « oiseaux », et un autre groupe « poissons ». Ils seraient alors termes de notre taxonomie.

Dans WordPress nous avons donc par défaut 2 taxonomies qui sont les catégories et les mots-clés. L’une est respectivement hiérarchique, l’autre ne l’est pas. La différence est qu’un terme d’une taxonomie hiérarchique peut avoir des sous-termes aussi communément appelés des enfants. La taxonomie non hiérarchique est dite plate.

Si je prends un Grand Corbeau (qui serait alors un post, peu importe son type) dans ma taxonomie hiérarchique animaux, je vais lui attribuer les termes « Oiseaux » et « Corvus » pour faire simple. Par contre, pour ses mots-clé je peux lui attribuer « Mâle » ou « Femelle« , « Albinos » s’il l’est, « Handicapé patte gauche » s’il a été abîmé car cela n’entre pas dans une classification précise de l’espèce. Mais je garde ces infos en mots-clés afin de pouvoir par la suite lister mes animaux albinos, mâles, handicapés.

Toujours là ?

Exode

Partons un peu plus loin.

Vous pouvez depuis WordPress 2.9 créer des types de contenus personnalisés (ou CPT) et aussi des taxonomies personnalisées (ou custom taxo), c’est là où ça devient aussi intéressant que compliqué. Pas difficile, mais compliqué.

Il ne faut pas oublier que depuis la création de WordPress les catégories existent et donc des tas de fonctions existent pour les lires, les lister, etc Mais depuis 2.9, vous ne pouvez plus utiliser ces fonctions qui ne se basent alors QUE sur une seule taxonomie, celle native de WordPress. Il vous faut utiliser celle qui est finalement imbriquée dans l’autre (on va y venir, inutile de montrer du code de suite).

Tout ça pour dire qu’il y a de quoi se perdre, mais afin de garder une rétrocompatibilité, les développeurs de WordPress n’ont pas souhaité déprécier ces anciennes fonctions. Ce qui est bien et pas bien à la fois.

Lévitique

Depuis WordPress 0.71 il existe des fonctions capables de lister les termes des catégories et des tags, il existe aussi des fonctions pour afficher les termes des catégories et des tags selon un article donné. Ceci ne fonctionne donc QUE pour ces 2 taxonomies là.

Depuis 2.9, si vous avez ajouté des taxonomies personnalisées, vous NE POUVEZ PLUS utiliser ces fonctions. « Rien de grave » et « normal » me direz vous, nouvelles fonctionnalités, nouvelles fonctions ! Oui c’est sûr, je les ai aurait aussi ajoutées si on m’avait demandé, mais il y a un mais.

Avant de lister, voici comment créer une taxonomie maison, gardons notre exemple d’animaux. J’utilise 2 sites qui sont GenerateWP.com et i18n pour Taxo de @screenfeedfr. Allez, démo, je fais un mélange des 2 sites pour sortir ceci :

<?php
/*
Plugin Name: Add "Animal" custom taxonomy
Description: Add the new custom taxonomy "animal", don't forget to flush your permalinks!
Author: Julio Potier
Author URI: http://boiteaweb.fr
*/

/* !---------------------------------------------------------------------------- */
/* !	REGISTER TAXONOMIES														 */
/* Generated with http://screenfeed.fr/tools/i18n-pour-taxo/					 */
/* ----------------------------------------------------------------------------- */

add_action( 'init', 'register_animal_taxonomy', 0 );
function register_animal_taxonomy() {

	// !Load i18n
	load_plugin_textdomain( 'my_plugin', false, basename( dirname( __FILE__ ) ) . '/languages/' );

	// !Animal Taxonomy
	$labels = array(
		'name'							=> _x( 'Animals', 'taxonomy general name', 'my_plugin' ),
		'singular_name'					=> _x( 'Animal', 'taxonomy singular name', 'my_plugin' ),
		'menu_name'						=> _x( 'Animals', 'taxonomy general name', 'my_plugin' ),
		'search_items'					=> __( 'Search Animals', 'my_plugin' ),
		'popular_items'					=> __( 'Popular Animals', 'my_plugin' ),
		'all_items'						=> __( 'All Animals', 'my_plugin' ),
		'parent_item'					=> __( 'Parent Animal', 'my_plugin' ),
		'parent_item_colon'				=> __( 'Parent Animal:', 'my_plugin' ),
		'edit_item'						=> __( 'Edit Animal', 'my_plugin' ),
		'view_item'						=> __( 'View Animal', 'my_plugin' ),
		'update_item'					=> __( 'Update Animal', 'my_plugin' ),
		'add_new_item'					=> __( 'Add New Animal', 'my_plugin' ),
		'new_item_name'					=> __( 'New Animal Name', 'my_plugin' ),
		'separate_items_with_commas' 	=> __( 'Separate animals with commas', 'my_plugin' ),
		'add_or_remove_items'			=> __( 'Add or remove animals', 'my_plugin' ),
		'choose_from_most_used'			=> __( 'Choose from the most used animals', 'my_plugin' ),
		'not_found'						=> __( 'No animals found.', 'my_plugin' ),
	);

	$rewrite = array(
		'slug'                       => 'animal',
		'with_front'                 => true,
		'hierarchical'               => false,
	);

	$args = array(
		'labels'                     => $labels,
		'hierarchical'               => true,
		'public'                     => true,
		'show_ui'                    => true,
		'show_admin_column'          => true,
		'show_in_nav_menus'          => true,
		'show_tagcloud'              => true,
		'rewrite'                    => $rewrite,
	);
	register_taxonomy( 'animal', array( 'post' ), $args );

}

add_filter( 'term_updated_messages', 'animal_taxonomy_messages' );
function animal_taxonomy_messages( $messages ) {

	$messages['animal'] = array(
		0 => '', // Unused. Messages start at index 1.
		1 => __( 'Animal added.', 'my_plugin' ),
		2 => __( 'Animal deleted.', 'my_plugin' ),
		3 => __( 'Animal updated.', 'my_plugin' ),
		4 => __( 'Animal not added.', 'my_plugin' ),
		5 => __( 'Animal not updated.', 'my_plugin' ),
		6 => __( 'Animals deleted.', 'my_plugin' ),
	);

	return $messages;
}

J’utilise register_taxonomy() qui permet de déclarer une taxonomie personnalisée dans mon installation.

Remarquez que le slug, – l’identifiant – de ma taxonomie est « animal » et non pas « animals » ni « animaux« . Je vous conseille de coder en anglais déjà, et les slugs, que ce soit taxo ou CPT, sont au singulier. Un terme est un animal et non pas un animaux tout simplement !

Pour la démo j’ai lié cette taxonomie aux articles de blogs, libre à vous d’avoir votre propre CPT qui serait « animalia » par exemple. N’appelez jamais un identifiant « type« , c’est un terme réservé, bonne amusement si vous tentez !

Maintenant qu’on a notre taxonomie maison, on va pouvoir jouer avec.

Nombres

Alors, combien de fonctions avons-nous pour toucher aux catégories, tags et animaux ? Rien que pour les catégories, j’en compte rapidement 37 … ouch … Il y a celles pour vérifier, celles pour afficher, celles pour l’ajout, suppression, etc

Puis celles qui vont toucher à toutes les taxonomiess, ou à une taxonomie en particulier, celles faites pour être utilisées dans la boucle ou hors de la boucle …

Je vous ai toujours ?

Ajoutons des animaux et jouons avec (façon de parler hein), ça sera plus simple avec des exemples concrets, j’ajoute 9 termes répartis en 3 parents avec chacun 2 enfants comme ceci :

9 termes de la taxonomie "animal"

9 termes de la taxonomie « animal »

J’ajoute maintenant 6 animaux (des posts donc) et leur attribue des catégories, des mots-clés et un classement animal :

6 animaux

6 animaux

Du code, des fonctions et des exemples

Allez, du code, voyons un peu comment je peux lister ce qui m’intéresse en me plaçant d’abord dans une page faites pour l’occasion, je vais lui demander de me lister les taxonomies disponibles :

get_taxonomies

get_taxonomies() : Cette fonction vous permet de lister les différentes taxonomies disponibles dans votre installation de WordPress.

Chez moi, j’ai donc 3 taxonomies, c’est ça ? FAUX, j’en ai 6, je vous ai menti et alors ? Je fais ce que je veux, je suis chez moi, c’est mon tuto !

Allez, regardez ces 6 taxonomies :

6 taxonomies et non pas 3

6 taxonomies et non pas 3

Nous retrouvons les 3 prévues, c’est à dire « category« , « post_tag » et « animal« . Les 3 autres sont « nav_menu » qui est la taxonomie liée aux menus de WordPress depuis 2.3, « link_category » qui est liée aux liens (la blogroll) disparus (cachés) depuis la 3.5 et « post_format » qui sont les formats des posts disponibles, ceci depuis 3.1.

A peine une utilisation de fonction et déjà des surprises. Et elle n’est pas anodine, je vous montre ça pour que vous ayiez toujours en tête que vous ne connaissez peut-être pas tout ce que cache le core de WordPress.

Si par exemple vous aviez voulu utiliser cette fonction pour lister les taxonomies disponibles pour les articles, alors vous auriez 3 mauvais résultats. Pour n’avoir que les 2 natives de WordPress en plus de la notre il faut utiliser les paramètres de la fonction comme ceci :

get_taxonomies( array( 'show_ui'=> true ) )
Les 3 taxonomies attendues

Les 3 taxonomies attendues

Maintenant je connais les taxonomies disponibles sur mon installation grâce au paramètre « show_ui » qui ne m’affiche alors que les taxonomies affichant leur interface utilisateur dans l’administration.

Ne confondez pas get_taxonomies() avec the_taxonomies() ! La plupart du temps (toujours ?) quand ça commence par « the_ » ce n’est utilisable uniquement que dans la boucle !

Allez, comment lister les termes ? Là on va rigoler …

get_categories

get_categories() permets de lister les termes disponibles dans la taxonomie « category » en dehors de la boucle.

Les 3 termes de mes catégories

Les 3 termes de mes catégories

Maintenant, je fais comment pour les mots-clés ? Facile !

get_tags

get_tags() fait la même chose que pour la taxonomie des catégories, mais avec la taxonomie des tags, les mots-clés !

Mes 6 tags

Mes 6 tags

Pas de surprise, j’ai mes mots-clés.

On continue, c’est facile non ? Alors, comment je fais pour les catégories ? get_categories(), pour les tags ? get_tags(), pour les animaux ? get_an ... euh ha ouè non …

C’est maintenant qu’on rigole. Il n’y a pas de fonction qui s’est automatiquement créée pour « suivre » votre taxonomie, vous devez donc utiliser la fonction générique qui permet de lire les termes d’une taxonomie.

get_terms

get_terms() est la fonction utilisée par get_categories() et get_tags(). Ces 2 dernières sont pour moi, encore présente pour des soucis de vieilles rétrocompatibilité et pourraient, ne plus être utilisées. Ce n’est que mon avis. Mais au lieu d’avoir 3 fonctions pour lister les termes, pourquoi par juste une seule, claire !

get_terms( 'category' ); // == get_categories()
get_terms( 'post_tag' ); // == get_tags()
get_terms( 'animal' );

La dernière ligne me donne alors :

Les 9 termes des animaux

Les 9 termes des animaux

N’est-ce pas sincèrement plus simple de ne gérer qu’une seule fonction ? De plus, son paramètre est très clair, il suffit de mettre l’identifiant de la taxonomie désirée. Notez que « tag » n’existe pas mais c’est « post_tag« . Vous ne le saviez pas ? Normal, get_tags() nous donne l’impression qu’il s’agit de « tags » …

Bon ok et après ? Après, voyons la même chose mais DANS la boucle cette fois.

the_taxonomies

the_taxonomies() affiche directement un texte formaté avec tous les termes de toutes les taxonomies liées à l’article actuellement dans la boucle.

Tous les termes de toutes les taxonomies

Tous les termes de toutes les taxonomies

Plutôt utile, j’aime, mais dommage qu’on ne sente pas la hiérarchie ! Crocodylus est un enfant de Reptilia, mais c’est juste classé dans l’ordre alphanumérique et aucun paramètre de tri ne le permet.

get_the_category

– get_the_category() renvoie les termes de catégories de l’article actuellement lu dans la boucle. Dans mon « Crocodile du nil« , cela donne alors :

Le terme de la catégorie pour mon Crocodile du Nil

Le terme de la catégorie pour mon Crocodile du Nil

get_the_category_list

– get_the_category_list() vous retourne une liste au format HTML des termes de catégories, et uniquement catégories.

the_category

– the_category() est la version affichée de get_the_category_list().

Le terme de la catégorie en HTML

Le terme de la catégorie en HTML

Même chose pour les mots-clés, vous devinez ?

get_the_tags

get_the_tags() renvoie les termes de la taxonomie des mots-clés de l’article actuellement dans la boucle. Dans ce même « Crocodile du nil« , cela donne :

Les 2 mots-clé de ce Crocodile du Nil

Les 2 mots-clé de ce Crocodile du Nil

the_tags

– the_tags() fait donc la même chose au format HTML.

Les 2 mots-clé de mon crocodile en HTML

Les 2 mots-clé de mon crocodile en HTML

Remarquez que, ne me demandez pas pourquoi, pour la taxonomie des tags, le préfixe « Mots-clés » est présent alors que pour la taxonomie catégorie, non.

Je vous laisse devinez pour les animaux ? the_an… et non toujours pas … Il faut encore chercher quelle est la fonction générique ! Il s’agit de get_terms et the_terms.

get_the_terms

get_the_terms() renvoie les termes de la taxonomie désirée, utilisation simple, elle remplace là aussi get_the_category() et get_the_tags().

<?php
get_the_terms( 0, 'category' ); // = get_the_category
get_the_terms( 0, 'post_tags' ); // = get_the_tags sans prefixe
get_the_terms( 0, 'animal' ); 
Les 2 termes animaux

Les 2 termes animaux

the_terms

the_terms() fait donc la même chose dans la boucle encore, et affiche directement en format HTML les termes de la taxonomie spécifiée.

Les 2 termes animaux au format HTML

Les 2 termes animaux au format HTML

Mis à part le préfixe des tags qui disparaît (et c’est logique finalement), ces fonctions font alors le travail des 2 autres, encore une fois, pourquoi devoir encore les utiliser !?

– wp_list_categories( $args ) qui va encore une fois faire un listing au format HTML, mais assez avancé cette fois. Vous pourrez même choisir la taxonomie dans $args ! Cela va donc TOUT lister, impossible de l’utiliser correctement dans la boucle. Vous pourrez choisir le style « list » ou « flat« . Avec « list », vous aurez visuellement la hiérarchie, sinon non, vous perdez même le title_li (Familles).

wp_list_categories( array( 'taxonomy'=>'animal', 'title_li'=>'Familles' ) )
"list" et "flat"

« list » et « flat »

wp_tag_cloud

– wp_tag_cloud( $args ) est une fonction permettant d’afficher le nuage de termes d’un article dans la boucle. Par défaut, et comme son nom l’indique, elle affichera les mots-clés, mais le paramètre $args permet de choisir une autre taxonomie.

"wp_tag_cloud" sans et avec paramètres

« wp_tag_cloud » sans et avec paramètres

Au dessus j’ai juste appelé la fonction wp_tag_cloud() seule, dessous j’ai décidé d’afficher d’utiliser la taxonomie « animal »  sous forme de liste, sans différence de taille grâce aux paramètres.

Seconde main

Les fonctions précédentes sont les plus utilisées dans les thèmes, celles que je rencontre le plus souvent. Il en existe une multitude, en voici une panoplie.

single_cat_title

– single_cat_title( $before ) affiche le titre du terme de la catégorie de d’archive en cours.

single_cat_title

single_cat_title( $before ) affiche le titre du terme des mots-clés de d’archive en cours.

single_term_title

single_term_title( $before ) affiche le titre du terme de la taxonomie de d’archive en cours.

category_exists

– category_exists( $category, $parent ) vérifie si le terme existe dans les catégories. Optionnellement vous pouvez en plus lui préciser un parent en 2ème paramètre.

tag_exists

– tag_exists( $post_tag ) vérifie si le terme existe dans les mots-clés.

term_exists

term_exists( $term, $taxonomy, $parent ) vérifie si le terme passé en paramètre existe dans la taxonomie spécifiée. Optionnellement vous pouvez en plus lui préciser un parent en 3ème paramètre.

if ( term_exists( 'crocodylus', 'animal', 25 ) ) { // 25 = reptilia
// Le terme existe et est bien un enfant de "25"
}

Elle fait donc elle aussi le travail des 2 autres (qui ne sont pas documentées dans le codex !), encore une fois …

is_category

is_category( $categories ) permet de savoir si nous sommes dans une page d’archive de la taxonomie « category« , le fait de visiter une de ces pages renvoie TRUE. Un paramètre optionnel permet de préciser un ou plusieurs termes.

is_tag

is_tag( $tags ) permet de savoir si nous sommes dans une page d’archive de la taxonomie « post_tag« , le fait de visiter une de ces pages renvoie TRUE. Un paramètre optionnel permet de préciser un ou plusieurs termes.

is_tax

is_tax( $taxonomies, $terms ) permet de savoir si nous sommes dans une page d’archive de n’importe quelle taxonomie SAUF category et post_tag, la bonne blague. Pourquoi ? Je ne sais pas.

Par contre elle prends 1 ou 2 paramètres optionnels qui sont la ou les taxonomies à vérifier, puis un ou plusieurs termes de cette taxonomie. Elle fait là encore le travail des 2 autres.

if ( is_tax( 'animal', 25 ) ) {
// vérifie si nous visitons la page d'archive des reptiles
}

in_category

in_category( $category, $_post ) vérifie si $_post ou l’article actuellement dans la boucle fait partie de la catégorie spécifiée. Je vous recommande de l’oublier, vraiment, au profit de …

has_term

has_term( $term, $taxonomy, $post ) qui fait la même chose en mieux. Donnez lui un terme et une taxonomie, elle renverra TRUE ou FALSE. Elle remplace has_category() et has_tag() par la même occasion. Le 3ème paramètre est optionnel, la fonction lira la boucle si dispo.

get_objects_in_term

get_objects_in_term( $terms_ids, $taxonomies ) vous retourne tous les IDs des posts qui ont le(s) terme(s) dans la(les) taxonomie(s) spécifiée(s).

</p>
<p>array_map( ‘intval’, get_objects_in_term( 25, ‘animal’ ) );
// équivaut à
get_posts( array( ‘animal’=>’reptilia’, ‘fields’=>’ids’, ‘orderby’=>’ID’, ‘order’=>’asc’ ) )

Entre ces 2 lignes qui font le même travail, la première est nettement meilleure en performances, cela dit, avec la première, il est impossible de sélectionner le type, statut d’article ou autre.

get_term & get_term_by

get_term( $term, $taxonomy, $output, $filter ) et get_term_by( $field, $term, $taxonomy, $output, $filter ) vous retournent un objet (selon $ouput) étant le $term de la $taxonomy demandée.

Le terme "reptilia"

Le terme « reptilia »

Je ne vois pas non plus d’avantage à utiliser get_term() qui fait un get_term_by( ‘id’, … ), pourquoi en faire 2 différentes ? La deuxième a certes un paramètre de plus, mais au moins on sait ce qu’on demande. Et si le « name » de ma taxonomie est un chiffre, ça ne posera pas de problème !

get_category_by_slug

– get_category_by_slug( $slug ) vous renvoie l’objet du terme de la catégorie. Euh … non, utilisez get_term_by() s’il vous plait !De toute façon elle n’en est qu’un wrapper.

get_term_children

– get_term_children( $term_id, $taxonomy ) vous renvoie tous les IDs des termes qui sont les enfants de $term_id dans $taxonomy.

get_term_link

– get_term_link( $term, $taxonomy ) renvoie l’URL du $term spécifié dans la $taxonomy désirée. Juste l’URL, pas le tag HTML A.

term_description, category_description, tag_description

term_description( $term_id, $taxonomy ) renvoie la description du $term_id de la $taxonomy demandée si elle est renseignée. Elle est la fonction générique de category_description() et tag_description().

"Les reptiles"

« Les reptiles »

wp_terms_checklist & wp_category_checklist

– wp_terms_checklist( $post_id, $args ) est une fonction du côté back-office, il faudra alors ajouter un require pour l’utiliser en front-office si besoin. Elle permet de créer une liste de case à cocher avec les termes de la taxonomie demandée dans $args. Elle est la générique de wp_category_checklist(). Si le premier paramètre est à 0, les coches ne seront pas cochées, si vous lui fournissez un véritable ID, elles le seront.

require( ABSPATH . 'wp-admin/includes/template.php' );
wp_terms_checklist( $GLOBALS['post']->ID, array( 'taxonomy'=>'animal', 'checked_ontop'=>false ) )
Les cases à cocher de ma taxonomie animal

Les cases à cocher de ma taxonomie animal

_get_term_hierarchy

– _get_term_hierarchy( $taxonomy ) est une fonction protégée (elle commence par un « _ »), ce qui ne nous empêche pas de l’utiliser, vous aurez peut-être besoin de faire un require par contre. Cela dit, j’aime bien cette fonction car elle va me retourner sous forme d’IDs la liste hiérarchisée des termes de $taxonomy mais en plus, elle gère son propre cache via la table wp_options et ça c’est top !

La taxonomie "animal"

La taxonomie « animal »

Maintenant que faire avec ça, et bien ça par exemple :

echo '<span>Familles<br>';
$terms_id = _get_term_hierarchy( 'animal' );
$post_terms = get_the_terms( $post->ID, 'animal' );
$terms_id = array_intersect_key( $terms_id, $post_terms );
foreach ( $terms_id as $parent => $enfants ) {
	$term_links = rtrim( $term_links, ', ' );
	if ( ! empty( $term_links) ){
		$term_links .= '<br />';
	}
	$term = get_term( $parent, 'animal' );
	$link = get_term_link( $term, 'animal' );
	if ( is_wp_error( $link ) )
		continue;
	$term_links .= '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a> : ';
	foreach ($enfants as $i => $id) {
		$term = get_term( $id, 'animal' );
		$link = get_term_link( $term, 'animal' );
		if ( is_wp_error( $link ) )
			continue;
		$term_links .= '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>, ';
	}
}
echo rtrim( $term_links, ', ' );
echo '</span><br>';

Ce qui donne

Les familles d'animaux, visuellement hiérarchique

Les familles d’animaux, visuellement hiérarchique

wp_unique_term_slug

– wp_unique_term_slug( $slug, $term ) vous retourne le $slug unique pour un $term donné. Si le slug existe déjà, WordPress va lui même gérer l’unicité de ce terme. La plupart du temps vous n’aurez pas besoin de vous en soucier, mais vous savez que ça existe maintenant.

Du code avancé

Voici quelques fonctions un peu plus avancées, peut-être plus pour les plugins que pour les thèmes, enfin je dis ça …

wp_insert_term, wp_update_term, wp_delete_term, wp_create_term

wp_insert_term(), wp_update_term(), wp_delete_term(), wp_create_term()

Ces 4 fonctions vont vous servir dans des développements avancés, ce qui nécessitent que ce soit le code qui ajoute des termes dans les taxonomies existantes et déjà déclarées.

wp_create_category, wp_update_category, wp_delete_category, wp_insert_category & wp_create_tag ?

Ha oui bien sur, il existe wp_create_category(), wp_update_category(), wp_delete_category(), wp_insert_category() qui font le travail pour les catégorie.

Ho et wp_create_tag() qui crée un tag. Pas d’update, insert, delete pour lui, ne me demandez pas pourquoi, utilisez « _term » !

Utilisez wp_create_term() afin que la création soit stoppée si le terme existe déjà, utilisez wp_insert_term() si vous souhaitez laisser WordPress créer un doublon avec le slug en « -2 ». Les 2 cas se valent.

Préférez encore une fois celles avec « term » plutôt que « category« , autant pour la compréhension du code, que pour une portabilité plus simple et aussi car elles sont finalement différentes et « term » permet plus de flexibilité et contient plus de hooks.

wp_set_object_terms, wp_set_object_terms, wp_set_post_terms, wp_get_post_terms

– wp_set_object_terms( $object_id, $terms, $taxonomy, $append ) va vous servir à lier des $terms d’une $taxonomy à un $object_id qui peut alors être un post ou tout autre chose, même un autre terme si l’idée vous tente. Le dernier paramètre $append sert à écraser ou non les termes existant. Notez que cela ne crée PAS de termes, une erreur sera retournée s’ils n’existent pas.

– wp_get_post_terms(  $object_ids, $taxonomies, $args ) fera ici l’opération inverse, c’est à lire de récupérer les termes liés à une $taxonomy pour les $objects_ids demandés. Le paramètre $args contient des options de récupération, je vous invite à les lire. Cette fonction est la plupart du temps remplaçable par une des premières rencontrées. Lire les termes d’une taxonomie, vous savez le faire plus facilement maintenant non ?

Les 2 autres wp_set_post_terms(), wp_get_post_terms() ne le font QUE pour les posts (tout type).

wp_delete_object_term_relationships

 wp_delete_object_term_relationships( $object_id, $taxonomies ) peut s’avérer très utile, elle supprime les relations entre l’$objects_id et les $taxonomies désirées.

tax_query

Les « tax query » sont une façon de récupérer des posts via des termes de taxonomies, natives ou non. Pour cela il faut se tourner du côté de WP Query.

Une façon simple de récupérer des posts liés à un terme particulier est :

$args = array( 'animal' => 'crocodylus' );
$query = new WP_Query( $args );

Ici, je vais récupérer les articles liés au terme « crocodylus » de la taxonomie « animal« . On peut compliquer la chose un peu avec :

$args = array(
	'tax_query' => array(
		'relation' => 'AND',
		array(
			'taxonomy' => 'animal',
			'field' => 'slug',
			'terms' => array( 'crocodylus', 'reptilia' )
		),
		array(
			'taxonomy' => 'post_tag',
			'field' => 'id',
			'terms' => array( 21, 12, 79 ),
			'operator' => 'OR'
		)
	)
);
$query = new WP_Query( $args );

Je récupère ici les posts qui ont les termes « crocodylus » ET « reptilia« , puis en plus que leurs mots-clés soient contenus dans les id 21, 12 ou 79.

Hooks !

Oui les hooks, vous connaissez ? Je vous en parle un peu car depuis le début de ce guide, je vous dis « utilisez plutôt celle-ci, n’utilisez plus celle là ».

Mais il y a un bémol, il s’agit du fait que dans les fonctions dédiées aux catégories se trouvent des hooks qui sont peut être utilisés par des plugins. En utilisant les fonctions génériques, vous risquez de passer à côté.

Les plugins, au moins ceux fait après 2.3, devraient penser que leur code peut être utilisé sur ces taxonomies personnalisées et non pas seulement sur la taxonomie catégorie native de WordPress n’agissant que sur les articles de type « post« .

Cette remarque est aussi valable pour les plugins qui agissent sur « post » ou « page » au lieu de laisser le choix des types d’articles, bref je m’écarte du sujet.

Si vous avez à coder quelque-chose qui se rapporte aux taxonomies, et si les catégories peuvent aussi être touchées, tout comme n’importe quelle autre taxonomie qui vous est impossible de connaitre tant cela dépends du site, alors vous devrez non seulement jouer sur les hooks des fonctions génériques MAIS aussi celles dédiées aux catégories (et tags bien sûr, selon le besoin de hiérarchie ou non).

Même pensée pour les CPT, ne codez pas juste pour « post » ou « page« , laissez si possible, le choix à l’utilisateur, je m’écarte encore pardon.

The end ?

Ce tutoriel n’est peut-être pas encore tout à fait complet, j’ai aussi omis volontairement des fonctions dépréciées, inutile de nous bourrer le crâne avec ça.

J’ai aussi zappé certaines fonctions qui sont utilisées dans d’autres fonctions de WordPress mais dont je doute fortement de l’utilité une fois en dehors.

Je compte sur vous pour me corriger, me dire ce qui manque à ce guide, s’il faut éclaircir des points etc Je suis conscient que l’article n’est peut-être pas super bien présenté, désolé, ça fait un peu pavé imbuvable, mea culpa j’ai fait ce qui me semblais être le mieux.

Lire la suite

Vous aimez ? Partagez !

33 commentaires

  1. madvic · juillet 2, 2014
    Très bon article ! De quoi remplacer le codex…
    • Julio Potier · juillet 2, 2014
      Merci. Le remplacer non, l’alimenter, oui :p
  2. Laurent Olivares · juillet 2, 2014
    Salut,

    joli rappel et tuto, j’ai mis ça de coté ;)

    Merci encore.

  3. Lorenzo · juillet 2, 2014
    Wow vraiment super cet article, je mets en favoris direct, beau boulot.
  4. Erick · juillet 2, 2014
    Whaaaa voila un article que je vais devoir lire plus d’une fois pour tout assimiler;
    mais encore une fois c’est bien rédiger et les exemples sont parlants
    Merci à toi !
    Je permet de te signaler une coquille :
    « vous renvoie les tous IDs des termes »
    • Julio Potier · juillet 2, 2014
      Mais de rien, oui il faut le relire plusieurs fois OU venir dessus quand on a besoin de trouver son bonheur.
      Merci pour la typo !
  5. Greg · juillet 2, 2014
    J’ai épuisé mon quota de RTT pour l’année :(
    • Julio Potier · juillet 2, 2014
      Merci pour ton com méga constructif x)
  6. Grégoire Noyelle · juillet 2, 2014
    Merci Julio. Une référence que j’ajoute à ma collection.

    Un copain (que tu connais) me demandais récemment comment ajouter une taxonomie dans l’URL d’un custom post type. As-tu une idée ou une piste.

    • Julio Potier · juillet 2, 2014
      Je lui ai parlé alors ;) Il faut faire avec les rewrites, rien de plus compliqué.
    • Grégoire Noyelle · juillet 2, 2014
      Merci
  7. La dormeuse · juillet 2, 2014
    Au secours ! Je ne comprends plus du tout ce que je croyais avoir compris auparavant :-)
  8. Yanos64 · juillet 2, 2014
    Et bien voilà enfin une explication claire sur le sujet !

    Depuis le temps que je patauge …

    Merci beaucoup ;)

  9. Julien Maury · juillet 2, 2014
    Les taxonomies servent à mettre en place une classification particulière. Catégories et tags sont des taxonomies built-in orientées blogging. Il est particulièrement intéressant de les utiliser dans le cadre d’une installation WordPress en tant que CMS combinées à des custom post types.

    Meilleure organisation côté administration et meilleur accès à l’information pour les visiteurs. On évite de tout mettre au même niveau et on pourra jouer avec le param « hierarchical » pour créer un système de taxonomies parentes et enfantes. Tout le reste c’est du jargon mais c’est bien la première fois que je le vois exposé aussi simplement et de manière quasi exhaustive. Merci.

    • Julien Maury · juillet 2, 2014
      Je précise qu’au début je parlais des custom taxonomies à utiliser avec WordPress en tant que CMS ^^
    • Julio Potier · juillet 2, 2014
      Merci à toi pour ce commentaire très utile !
  10. Rédaction Web · juillet 2, 2014
    Article très intéressant et très complet. Néanmoins, il m’a fallu le relire 3 fois pour bien comprendre.
  11. @ReasonableGeek · juillet 2, 2014
    Très bon travail. Merci pour ce récap !
    J’ai toujours un doute sur les questions de performances quand on veut faire un peu « gros » (par exemple je me suis amusé à mettre en taxo les +36 000 communes de France classées par Région et Département de manière hiérarchique (avec code postal en Slug).
    Bon bein… « ça rame » si on reste dans du « standard » (affichage en Admin et requêtes « codex ») – après on va un peu plus loin bien sûr…

    WordPress se cherche un peu par moment entre le poids de la rétrocompatibilité à tout prix et les trucs qui sont là mais pas tout à fait (genre le « term_group – Not fully implemented (avoid using) » de get_terms….)
    Mais ça reste le meilleur des CMS pour le moment :-p

    Encore merci pour l’article – et les autres ^^

  12. Ghalem · juillet 2, 2014
    Bonjour,

    Je suis un novice et j’ai hélas! lâché prise à « Du code, des fonctions et des exemples ».
    Je m’excuse, mais je n’ai pas votre dextérité.
    Je cherche seulement à créer des nouvelles catégories

    Merci tout de même

    m.Ghalem

  13. David Mounou · juillet 2, 2014
    Bonjour

    Je tenais à vous remercier et à vous féliciter pour cet article, qui m’a accompagné plusieurs jours comme « bible » et référence dans la réalisation de mon projet (cf signature).

    J’y ai trouvé 99% des ressources et surtout des concepts dont j’avais besoin pour créer des CPT, leurs taxonomies propres, et les termes associés.

    J’ai ainsi pu créer des fiches de raquettes avec leurs caractéristiques, les comparer à d’autres caractéristiques pour les classer, etc : http://www.tennis-perf.com/raquettes/wilson-blade-104-2

    Aujourd’hui je bute sur un écueil de taille : sur une fiche de raquette, je souhaite lister les raquettes (posts) présentant EXACTEMENT les mêmes termes de la taxonomie « raquette_data ».
    Ca marche très bien si je saisis les terms à la main:

    
    args = array(
    	‘tax_query’ => array(
    		‘relation’ => ‘AND’,
    
    		array(
    			‘taxonomy’ => ‘raquette_data’,
    			‘field’  =>  ‘slug’,
    			‘operator’ => ‘AND’,
    			
    			‘terms’  => array(‘en-manche’, ‘ouvert’, ‘moyen-tamis’, ‘lourd’),
            ),
    		
    	
    			
    		),
    	);
    	
    $query = new WP_Query( $args );
    ?>

    Mais je ne parviens pas à les rendre dynamiques en allant chercher ceux du post en question. Je pense que le fait que la taxonomy raquette_data est hiérarchique, et que parmi les terms du posts, il va aussi chercher les terms parents.

    Auriez-vous une idée, sachant que votre billet m’a déjà tellement aidé que je ne vous en tiendrai pas rigueur dans la négative.

    Bien cordialement

    DM

    • Julio Potier · juillet 2, 2014
      Si le fait de récupérer les termes parents pose un problème, il suffit de filtrer les résultats en ne gardant que ceux qui ont un ID parent > 0, vous n’aurez alors que les enfants.
      Pour filtrer il faut utiliser la fonction PHP array_filter avec une callback maison, voire la doc PHP.
      Bon courage
  14. BenM · juillet 2, 2014
    Bonjour,
    C’est très complet, merci !
    Sauriez-vous s’il existe une explication un peu plus détaillée que le codex sur les paramètres (j’ai le même problème avec les custom post types) ?
    Par exemple, l’utilité de show_admin_column, des explications sur la partie rewrite, etc.
    Je n’ai également pas vraiment compris l’utilité de register_taxonomy_for_object_type.
    Merci.
    • Julio Potier · juillet 2, 2014
      Bonsoir, la doc dit « Whether to allow automatic creation of taxonomy columns on associated post-types table. », comment être plus clair si ce n’est qu’elle soit disponible en français :)
  15. anødine · juillet 2, 2014
    Après cette petite session d’analyse, je me relance et essaie d’aller plus loin… Moi qui pensais qu’après 7 mois de html, css, php, sql, expressions régulières… j’en avais fini avec la théorie… mais non il me reste encore le codex… enfin une bonne partie. Merci en-core ;)
  16. Serge · juillet 2, 2014
    Bonjour,
    super article, merci.
    Une petite question (je profite de l’occasion).
    J’ai besoin d’une taxonomie hiérarchique qui devrait être partagée sur plusieurs sites d’un réseau, mais uniquement le tronc et les branches principales (cette partie non modifiable par les admins des sous domaines) et leur laissant évidemment la possibilité de créer leurs propres branches et feuilles.
    Comment envisagerais tu le problème ?
    Merci d’avance pour tes conseils.
    • Julio Potier · juillet 2, 2014
      Bonjour Serge
      Amaury de BeApi me réponds ceci pour toi sur slack:
      Amaury Balmer [11:28 AM]
      https://github.com/herewithme/bea-content-sync-fusion
      + du code spécifique
      c’est touchy ^^

      ps : vient sur slack ;)

    • Serge · juillet 2, 2014
      Waouh … trop cool ! et quelle rapidité !
      Je fonce voir ça.
      Merci
  17. JeanYves · juillet 2, 2014
    Pas mal cet article sur la taxonomie. Effectivement c’est vraiment casse-tête parfois, par contre une fois la politique et stratégie bien en place, c’est un point positif pour le site. Côté code c’est pas bien compliqué à mettre en oeuvre mais ca bouffe du temps. Je vais de ce pas lire un peu les autres articles du site ;)
    Merci.
  18. Karatestream · juillet 2, 2014
    Très utile, merci beaucoup.
    Vous pouvez nous conseiller des plugins qui gèrent çà?

    Merci