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> |