Quelques secrets du fichier functions.php

Quand j’avais écrit mon article sur le fichier wp-config.php, Bruno Les Bons Tuyaux m’avait demandé d’en faire autant pour le fichier functions.php qui lui se trouve dans le thème. L’article a un peu trainé, et c’est tant mieux, parce que j’aurai beaucoup plus de choses à dire (moi bavarde ?)

Ne pas mélanger plugin et fichier functions.php

Quand on prend un thème tout fait, on s’aperçoit que très souvent, le fichier du thème, functions.php intègre un certain nombre d’informations qui vont en réalité jouer sur la présentation des données. C’est un peu un travers inhérent à WordPress qui n’est pas très strict sur la séparation entre contenant et contenu, mais ce n’est pas une raison pour charger la barque :)
En gros, tout ce que vous aimeriez retrouver facilement si vous changez de thème n’a rien à voir dans le fichier functions.php. Tout ce qui touche à vos données, à la façon de les traiter, de les stocker, de les modifier, est personna non grata dans le fichier functions.php, même si c’est là que ça se met par défaut.

Personnellement, je sépare la présentation, qui va dans le fichier functions.php et les données, qui vont dans un plugin que j’appelle « Gestion du Site », et qui restera donc actif si je change de thème.

Ce qui va dans le fichier functions.php en toute logique

  • les différentes tailles de vignettes (thumbnail)
  • tout ce qui va avoir trait à la modification des fonctions WordPress d’affichage (par exemple modifier le Read More), dont vous pouvez voir de nombreux exemples dans le fichier functions de Twenty-Ten
  • tout ce qui est lié purement à la présentation (notamment si on fait plusieurs boucles sur la page d’accueil, si on exclut certaines catégories, si on met des articles en avant)
  • toutes les options de gestion du thème qui concernent la présentation, pour les thèmes à option (nombre de sidebar, positionnement, css, etc)

Et c’est tout !

Ce qui y va et qui pourrait être mieux ailleurs

Les sidebars et les widget

Les sidebars et les widget (au moins en partie), parce que les widgets que vous mettez dans la sidebar sont des éléments de contenu de votre site. Il est donc très désagréable d’être obligé de « refaire » sa sidebar quand on change de thème. Et même quand on revient au thème d’origine, les widget sont perdus. En fait, WordPress stocke les widgets activés par rapport à l’id de la sidebar. Si elle diffère d’un thème à l’autre, le widget saute. Or même entre les thèmes de base de WordPress, l’id des sidebars change.

C’est comme ça, parce que c’était l’endroit où c’était le plus facile à stocker, mais ça serait mieux ailleurs.

Où ? Dans le fameux plugin de gestion de site. On peut parfaitement y placer la déclaration des sidebars, et l’action widget_init

Les sidebars ne seront pas perdues si on change de thème. (Mais évidemment, il faudra modifier le thème pour modifier les noms des sidebar).

En revanche, le placement des sidebars lui-même relève de la présentation, et se fait bien dans le thème.

Nb : si on veut être puriste, la déclaration des sidebar elle même contient des éléments de présentation avec le code HTML qui doit entourer les widget. Je suis d’accord sur le principe, néanmoins ce code est assez lié à la façon de structurer ses données et finalement plus rattaché au contenu (quel texte est ce que je veux mettre sur mes pages et avec quelle structuration sémantique).

Les menus

La même logique peut être appliquée aux menus… vous voyiez que je suis en train de vider ce pauvre fichier functions.php de toute sa substance ! Le menu est réellement à la limite entre présentation et données, mais on peut considérer que l’architecture des menus, son contenu et sa hiérarchie sont indépendants du thème. On peut aussi considérer qu’en fonction du thème on présentera ses données en un ou deux ou trois menus…

Je me suis décidée à passer la déclaration de mes menus en dehors du fichier config.php quand j’ai dû refaire un menu qui avait en tout une trentaine d’entrées, un mélange hiérarchisé de pages, articles, custom types et liens spécifiques…

