Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #10004 and #12320 -- Enabled the makemessages management comman…

…d to collect comments for translators that start with the "Translators" keyword. Thanks for the report and patches, martinb and Claude Paroz.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14595 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 17b329ae08f9e3886da2baafc9e53949000480f9 1 parent d7ad02f
@jezdez jezdez authored
View
9 django/core/management/commands/makemessages.py
@@ -196,7 +196,7 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
'xgettext -d %s -L Perl %s --keyword=gettext_noop '
'--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 '
'--keyword=pgettext:1c,2 --keyword=npgettext:1c,2,3 '
- '--from-code UTF-8 -o - "%s"' % (
+ '--from-code UTF-8 --add-comments=Translators -o - "%s"' % (
domain, wrap, os.path.join(dirpath, thefile)
)
)
@@ -240,8 +240,9 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
'--keyword=ugettext_noop --keyword=ugettext_lazy '
'--keyword=ungettext_lazy:1,2 --keyword=pgettext:1c,2 '
'--keyword=npgettext:1c,2,3 --keyword=pgettext_lazy:1c,2 '
- '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 -o - '
- '"%s"' % (domain, wrap, os.path.join(dirpath, thefile))
+ '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 '
+ '--add-comments=Translators -o - "%s"' % (
+ domain, wrap, os.path.join(dirpath, thefile))
)
msgs, errors = _popen(cmd)
if errors:
@@ -282,6 +283,8 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
raise CommandError("errors happened while running msgmerge\n%s" % errors)
elif not invoked_for_django:
msgs = copy_plural_forms(msgs, locale, domain, verbosity)
+ msgs = msgs.replace(
+ "#. #-#-#-#-# %s.pot (PACKAGE VERSION) #-#-#-#-#\n" % domain, "")
f = open(pofile, 'wb')
try:
f.write(msgs)
View
6 django/template/__init__.py
@@ -82,6 +82,7 @@
VARIABLE_TAG_END = '}}'
COMMENT_TAG_START = '{#'
COMMENT_TAG_END = '#}'
+TRANSLATOR_COMMENT_MARK = 'Translators'
SINGLE_BRACE_START = '{'
SINGLE_BRACE_END = '}'
@@ -237,7 +238,10 @@ def create_token(self, token_string, in_tag):
elif token_string.startswith(BLOCK_TAG_START):
token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip())
elif token_string.startswith(COMMENT_TAG_START):
- token = Token(TOKEN_COMMENT, '')
+ content = ''
+ if token_string.find(TRANSLATOR_COMMENT_MARK):
+ content = token_string[len(COMMENT_TAG_START):-len(COMMENT_TAG_END)].strip()
+ token = Token(TOKEN_COMMENT, content)
else:
token = Token(TOKEN_TEXT, token_string)
return token
View
17 django/utils/translation/trans_real.py
@@ -427,14 +427,23 @@ def templatize(src):
does so by translating the Django translation tags into standard gettext
function invocations.
"""
- from django.template import Lexer, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK
+ from django.template import Lexer, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK, TOKEN_COMMENT
out = StringIO()
intrans = False
inplural = False
singular = []
plural = []
+ incomment = False
+ comment = []
for t in Lexer(src, None).tokenize():
- if intrans:
+ if incomment:
+ if t.token_type == TOKEN_BLOCK and t.contents == 'endcomment':
+ out.write(' # %s' % ''.join(comment))
+ incomment = False
+ comment = []
+ else:
+ comment.append(t.contents)
+ elif intrans:
if t.token_type == TOKEN_BLOCK:
endbmatch = endblock_re.match(t.contents)
pluralmatch = plural_re.match(t.contents)
@@ -488,6 +497,8 @@ def templatize(src):
elif cmatches:
for cmatch in cmatches:
out.write(' _(%s) ' % cmatch)
+ elif t.contents == 'comment':
+ incomment = True
else:
out.write(blankout(t.contents, 'B'))
elif t.token_type == TOKEN_VAR:
@@ -500,6 +511,8 @@ def templatize(src):
out.write(' %s ' % p.split(':',1)[1])
else:
out.write(blankout(p, 'F'))
+ elif t.token_type == TOKEN_COMMENT:
+ out.write(' # %s' % t.contents)
else:
out.write(blankout(t.contents, 'X'))
return out.getvalue()
View
16 docs/releases/1.3-alpha-2.txt
@@ -39,6 +39,22 @@ See the :doc:`reference documentation of the app </ref/contrib/staticfiles>`
for more details or learn how to :doc:`manage static files
</howto/static-files>`.
+Translation comments
+~~~~~~~~~~~~~~~~~~~~
+
+If you would like to give translators hints about a translatable string, you
+can add a comment prefixed with the ``Translators`` keyword on the line
+preceding the string, e.g.::
+
+ def my_view(request):
+ # Translators: This message appears on the home page only
+ output = ugettext("Welcome to my site.")
+
+The comment will appear in the resulting .po file and should also be
+displayed by most translation tools.
+
+For more information, see :ref:`translator-comments`.
+
Backwards-incompatible changes in 1.3 alpha 2
=============================================
View
10 docs/releases/1.3.txt
@@ -121,13 +121,17 @@ value, protect, or do nothing.
For more information, see the :attr:`~django.db.models.ForeignKey.on_delete`
documentation.
-Contextual markers in translatable strings
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Contextual markers and comments for translatable strings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For translation strings with ambiguous meaning, you can now
use the ``pgettext`` function to specify the context of the string.
-For more information, see :ref:`contextual-markers`
+And if you just want to add some information for translators, you
+can also add special translator comments in the source.
+
+For more information, see :ref:`contextual-markers` and
+:ref:`translator-comments`.
Everything else
~~~~~~~~~~~~~~~
View
24 docs/topics/i18n/internationalization.txt
@@ -100,6 +100,30 @@ instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
have more than a single parameter. If you used positional interpolation,
translations wouldn't be able to reorder placeholder text.
+.. _translator-comments:
+
+Comments for translators
+------------------------
+
+.. versionadded:: 1.3
+
+If you would like to give translators hints about a translatable string, you
+can add a comment prefixed with the ``Translators`` keyword on the line
+preceding the string, e.g.::
+
+ def my_view(request):
+ # Translators: This message appears on the home page only
+ output = ugettext("Welcome to my site.")
+
+This also works in templates with the :ttag:`comment` tag:
+
+.. code-block:: django+html
+
+ {% comment %}Translators: This is a text of the base template {% endcomment %}
+
+The comment will then appear in the resulting .po file and should also be
+displayed by most translation tools.
+
Marking strings as no-op
------------------------
View
8 tests/regressiontests/i18n/commands/__init__.py
@@ -0,0 +1,8 @@
+from django.utils.translation import ugettext as _
+
+# Translators: This comment should be extracted
+dummy1 = _("This is a translatable string.")
+
+# This comment should not be extracted
+dummy2 = _("This is another translatable string.")
+
View
13 tests/regressiontests/i18n/commands/extraction.py
@@ -38,7 +38,18 @@ def assertNotMsgId(self, msgid, s, use_quotes=True):
return self.assert_(not re.search('^msgid %s' % msgid, s, re.MULTILINE))
-class TemplateExtractorTests(ExtractorTests):
+class BasicExtractorTests(ExtractorTests):
+
+ def test_comments_extractor(self):
+ os.chdir(self.test_dir)
+ management.call_command('makemessages', locale=LOCALE, verbosity=0)
+ self.assert_(os.path.exists(self.PO_FILE))
+ po_contents = open(self.PO_FILE, 'r').read()
+ self.assert_('#. Translators: This comment should be extracted' in po_contents)
+ self.assert_('This comment should not be extracted' not in po_contents)
+ # Comments in templates
+ self.assert_('#. Translators: Django template comment for translators' in po_contents)
+ self.assert_('#. Translators: Django comment block for translators' in po_contents)
def test_templatize(self):
os.chdir(self.test_dir)
View
7 tests/regressiontests/i18n/commands/templates/test.html
@@ -1,5 +1,8 @@
{% load i18n %}
+{% comment %}Translators: Django comment block for translators {% endcomment %}
{% trans "This literal should be included." %}
{% trans "This literal should also be included wrapped or not wrapped depending on the use of the --no-wrap option." %}
-{% blocktrans %}I think that 100% is more that 50% of anything.{% endblocktrans %}
-{% blocktrans with 'txt' as obj %}I think that 100% is more that 50% of {{ obj }}.{% endblocktrans %}
+{# Translators: Django template comment for translators #}
+<p>{% blocktrans %}I think that 100% is more that 50% of anything.{% endblocktrans %}</p>
+{% blocktrans with 'txt' as obj %}I think that 100% is more that 50% of {{ obj }}.{% endblocktrans %}
Please sign in to comment.
Something went wrong with that request. Please try again.