. WebdeZign
web design, intégration web et WordPress

filtres & actions : les hooks se dévoilent

Comme je n’ai aucune formation en programmation et que c’est à partir de sa surface et avec de simples palmes et tuba que j’ai commencé à plonger dans l’océan WordPress, ma réflexion et ma compréhension se heurtent à des parties du puzzle pour lesquelles j’ai bien repéré quelques pièces mais « ça veut pas »…. Je vois du code, je sais de mieux en mieux le décrypter, je pourrais même dire que je peux lire du code, surtout celui constitutif d’un thème WP, de ses fonctions et fonctionnalités. Et pourtant, certaines ‘manières de paramétrer’ m’échappent encore.

C’était par exemple le cas à propos des hooks, ces add_filter() et add_action() aux pouvoirs magiques.

Dans ma ‘lecture’ du code, je tombais fréquemment sur deux autres appels, ressemblants et apparemment en lien de correspondance avec ce que j’avais compris être les hooks : les apply_filters() et do_action(). Mais, depuis la création de mon premier hook (dont le contenu m’avait été largement soufflé par Willy), j’étais intriguée par le choix du ‘hook’ template_include (il sort d’où, ce truc ? comment trouver celui qui conviendra à une autre fonction ?) et par le fait que je voyais parfois des apply_filters() dans le code, sans comprendre comment cet élément pouvait être lié à celle que je pouvais provoquer avec add_filter().

Je lis couramment l’anglais, mais ce n’est de loin pas ma langue maternelle ou une langue dans laquelle je me sens en ‘mode automatique’. Cela ne m’empêche pas de faire énormément de recherches quand j’ai un os à ronger et j’en arrive parfois à oublier que j’ai des ressources dans ma bibliothèque, qu’elle soit numérique ou papier… et en français !!! Par exemple, le livre WordPress paru aux éditions Pearson dont la 3e édition date de 2013 (auteurs : Xavier Borderie, Francis Chouquet, Amaury Balmer).

wordpress-pearson-borderie-2013-800px

Je vous recommande la lecture de cet ouvrage qui permet de bien comprendre l’écosystème WordPress, c’est une excellente couche de base pour qui veut entrer dans le code.

Pour moi, tout – ou presque ! – s’est éclairci en page 482 !

Je cite :

L’API la plus importante de WordPress est celle des hooks. (… déjà, cette simple phrase vient éclairer ce qu’est une API …)

Ces crochets [je continue à écrire hooks parce que c’est ce qui est le plus répandu dans la communauté, me semble-t-il, et parce que ça lève toute ambiguïté par rapport aux différentes traductions en français] sont parsemés dans tout le code de WP par l’équipe de développement. (…) pour chaque action, chaque événement ou chaque comportement de WP, ils ont placé stratégiquement des ‘crochets’ susceptibles d’être utilisés par les développeurs d’extensions qui peuvent y « accrocher » une fonction PHP de leur cru. (…)

Il s’agit de modifier ou étendre le comportement de WP par les actions et les filtres.

Les filtres vont permettre de modifier le comportement de WP alors que les actions vont étendre une fonctionnalité.

Jusque là, rien de bien nouveau. Ce que j’ai enfin compris, c’est que le core de WordPress est bourré de « possibilités » (crochet présent) de venir s’y accrocher (crochet actif). Du côté de WordPress, les hooks offerts, présents, prêts à être utilisés par le développeur se distinguent par la présence de apply_filters( ‘filter_name’, $variable? ) pour les filtres et de do_action pour les actions. Pour venir s’y crocher, le ‘crochet actif’ est une fonction appelée avec add_filter( ‘filter_name’, ‘function_name’ ) ou add_action( ‘action_name’, ‘function_name’ ) que l’on placera dans le fichier functions.php d’un thème par exemple.

C’est en effet ce que j’ai réalisé il y a quelques jours : un hook pour attribuer un ‘single.php’ particulier à chaque catégorie. J’en ai décrit les étapes dans cet article et je vais reprendre cet exemple pour analyser ce que j’ai dit au-dessus.

apply_filters() et add_filter()

Pour demander à WordPress de prendre, non pas le fichier ‘single.php’ pour afficher un article, mais selon la catégorie de celui-ci de déclencher l’affichage d’un template personnalisé ‘single-category1.php’, voici le code transmis par mon ami Willy :

add_filter('template_include','template_type_by_cat');
function template_type_by_cat( $template ) {
  if ( is_single() && in_category( 'category1' )  ) {
        $new_template = locate_template( array( 'single-category1.php' ) );
        if ( '' != $new_template ) {
            return $new_template ;
        }
    }    
    elseif ( is_single() && in_category( 'category2' )  ) {
        $new_template = locate_template( array( 'single-category2.php' ) );
        if ( '' != $new_template ) {
            return $new_template ;
        }
    }    
    elseif ( is_single() && in_category( 'category3' )  ) {
	$new_template = locate_template( array( 'single-category3.php' ) );
        if ( '' != $new_template ) {
            return $new_template ;
	}
    }
  return $template;
  }

