Jinja: рд╡реНрд╣реЙрдЯреНрд╕рдПрдк рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рд▓рд┐рдП рдзрди рдЪрд┐рд╣реНрди (+) рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛: рдЯреИрдЧ рдирд╛рдо рдЕрдкреЗрдХреНрд╖рд┐рдд

рдХреЛ рдирд┐рд░реНрдорд┐рдд 15 рдЬреБрд▓ре░ 2017  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: pallets/jinja

рдЕрдкреЗрдХреНрд╖рд┐рддреН рд╡реНрдпрд╡рд╣рд╛рд░

рдорд╛рди рд▓реЗрдВ рдХрд┐ trim_blocks рд╣рдореЗрд╢рд╛ False ред

рдЬрдм lstrip_blocks рдХреЛ True рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЬрд┐рдиреНрдЬрд╛ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

<!-- 1 -->
    <!-- 2 -->
foo<!-- 3 -->
<!-- 4 -->
<!-- 5 -->

рдФрд░ рдЬрдм рдпрд╣ False , рддреЛ рдЬрд┐рдиреНрдЬрд╛ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

    <!-- 1 -->
    <!-- 2 -->
    foo<!-- 3 -->
    <!-- 4 -->
    <!-- 5 -->

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░

рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ,

jinja2.exceptions.TemplateSyntaxError: рдЯреИрдЧ рдирд╛рдо рдЕрдкреЗрдХреНрд╖рд┐рдд

рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛрдб

    <!-- 1 -->
    {%+ if True %}<!-- 2 -->
    foo<!-- 3 -->
    {% endif %}<!-- 4 -->
    <!-- 5 -->

рдирд┐рдореНрди рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рднреА рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛ рд╣реИ:

    <!-- 1 -->
    {% if True %}<!-- 2 -->
    foo<!-- 3 -->
    {%+ endif %}<!-- 4 -->
    <!-- 5 -->

рдкреВрд░реНрдг рдЯреНрд░реЗрд╕рдмреИрдХ

Traceback (most recent call last):
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/sunqingyao/PycharmProjects/microblog/app/views.py", line 22, in index
    posts=posts
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/flask/templating.py", line 133, in render_template
    return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/environment.py", line 869, in get_or_select_template
    return self.get_template(template_name_or_list, parent, globals)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/environment.py", line 830, in get_template
    return self._load_template(name, self.make_globals(globals))
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/environment.py", line 804, in _load_template
    template = self.loader.load(self, name, globals)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/loaders.py", line 125, in load
    code = environment.compile(source, name, filename)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/environment.py", line 591, in compile
    self.handle_exception(exc_info, source_hint=source_hint)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "/home/sunqingyao/PycharmProjects/microblog/app/templates/demo.html", line 2, in template
    {%+ if True %}<!-- 2 -->
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/environment.py", line 497, in _parse
    return Parser(self, source, name, encode_filename(filename)).parse()
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/parser.py", line 896, in parse
    result = nodes.Template(self.subparse(), lineno=1)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/parser.py", line 878, in subparse
    rv = self.parse_statement()
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/parser.py", line 125, in parse_statement
    self.fail('tag name expected', token.lineno)
  File "/home/sunqingyao/Envs/flask-mega/lib/python3.6/site-packages/jinja2/parser.py", line 59, in fail
    raise exc(msg, lineno, self.name, self.filename)
jinja2.exceptions.TemplateSyntaxError: tag name expected

рдЖрдкрдХрд╛ рдкрд░реНрдпрд╛рд╡рд░рдг

  • рдкрд╛рдпрдерди рд╕рдВрд╕реНрдХрд░рдг: 3.6.1+
  • рдЬрд┐рдВрдЬрд╛ рд╕рдВрд╕реНрдХрд░рдг: рдЬрд┐рдВрдЬрд╛2==2.9.6

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рд╣рдореЗрдВ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдо рдЗрд╕реЗ рд╕реНрд╡рдпрдВрд╕реЗрд╡рдХреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реАрдорд┐рдд рдЦрд╛рд▓реА рд╕рдордп рдХреЗ рд╕рд╛рде рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВред рдЬрдм рд╣рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рд╣рдо рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдкреИрдЪ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдореБрджрд╛рдп рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЗрд╕рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рдПрдХ рдкреАрдЖрд░ рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВред

