Faut-il vraiment dupliquer tout un fichier theme.json pour changer une police et deux couleurs selon la langue affichée ? C’est la question posée par ce projet de site institutionnel disponible en français, anglais, allemand et néerlandais, où la version allemande devait afficher une police à empattements plus adaptée à la lecture de textes juridiques plus longs, sans toucher aux trois autres langues.
Ce billet présente la méthode retenue pour appliquer une variation de style globale distincte par langue avec WPML, en conservant une source unique de vérité pour le fichier theme.json. La compatibilité avec Polylang et la traduction automatique des patterns ne sont pas abordées ici, ce projet reposant exclusivement sur WPML.
Pourquoi éviter la duplication de theme.json
L’éditeur de site permet nativement de proposer plusieurs variations de style dans le dossier styles/ du thème, sélectionnables manuellement depuis le Style Book. Cette approche convient pour des variations choisies par un utilisateur, mais pas pour une bascule automatique selon la langue de navigation détectée par WPML : rien dans le mécanisme natif ne relie une variation de style à une langue.
Dupliquer entièrement le theme.json par langue aurait résolu le problème à court terme, au prix d’une maintenance quadruplée à chaque évolution de palette ou de typographie commune aux quatre langues. La solution retenue s’appuie plutôt sur un filtre PHP qui fusionne une surcouche spécifique à la langue par-dessus le theme.json commun.
Structurer la surcouche par langue
Un dossier lang-overrides/ a été ajouté au thème, contenant un fichier JSON minimal par langue nécessitant une variation, par exemple de.json pour l’allemand, contenant uniquement les clés à surcharger.

{
"version": 2,
"settings": {
"typography": {
"fontFamilies": [
{
"fontFamily": "\"Source Serif Pro\", serif",
"slug": "corps-texte",
"name": "Corps de texte (DE)"
}
]
}
}
}
Fusionner la surcouche via un filtre
Le filtre wp_theme_json_data_theme, disponible depuis WordPress 6.1, permet d’intercepter les données du theme.json avant leur application et d’y injecter une fusion conditionnelle selon la langue courante, détectée via la fonction WPML apply_filters( 'wpml_current_language', null ).
add_filter( 'wp_theme_json_data_theme', function( $theme_json ) {
$langue = apply_filters( 'wpml_current_language', null );
$chemin = get_theme_file_path( "lang-overrides/{$langue}.json" );
if ( ! file_exists( $chemin ) ) {
return $theme_json;
}
$surcouche = json_decode( file_get_contents( $chemin ), true );
return $theme_json->update_with( $surcouche );
} );
La méthode update_with() de la classe WP_Theme_JSON_Data effectue une fusion récursive : seules les clés présentes dans la surcouche sont modifiées, le reste du theme.json commun reste inchangé. C’est ce comportement de fusion, plutôt que de remplacement, qui rend l’approche viable sans duplication.
Un piège avec le cache d’objet
WordPress met en cache le résultat calculé du theme.json fusionné. Sans précaution, un visiteur naviguant entre deux langues sur un site avec un cache de page agressif pouvait recevoir la variation de style d’une langue précédente. La solution a consisté à inclure le code de langue dans la clé de variation du cache de page, à la charge de la configuration du plugin de cache utilisé sur le site.
Vérifier le rendu dans l’éditeur
- Basculer la langue d’édition dans WPML avant d’ouvrir le Style Book permet de vérifier que la variation de style s’applique bien à l’intérieur même de l’éditeur, pas seulement côté public.
- Un contrôle visuel systématique des quatre langues avant chaque livraison évite qu’une modification du
theme.jsoncommun ne casse silencieusement une surcouche devenue incompatible. - Les traducteurs du site, non techniques, n’ont aucune action à effectuer sur les styles : la bascule est entièrement automatique selon la langue de la page consultée.
Un filtre de fusion coûte quelques lignes de PHP mais évite des années de divergence silencieuse entre des fichiers JSON dupliqués.
En résumé
Le filtre wp_theme_json_data_theme ouvre une porte peu documentée mais précieuse pour des besoins de personnalisation conditionnelle du thème.json, au-delà du seul cas multilingue traité ici : variation selon le rôle de l’utilisateur, selon une préférence enregistrée, ou selon toute autre condition calculable côté PHP. La discipline à conserver reste la même : ne surcharger que le strict nécessaire, et laisser le fichier commun porter l’essentiel de l’identité visuelle du site.