Ce qui n’a rien à faire dans le fichier functions.php du thème

  • les customs content et les custom taxonomies, et tout ce qui va avec (et notamment les metabox)
  • les post formats, car contrairement à leur nom, ils ne sont pas un formatage, mais une identification d’un type de post, standard, qui doit se retrouver à travers tous les thèmes qui les utilisent et qui choisiront de les formater d’une façon ou d’une autre. On est donc là encore dans le traitement de la donnée.
  • la taille mémoire allouée à php (qui elle ira dans la config de votre hébergement ou dans le fichier wp-config.php

Attention à la déclaration des fonctions et à l’utilisation des hooks

Cela va sans dire, mais cela va encore mieux en le disant :

  • donnez des noms très spécifiques à vos fonctions, pour éviter un conflit avec un plugin qui utiliserait les mêmes noms (les noms français sont relativement sûrs dans l’univers de WordPress)
  • même après avoir donné des noms spécifiques, testez toujours si votre fonction est déclarée avant de l’initialiser, et avant de l’utiliser dans votre thème. Un petit if (!function_exists(‘lenomdemafonction’)) avant de lancer l’initialisation, au contraire un petit if (function_exists(‘lenomdemafonction’)) à l’utilisation épargne bien des déboires dans le thème.
  • c’est particulièrement important pour l’utilisation des hooks, et pour les « plugins de plugins ». Par exemple, la plupart des boutons supplémentaires de TinyMce sont codés sur le modèle d’un template disponible sur le site de l’éditeur. Cela m’est déjà arrivé de me retrouver avec deux boutons utilisant le même nom de fonction pour s’initialiser. Heureusement, ce n’est pas le type de plugin qui a besoin d’une mise à jour fréquente, copier – coller le code dans un plugin maison, modifier les noms de fonctions, et zou…

Oui mais les thèmes à options ?

Et sans, d’ailleurs… la plupart des créateurs de thèmes mélangent allègrement dans leur fichier functions.php ce qui concerne les données et ce qui est du ressort de la présentation. Cela « emprisonne » donc, car au moment de changer de thème, on risque de perdre des informations. Je pense notamment aux thèmes avec des « sections » spécifiques comme un portfolio, qui se basent maintenant souvent sur les custom post types.

En réalité, ces thèmes sont une combinaison d’une présentation et d’un plugin de gestion de portfolio. Il est exact que pour beaucoup d’utilisateurs débutants, ce serait un peu complexe (ça l’est déjà pour certains quand le thème est livré dans un dossier qui comprend des plugins, le dossier du thème, et éventuellement des sources en .psd), mais en pratique, sur le long terme, ce serait mieux d’effectuer cette séparation.

Dans le prochain article, on rentrera dans le code, avec les différentes fonctions. Un article entier sera réservé aux custom types et aux custom taxonomies.

Parcourir la sérieProchain article

8 commentaires

  1. Olivier Auteur août 8, 2011 (11:24 )

    Merci pour tout ça. Il te reste à le compléter par ta sélection des meilleurs « hooks » à mettre dans le functions.php :-)

    Répondre à Olivier
  2. Pour les « meilleurs hooks », « stay tuned » ^^ (quoi qu’il n’y aura pas de révélations fracassantes)

    Pour l’autre article, en fait, pour d’autres raisons (séparer données et présentation) j’arrive à peu près à un même résultat. Mes plus gros functions.php doivent être en dessous de 500 lignes (avec toutes les lignes blanches pour bien aérer le code). 

    Après tout dépend de la façon de structurer son code. Si l’idée de séparer admin et frontend est séduisante, dans la pratique elle peut être assez pénible. Notamment en ce qui concerne toute la définition des customs, où je trouve plus facile d’avoir dans un fichier unique tout ce qui concerne un type de post ou de taxo que dans plusieurs. Et par exemple, dans la déclaration de ton type de post, tu créés les labels, pour l’admin comme pour le front-end, et le slug pour le rewriting. 

    Il me semble aussi – mais je dis peut être une bourde – que le fichiers functions.php est en require_once. A vérifier / confirmer / invalider par des experts. 

    De toute façon, les thèmes ayant les functions.php les plus obèses sont les thèmes à option grand public, Thesis, Genesis, Suffision… c’est une des raisons pour lesquelles je ne les aime pas trop.

    Répondre à Marie-Aude
  3. Bjr,

    * tu as omis de parler des functions.php dans le cas d’un child theme.
    * « donnez des noms très spécifiques à vos fonctions » ou bien passer par une classe !

    Répondre à arena
    • Bonjour,
      pour moi il n’y a pas de spécificités particulières dans le cas d’un thème enfant :) on « rajouter » ce qu’on veut, et souvent dans mon cas, on soustrait … je passe les trois quarts de ce fichier functions.php à « unregister » les hooks tu thème parent…
      Oui on peut aussi passer par des classes, bien sûr

      Répondre à Marie-Aude
  4. Bon article et bons conseils

    Concernant la séparation du functions.php, je trouve que c’est une bonne idée, et personnellement je fais ça avec tous mes plugins depuis longtemps. Non seulement cela permet un gain (souvent négligeable) en terme de rapidité d’execution et de mémoire utilisée, mais surtout cela facilite grandement la maintenance. C’est plus facile de chercher quelquechose et de l’éditer dans un des 3 fichiers de 100 lignes que dans un gros fichier de 300 lignes qui regroupe tout.

    Autre astuce non abordée dans cet article : plutôt que de faire
    if( function_exists( ‘montheme_mafonction’ ) )
    montheme_mafonction();
    on peut faire, dans un functions.php :
    add_action( ‘montheme_mafonction’, ‘montheme_mafonction’ );
    et dans le theme lui-même, simplement :
    do_action( ‘montheme_mafonction’ );
    Code plus simple dans le theme et si la fonction en question n’est plus disponible, aucune erreur générée. Plus d’infos et d’exemples sur ce principe : https://nacin.com/2010/05/18/rethinking-template-tags-in-plugins/

    Répondre à Ozh
  5. Bonjour Ozh, et merci pour l’astuce, elle est excellente !

    Répondre à Marie-Aude
  6. Bonjour Marie-Aude, je tombe là-dessus suite à l’article de BBXdesign. Je découvre notamment que l’on peut désactiver des fonctions d’un thème parent (et moi qui modifiais ça à la main !) et qu’il faut séparer les custom post. Faut que je regarde ça plus précisément.

    Répondre à Li-An

Commenter

*Informations requises Merci de donner les informations requises

  • Pas de liens raccourcis
  • L'auteur doit s'identifier avec son pseudo, son nom, son prénom ou s'il le veut le nom de son entreprise ou de son site, sauf si celui-ci correspond à des mots clés. Toutes les combinaisons sont permises dans ce cadre.
  • L'url peut être celle d'un site ou profil de réseau social, uniquement la page d'accueil
  • Pas d'adresse email jetable

*

*