mirror of https://github.com/django/django.git
Fixed #25297 -- Allowed makemessages to work with {% trans %} tags that use template filters.
This commit is contained in:
parent
cc968b9c90
commit
e7b7f94678
|
@ -529,7 +529,14 @@ def blankout(src, char):
|
||||||
|
|
||||||
|
|
||||||
context_re = re.compile(r"""^\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?'))\s*""")
|
context_re = re.compile(r"""^\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?'))\s*""")
|
||||||
inline_re = re.compile(r"""^\s*trans\s+((?:"[^"]*?")|(?:'[^']*?'))(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?\s*""")
|
inline_re = re.compile(
|
||||||
|
# Match the trans 'some text' part
|
||||||
|
r"""^\s*trans\s+((?:"[^"]*?")|(?:'[^']*?'))"""
|
||||||
|
# Match and ignore optional filters
|
||||||
|
r"""(?:\s*\|\s*[^\s:]+(?::(?:[^\s'":]+|(?:"[^"]*?")|(?:'[^']*?')))?)*"""
|
||||||
|
# Match the optional context part
|
||||||
|
r"""(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?\s*"""
|
||||||
|
)
|
||||||
block_re = re.compile(r"""^\s*blocktrans(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?(?:\s+|$)""")
|
block_re = re.compile(r"""^\s*blocktrans(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?')))?(?:\s+|$)""")
|
||||||
endblock_re = re.compile(r"""^\s*endblocktrans$""")
|
endblock_re = re.compile(r"""^\s*endblocktrans$""")
|
||||||
plural_re = re.compile(r"""^\s*plural$""")
|
plural_re = re.compile(r"""^\s*plural$""")
|
||||||
|
|
|
@ -58,6 +58,18 @@ continued here.{% endcomment %}
|
||||||
{% trans "Translatable literal #7b" as var context "Special trans context #2" %}
|
{% trans "Translatable literal #7b" as var context "Special trans context #2" %}
|
||||||
{% trans "Translatable literal #7c" context "Special trans context #3" as var %}
|
{% trans "Translatable literal #7c" context "Special trans context #3" as var %}
|
||||||
|
|
||||||
|
{% trans "Translatable literal #7.1a" | upper context "context #7.1a" %}
|
||||||
|
{% trans "Translatable literal #7.1b" |upper as var context "context #7.1b" %}
|
||||||
|
{% trans "Translatable literal #7.1c"| upper context "context #7.1c" as var %}
|
||||||
|
|
||||||
|
{% trans "Translatable literal #7.1d"|add:" foo" context "context #7.1d" %}
|
||||||
|
{% trans "Translatable literal #7.1e"|add:' ûè本' as var context "context #7.1e" %}
|
||||||
|
{% with foo=" foo" %}
|
||||||
|
{% trans "Translatable literal #7.1f"|add:foo context "context #7.1f" as var %}
|
||||||
|
{% endwith %}
|
||||||
|
{% trans "Translatable literal #7.1g"|add:2 context "context #7.1g" as var %}
|
||||||
|
{% trans "Translatable literal #7.1h" | add:"foo" | add:2 context "context #7.1h" as var %}
|
||||||
|
|
||||||
{% blocktrans context "Special blocktrans context #1" %}Translatable literal #8a{% endblocktrans %}
|
{% blocktrans context "Special blocktrans context #1" %}Translatable literal #8a{% endblocktrans %}
|
||||||
{% blocktrans count 2 context "Special blocktrans context #2" %}Translatable literal #8b-singular{% plural %}Translatable literal #8b-plural{% endblocktrans %}
|
{% blocktrans count 2 context "Special blocktrans context #2" %}Translatable literal #8b-singular{% plural %}Translatable literal #8b-plural{% endblocktrans %}
|
||||||
{% blocktrans context "Special blocktrans context #3" count 2 %}Translatable literal #8c-singular{% plural %}Translatable literal #8c-plural{% endblocktrans %}
|
{% blocktrans context "Special blocktrans context #3" count 2 %}Translatable literal #8c-singular{% plural %}Translatable literal #8c-plural{% endblocktrans %}
|
||||||
|
@ -79,7 +91,7 @@ continued here.{% endcomment %}
|
||||||
line breaks, this time
|
line breaks, this time
|
||||||
should be trimmed.
|
should be trimmed.
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% trans "I'm on line 82" %}
|
{% trans "Get my line number" %}
|
||||||
|
|
||||||
{% blocktrans trimmed count counter=mylist|length %}
|
{% blocktrans trimmed count counter=mylist|length %}
|
||||||
First `trans`, then `blocktrans` with a plural
|
First `trans`, then `blocktrans` with a plural
|
||||||
|
|
|
@ -102,15 +102,28 @@ class ExtractorTests(SimpleTestCase):
|
||||||
# #: path/to/file.html:123
|
# #: path/to/file.html:123
|
||||||
cwd_prefix = ''
|
cwd_prefix = ''
|
||||||
parts = ['#: ']
|
parts = ['#: ']
|
||||||
parts.append(os.path.join(cwd_prefix, *comment_parts))
|
|
||||||
|
path = os.path.join(cwd_prefix, *comment_parts)
|
||||||
|
parts.append(path)
|
||||||
|
|
||||||
|
if isinstance(line_number, six.string_types):
|
||||||
|
line_number = self._get_token_line_number(path, line_number)
|
||||||
if line_number is not None:
|
if line_number is not None:
|
||||||
parts.append(':%d' % line_number)
|
parts.append(':%d' % line_number)
|
||||||
|
|
||||||
needle = ''.join(parts)
|
needle = ''.join(parts)
|
||||||
if assert_presence:
|
if assert_presence:
|
||||||
return self.assertIn(needle, po_contents, '"%s" not found in final .po file.' % needle)
|
return self.assertIn(needle, po_contents, '"%s" not found in final .po file.' % needle)
|
||||||
else:
|
else:
|
||||||
return self.assertNotIn(needle, po_contents, '"%s" shouldn\'t be in final .po file.' % needle)
|
return self.assertNotIn(needle, po_contents, '"%s" shouldn\'t be in final .po file.' % needle)
|
||||||
|
|
||||||
|
def _get_token_line_number(self, path, token):
|
||||||
|
with open(path) as f:
|
||||||
|
for line, content in enumerate(f, 1):
|
||||||
|
if token in force_text(content):
|
||||||
|
return line
|
||||||
|
self.fail("The token '%s' could not be found in %s, please check the test config" % (token, path))
|
||||||
|
|
||||||
def assertLocationCommentPresent(self, po_filename, line_number, *comment_parts):
|
def assertLocationCommentPresent(self, po_filename, line_number, *comment_parts):
|
||||||
"""
|
"""
|
||||||
self.assertLocationCommentPresent('django.po', 42, 'dirA', 'dirB', 'foo.py')
|
self.assertLocationCommentPresent('django.po', 42, 'dirA', 'dirB', 'foo.py')
|
||||||
|
@ -121,7 +134,11 @@ class ExtractorTests(SimpleTestCase):
|
||||||
|
|
||||||
(or `#: .\dirA\dirB\foo.py:42` on Windows)
|
(or `#: .\dirA\dirB\foo.py:42` on Windows)
|
||||||
|
|
||||||
None can be passed for the line_number argument to skip checking of the :42 suffix part.
|
None can be passed for the line_number argument to skip checking of
|
||||||
|
the :42 suffix part.
|
||||||
|
A string token can also be pased as line_number, in which case it
|
||||||
|
will be searched in the template, and its line number will be used.
|
||||||
|
A msgid is a suitable candidate.
|
||||||
"""
|
"""
|
||||||
return self._assertPoLocComment(True, po_filename, line_number, *comment_parts)
|
return self._assertPoLocComment(True, po_filename, line_number, *comment_parts)
|
||||||
|
|
||||||
|
@ -179,8 +196,8 @@ class BasicExtractorTests(ExtractorTests):
|
||||||
# should be trimmed
|
# should be trimmed
|
||||||
self.assertMsgId("Again some text with a few line breaks, this time should be trimmed.", po_contents)
|
self.assertMsgId("Again some text with a few line breaks, this time should be trimmed.", po_contents)
|
||||||
# #21406 -- Should adjust for eaten line numbers
|
# #21406 -- Should adjust for eaten line numbers
|
||||||
self.assertMsgId("I'm on line 82", po_contents)
|
self.assertMsgId("Get my line number", po_contents)
|
||||||
self.assertLocationCommentPresent(self.PO_FILE, 82, 'templates', 'test.html')
|
self.assertLocationCommentPresent(self.PO_FILE, 'Get my line number', 'templates', 'test.html')
|
||||||
|
|
||||||
def test_force_en_us_locale(self):
|
def test_force_en_us_locale(self):
|
||||||
"""Value of locale-munging option used by the command is the right one"""
|
"""Value of locale-munging option used by the command is the right one"""
|
||||||
|
@ -235,6 +252,11 @@ class BasicExtractorTests(ExtractorTests):
|
||||||
self.assertIn('msgctxt "Special trans context #3"', po_contents)
|
self.assertIn('msgctxt "Special trans context #3"', po_contents)
|
||||||
self.assertMsgId("Translatable literal #7c", po_contents)
|
self.assertMsgId("Translatable literal #7c", po_contents)
|
||||||
|
|
||||||
|
# {% trans %} with a filter
|
||||||
|
for minor_part in 'abcdefgh': # Iterate from #7.1a to #7.1h template markers
|
||||||
|
self.assertIn('msgctxt "context #7.1{}"'.format(minor_part), po_contents)
|
||||||
|
self.assertMsgId('Translatable literal #7.1{}'.format(minor_part), po_contents)
|
||||||
|
|
||||||
# {% blocktrans %}
|
# {% blocktrans %}
|
||||||
self.assertIn('msgctxt "Special blocktrans context #1"', po_contents)
|
self.assertIn('msgctxt "Special blocktrans context #1"', po_contents)
|
||||||
self.assertMsgId("Translatable literal #8a", po_contents)
|
self.assertMsgId("Translatable literal #8a", po_contents)
|
||||||
|
@ -578,7 +600,7 @@ class LocationCommentsTests(ExtractorTests):
|
||||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_location=False)
|
management.call_command('makemessages', locale=[LOCALE], verbosity=0, no_location=False)
|
||||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||||
# #16903 -- Standard comment with source file relative path should be present
|
# #16903 -- Standard comment with source file relative path should be present
|
||||||
self.assertLocationCommentPresent(self.PO_FILE, 55, 'templates', 'test.html')
|
self.assertLocationCommentPresent(self.PO_FILE, 'Translatable literal #6b', 'templates', 'test.html')
|
||||||
|
|
||||||
# #21208 -- Leaky paths in comments on Windows e.g. #: path\to\file.html.py:123
|
# #21208 -- Leaky paths in comments on Windows e.g. #: path\to\file.html.py:123
|
||||||
self.assertLocationCommentNotPresent(self.PO_FILE, None, 'templates', 'test.html.py')
|
self.assertLocationCommentNotPresent(self.PO_FILE, None, 'templates', 'test.html.py')
|
||||||
|
|
Loading…
Reference in New Issue