diff --git a/docs/translating/translating.md b/docs/translating/translating.md index 3a9b023998..7c0c9388d7 100644 --- a/docs/translating/translating.md +++ b/docs/translating/translating.md @@ -100,11 +100,9 @@ There are a few ways to see your translations in the Zulip UI: prioritization (mostly copied from the Django docs): 1. It looks for the language code as a URL prefix (e.g. `/de/login/`). - 2. It looks for the `LANGUAGE_SESSION_KEY` key in the current user's - session (the Zulip language UI option ends up setting this). - 3. It looks for the cookie named 'django_language'. You can set a + 1. It looks for the cookie named 'django_language'. You can set a different name through the `LANGUAGE_COOKIE_NAME` setting. - 4. It looks for the `Accept-Language` HTTP header in the HTTP request + 1. It looks for the `Accept-Language` HTTP header in the HTTP request (this is how browsers tell Zulip about the OS/browser language). * Using an HTTP client library like `requests`, `cURL` or `urllib`, diff --git a/zerver/lib/i18n.py b/zerver/lib/i18n.py index b77d6e93cb..65dbf97d4e 100644 --- a/zerver/lib/i18n.py +++ b/zerver/lib/i18n.py @@ -95,8 +95,10 @@ def get_and_set_request_language( request_language = user_configured_language translation.activate(request_language) - # We also save the language to the user's session, so that + # We also want to save the language to the user's cookies, so that # something reasonable will happen in logged-in portico pages. - request.session[translation.LANGUAGE_SESSION_KEY] = translation.get_language() + # We accomplish that by setting a flag on the request which signals + # to LocaleMiddleware to set the cookie on the response. + request._set_language = translation.get_language() return request_language diff --git a/zerver/middleware.py b/zerver/middleware.py index 05c0b48f0d..11d65b7ffc 100644 --- a/zerver/middleware.py +++ b/zerver/middleware.py @@ -371,6 +371,7 @@ def csrf_failure(request: HttpRequest, reason: str="") -> HttpResponse: class LocaleMiddleware(DjangoLocaleMiddleware): def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse: + # This is the same as the default LocaleMiddleware, minus the # logic that redirects 404's that lack a prefixed language in # the path into having a language. See @@ -382,6 +383,13 @@ class LocaleMiddleware(DjangoLocaleMiddleware): if not (i18n_patterns_used and language_from_path): patch_vary_headers(response, ('Accept-Language',)) response.setdefault('Content-Language', language) + + # An additional responsibility of our override of this middleware is to save the user's language + # preference in a cookie. That determination is made by code handling the request + # and saved in the _set_language flag so that it can be used here. + if hasattr(request, '_set_language'): + response.set_cookie(settings.LANGUAGE_COOKIE_NAME, request._set_language) + return response class RateLimitMiddleware(MiddlewareMixin):