【问题标题】:Relative URLs with Google App Engine and Jinja2Google App Engine 和 Jinja2 的相对 URL
【发布时间】:2012-09-07 07:43:57
【问题描述】:

我将 Jinja2 与 Google App Engine 结合使用。我正在尝试使用相对路径通过我的 edit.html 模板加载 base.html。

我的主题目录结构是这样的...

  • 应用程序根
    • 主题
      • 默认
        • 管理员
          • edit.html
        • base.html

我已经在模板中尝试过这个...

{% extends "../base.html" %}

返回这个...

TemplateNotFound: ../base.html

当我这样做时......

{% extends "base.html" %}

我的 edit.html 模板加载,但没有 base.html。

如何访问从edit.html返回的一个目录base.html?

现在是代码...

app.yaml

application: myblog
version: 1
runtime: python27
api_version: 1
threadsafe: no

handlers:

- url: /admin/.*
  script: admin.app
  login: admin

- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: static.app

builtins:
- remote_api: on

libraries:
- name: webapp2
  version: "2.5.1"

- name: jinja2
  version: latest

config.py

blog_name = 'My Blog'
theme = 'default'
post_path_format = '/%(year)d/%(month)02d/%(slug)s'

admin.py

def render_template(template_name, template_vals=None, theme=None):
    template_path = os.path.join(os.path.dirname(__file__),
        'themes', theme or config.theme)
    env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_path))
    template = env.get_template(template_name)
    return template.render(**(template_vals or {}))

class BlogPost(db.Model):
    #The URL path to the blog post. Posts have a path if they are published.
    path = db.StringProperty()
    title = db.StringProperty(required=True, indexed=False)
    body = db.TextProperty(required=True)
    published = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)

    def render(self):
        template_vals = {
            'config': config,
            'post': self,
        }
        return render_template("post.html", template_vals)


form = model_form(BlogPost, Form)

class PostForm(form):
    pass

class PostHandler(webapp2.RequestHandler):

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

    def render_to_response(
            self, template_name, template_vals=None, theme=None):
        template_name = os.path.join("admin", template_name)
        self.response.out.write(render_template(
            template_name, template_vals, theme))

    def render_form(self, form):
        self.render_to_response("edit.html", {'form': form})

    def get(self):
        self.render_form(PostForm())

app = webapp2.WSGIApplication([('/admin/newpost', PostHandler)],
                              debug=True)

edit.html

{% extends "../base.html" %}
{% block title %}Testing New Post Template{% endblock %}
{% block body %}
  <form method="post" action="">
    <table>

<div>{{ form.title.label }}: {{ form.title(class="css_class") }}</div>
{% if form.title.errors %}
        <ul class="errors">{% for error in form.name.errors %}<li>{{ error }}</li>{% endfor %}</ul>
    {% endif %}

<div>{{ form.body.label }}: {{ form.body() }}</div>
{% if form.body.errors %}
        <ul class="errors">{% for error in form.body.errors %}<li>{{ error }}</li>{% endfor %}</ul>
    {% endif %}

    </table>
    <input type="submit" />
  </form>
{% endblock %}

全栈跟踪

ERROR    2012-09-07 07:45:42,964 webapp2.py:1553] ../base.html
Traceback (most recent call last):
  File "/home/john/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1536, in __call__
    rv = self.handle_exception(request, response, e)
  File "/home/john/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/home/john/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/home/john/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/home/john/google_projects/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/home/john/google_projects/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/home/john/google_projects/sprucepress/admin.py", line 86, in get
    self.render_form(PostForm())
  File "/home/john/google_projects/sprucepress/admin.py", line 83, in render_form
    self.render_to_response("edit.html", {'form': form})
  File "/home/john/google_projects/sprucepress/admin.py", line 80, in render_to_response
    template_name, template_vals, theme))
  File "/home/john/google_projects/sprucepress/admin.py", line 34, in render_template
    return template.render(**(template_vals or {}))
  File "/home/john/google_projects/google_appengine/lib/jinja2/jinja2/environment.py", line 894, in render
    return self.environment.handle_exception(exc_info, True)
  File "/home/john/google_projects/sprucepress/themes/default/admin/edit.html", line 1, in top-level template code
    {% extends "../base.html" %}
TemplateNotFound: ../base.html

【问题讨论】:

  • 如果你这样做{% extends "themes/default/base.html" %}会发生什么?
  • 同样的错误,但出现“TemplateNotFound:themes/default/base.html”
  • 或{% extends "default/base.html" %},除此之外我不确定您如何指定模板。我不相信你可以使用extends 的相对路径,但我可能是错的。您还可以查看webapp2_extra/jinja2,也许来源可以阐明这个问题。
  • 看起来有可能,但我不知道如何在我的代码中实现solution。

标签: google-app-engine jinja2


【解决方案1】:

好吧,我想通了……

这是我学到的……

  • 不要将您的主题文件夹设为静态文件夹。这是一个很大的禁忌because on GAE static files are not available to the application。如果 Google App Engine 告诉您该文件不可访问,这可能是原因!

  • 在 Jinja2 中,所有文件都与您分配给 jinja2 环境的文件夹相关...而不是模板文件!所以,就我而言……“默认”主题文件夹是我的 jinja 环境的根文件夹。我不是../base.html,而是base.html,它可以工作,因为base.html在我告诉jinja2用来加载模板的默认文件夹中。

  • 最后,如果你想让 jinja2 在多个文件夹中查找文件,你 can。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-22
    • 2012-06-06
    • 1970-01-01
    • 2011-03-06
    • 2012-08-17
    • 1970-01-01
    • 2012-09-14
    • 2011-06-08
    相关资源
    最近更新 更多