Fixed #15318 -- Added settings for language cookie max-age, path, domain
Introduced a number of settings to configure max-age, path, and domain for the language cookie: LANGUAGE_COOKIE_AGE, LANGUAGE_COOKIE_PATH and LANGUAGE_COOKIE_DOMAIN. Thanks sahid for the suggestion.
This commit is contained in:
parent
c679cb7f60
commit
8c98f39624
|
@ -140,7 +140,13 @@ LANGUAGES_BIDI = ("he", "ar", "fa", "ur")
|
|||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
LOCALE_PATHS = ()
|
||||
|
||||
# Settings for language cookie
|
||||
LANGUAGE_COOKIE_NAME = 'django_language'
|
||||
LANGUAGE_COOKIE_AGE = None
|
||||
LANGUAGE_COOKIE_DOMAIN = None
|
||||
LANGUAGE_COOKIE_PATH = '/'
|
||||
|
||||
|
||||
# If you set this to True, Django will format dates, numbers and calendars
|
||||
# according to user current locale.
|
||||
|
|
|
@ -38,7 +38,10 @@ def set_language(request):
|
|||
if hasattr(request, 'session'):
|
||||
request.session[LANGUAGE_SESSION_KEY] = lang_code
|
||||
else:
|
||||
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
|
||||
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
|
||||
max_age=settings.LANGUAGE_COOKIE_AGE,
|
||||
path=settings.LANGUAGE_COOKIE_PATH,
|
||||
domain=settings.LANGUAGE_COOKIE_DOMAIN)
|
||||
return response
|
||||
|
||||
|
||||
|
|
|
@ -1362,6 +1362,40 @@ See :ref:`how-django-discovers-language-preference` for more details.
|
|||
|
||||
.. _list of language identifiers: http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
|
||||
.. setting:: LANGUAGE_COOKIE_AGE
|
||||
|
||||
LANGUAGE_COOKIE_AGE
|
||||
-------------------
|
||||
|
||||
.. versionadded:: 1.7
|
||||
|
||||
Default: ``None`` (expires at browser close)
|
||||
|
||||
The age of the language cookie, in seconds.
|
||||
|
||||
.. setting:: LANGUAGE_COOKIE_DOMAIN
|
||||
|
||||
LANGUAGE_COOKIE_DOMAIN
|
||||
----------------------
|
||||
|
||||
.. versionadded:: 1.7
|
||||
|
||||
Default: ``None``
|
||||
|
||||
The domain to use for the language cookie. Set this to a string such as
|
||||
``".example.com"`` (note the leading dot!) for cross-domain cookies, or use
|
||||
``None`` for a standard domain cookie.
|
||||
|
||||
Be cautious when updating this setting on a production site. If you update
|
||||
this setting to enable cross-domain cookies on a site that previously used
|
||||
standard domain cookies, existing user cookies that have the old domain
|
||||
will not be updated. This will result in site users being unable to switch
|
||||
the language as long as these cookies persist. The only safe and reliable
|
||||
option to perform the switch is to change the language cookie name
|
||||
permanently (via the :setting:`SESSION_COOKIE_NAME` setting) and to add
|
||||
a middleware that copies the value from the old cookie to a new one and then
|
||||
deletes the old one.
|
||||
|
||||
.. setting:: LANGUAGE_COOKIE_NAME
|
||||
|
||||
LANGUAGE_COOKIE_NAME
|
||||
|
@ -1373,6 +1407,31 @@ The name of the cookie to use for the language cookie. This can be whatever
|
|||
you want (but should be different from :setting:`SESSION_COOKIE_NAME`). See
|
||||
:doc:`/topics/i18n/index`.
|
||||
|
||||
.. setting:: LANGUAGE_COOKIE_PATH
|
||||
|
||||
LANGUAGE_COOKIE_PATH
|
||||
--------------------
|
||||
|
||||
.. versionadded:: 1.7
|
||||
|
||||
Default: ``/``
|
||||
|
||||
The path set on the language cookie. This should either match the URL path of your
|
||||
Django installation or be a parent of that path.
|
||||
|
||||
This is useful if you have multiple Django instances running under the same
|
||||
hostname. They can use different cookie paths and each instance will only see
|
||||
its own language cookie.
|
||||
|
||||
Be cautious when updating this setting on a production site. If you update this
|
||||
setting to use a deeper path than it previously used, existing user cookies that
|
||||
have the old path will not be updated. This will result in site users being
|
||||
unable to switch the language as long as these cookies persist. The only safe
|
||||
and reliable option to perform the switch is to change the language cookie name
|
||||
permanently (via the :setting:`SESSION_COOKIE_NAME` setting), and to add
|
||||
a middleware that copies the value from the old cookie to a new one and then
|
||||
deletes the one.
|
||||
|
||||
.. setting:: LANGUAGES
|
||||
|
||||
LANGUAGES
|
||||
|
@ -2801,7 +2860,10 @@ Globalization (i18n/l10n)
|
|||
* :setting:`FIRST_DAY_OF_WEEK`
|
||||
* :setting:`FORMAT_MODULE_PATH`
|
||||
* :setting:`LANGUAGE_CODE`
|
||||
* :setting:`LANGUAGE_COOKIE_AGE`
|
||||
* :setting:`LANGUAGE_COOKIE_DOMAIN`
|
||||
* :setting:`LANGUAGE_COOKIE_NAME`
|
||||
* :setting:`LANGUAGE_COOKIE_PATH`
|
||||
* :setting:`LANGUAGES`
|
||||
* :setting:`LOCALE_PATHS`
|
||||
* :setting:`MONTH_DAY_FORMAT`
|
||||
|
|
|
@ -559,6 +559,10 @@ Internationalization
|
|||
app or project message file. See :ref:`how-to-create-language-files` for
|
||||
details.
|
||||
|
||||
* The following settings to adjust the language cookie options were introduced:
|
||||
:setting:`LANGUAGE_COOKIE_AGE`, :setting:`LANGUAGE_COOKIE_DOMAIN`
|
||||
and :setting:`LANGUAGE_COOKIE_PATH`.
|
||||
|
||||
* Added :ref:`format definitions <format-localization>` for Esperanto.
|
||||
|
||||
Management Commands
|
||||
|
|
|
@ -1575,6 +1575,20 @@ which returns the language used in the current thread,
|
|||
for the current thread, and ``django.utils.translation.check_for_language()``
|
||||
which checks if the given language is supported by Django.
|
||||
|
||||
Language cookie
|
||||
---------------
|
||||
|
||||
A number of settings can be used to adjust language cookie options:
|
||||
|
||||
* :setting:`LANGUAGE_COOKIE_NAME`
|
||||
|
||||
.. versionadded:: 1.7
|
||||
|
||||
* :setting:`LANGUAGE_COOKIE_AGE`
|
||||
* :setting:`LANGUAGE_COOKIE_DOMAIN`
|
||||
* :setting:`LANGUAGE_COOKIE_PATH`
|
||||
|
||||
|
||||
Implementation notes
|
||||
====================
|
||||
|
||||
|
|
|
@ -51,6 +51,25 @@ class I18NTests(TestCase):
|
|||
def test_setlang_reversal(self):
|
||||
self.assertEqual(reverse('set_language'), '/i18n/setlang/')
|
||||
|
||||
def test_setlang_cookie(self):
|
||||
# we force saving language to a cookie rather than a session
|
||||
# by excluding session middleware and those which do require it
|
||||
test_settings = dict(
|
||||
MIDDLEWARE_CLASSES=('django.middleware.common.CommonMiddleware',),
|
||||
LANGUAGE_COOKIE_NAME='mylanguage',
|
||||
LANGUAGE_COOKIE_AGE=3600 * 7 * 2,
|
||||
LANGUAGE_COOKIE_DOMAIN='.example.com',
|
||||
LANGUAGE_COOKIE_PATH='/test/',
|
||||
)
|
||||
with self.settings(**test_settings):
|
||||
post_data = dict(language='pl', next='/views/')
|
||||
response = self.client.post('/i18n/setlang/', data=post_data)
|
||||
language_cookie = response.cookies.get('mylanguage')
|
||||
self.assertEqual(language_cookie.value, 'pl')
|
||||
self.assertEqual(language_cookie['domain'], '.example.com')
|
||||
self.assertEqual(language_cookie['path'], '/test/')
|
||||
self.assertEqual(language_cookie['max-age'], 3600 * 7 * 2)
|
||||
|
||||
def test_jsi18n(self):
|
||||
"""The javascript_catalog can be deployed with language settings"""
|
||||
for lang_code in ['es', 'fr', 'ru']:
|
||||
|
|
Loading…
Reference in New Issue