J’ai compris le fonctionnement de la fonction :

  • nous déterminons une fonction que nous appelons ‘template_type_by_cat’ dont la variable est $template,
  • nous choisissons le cas de figure à exécuter avec la condition « if… » et questionnons
    • si c’est une page d’article à afficher qui se trouve dans la ‘category1’, on détermine une variable temporaire $new_template qui prendra la valeur résultant de l’appel à ‘locate_template’ (un ‘tag’ ou un ‘hook’ de WP ou comment on appelle ça ?), càd localise le template attribué à cette catégorie ‘single-category1.php’ > si la variable temporaire n’est pas vide, on la renvoie à la variable $template de la fonction
  • que se passera-t-il si l’article choisi n’est ni dans aucune des trois catégories ? c’est à mon avis une faiblesse de mon code que je vais devoir traiter.

Je l’ai mis en place dans le fichier functions.php et, ô miracle, ça a fonctionné, avec bien sûr les fichiers prêts en arrière-plan pour les différents choix en fonction de la catégorie…! Le fait que cela fonctionne ne m’a pas empêchée de m’interroger sur :

  • la différence entre ce add_filter() et l’autre expression – apply_filters() – que je voyais deci delà
  • comment est-il possible de connaître toutes ces expressions – telles que template_include – qui permettent de faire ces choses ?

Il est évident qu’il me fallait pour cela prendre conscience de l’existence de l’autre partie des hooks, celle prévue par les développeurs de WP et disséminée à coup de apply_filters() et do_action() dans le core de leur code.

On ne touche pas au core de WP, on vient se crocher dessus.

Mais alors, comment savoir sur quoi et où se crocher ? En cherchant les portions de code que les développeurs ont prévu pour ça !! Donc, il faut explorer le code à la recherche, pour les filtres, de toutes les occurrences de l’expression apply_filters(). Dans le livre cité, paru en 2013 et contemporain de la version WP 3.5, on dénombrait près de 2000 hooks dans le code.

Pour l’exercice, il nous faudrait donc trouver où, dans le code de WordPress, se situe cet apply_filters( ‘template_include’, $variable ). Et comme disait Willy en conférence lors du WordCamp à Paris en 2015, pour apprendre le code, il faut lire du code. Alors, à ma pioche et à ma pelle, je m’en vais creuser…

Bingo, 3 minutes plus tard. Merci les fonctionnalités informatiques de recherche !! Le hook en question se trouve dans le fichier /wp-includes/template-loader.php* et se présente ainsi :

if ( defined('WP_USE_THEMES') && WP_USE_THEMES ) :
	$template = false;
	if     ( is_embed()          && $template = get_embed_template()          ) :
	elseif ( is_404()            && $template = get_404_template()            ) :
	elseif ( is_search()         && $template = get_search_template()         ) :
	elseif ( is_front_page()     && $template = get_front_page_template()     ) :
	elseif ( is_home()           && $template = get_home_template()           ) :
	elseif ( is_post_type_archive() && $template = get_post_type_archive_template() ) :
	elseif ( is_tax()            && $template = get_taxonomy_template()       ) :
	elseif ( is_attachment()     && $template = get_attachment_template()     ) :
		remove_filter('the_content', 'prepend_attachment');
	elseif ( is_single()         && $template = get_single_template()         ) :
	elseif ( is_page()           && $template = get_page_template()           ) :
	elseif ( is_singular()       && $template = get_singular_template()       ) :
	elseif ( is_category()       && $template = get_category_template()       ) :
	elseif ( is_tag()            && $template = get_tag_template()            ) :
	elseif ( is_author()         && $template = get_author_template()         ) :
	elseif ( is_date()           && $template = get_date_template()           ) :
	elseif ( is_archive()        && $template = get_archive_template()        ) :
	elseif ( is_paged()          && $template = get_paged_template()          ) :
	else :
		$template = get_index_template();
	endif;
	/**
	 * Filters the path of the current template before including it.
	 *
	 * @since 3.0.0
	 *
	 * @param string $template The path of the template to include.
	 */
	if ( $template = apply_filters( 'template_include', $template ) ) {
		include( $template );
	} elseif ( current_user_can( 'switch_themes' ) ) {
		$theme = wp_get_theme();
		if ( $theme->errors() ) {
			wp_die( $theme->errors() );
		}
	}
	return;
endif;

 

Toute la première partie est un résumé de la Hierarchy ^^ et montre la détermination par défaut des templates de page utilisés en fonction de la ‘demande’ du visiteur.

Notre hook est juste en-dessous :

	if ( $template = apply_filters( 'template_include', $template ) ) {
		include( $template );

 

Ce seul petit bout de code me permet, à moi, d’ajouter un add_filter ( ‘template_include‘, ‘mon_nom_de_fonction’ ) dans le functions.php de mon thème qui me permettra de ‘manipuler’ grâce à une fonction la valeur de la variable $template et ainsi modifier le comportement par défaut de WP.

Bon ben ça c’est fait !

Des remarques, des suggestions ? Des corrections ? N’hésitez pas, je suis là pour apprendre.


*c’est d’ailleurs une information que le Codex WP donne systématiquement pour chaque fonction : l’endroit où elle se situe dans le core de WordPress.

 

Tita

Conceptrice & CEO chez Tita Créations
Passionnée de chevaux, de nature, d'écriture... et d'informatique, j'ai découvert cette dernière avec un tout premier modèle d'ordinateur portable : un SHARP écran cristaux liquides d'au moins 10kg ! ... 1988
Aujourd'hui, je donne libre cours à ma créativité dans les domaines du web design, de la gestion de projet et de la gestion de contenu.


Commenter