diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
index 8c73d76..f02a3c8 100644
a
|
b
|
def make_messages(locale=None, domain='django', verbosity='1', all=False,
|
220 | 220 | os.unlink(os.path.join(dirpath, thefile)) |
221 | 221 | elif domain == 'django' and (file_ext == '.py' or file_ext in extensions): |
222 | 222 | thefile = file |
| 223 | orig_file = os.path.join(dirpath, file) |
223 | 224 | if file_ext in extensions: |
224 | | src = open(os.path.join(dirpath, file), "rU").read() |
| 225 | src = open(orig_file, "rU").read() |
225 | 226 | thefile = '%s.py' % file |
| 227 | f = open(os.path.join(dirpath, thefile), "w") |
226 | 228 | try: |
227 | | f = open(os.path.join(dirpath, thefile), "w") |
228 | | try: |
229 | | f.write(templatize(src)) |
230 | | finally: |
231 | | f.close() |
232 | | except SyntaxError, msg: |
233 | | msg = "%s (file: %s)" % (msg, os.path.join(dirpath, file)) |
234 | | raise SyntaxError(msg) |
| 229 | f.write(templatize(src, orig_file[2:])) |
| 230 | finally: |
| 231 | f.close() |
235 | 232 | if verbosity > 1: |
236 | 233 | sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) |
237 | 234 | cmd = ( |
… |
… |
def make_messages(locale=None, domain='django', verbosity='1', all=False,
|
250 | 247 | |
251 | 248 | if thefile != file: |
252 | 249 | old = '#: '+os.path.join(dirpath, thefile)[2:] |
253 | | new = '#: '+os.path.join(dirpath, file)[2:] |
| 250 | new = '#: '+orig_file[2:] |
254 | 251 | msgs = msgs.replace(old, new) |
255 | 252 | if os.path.exists(potfile): |
256 | 253 | # Strip the header |
diff --git a/django/template/base.py b/django/template/base.py
index c6d646e..e9b69ec 100644
a
|
b
|
class Token(object):
|
139 | 139 | def __init__(self, token_type, contents): |
140 | 140 | # token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT. |
141 | 141 | self.token_type, self.contents = token_type, contents |
| 142 | self.line_no = None |
142 | 143 | |
143 | 144 | def __str__(self): |
144 | 145 | return '<%s token: "%s...">' % \ |
… |
… |
class Lexer(object):
|
164 | 165 | def __init__(self, template_string, origin): |
165 | 166 | self.template_string = template_string |
166 | 167 | self.origin = origin |
| 168 | self.lineno = 1 |
167 | 169 | |
168 | 170 | def tokenize(self): |
169 | 171 | "Return a list of tokens from a given template_string." |
… |
… |
class Lexer(object):
|
193 | 195 | token = Token(TOKEN_COMMENT, content) |
194 | 196 | else: |
195 | 197 | token = Token(TOKEN_TEXT, token_string) |
| 198 | token.lineno = self.lineno |
| 199 | self.lineno += token_string.count('\n') |
196 | 200 | return token |
197 | 201 | |
198 | 202 | class Parser(object): |
diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
index 0e1b4f8..e3edb65 100644
a
|
b
|
def to_locale(language):
|
104 | 104 | def get_language_from_request(request): |
105 | 105 | return _trans.get_language_from_request(request) |
106 | 106 | |
107 | | def templatize(src): |
108 | | return _trans.templatize(src) |
| 107 | def templatize(src, origin=None): |
| 108 | return _trans.templatize(src, origin) |
109 | 109 | |
110 | 110 | def deactivate_all(): |
111 | 111 | return _trans.deactivate_all() |
diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index 832acc7..a5c612b 100644
a
|
b
|
endblock_re = re.compile(r"""^\s*endblocktrans$""")
|
421 | 421 | plural_re = re.compile(r"""^\s*plural$""") |
422 | 422 | constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""") |
423 | 423 | |
424 | | def templatize(src): |
| 424 | def templatize(src, origin=None): |
425 | 425 | """ |
426 | 426 | Turns a Django template into something that is understood by xgettext. It |
427 | 427 | does so by translating the Django translation tags into standard gettext |
… |
… |
def templatize(src):
|
435 | 435 | plural = [] |
436 | 436 | incomment = False |
437 | 437 | comment = [] |
438 | | for t in Lexer(src, None).tokenize(): |
| 438 | for t in Lexer(src, origin).tokenize(): |
439 | 439 | if incomment: |
440 | 440 | if t.token_type == TOKEN_BLOCK and t.contents == 'endcomment': |
441 | 441 | out.write(' # %s' % ''.join(comment)) |
… |
… |
def templatize(src):
|
465 | 465 | elif pluralmatch: |
466 | 466 | inplural = True |
467 | 467 | else: |
468 | | raise SyntaxError("Translation blocks must not include other block tags: %s" % t.contents) |
| 468 | filemsg = '' |
| 469 | if origin: |
| 470 | filemsg = 'file %s, ' % origin |
| 471 | raise SyntaxError("Translation blocks must not include other block tags: %s (%sline %d)" % (t.contents, filemsg, t.lineno)) |
469 | 472 | elif t.token_type == TOKEN_VAR: |
470 | 473 | if inplural: |
471 | 474 | plural.append('%%(%s)s' % t.contents) |
diff --git a/tests/regressiontests/i18n/commands/extraction.py b/tests/regressiontests/i18n/commands/extraction.py
index 3e8d2d6..9061863 100644
a
|
b
|
class BasicExtractorTests(ExtractorTests):
|
59 | 59 | self.assertMsgId('I think that 100%% is more that 50%% of anything.', po_contents) |
60 | 60 | self.assertMsgId('I think that 100%% is more that 50%% of %\(obj\)s.', po_contents) |
61 | 61 | |
| 62 | def test_extraction_error(self): |
| 63 | os.chdir(self.test_dir) |
| 64 | shutil.copyfile('./templates/template_with_error.txt', './templates/template_with_error.html') |
| 65 | self.assertRaises(SyntaxError, management.call_command, 'makemessages', locale=LOCALE, verbosity=0) |
| 66 | try: |
| 67 | management.call_command('makemessages', locale=LOCALE, verbosity=0) |
| 68 | except SyntaxError, e: |
| 69 | self.assertEqual(str(e), 'Translation blocks must not include other block tags: blocktrans (file templates/template_with_error.html, line 3)') |
| 70 | finally: |
| 71 | os.remove('./templates/template_with_error.html') |
| 72 | os.remove('./templates/template_with_error.html.py') # Waiting for #8536 to be fixed |
| 73 | |
62 | 74 | |
63 | 75 | class JavascriptExtractorTests(ExtractorTests): |
64 | 76 | |
diff --git a/tests/regressiontests/i18n/commands/templates/template_with_error.txt b/tests/regressiontests/i18n/commands/templates/template_with_error.txt
new file mode 100644
index 0000000..c2b93bd
-
|
+
|
|
| 1 | {% load i18n %} |
| 2 | <p>This template contains an error (no endblocktrans)</p> |
| 3 | <p>{% blocktrans %}This should fail{% blocktrans %}</p> |