Skip to content

French interface translation - #110

Merged
karatektus merged 2 commits into
karatektus:mainfrom
jo2904:feat/french-locale
Oct 14, 2026
Merged

karatektus merged 2 commits into
karatektus:mainfrom
jo2904:feat/french-locale

Conversation

@jo2904

@jo2904 jo2904 commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Adds French as an interface language.

What changes

  • Catalogues: translations/messages.fr.yaml covers all 3,118 keys of the English catalogue, plus validators.fr.yaml and security.fr.yaml. CatalogueParityTest now checks French alongside German and pirate English.
  • Registration:
    • AppLocale::French (fr, « Français », 🇫🇷) is added, and fr joins framework.enabled_locales.
    • Both language pickers (Settings → General and the first-run install) read AppLocale::cases(), so French shows up there without further changes.
  • Clock: French defaults to the 24-hour clock, as German does (ClockFormat::forLocale()); a test is added.
  • Emoji picker: assets/emoji/fr/data.json, so emoji search works with French names.
    • It comes from the same emoji-picker-element-data release as en/ and de/; I checked that those two are byte-identical to the published ones.
    • The template now picks de, fr or en instead of testing only for de.
  • Docs: the README and features/appearance.md now list the language (German translation and its hash updated), and the CHANGELOG has an entry under a new Unreleased section.

Translation choices

  • Formal register. It uses « vous », the usual register for French software; the German catalogue uses « du », and no test enforces either for French.

  • Terminology:

    English French
    calendar agenda
    label libellé
    star suivi (as in Gmail's French UI)
    snooze mettre en attente

    Google and Microsoft console labels are written as their French UIs show them.

  • Typography:

    • The typographic apostrophe (’) is used throughout, so single-quoted YAML never needs '' escaping.
    • Values containing the French spaced colon (« : ») are quoted, because YAML rejects them unquoted.
  • Checks: every key's placeholders (%x%, {x}, {{ x }}) and plural forms match the English. All three files load through Symfony's YAML loader, and debug:translation fr --only-missing reports nothing.

Not in this PR

Testing

Run here without Postgres:

  • translation parity and catalogue parsing;
  • documentation tests;
  • ClockFormatResolverTest;
  • PHPStan on the changed PHP;
  • lint:twig.

EmbeddingPresetTest, which boots the translator for every locale including fr, and the clock rendering tests need the database stack.

🤖 Generated with Claude Code

https://claude.ai/code/session_018nYWPc4bWacb79hm4ytfni

jo2904 and others added 2 commits October 13, 2026 23:33
Les 3 118 clés de messages.en.yaml, plus les domaines validators et
security, traduits en français. Le catalogue seul ne change rien à
l'écran : la locale est déclarée au commit suivant. CatalogueParityTest
vérifie désormais le français comme l'allemand et le pirate. C'est le
seul garde-fou, car Symfony retombe sans bruit sur l'anglais quand une
clé manque.

Choix de traduction, pour qui reprendra ces fichiers :
- Vouvoiement, l'usage des logiciels en français, alors que
  l'allemand tutoie. Aucun test ne l'impose, contrairement à
  GermanIsInformalTest.
- « Agenda » pour calendar, « libellé » pour label, « suivi » pour
  star (comme Gmail en français), « mettre en attente » pour snooze,
  « courrier » pour mail quand c'est le contenu et « mail » pour un
  message. Les termes des consoles Google et Microsoft sont repris tels
  que leurs interfaces françaises les affichent.
- Apostrophe typographique (’) partout dans le texte. Avec une
  apostrophe droite, chaque chaîne entre guillemets simples devrait la
  doubler, et un oubli casse le fichier entier. L'espace avant « : » à
  la française oblige aussi à mettre la valeur entre guillemets :
  security.fr.yaml ne se chargeait plus à cause de ça (« A colon cannot
  be used in an unquoted mapping value »). C'est corrigé et vérifié en
  chargeant les trois fichiers.
- Placeholders (%count%, {skinTone}, {{ limit }}) et formes plurielles
  ({0}…|{1}…|]1,Inf[…) contrôlés clé par clé contre l'anglais : aucun
  écart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018nYWPc4bWacb79hm4ytfni
Ajoute 'fr' à AppLocale et à framework.enabled_locales, qui doivent
rester synchronisés (le commentaire de translation.yaml le dit). Le
sélecteur de langue des réglages et celui de l'installation lisent
AppLocale::cases() : « 🇫🇷 Français » y apparaît sans autre
modification.

Deux réglages suivent la langue et devaient connaître le français :
- ClockFormat::forLocale() : le français écrit 14 h 00, donc 24 heures
  par défaut comme l'allemand. Sans ça, un utilisateur francophone qui
  n'a rien choisi verrait « 2 PM ». Testé dans ClockFormatResolverTest.
- Le sélecteur d'emoji charge ses noms et mots-clés par langue (la
  recherche « cœur » ne trouve rien dans les données anglaises).
  assets/emoji/fr/data.json vient de emoji-picker-element-data, comme
  en/ et de/. J'ai vérifié que ces deux fichiers sont identiques octet
  pour octet à ceux publiés par le paquet, donc fr/ vient bien de la
  même source. Le gabarit choisit maintenant de, fr ou en d'après la
  langue au lieu du seul test « starts with 'de' ».

Laissé tel quel : DeterministicDateDetector, qui lit les dates dans le
contenu des mails selon leur langue, et non la langue de l'interface.
Apprendre les dates françaises (« le 4 août ») est un autre chantier.

Docs : README, features/appearance.md (et sa traduction allemande, avec
le hash mis à jour), et une entrée de CHANGELOG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018nYWPc4bWacb79hm4ytfni
@karatektus
karatektus merged commit 245a84f into karatektus:main Oct 14, 2026
8 checks passed
@karatektus

Copy link
Copy Markdown
Owner

Merged, thank you — the catalogues are excellent. On top of it I added French to the content readers rather than leaving it for later: the calendar date detector (months, weekdays, 1er, 14h30, demain/après-demain, mardi prochain, French quote attributions), day-first slashed dates for French readers, and French vocabulary in the invoice and login-code extractors (b4b4eb1).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants