Skip to content

Internationalisation

L’API est traduite côté serveur : les champs errors[].detail et toute chaîne destinée à l’affichage sont rendus dans la locale active (en plus du meta.code toujours présent et stable, qui reste la source de vérité programmatique pour le client).

  • fr-FR — locale par défaut applicative
  • en-US

Catalogues sous resources/lang/<locale>/ (auth.php, users.php, validation.php, errors.php, mails.php). Format ICU MessageFormat (interpolation {name}, pluriels {count, plural, =1{...} other{...}}).

Le LocaleResolverMiddleware pose i18n.locale sur la requête et renseigne le header Content-Language sur la réponse. Ordre de priorité (première règle qui matche) :

  1. Setting locale de l’utilisateur authentifié (lu via UserSettingService). Le middleware tourne après AuthenticationMiddleware sur les routes protégées.
  2. Négociation du header Accept-Language contre la liste des locales supportées (q-values respectés, fallback langue-only frfr-FR).
  3. Locale applicative par défaut (fr-FR).

Si une clé manque dans la locale active, le Translator la cherche dans la locale fr-FR (locale historique, présumée complète à 100%). Si elle manque aussi là-bas, la clé brute est renvoyée et un warning est loggé.

Les emails transactionnels (email_confirmation, password_reset, …) sont toujours rendus dans la locale du destinataire (lue sur son setting locale), jamais celle de l’acteur qui déclenche l’envoi. Voir ConfirmationEmailSender et PasswordResetEmailSender.

Le setting locale est restreint aux locales effectivement supportées (= dossiers présents sous resources/lang/). Choisir fr-FR ou en-US actuellement ; toute autre valeur est rejetée avec setting.invalidLocale. Cette restriction est volontaire : accepter ja-JP produirait une UI en français (fallback) — autant le refuser à la source.


Liste les locales effectivement supportées par l’application (présence d’un catalogue sous resources/lang/), enrichies avec les libellés (anglais et natif) issus de la table SQL locale. Différent de la liste des 377 entrées BCP-47 que contient cette même table.

{
"jsonapi": { "version": "1.1" },
"data": [
{
"type": "locales",
"id": "en-US",
"attributes": {
"name": "English",
"nativeName": "English",
"isDefault": false
}
},
{
"type": "locales",
"id": "fr-FR",
"attributes": {
"name": "French",
"nativeName": "français",
"isDefault": true
}
}
],
"meta": { "count": 2, "default": "fr-FR" }
}
  • Notes :
    • Tri alphabétique par id.
    • isDefault flag la locale applicative par défaut (fr-FR).
    • Header de réponse Content-Language reflète la locale active de la requête courante.
    • Ajout d’une nouvelle locale = créer le dossier resources/lang/<tag>/ avec les 5 catalogues (auth.php, users.php, validation.php, errors.php, mails.php). Vérifier ensuite que la ligne locale.id = '<tag>' existe en base.