Skip to content

Commit

Permalink
[Translator] Handle W3C locale format on document element
Browse files Browse the repository at this point in the history
According to W3C[1] (and RFC1766) the valid format for language codes is
"primary-code"-"subcode", but Symfony expects underscores as separator,
resulting in broken translations.

This changes language codes specified in the correct format for HTML to
the Symfony format when reading the "lang" attribute.

Fixes #2378

[1] https://www.w3.org/TR/html401/struct/dirlang.html#h-8.1.1
  • Loading branch information
aleho committed Nov 20, 2024
1 parent ed31702 commit 8eab198
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/Translator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 2.22.0

- Support both the Symfony format (`fr_FR`) and W3C specification (`fr-FR`) for locale subcodes.

## 2.20.0

- Add `throwWhenNotFound` function to configure the behavior when a translation is not found.
Expand Down
2 changes: 1 addition & 1 deletion src/Translator/assets/dist/translator_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ function setLocale(locale) {
function getLocale() {
return (_locale ||
document.documentElement.getAttribute('data-symfony-ux-translator-locale') ||
document.documentElement.lang ||
(document.documentElement.lang ? document.documentElement.lang.replace('-', '_') : null) ||
'en');
}
function throwWhenNotFound(enabled) {
Expand Down
4 changes: 2 additions & 2 deletions src/Translator/assets/src/translator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export function setLocale(locale: LocaleType | null) {
export function getLocale(): LocaleType {
return (
_locale ||
document.documentElement.getAttribute('data-symfony-ux-translator-locale') || // <html data-symfony-ux-translator-locale="en">
document.documentElement.lang || // <html lang="en">
document.documentElement.getAttribute('data-symfony-ux-translator-locale') || // <html data-symfony-ux-translator-locale="en_US">
(document.documentElement.lang ? document.documentElement.lang.replace('-', '_') : null) || // <html lang="en-US">
'en'
);
}
Expand Down
12 changes: 12 additions & 0 deletions src/Translator/assets/test/translator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ describe('Translator', () => {
});
});

describe('getLocale', () => {
test('with subcode', () => {
// allow format according to W3C
document.documentElement.lang = 'de-AT';
expect(getLocale()).toEqual('de_AT');

// or "incorrect" Symfony locale format
document.documentElement.lang = 'de_AT';
expect(getLocale()).toEqual('de_AT');
});
});

describe('setLocale', () => {
test('custom locale', () => {
setLocale('fr');
Expand Down
7 changes: 4 additions & 3 deletions src/Translator/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ Configuring the default locale

By default, the default locale is ``en`` (English) that you can configure through many ways (in order of priority):

#. With ``setLocale('your-locale')`` from ``@symfony/ux-translator`` package
#. Or with ``<html data-symfony-ux-translator-locale="your-locale">`` attribute
#. Or with ``<html lang="your-locale">`` attribute
#. With ``setLocale('de')`` or ``setLocale('de_AT')`` from ``@symfony/ux-translator`` package
#. Or with ``<html data-symfony-ux-translator-locale="{{ app.request.locale }}">`` attribute (e.g., ``de_AT`` or ``de`` using Symfony locale format)
#. Or with ``<html lang="{{ app.request.locale|replace({ '_': '-' }) }}">`` attribute (e.g., ``de-AT`` or ``de`` following the `W3C specification on language codes`_)

Detecting missing translations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -191,3 +191,4 @@ https://symfony.com/doc/current/contributing/code/bc.html
.. _`the Symfony UX initiative`: https://ux.symfony.com/
.. _StimulusBundle configured in your app: https://symfony.com/bundles/StimulusBundle/current/index.html
.. _`ICU Message Format`: https://symfony.com/doc/current/reference/formats/message_format.html
.. _`W3C specification on language codes`: https://www.w3.org/TR/html401/struct/dirlang.html#h-8.1.1

0 comments on commit 8eab198

Please sign in to comment.