зеркало из https://github.com/mozilla/bedrock.git
Allow pages to be activated per locale.
Fix bug 794059.
This commit is contained in:
Родитель
3cfd1c3714
Коммит
35cefae690
|
@ -1,9 +1,12 @@
|
|||
from django.conf import settings
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
from dotlang import get_lang_path
|
||||
import jingo
|
||||
from funfactory.urlresolvers import split_path
|
||||
from jinja2.exceptions import TemplateNotFound
|
||||
|
||||
from dotlang import get_lang_path, lang_file_is_active
|
||||
|
||||
|
||||
def render(request, template, context={}, **kwargs):
|
||||
"""
|
||||
|
@ -18,8 +21,21 @@ def render(request, template, context={}, **kwargs):
|
|||
|
||||
if present, otherwise, it'll render the specified (en-US) template.
|
||||
"""
|
||||
# Every template gets its own .lang file, so figure out what it is
|
||||
# and pass it in the context
|
||||
context['langfile'] = get_lang_path(template)
|
||||
|
||||
# Look for localized template if not default lang.
|
||||
if request.locale != settings.LANGUAGE_CODE:
|
||||
|
||||
# redirect to default lang if locale not active
|
||||
if not (settings.DEV or
|
||||
lang_file_is_active(context['langfile'], request.locale)):
|
||||
return HttpResponseRedirect('/' + '/'.join([
|
||||
settings.LANGUAGE_CODE,
|
||||
split_path(request.get_full_path())[1]
|
||||
]))
|
||||
|
||||
localized_tmpl = '%s/templates/%s' % (request.locale, template)
|
||||
try:
|
||||
return jingo.render(request, localized_tmpl, context, **kwargs)
|
||||
|
@ -27,8 +43,4 @@ def render(request, template, context={}, **kwargs):
|
|||
# If not found, just go on and try rendering the parent template.
|
||||
pass
|
||||
|
||||
# Every template gets its own .lang file, so figure out what it is
|
||||
# and pass it in the context
|
||||
context['langfile'] = get_lang_path(template)
|
||||
|
||||
return jingo.render(request, template, context, **kwargs)
|
||||
|
|
|
@ -155,3 +155,30 @@ def get_lang_path(path):
|
|||
path = '/'.join(p)
|
||||
base, ext = os.path.splitext(path)
|
||||
return base
|
||||
|
||||
|
||||
def lang_file_is_active(path, lang):
|
||||
"""
|
||||
If the lang file for a locale exists and has the correct comment returns
|
||||
True, and False otherwise.
|
||||
:param path: the relative lang file name
|
||||
:param lang: the language code
|
||||
:return: bool
|
||||
"""
|
||||
rel_path = os.path.join('locale', lang, '%s.lang' % path)
|
||||
cache_key = 'active:%s' % rel_path
|
||||
is_active = cache.get(cache_key)
|
||||
if is_active is None:
|
||||
is_active = False
|
||||
fpath = os.path.join(settings.ROOT, rel_path)
|
||||
try:
|
||||
with codecs.open(fpath, 'r', 'utf-8', errors='replace') as lines:
|
||||
firstline = lines.readline()
|
||||
if firstline.startswith('## active ##'):
|
||||
is_active = True
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
cache.set(cache_key, is_active, settings.DOTLANG_CACHE)
|
||||
|
||||
return is_active
|
||||
|
|
|
@ -4,17 +4,74 @@ import os
|
|||
|
||||
from django.conf import settings
|
||||
from django.core import mail
|
||||
from django.core.urlresolvers import clear_url_caches
|
||||
from django.test.client import Client
|
||||
|
||||
from jingo import env
|
||||
from jinja2 import FileSystemLoader
|
||||
from mock import patch
|
||||
from nose.tools import assert_not_equal, eq_
|
||||
from nose.tools import assert_not_equal, eq_, ok_
|
||||
from pyquery import PyQuery as pq
|
||||
from tower.management.commands.extract import extract_tower_python
|
||||
|
||||
from l10n_utils.dotlang import _, FORMAT_IDENTIFIER_RE, parse, translate
|
||||
from l10n_utils.dotlang import (_, FORMAT_IDENTIFIER_RE, lang_file_is_active,
|
||||
parse, translate)
|
||||
from mozorg.tests import TestCase
|
||||
|
||||
|
||||
ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_files')
|
||||
LANG_FILES = 'test_file'
|
||||
TEMPLATE_DIRS = (os.path.join(ROOT, 'templates'),)
|
||||
|
||||
|
||||
@patch.object(env, 'loader', FileSystemLoader(TEMPLATE_DIRS))
|
||||
@patch.object(settings, 'ROOT_URLCONF', 'l10n_utils.tests.test_files.urls')
|
||||
@patch.object(settings, 'ROOT', ROOT)
|
||||
class TestLangFilesActivation(TestCase):
|
||||
def setUp(self):
|
||||
clear_url_caches()
|
||||
self.client = Client()
|
||||
|
||||
@patch.object(settings, 'DEV', False)
|
||||
def test_lang_file_is_active(self):
|
||||
"""
|
||||
`lang_file_is_active` should return true if lang file has the
|
||||
comment, and false otherwise.
|
||||
"""
|
||||
ok_(lang_file_is_active('active_de_lang_file', 'de'))
|
||||
ok_(not lang_file_is_active('active_de_lang_file', 'es'))
|
||||
ok_(not lang_file_is_active('inactive_de_lang_file', 'de'))
|
||||
ok_(not lang_file_is_active('does_not_exist', 'de'))
|
||||
|
||||
@patch.object(settings, 'DEV', False)
|
||||
def test_active_locale_not_redirected(self):
|
||||
""" Active lang file should render correctly. """
|
||||
response = self.client.get('/de/active-de-lang-file/')
|
||||
eq_(response.status_code, 200)
|
||||
doc = pq(response.content)
|
||||
eq_(doc('h1').text(), 'Die Lage von Mozilla')
|
||||
|
||||
@patch.object(settings, 'DEV', False)
|
||||
@patch.object(settings, 'LANGUAGE_CODE', 'en-US')
|
||||
def test_inactive_locale_redirected(self):
|
||||
""" Inactive locale should redirect to en-US. """
|
||||
response = self.client.get('/de/inactive-de-lang-file/')
|
||||
eq_(response.status_code, 302)
|
||||
eq_(response['location'],
|
||||
'http://testserver/en-US/inactive-de-lang-file/')
|
||||
response = self.client.get('/de/inactive-de-lang-file/', follow=True)
|
||||
doc = pq(response.content)
|
||||
eq_(doc('h1').text(), 'The State of Mozilla')
|
||||
|
||||
@patch.object(settings, 'DEV', True)
|
||||
def test_inactive_locale_not_redirected_dev_true(self):
|
||||
"""
|
||||
Inactive lang file should not redirect in DEV mode.
|
||||
"""
|
||||
response = self.client.get('/de/inactive-de-lang-file/')
|
||||
eq_(response.status_code, 200)
|
||||
doc = pq(response.content)
|
||||
eq_(doc('h1').text(), 'Die Lage von Mozilla')
|
||||
|
||||
|
||||
class TestDotlang(TestCase):
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
## active ##
|
||||
|
||||
;The State of Mozilla
|
||||
Die Lage von Mozilla
|
||||
|
||||
|
||||
;Mozilla‘s vision of the Internet is a place where anyone can access information, a place where everyone can hack and tinker; one that has openness, freedom and transparency; where users have control over their personal data and where all minds have the freedom to create and to consume without walls or tight restrictions.
|
||||
Mozillas Vision des Internets ist ein Ort, wo jeder auf Informationen zugreifen kann, ein Ort, wo jeder programmieren und herumspielen kann; einer, der offen, frei und transparent ist; wo Benutzer die Kontrolle über ihre persönlichen Daten haben und wo jeder Geist die Freiheit hat, zu schaffen und zu konsumieren, ohne Mauern oder enge Einschränkungen.
|
|
@ -0,0 +1,6 @@
|
|||
;The State of Mozilla
|
||||
Die Lage von Mozilla
|
||||
|
||||
|
||||
;Mozilla‘s vision of the Internet is a place where anyone can access information, a place where everyone can hack and tinker; one that has openness, freedom and transparency; where users have control over their personal data and where all minds have the freedom to create and to consume without walls or tight restrictions.
|
||||
Mozillas Vision des Internets ist ein Ort, wo jeder auf Informationen zugreifen kann, ein Ort, wo jeder programmieren und herumspielen kann; einer, der offen, frei und transparent ist; wo Benutzer die Kontrolle über ihre persönlichen Daten haben und wo jeder Geist die Freiheit hat, zu schaffen und zu konsumieren, ohne Mauern oder enge Einschränkungen.
|
|
@ -0,0 +1,14 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>{{ _('The State of Mozilla') }}</h1>
|
||||
<p>
|
||||
{% trans %}
|
||||
Mozilla‘s vision of the Internet is a place where anyone can
|
||||
access information, a place where everyone can hack and tinker;
|
||||
one that has openness, freedom and transparency; where users have
|
||||
control over their personal data and where all minds have the
|
||||
freedom to create and to consume without walls or tight restrictions.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>{{ _('The State of Mozilla') }}</h1>
|
||||
<p>
|
||||
{% trans %}
|
||||
Mozilla‘s vision of the Internet is a place where anyone can
|
||||
access information, a place where everyone can hack and tinker;
|
||||
one that has openness, freedom and transparency; where users have
|
||||
control over their personal data and where all minds have the
|
||||
freedom to create and to consume without walls or tight restrictions.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -4,4 +4,6 @@ from mozorg.util import page
|
|||
|
||||
urlpatterns = patterns('',
|
||||
page('trans-block-reload-test', 'trans_block_reload_test.html'),
|
||||
page('active-de-lang-file', 'active_de_lang_file.html'),
|
||||
page('inactive-de-lang-file', 'inactive_de_lang_file.html'),
|
||||
)
|
||||
|
|
|
@ -18,14 +18,14 @@ ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_files')
|
|||
TEMPLATE_DIRS = (os.path.join(ROOT, 'templates'),)
|
||||
|
||||
|
||||
@patch.object(env, 'loader', FileSystemLoader(TEMPLATE_DIRS))
|
||||
@patch.object(settings, 'ROOT_URLCONF', 'l10n_utils.tests.test_files.urls')
|
||||
@patch.object(settings, 'ROOT', ROOT)
|
||||
class TestTransBlocks(TestCase):
|
||||
def setUp(self):
|
||||
clear_url_caches()
|
||||
self.client = Client()
|
||||
|
||||
@patch.object(env, 'loader', FileSystemLoader(TEMPLATE_DIRS))
|
||||
@patch.object(settings, 'ROOT_URLCONF', 'l10n_utils.tests.test_files.urls')
|
||||
@patch.object(settings, 'ROOT', ROOT)
|
||||
def test_trans_block_works(self):
|
||||
""" Sanity check to make sure translations work at all. """
|
||||
response = self.client.get('/de/trans-block-reload-test/')
|
||||
|
|
Загрузка…
Ссылка в новой задаче