Les thèmes WordPress sont de plus en plus courus par tous : débutants, blogueurs confirmés ou professionnels du web. Il est possible d’en obtenir gratuitement un peu partout sur la toile, pas toujours de bonne qualité, pas toujours très sécurisés, comme il est possible d’en obtenir de payants (je n’ai pas dit qu’ils étaient mieux). Dans tous les cas il est possible de les personnaliser.

Plusieurs solutions

Wild tweaking

La première, la moins propre, consiste à modifier directement les fichiers du thème, améliorer les portions de code des articles, des commmentaires, ou simplement de l’en-tête de votre document ou du fichier functions.php pour ajouter quelques morceaux de code trouvés sur la toile.
Soit. Mais sachez qu’en faisant cela, il ne vous sera plus possible de mettre à jour votre thème. (en tout cas pas automatiquement)

En effet, à l’instar des plugins, les thèmes sont versionnés et peuvent subir des mises à jour (amélioration de fonctionnalité, mise à jour de sécurité, etc.). S’il vous prenait l’envie de mettre à jour un thème modifié par vos soins, vos modifications seraient alors écrasées.

Cette solution de modification n’est donc possible que si vous êtes sûr de la sécurité du thème et uniquement si vous ne souhaitez pas effectuer de mise à jour. Autant vous dire que ce n’est donc pas la meilleure des solutions.

Child Theme

La seconde solution, de loin ma préférée : créer un thème enfant.
La création d’un thème enfant n’est pas très complexe et permet de bénéficier du thème parent tout en autorisant la modification de certains fichiers à partir du thème enfant.
Sa création se résume en quelques étapes seulement :

  1. Créer un dossier de thème
  2. Définir le thème de référence
  3. Modifier le thème à partir du thème enfant

Voyons cela en détail avec des exemples concrets.

Child theme « Little Twenty »

Nous allons créer un thème enfant à partir du thème Twenty Eleven, nous l’appellerons Little Twenty (ou LT)

Création du dossier de thème

Le dossier du thème enfant se met avec les autres dossiers dans wp-content/themes/. Créez un dossier nommé little-twenty.
Dans ce dossier, créez un fichier style.css avec comme contenu de base :

/*
Theme Name: Little Twenty
Description: Thème enfant de Twenty Eleven
Author: CreativeJuiz
Author URI: http://creativejuiz.com
Version: 1.0.0
Template: twentyeleven
*/

Ce morceau est relativement clair, la première ligne définit le nom visible de votre thème, la seconde une description, la troisième le nom de l’auteur, la quatrième son URL et la cinquième le numéro de version de votre thème enfant. Toutes ces lignes servent de descriptif qui s’affichera dans l’espace d’administration (Apparence > Thèmes), vous êtes relativement libres sur le contenu à renseigner.
Le morceau le plus important est le dernier qui est le « slug » du thème de référence, le thème parent. Ce slug correspond au nom du dossier du thème que l’on souhaite modifier, ici Twenty Eleven, qui porte comme nom de dossier « twentyeleven ».

Une fois que vous avez cela, vous avez créé votre Child Theme qui apparait déjà dans la liste des thèmes disponibles depuis votre back-office.

Apparition du thème enfant dans Apparance > Thèmes de l'espace d'admin

Vous pouvez d’ores et déjà l’activer, celui-ci va simplement adopter le comportement de son thème parent, puisque nous n’avons encore aucun fichier « template » dans notre dossier de thème.
Petit hic cependant, la feuille de styles du thème enfant remplace déjà celle du thème parent. Deux solutions s’offrent ici à vous : copier le contenu de style.css de TwentyEleven pour le coller dans votre CSS du thème LT, ou créer un import en CSS avec la règle suivante :

@import url("../twentyeleven/style.css");

À placer à la suite des quelques lignes vues précédemment.
Pour des raisons de performance je conseillerais plutôt la première solution (c’est à dire la copie du contenu de la feuille de styles du thème parent), qui vous permettra même de modifier la CSS en cas de besoin.

