【问题标题】:Jinja2 install issueJinja2 安装问题
【发布时间】:2016-05-16 03:11:02
【问题描述】:

在我的 html 模板中尝试 {% set foo = 42 %} 时收到以下错误消息。当不使用set 时,模板可以正常工作。

TemplateSyntaxError: Invalid block tag: 'set', expected 'endblock' or 'endblock content'

下面我按照 cmets 的建议添加了完整的会话日志。

*** Running dev_appserver with the following flags:
    --skip_sdk_update_check=yes --port=15093 --admin_port=8018
Python command: /usr/bin/python2.7
INFO     2016-05-14 18:36:26,513 devappserver2.py:762] Skipping SDK update check.
INFO     2016-05-14 18:36:26,696 api_server.py:204] Starting API server at: http://localhost:56265
INFO     2016-05-14 18:36:26,701 dispatcher.py:197] Starting module "default" running at: http://localhost:15093
INFO     2016-05-14 18:36:26,704 admin_server.py:118] Starting admin server at: http://localhost:8018
ERROR    2016-05-14 18:37:48,778 webapp2.py:1528] Invalid block tag: 'set', expected 'endblock' or 'endblock content'
Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1077, in __call__
    return handler.dispatch()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 547, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 545, in dispatch
    return method(*args, **kwargs)
  File "/Users/brian/googleapps/lastturn/views.py", line 187, in get
    self.response.out.write(template.render(path, template_values))
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 91, in render
    t = _load_internal_django(template_path, debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 165, in _load_internal_django
    template = django.template.loader.get_template(file_name)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 160, in get_template
    template = get_template_from_string(template, origin, template_name)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 168, in get_template_from_string
    return Template(source, origin, name)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 158, in __init__
    self.nodelist = compile_string(template_string, origin)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 186, in compile_string
    return parser.parse()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
    compiled_result = compile_func(self, token)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 195, in do_extends
    nodelist = parser.parse()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
    compiled_result = compile_func(self, token)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 173, in do_block
    nodelist = parser.parse(('endblock', 'endblock %s' % block_name))
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 279, in parse
    self.invalid_block_tag(token, command, parse_until)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 332, in invalid_block_tag
    raise self.error(token, "Invalid block tag: '%s', expected %s" % (command, get_text_list(["'%s'" % p for p in parse_until])))
TemplateSyntaxError: Invalid block tag: 'set', expected 'endblock' or 'endblock content'
ERROR    2016-05-14 18:37:48,784 wsgi.py:279] 
Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/runtime/wsgi.py", line 267, in Handle
    result = handler(dict(self._environ), self._StartResponse)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1519, in __call__
    response = self._internal_error(e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 1077, in __call__
    return handler.dispatch()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 547, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.3/webapp2.py", line 545, in dispatch
    return method(*args, **kwargs)
  File "/Users/brian/googleapps/lastturn/views.py", line 187, in get
    self.response.out.write(template.render(path, template_values))
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 91, in render
    t = _load_internal_django(template_path, debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 165, in _load_internal_django
    template = django.template.loader.get_template(file_name)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 160, in get_template
    template = get_template_from_string(template, origin, template_name)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 168, in get_template_from_string
    return Template(source, origin, name)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 158, in __init__
    self.nodelist = compile_string(template_string, origin)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 186, in compile_string
    return parser.parse()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
    compiled_result = compile_func(self, token)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 195, in do_extends
    nodelist = parser.parse()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
    compiled_result = compile_func(self, token)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 173, in do_block
    nodelist = parser.parse(('endblock', 'endblock %s' % block_name))
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 279, in parse
    self.invalid_block_tag(token, command, parse_until)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 332, in invalid_block_tag
    raise self.error(token, "Invalid block tag: '%s', expected %s" % (command, get_text_list(["'%s'" % p for p in parse_until])))
TemplateSyntaxError: Invalid block tag: 'set', expected 'endblock' or 'endblock content'
INFO     2016-05-14 18:37:48,792 module.py:812] default: "GET / HTTP/1.1" 500 -

下面我添加了我对views.py 所做的修改。注释掉的行表示原始的 jinja2 环境语句。这些修订是对 cme​​ts 提出的建议的回应。但我仍然收到相同的错误消息,这似乎表明 jinja2 没有被使用。

TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'templates')
#jinja_environment = \
#jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_DIR))

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)

