Allow pages to be activated per locale.

Fix bug 794059.
This commit is contained in:
Paul McLanahan 2012-11-12 16:21:06 -05:00
Родитель 3cfd1c3714
Коммит 35cefae690
9 изменённых файлов: 150 добавлений и 10 удалений

Просмотреть файл

@ -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
;Mozillas 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
;Mozillas 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 %}
Mozillas 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 %}
Mozillas 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/')