Modification des templates

Il vous est désormais possible d’éditer les portions du templates parent comme bon vous semble. Comment ? Simplement en copiant le fichier à modifier depuis le thème parent, et en le collant dans votre thème enfant.
Désormais les modifications à apporter se feront sur les fichiers que vous copierez depuis le thème parent.
Prenons un exemple.

Copiez le fichier header.php du thème parent (TwentyEleven, pour rappel), puis collez-le dans votre thème enfant.
Vous avez maintenant dans votre dossier la feuille de style, et ce fichier header.php.
Ouvrez le fichier header.php pour édition et remplacez

<h2 id="site-description"><?php bloginfo( 'description' ); ?></h2>

par

<p id="site-description"><?php bloginfo( 'description' ); ?></p>

Le remplacement de h2 par p n’aura aucune incidence visuelle, par contre vous constaterez que le code a bel et bien changé.

Modifications des autres fichiers (images, JS, CSS, etc.)

Vous en avez fait l’expérience avec le fichier style.css : créer un fichier dans votre thème enfant qui porte le même nom qu’un fichier présent dans le thème parent vous permet de remplacer ce dernier.

Par exemple, vous souhaitez modifier le fichier images/search.png qui représente la loupe présente dans les champs de recherche du thème parent. Créez le dossier images dans LT, puis placez-y une image search.png. (prenez une icône sur le web pour effectuer le test, si ça vous dit)
L’autre possibilité aurait été d’écraser le style CSS appliqué à ce type de champ de formulaire, puisque cette image est placée en background-image.

Chacun des fichiers du thème parent est donc éditable de la sorte.

Ajout de templates, d’images, styles, etc.

L’ajout de template est possible : comme vous le feriez pour un thème parent, créer simplement votre template dans le thème enfant. En respectant la hiérarchie des templates de WordPress, vous pouvez par exemple créer une page spécifique pour l’auteur dont l’identifiant est 2 en créant le fichier author-2.php à la racine de votre thème.

L’ajout d’image se fait comme vous le feriez pour n’importe quel projet, créez votre image, dans n’importe quel dossier, puis appelez là dans votre thème (via CSS) ou dans votre code HTML.

Attention ! Lorsque vous cherchez à insérer une nouvelle image, le code suivant ne fonctionne plus :

<img src="<?php bloginfo('template_directory'); ?>/img/mon-image.jpg" />

En effet, la valeur « template_directory » de bloginfo() retourne le dossier du thème parent : http://domain.tld/wp-content/themes/twentyeleven
À la place, utilisez la fonction :

get_stylesheet_directory_uri();

Cette fonction retourne le dossier du thème enfant : http://domain.tld/wp-content/themes/little-twenty.

L’ajout de feuille de styles ou JavaScript se fait de la même manière que les images : nommez vos fichiers de la même manière que ceux du thème parent pour les écraser, ou chargez-en de nouveaux dans vos templates avec les fonctions wp_register_style() et wp_register_script(). Je vous laisse consulter la documentation pour plus de détails.

Les fichiers spéciaux

J’entends par fichiers spéciaux, les fichiers qui n’ont pas tout à fait le même comportement que les précédents.

Le fichier screenshot.png

Ce fichier permet d’afficher un aperçu du thème dans l’administration. C’est un fichier PNG de 300 pixels de large et 225 de hauteur.
Ce fichier n’est pas chargé depuis le thème parent, il vous faudra donc le créer pour votre thème enfant.

Le fichier functions.php

Le fichier functions.php ne fonctionne pas sur le principe des templates. En effet lorsque vous créez un fichier functions.php pour votre thème enfant, celui est chargé en premier, puis le même fichier du thème parent est chargé par la suite.
Les deux fichiers functions.php sont donc chargés l’un après l’autre, thème enfant, puis thème parent.

De cette logique découle une problématique que vous finirez par rencontrer : « Cannot redeclare function_name() (previously declared in […]) ».
En effet, PHP ne permet pas de déclarer deux fois une fonction portant le même nom, ce qui provoque une erreur.

