Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #535 from pmclanahan/bug-821330-contribute-form-no…

…t-translating

Bug 821330: Fix translations on contribute page.
  • Loading branch information...
commit b8435608209e4f23bc050b8e6e6ca11d29ae16d9 2 parents 92b1e85 + d1b9805
@pmclanahan pmclanahan authored
View
3  apps/mozorg/email_contribute.py
@@ -12,8 +12,9 @@
from l10n_utils.dotlang import _lazy as _
-fa = namedtuple('FunctionalArea', ['id', 'name', 'subject', 'contacts'])
+fa = namedtuple('FunctionalArea', ['id', 'name', 'subject', 'contacts'])
+LANG_FILES = 'mozorg/contribute'
FUNCTIONAL_AREAS = (
fa('support',
_('Helping Users'),
View
1  apps/mozorg/forms.py
@@ -23,6 +23,7 @@
LANGS = settings.NEWSLETTER_LANGUAGES
LANGS_TO_STRIP = ['en-US', 'es']
PARENTHETIC_RE = re.compile(r' \([^)]+\)$')
+LANG_FILES = 'mozorg/contribute'
def strip_parenthetical(lang_name):
View
62 lib/l10n_utils/dotlang.py
@@ -10,17 +10,18 @@
It caches them using the django caching library, but it could
potentially just use thread-local variables. Caching seems safer at
the expense of another caching layer."""
-
import codecs
import inspect
import os
import re
+from functools import partial
from django.conf import settings
from django.core.cache import cache
from django.utils import translation
from django.utils.functional import lazy
+from jinja2 import Markup
from tower.management.commands.extract import tweak_message
@@ -99,22 +100,12 @@ def translate(text, files):
message = '%s\n\n%s\n%s' % (explanation, text,
trans[tweaked_text])
mail_error(rel_path, message)
- return text
- return trans[tweaked_text]
- return text
+ return Markup(text)
+ return Markup(trans[tweaked_text])
+ return Markup(text)
-def _(text, *args):
- """
- Translate a piece of text from the global files. If `LANG_FILES` is defined
- in the module from which this function is called, those files (or file)
- will be searched first for the translation, followed by the default files.
-
- :param text: string to translate
- :param args: items for interpolation into `text`
- :return: translated string
- """
- lang_files = settings.DOTLANG_FILES
+def _get_extra_lang_files():
frame = inspect.currentframe()
if frame is None:
if settings.DEBUG:
@@ -124,14 +115,40 @@ def _(text, *args):
'source files will not work.', RuntimeWarning)
else:
try:
- # gets value of LANG_FILE constant in calling module if specified
- new_lang_files = frame.f_back.f_globals.get('LANG_FILES')
+ # gets value of LANG_FILE constant in calling module if specified.
+ # have to go back 2x to compensate for this function.
+ new_lang_files = frame.f_back.f_back.f_globals.get('LANG_FILES', [])
finally:
del frame
if new_lang_files:
if isinstance(new_lang_files, basestring):
new_lang_files = [new_lang_files]
- lang_files = new_lang_files + lang_files
+ return new_lang_files
+
+
+def _(text, *args, **kwargs):
+ """
+ Translate a piece of text from the global files. If `LANG_FILES` is defined
+ in the module from which this function is called, those files (or file)
+ will be searched first for the translation, followed by the default files.
+
+ :param text: string to translate
+ :param args: items for interpolation into `text`
+ :param lang_files: extra lang file names to search for a translation.
+ NOTE: DO NOT USE THIS for string extraction. It will NOT respect
+ the values in this kwarg when extracting strings. This is only useful
+ if you know the string is in a different file but you don't want to
+ add that file for the whole module via the `LANG_FILES` constant.
+ :return: translated string
+ """
+ lang_files = kwargs.pop('lang_files', [])
+ if isinstance(lang_files, list):
+ lang_files = lang_files[:]
+ else:
+ lang_files = [lang_files]
+ if not lang_files:
+ lang_files += _get_extra_lang_files()
+ lang_files += settings.DOTLANG_FILES
text = translate(text, lang_files)
if args:
@@ -139,7 +156,14 @@ def _(text, *args):
return text
-_lazy = lazy(_, unicode)
+_lazy_proxy = lazy(_, unicode)
+
+
+def _lazy(*args, **kwargs):
+ lang_files = _get_extra_lang_files()
+ if lang_files:
+ return partial(_lazy_proxy, lang_files=lang_files)(*args, **kwargs)
+ return _lazy_proxy(*args, **kwargs)
def get_lang_path(path):
View
4 lib/l10n_utils/helpers.py
@@ -36,9 +36,7 @@ def gettext(ctx, text):
"""Translate a string, loading the translations for the locale if
necessary."""
install_lang_files(ctx)
-
- trans = translate(text, ctx['request'].langfiles)
- return jinja2.Markup(trans)
+ return translate(text, ctx['request'].langfiles)
@jingo.register.function
View
62 lib/l10n_utils/tests/test_dotlang.py
@@ -20,7 +20,7 @@
from tower.management.commands.extract import extract_tower_python
from l10n_utils.dotlang import (_, FORMAT_IDENTIFIER_RE, lang_file_is_active,
- parse, translate)
+ parse, translate, _lazy)
from mozorg.tests import TestCase
@@ -201,6 +201,66 @@ def test_gettext_searches_specified_lang_files(self, trans_patch):
LANG_FILES = old_lang_files
@patch('l10n_utils.dotlang.translate')
+ def test_gettext_searches_kwarg_specified_lang_files(self, trans_patch):
+ """
+ The `l10n_utils.dotlang._` function should search .lang files
+ specified in the `lang_files` keyword arg, and not the ones from the
+ module.
+ """
+ # test the case when LANG_FILES is a string
+ trans_str = 'Translate me'
+ _(trans_str, lang_files='maude')
+ call_lang_files = ['maude'] + settings.DOTLANG_FILES
+ trans_patch.assert_called_with(trans_str, call_lang_files)
+
+ # test the case when LANG_FILES is a list
+ lang_files_list = ['maude', 'bunny', 'uli']
+ _(trans_str, lang_files=lang_files_list)
+ print lang_files_list
+ call_lang_files = lang_files_list + settings.DOTLANG_FILES
+ trans_patch.assert_called_with(trans_str, call_lang_files)
+
+ @patch('l10n_utils.dotlang.translate')
+ def test_gettext_lazy_searches_kwarg_specified_lang_files(self, trans_patch):
+ """
+ The `l10n_utils.dotlang._lazy` function should search .lang files
+ specified in the `lang_files` keyword arg, and not the ones from the
+ module.
+ """
+ # test the case when LANG_FILES is a string
+ trans_str = 'Translate me'
+ # have to call __unicode__ directly because the value is a Mock
+ # object, and the `unicode()` function throws an exception.
+ _lazy(trans_str, lang_files='maude').__unicode__()
+ call_lang_files = ['maude'] + settings.DOTLANG_FILES
+ trans_patch.assert_called_with(trans_str, call_lang_files)
+
+ # test the case when LANG_FILES is a list
+ lang_files_list = ['maude', 'bunny', 'uli']
+ _lazy(trans_str, lang_files=lang_files_list).__unicode__()
+ print lang_files_list
+ call_lang_files = lang_files_list + settings.DOTLANG_FILES
+ trans_patch.assert_called_with(trans_str, call_lang_files)
+
+ @patch('l10n_utils.dotlang.translate')
+ def test_lazy_gettext_searches_specified_lang_files(self, trans_patch):
+ """
+ The `l10n_utils.dotlang._lazy` function should search .lang files
+ specified in the module from which it's called before the
+ default files.
+ """
+ from l10n_utils.tests.test_files import extract_me_with_langfiles_lazy
+
+ dude_says = extract_me_with_langfiles_lazy.do_translate()
+ dirty_string = u"I'm The Dude, so that's what you call me, man."
+ self.assertFalse(trans_patch.called)
+ # have to call __unicode__ directly because the value is a Mock
+ # object, and the `unicode()` function throws an exception.
+ dude_says.__unicode__()
+ trans_patch.assert_called_with(dirty_string, ['donnie', 'walter'] +
+ settings.DOTLANG_FILES)
+
+ @patch('l10n_utils.dotlang.translate')
def test_gettext_works_without_extra_lang_files(self, trans_patch):
"""
The `l10n_utils.dotlang._` function should search the default .lang
View
16 lib/l10n_utils/tests/test_files/extract_me_with_langfiles_lazy.py
@@ -0,0 +1,16 @@
+# coding: utf-8
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from l10n_utils.dotlang import _lazy as _
+
+
+LANG_FILES = [
+ 'donnie',
+ 'walter',
+]
+
+def do_translate():
+ return _(u"I'm The Dude, so that's what you call me, man.")
Please sign in to comment.
Something went wrong with that request. Please try again.