рд╕рднреА 5 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреНрд░реЗрд░рдгрд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ?
рд╕рдВрджрд░реНрдн: https://stackoverflow.com/questions/35775207/remove-unnecessary-whitespace-from-jinja-rendered-template#35777386
рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ '-+' рдХреЙрдореНрдмреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ {%... рд╕реЗ рдкрд╣рд▓реЗ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрддреНрддрд░рджрд╛рдпреА (jinja2-) рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ (рддрд░реНрдХ рдФрд░ рд╕рд╛рдордЧреНрд░реА рдХреА рдорд┐рд╢реНрд░рд┐рдд рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдЗрдВрдбреЗрдВрдЯрд┐рдВрдЧ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП):

<root_element>
  {%- if ... +%}
  <property>

  </property>
  {%- if ... +%}
 strips before

рд╣рдореЗрдВ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдо рдЗрд╕реЗ рд╕реНрд╡рдпрдВрд╕реЗрд╡рдХреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реАрдорд┐рдд рдЦрд╛рд▓реА рд╕рдордп рдХреЗ рд╕рд╛рде рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВред рдЬрдм рд╣рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рд╣рдо рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдкреИрдЪ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдореБрджрд╛рдп рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЗрд╕рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рдПрдХ рдкреАрдЖрд░ рд╕рдмрдорд┐рдЯ рдХрд░реЗрдВред

#749 . рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд
#750 . рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд

рдпрд╣рд╛рдБ рд╕рдорд╕реНрдпрд╛ рдХреЗрд╡рд▓ рдпрд╣ рдкреНрд░рддреАрдд рд╣реЛрддреА рд╣реИ рдХрд┐ рдЬрдм lstrip_blocks = False, рд╕рд┐рдВрдЯреИрдХреНрд╕ "{%+ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ%}" рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ "jinja2.exceptions.TemplateSyntaxError: рдЯреИрдЧ рдирд╛рдо рдЕрдкреЗрдХреНрд╖рд┐рдд" рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рдХрдореЛрдмреЗрд╢ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ lstrip_blocks рдкрд╣рд▓реЗ рд╕реЗ рдЕрдХреНрд╖рдо рд╣реЛрдиреЗ рдкрд░ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рдврдВрдЧ рд╕реЗ рд╡рд┐рдлрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг:

рдпрд╣ рдХрд╛рдо:

from jinja2 import Environment
env = Environment(lstrip_blocks=True, trim_blocks=False)
str7481 = '''
    <!-- 1 -->
    {%+ if True %}<!-- 2 -->
    foo<!-- 3 -->
    {% endif %}<!-- 4 -->
    <!-- 5 -->'''
str7482 = '''
    <!-- 1 -->
    {% if True %}<!-- 2 -->
    foo<!-- 3 -->
    {%+ endif %}<!-- 4 -->
    <!-- 5 -->'''
print(env.from_string(str7481).render())
print(env.from_string(str7482).render())

рдпрд╣ рдирд╣реАрдВ рдХрд░рддрд╛:

from jinja2 import Environment
env = Environment(lstrip_blocks=False, trim_blocks=False)
str7481 = '''
    <!-- 1 -->
    {%+ if True %}<!-- 2 -->
    foo<!-- 3 -->
    {% endif %}<!-- 4 -->
    <!-- 5 -->'''
str7482 = '''
    <!-- 1 -->
    {% if True %}<!-- 2 -->
    foo<!-- 3 -->
    {%+ endif %}<!-- 4 -->
    <!-- 5 -->'''
print(env.from_string(str7481).render())
print(env.from_string(str7482).render())

рдореИрдВрдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ @davidism рдХреЗ рд╕рд╛рде рдЪрд░реНрдЪрд╛ рдХреА рдФрд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдХрд┐ рдЬрдм lstrip_blocks = False рддреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдирд╣реАрдВ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ '{%+' рдЕрднреА рднреА рд╡реИрдз рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдЕрд░реНрдерд╢рд╛рд╕реНрддреНрд░ рдХреЗрд╡рд▓ '+' рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╣реИред рдореИрдВ рдПрдХ рдкреАрдЖрд░ рд╕рдмрдорд┐рдЯ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рдЗрд╕ рд╕рдВрднрд╛рд╡рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд░рддрд╛ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

samatjain picture samatjain  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

delroth picture delroth  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Yannik picture Yannik  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

glasserc picture glasserc  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

RickGray picture RickGray  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