class BaseHandler(webapp2.RequestHandler):

    @webapp2.cached_property
    def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

    def render_template(
        self,
        filename,
        template_values,
        **template_args
        ):
#template = jinja_environment.get_template(filename)
    template = JINJA_ENVIRONMENT.get_template(filename)
        self.response.out.write(template.render(template_values))

下面是base.html模板。

<html>
  <head>
    <link rel="stylesheet" href="/static/css/reset.css">
    <link rel="stylesheet" href="/static/css/style.css">
  </head>
  <body>
    <div class="wrapper">
    {% block content %}
    {% endblock content %}
    </div>
  </body>
</html>

下面是实际模板的“心脏”。所谓“心”,我的意思是我已经放弃了胆量,因为这只是一个测试。

{% extends "base.html" %}
    {% block content %}
    <center>
        <h1>Create or edit your own Blog</h1>
      </center>
      {% set foo = 42 %}
      {{ foo }}

    {% endblock content %}

This answer suggests to me that jinja2 is not installed (properly?).

我必须更改安装的其他部分吗?

This answer shows more input about ipython installation, 但我使用的 google-app-engine 可能有所不同。下面的清单确认已安装 Jinja2 2.8。

server:~ brian$ pip freeze
Warning: cannot find svn location for setuptools===0.6c12dev-r85381
all==0.0.6
altgraph==0.7.1
atari-py==0.0.17
bdist-mpkg==0.4.4
bonjour-py==0.3
caller-module==0.0.9
Django==1.3.1
include-server===3.1-toolwhip.1
Jinja2==2.8
macholib==1.3
MarkupSafe==0.23
mod-python==3.3.1
modulegraph==0.8.1
numpy==1.11.0
PIL==1.1.7
Pillow==3.2.0
public==0.0.0
py2app==0.5.3
pyglet==1.2.4
pyobjc-core==2.3.2a0
pyobjc-framework-AddressBook==2.3.2a0

pyOpenSSL==0.12
PyRSS2Gen==1.0.0
python-dateutil==1.5
PyYAML==3.11
render==1.0.0
requests==2.9.1
six==1.10.0
Twisted==11.0.0
xattr==0.6.1
zope.interface==3.5.1
You are using pip version 8.1.1, however version 8.1.2 is available.
server:~ brian$ 

【问题讨论】:

  • 我们可以看看您的模板或至少完整的block 围绕您的可疑陈述吗?
  • 是的,请查看修改后的问题。
  • jinja2 的语法是正确的。但是您的应用程序似乎使用的是 django 模板,而不是 jinja2 模板 - 语法略有不同。请参阅@Blender 的 cmets 至 stackoverflow.com/questions/20306640/…
  • 可能不正确,尽管如此 - 至少 GAE 的 jinja2-2.6 确实 会引发 TemplateSyntaxError - 它存在于其 jinja2/exceptions.py 文件中。完整的回溯可能仍能准确指出实际使用了哪些模板。
  • 丹,我又修改了问题。我怀疑问题是我的 gae 项目中的 Templates 子目录没有正确传递给 jinja 环境。完整的回溯只提到 django,而不是 jinja。您是否看到任何可能的修复?

标签: google-app-engine jinja2


【解决方案1】:

在通过 cmets 对我最初的问题提供了很多帮助之后,我终于回答了我的问题。我对 webapp2 和 Jinja 都有 template.render() 感到困惑,但它们是不同的。

来自 webapp 的

template.render() 似乎需要 2 个参数——路径和模板名称——而我当前的代码使用这种格式。但是,我想使用 Jinja2,其中 template.render() 只需要 1 个参数——模板名称。

根据google docs for using Jinja in the guestbook app,显示以下格式。

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)

但事实证明,我选择的 BaseHandler 类不能很好地工作,它将模板放在他们自己的子目录“模板”中。相反,我使用了以下代码,其中 TEMPLATE_DIR 替换了“loader =”语句中的 file

TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'templates')
JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(TEMPLATE_DIR ),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)

顺便说一句,我不再导入 webapp template。我在“get def”中使用了以下样式。

template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.out.write(template.render( template_values))

因此,虽然问题是“Jinja 安装问题”,但问题并不完全在于安装,而是我在将 Jinja 与现有目录结构集成时遇到了困难。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-07
    • 2021-05-31
    • 2016-12-13
    • 1970-01-01
    • 2012-05-07
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多