5

Google App Engine で Jinja2 を使用しています。私のedit.htmlテンプレートでbase.htmlをロードするために相対パスを使用しようとしています。

私のテーマのディレクトリ構造は次のようになります...

  • アプリケーションルート
    • テーマ
      • デフォルト
        • 管理者
          • edit.html
        • base.html

テンプレートでこれを試してみました...

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

これを返す...

TemplateNotFound: ../base.html

これをすると…

{% extends "base.html" %}

私の edit.html テンプレートは読み込まれますが、base.html はありません。

edit.html から 1 つ戻ったディレクトリにある 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
4

1 に答える 1

10

なるほど、わかった……。

これが私が学んだことです...

  • テーマ フォルダーを静的フォルダーにしないでください。GAE ではアプリケーションで静的ファイルを使用できないため、これは大したことではありません。Google App Engine がファイルにアクセスできないと言っている場合、これが原因である可能性があります。

  • Jinja2 では、すべてのファイルは、テンプレート ファイルではなく、jinja2 環境に割り当てたフォルダーに関連しています。したがって、私の場合...「デフォルト」のテーマフォルダーは、ジンジャ環境のルートフォルダーでした。代わりに../base.htmlbase.htmlbase.html が jinja2 にテンプレートの読み込みに使用するように指示したデフォルトのフォルダーにあるため、機能します。

  • 最後に、jinja2 に複数のフォルダー内のファイルを検索させたい場合は .

于 2012-09-09T13:24:38.070 に答える