Trois formats numériques différents devaient cohabiter sur le même thème : virgule décimale et espace insécable pour le français, point décimal et virgule pour l’anglais américain, virgule décimale et point pour l’allemand. Rien d’exotique en soi, mais le thème en question gérait sa propre couche d’internationalisation, sans extension de traduction dédiée, et laissait jusque-là chaque développeur formater les nombres à sa main, au gré des besoins — un terrain fertile pour des incohérences difficiles à repérer après coup.
Le problème : un formatage dispersé, source d’incohérences
Avant cette recette, chaque template du thème appelait number_format() avec des paramètres saisis en dur, différents d’un fichier à l’autre. Un prix affiché sur une fiche produit utilisait une virgule comme séparateur décimal, tandis qu’un total de panier ailleurs sur la même page utilisait un point — une incohérence purement accidentelle, née de développeurs différents ayant travaillé sur ces deux zones à des moments différents.
Le snippet : une configuration centralisée par locale
function get_locale_number_config( $locale = null ) {
$locale = $locale ?: determine_locale();
$configs = [
'fr_FR' => [ 'decimals' => ',', 'thousands' => ' ', 'unit_position' => 'after' ],
'en_US' => [ 'decimals' => '.', 'thousands' => ',', 'unit_position' => 'before' ],
'de_DE' => [ 'decimals' => ',', 'thousands' => '.', 'unit_position' => 'after' ],
];
return $configs[ $locale ] ?? $configs['en_US'];
}
function format_price_for_locale( $amount, $currency_symbol, $locale = null ) {
$config = get_locale_number_config( $locale );
$formatted = number_format(
(float) $amount,
2,
$config['decimals'],
$config['thousands']
);
return 'before' === $config['unit_position']
? $currency_symbol . $formatted
: $formatted . ' ' . $currency_symbol;
}
Cette fonction unique remplace tous les appels dispersés à number_format() dans les templates. Elle s’appuie sur determine_locale(), la fonction native de WordPress qui résout la locale active pour la requête courante — pas besoin d’extension tierce pour connaître la langue en cours.

Fiabiliser à l’écriture, pas seulement à l’affichage
Le vrai gain de cette recette ne vient pas seulement d’un affichage cohérent, mais d’une validation systématique au moment où un nombre est saisi ou importé, avant tout enregistrement en base. Un champ personnalisé de prix, par exemple, valide la saisie contre un format numérique strict avant de la convertir en valeur flottante stockée de façon uniforme :
function sanitize_locale_number_input( $raw_value, $locale = null ) {
$config = get_locale_number_config( $locale );
$normalized = str_replace( $config['thousands'], '', $raw_value );
$normalized = str_replace( $config['decimals'], '.', $normalized );
if ( ! is_numeric( $normalized ) ) {
return new WP_Error( 'invalid_number', __( 'Format numérique invalide.', 'mon-theme' ) );
}
return (float) $normalized;
}
Cette étape de validation transforme systématiquement la saisie utilisateur, quelle que soit sa locale d’origine, vers une représentation interne unique (un flottant PHP standard), avant de la reformater à l’affichage selon la locale du visiteur. C’est cette séparation entre stockage neutre et affichage localisé qui évite les incohérences constatées au départ.
Variantes possibles
Variante 1 : unités de mesure conditionnelles
La même configuration par locale peut porter une clé supplémentaire pour basculer entre système métrique et système impérial, utile pour un catalogue technique vendu à la fois en Europe et en Amérique du Nord.
Variante 2 : devise déduite de la locale plutôt que fixée
Sur un site multi-devises, la fonction peut être étendue pour déduire un symbole de devise par défaut selon la locale, tout en conservant la possibilité de le forcer explicitement quand la devise réelle diffère de la convention associée à la langue.
Variante 3 : cache par locale pour les configurations lourdes
Si le tableau de configuration grossit avec de nombreuses locales et options, un appel à wp_cache_get() avec la locale comme clé évite de reconstruire ce tableau à chaque appel de fonction sur une page à fort volume d’affichage numérique.
- Centraliser tout formatage numérique dans une seule fonction, jamais dispersé dans les templates
- Valider systématiquement la saisie avant stockage, pas seulement à l’affichage
- Prévoir une valeur de repli explicite pour toute locale non configurée
Un format numérique mal aligné avec la langue affichée reste l’un des détails les plus discrets d’un site multilingue — et l’un des plus agaçants pour un visiteur qui doit s’arrêter pour relire un prix deux fois.
En résumé
Centraliser le formatage numérique par locale dans une fonction unique, testée et validée à l’écriture, évite la dispersion de règles ad hoc dans chaque template. Cette recette reste volontairement simple : pas d’extension supplémentaire, juste une convention de code appliquée avec discipline sur l’ensemble du thème.