Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Switch Bedrock to using Django's own i18n mechanism (#14327)
* [Breaking] Drop our custom locale middleware and switch to Django's * [Breaking] Allow mixed-case lang codes as settings.LANGUAGES and related lang-code lookups * [Breaking] Use i18n_patterns to lang-code prefix relevant paths in mozorg.urls This includes splitting mozorg.urls into two groups so we only use i18n_patterns with paths that need it. We've kept the main, localed, group's name to be urls.py to reduce the chance of merge conflicts, as this piece of work is likely to need rebasing against main quite a lot until it's ready. The decision about which get prefixed and which do not is based on the settings SUPPORTED_NONLOCALES and SUPPORTED_LOCALE_IGNORE that were used in our former i18n machinery. At the time of committing, they still exist, but both of should be able to be removed once this work is done (or at least moved to power some tests) * [Breaking] We now have /en-US/ resolving/rendering for the homepage, but not yet /fr/ We use a prefixer for our i18n_urlpatterns so that when we reverse() and resolve() we allow for a custom prefix that is normalized to our mixed-case lang codes. Tests are needed. * Add middleware to fix up the lang code in the path This essentially replaces urlresolves.Prefixer.fix() Tests are needed. * Lay in custom middleware that lightly wraps LocaleMiddleware to normalize lang codes * Switch to using django.utils.translation to track the active locale * Ensure the request is annotated with the relevant lang_code, so that it's available in templates * Refactor base test class with simpler locale-activation logic using django core i18n * Minor fix to modern way to call pytest * Fix serving of sitemap_none.xml to be without locale * Small-as-possible changes to get test suite running/not erroring * Fixup VPN Resource Centre tests - enabling a non-real locale was trickiest part * Update tests for accepted locales Note that we no longer have a lowercase-to-mixed-case lang lookup, so this test changes but might become redundant later in the refactor * Improve naming in helper * [Breaking] Add placeholder failing tests * Extend Django's support for get_language_info to include our three-character lang names, which it doesn't have by default This is a part of ensuring three-letter country codes still work, but it might be redundant - TBC * Use Django's bidi-lang-checker, not ours * Drop unnecessary work in custom locale middleware This was useful before we started using i18n_patterns, but now not all of it is needed. Some still is, though * Fixup redirects behaviour (using /webvision/ as an example case) * Redirects don't need url prefixing via i18n_patterns, so we're moving them to nonlocale_urls instead. * When detecting a language, en-CA was being picked over en-US, which is avoided by ensuring en-US is at the start of the languages list * Note that for the webvision redirect we needed to add: * locale_prefix=True * prepend_locale=False * Amend VPNRC tests - tweaking where appropriate; also dropped a fiddly and unrealistic test * Expand test coverage of redirects in bedrock.mozorg * Fix need for fallback to settings.LANGUAGE_CODE if no language can be detected/retrieved * Reinstate logic to handle fallback to appropriate locale based on Accept-Language header * Move mozorg redirect() calls to redirects.py to avoid the routes having lang codes prefixed to them * Fixup l10n_utils.render behaviour via minimal tweaks to tests * Add regression-check tests for utility views * Improve normalize_locale via tests, including tests for Pocket Mode * Add tests for i18n helpers * Improve language normalization + tests * Move careers redirects to own file, so that they remain lang-code agnostic * Move foundation redirect out of urls.py so that it remains language agnostic * Move redirects out of urls.py so that they remain language agnostic - tweak _one_ test related to this * Avoid unnecessarily adding lang code to a reversed() url in our redirector - we don't need it unless we explicitly ask for it * Fix lang codes for CANONICAL_LANGS for mozorg mode * Tidy up tests * Fixing tests with settings=DEV * Contentful-related tests needed the dev-urls config wrapping in URLpatterns to make it work as per the real site; if we just specced dev_urls they did not work because they were not i18n-patterned * Default a locale to '' not None - the latter causes Locale page to blow up and the former matches original behaviour better * Ensure no-JS language changing works Fixes #5931 See #5931 for context * Formatting fix after rebasing on main * Rename our get_language helper to make it clearer what it does * Monkeypatch Django's check_for_language() because it looks in the wrong place for us By default check_for_language() seeks gettext-compatible files in locale/ directories in the project, but we don't have those because our l10n is handled using Fluent strings in the www-l10n-team directory, cloned from their git repo. So, instead, we just perform a light check to see whether a given lang is among the langs that shold be available. The actual decision about whether we have have (enough) Fluent strings available for that locale happens in lib.l10n_utils.render() * Expand test coverage of our custom prefixer * Bring bedrock.base.i18n up to 100% coverage * Add tests for language-code fixup + slight refactor to ensure it doesn't to _too_ much * Fix failing startup check for Pocket mode that blocked everything running * Drop unnecessary-after-all patching of LANG_INFO - we found a different route to making check_for_language work; this was the wrong direction * Add a little extra logging to the language-fixup redirects we're doing * Minor test polishing * Support special-case showing of a locale list at / if no accept-lang header is present This changeset ensures we retain the existing behaviour where a robot/spider going to / with no accept-language header gets a 200 OK response but with a locale-picker page, NOT the homepage. The fix here was to avoid running Django's LocaleMiddleware when (and only when) we detect the special case of a request for the root path and no Accept-Language header - which is basically a call for the root page with no way to determine the client's locale. (We don't use sessions in Bedrock so Django will never find a language code in a session anyway) * Improve naming to avoid confusion between polish (verb) and Polish in split_path_and_polish_lang * Improve in-code docs for BedrockLangCodeFixupMiddleware * Test tweak after rebasing on main (which now has Django 4.2)
- Loading branch information