« Template used: page-onglet-tarifs.php » affichait encore la barre de débogage, alors que ce fichier avait été supprimé du thème depuis la migration vers un thème hybride quinze jours plus tôt. L’extension qui gérait cette page utilisait un filtre template_include classique pour forcer l’affichage d’un template spécifique selon le contenu affiché ; ce filtre continuait d’exister dans le code, mais son retour n’avait plus le moindre effet visible.
Symptôme : un filtre qui s’exécute sans rien changer
Un point d’arrêt placé dans le callback confirmait qu’il s’exécutait bien, avec la bonne valeur de retour — le chemin vers un fichier page-tarifs.php toujours présent dans le thème parent classique conservé pour compatibilité. Pourtant, la page affichée à l’écran ne correspondait pas à ce fichier, mais bien au template de bloc page.html défini par le nouveau thème hybride.
Diagnostic : deux filtres sur le même hook, un seul gagne

Le mécanisme de résolution de template d’un thème hybride s’appuie lui aussi sur le filtre template_include, comme n’importe quel thème classique : le cœur y ajoute son propre callback, chargé de vérifier l’existence d’un template de bloc correspondant et de retourner, le cas échéant, un fichier PHP intermédiaire qui se charge lui-même de rendre le contenu du template de bloc. Quand ce callback du cœur s’exécute après celui de l’extension sur le même hook, à priorité égale, c’est la valeur qu’il retourne qui l’emporte pour la suite de la chaîne — pas celle fournie par l’extension plus tôt dans l’exécution.
// Callback de l'extension, priorité par défaut
add_filter( 'template_include', function ( $template ) {
if ( is_page( 'tarifs' ) ) {
return get_template_directory() . '/page-tarifs.php';
}
return $template;
} );
// Callback interne du cœur, ajouté plus tard sur le même hook
// et qui reçoit déjà la valeur retournée ci-dessus en argument
Le callback du cœur reçoit en argument la valeur déjà modifiée par l’extension, mais s’il détermine qu’un template de bloc existe pour cette même page, il retourne son propre chemin sans tenir compte de ce qui lui a été transmis : l’extension n’a jamais d’erreur, elle est simplement court-circuitée plus loin dans la chaîne de filtres.
Correctif : reprendre la main avec une priorité plus tardive
La solution la plus directe consiste à augmenter la priorité du filtre de l’extension pour qu’il s’exécute après celui du cœur, et à faire en sorte qu’il respecte, lui, la décision qui lui est transmise quand elle correspond à un template de bloc volontairement défini :
add_filter( 'template_include', function ( $template ) {
if ( is_page( 'tarifs' ) && ! wp_is_block_theme() ) {
return get_template_directory() . '/page-tarifs.php';
}
return $template;
}, 20 );
La condition ! wp_is_block_theme() évite en plus de forcer un ancien template PHP sur un thème qui, désormais, gère cette page via un template de bloc dédié — le vrai correctif de fond, au-delà du simple ajustement de priorité, consistait à recréer ce template dans l’éditeur de site plutôt qu’à perpétuer un fichier PHP devenu redondant.
Prévention pour la suite
- lors d’une migration vers un thème hybride, recenser tous les usages de
template_include,template_redirectet des fichiers de template hérités avant de les considérer obsolètes ; - ne pas se fier à l’absence d’erreur PHP pour conclure qu’un filtre fonctionne encore comme prévu : un filtre silencieusement court-circuité ne journalise rien ;
- préférer, quand c’est possible, migrer la logique conditionnelle vers un template de bloc dédié plutôt que de maintenir un filtre PHP en parallèle du nouveau système.
Après une migration vers un thème hybride, nous vérifions systématiquement chaque filtre
template_includehérité avec la barre de débogage active : c’est le moyen le plus rapide de voir quel template est réellement rendu, indépendamment de ce que le code source laisse supposer.
Ce qu’il faut retenir
Un thème hybride n’a rien retiré au filtre template_include, il a simplement ajouté un acteur supplémentaire sur ce même hook, avec une priorité qui lui donne le dernier mot dans la plupart des cas de migration. Un filtre existant qui semble ne plus fonctionner mérite d’être vérifié sous cet angle avant d’être suspecté de bug.