Faisons un essai et analysons-le (attention, faites ça en local, on va créer un conflit) :

  • Dans votre child theme LT, créez le fichier functions.php
  • Entrez le code suivant, qui permet de redéfinir le nombre de mots de l’extrait d’article
    <?php 
    function twentyeleven_excerpt_length( $length ) {
    	return 50;
    }
    add_filter( 'excerpt_length', 'twentyeleven_excerpt_length' );
    ?>
  • Rechargez la page d’accueil du votre site, une erreur PHP apparait.

Nous venons de définir la fonction twentyeleven_excerpt_length, soit parce qu’on a accidentellement utilisé le même nom de fonction, soit parce qu’on voulait écraser l’effet de la fonction du thème parent. Sauf que cette fonction est déclarée deux fois par deux fichiers functions.php différents.
Voici ce qui se passe :

  1. le fichier functions.php de LT (le thème enfant) est lu
  2. twentyeleven_excerpt_length est déclarée pour la première fois
  3. le fichier functions.php de TwentyElevent (le thème parent) est lu
  4. twentyeleven_excerpt_length est déclarée pour la seconde fois
  5. PHP ne comprend pas : Paf ! Erreur !

Comment éviter ce problème ?

En utilisant la fonction function_exists() de PHP. En contrôlant si la fonction existe déjà, on peut déclarer conditionnellement une fonction.

<?php 
if ( !function_exists('twentyeleven_excerpt_length')) {
   function twentyeleven_excerpt_length( $length ) {
      return 50;
   }
   add_filter( 'excerpt_length', 'twentyeleven_excerpt_length' );
}
?>

« Si la fonction twentyeleven_excerpt_length n’existe pas, alors on la déclare. »

Ok pour le principe, mais c’est sur le thème parent qu’il faut faire cette manipulation, or on a dit précédemment qu’on s’interdisait à modifier sauvagement le thème parent.
On est bloqué ! Le thème parent est mal construit !

Il ne vous reste plus qu’à prévenir l’auteur du thème qu’il a mal pensé son code.

Cependant, WordPress prévoit quelque chose : chaque fonction créée et liée à un hook est considérée comme une « action » sur ce hook, il est donc possible de retirer ces actions.
Voici un code type qui reprend notre exemple précédent :

<?php
add_action('after_setup_theme','remove_parent_functions');
function remove_parent_functions() {
   remove_action('excerpt_length','twentyeleven_excerpt_length');
   add_action('excerpt_length','new_twentyeleven_excerpt_length');
}
 
function new_twentyeleven_excerpt_length($length){
   return 75;
}
add_filter('excerpt_length', 'new_twentyeleven_excerpt_length');

Il reste impossible d’utiliser le même nom de fonction, cependant nous avons supprimer l’action de la fonction initiale.
Cela reste un petit bidouillage malgré tout.
Merci à Julien et son article pour cette dernière astuce !

Développeurs de thème, pensez à contrôler l’existence des fonctions avant de les déclarer ! Merci.

Résumons en quelques points

Pour modifier un thème, vous devez dans l’idéal :

  • Créer un thème enfant
  • Écraser les templates, images, scripts et CSS en créant des fichiers de mêmes noms que le thème parent dans le dossier du thème enfant
  • Ajouter autant de templates, script, CSS ou images que je le souhaite, mais :
    • utiliser bloginfo('stylesheet_directory') pour appeler mes fichiers
    • Penser à utiliser wp_register_style() et wp_register_scripts()
  • Penser aux fichiers spéciaux
    • screenshot.png : pour ajouter un aperçu de votre thème au back-office
    • functions.php : les deux fichiers (thème parent et thème enfant) sont chargés

Pour ne pas avoir été beaucoup plus loin dans l’exploration des thèmes, je vais m’arrêter là, mais n’hésitez pas à apporter votre expertise ou toute information complémentaire afin de corriger ou compléter cet article.
Merci :)