2012-09-07 69 views
5

我使用Jinja2和Google App Engine。在試圖使用相對路徑來加載我的edit.html模板的base.html。Google App Engine和Jinja2的相對URL

我的主題目錄結構看起來像這樣...

  • 應用程序根
    • 主題
      • 默認
        • 管理
          • edit.html
        • base.html文件

我在模板中嘗試這個...

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

返回此...

TemplateNotFound: ../base.html 

當我做的時候是...

{% extends "base.html" %} 

我的edit.html模板加載,但沒有base.html。

如何訪問base.html這是從edit.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 
+0

如果您使用'{%extends'themes/default/base.html「%}',會發生什麼? –

+0

同樣的錯誤,但是使用「TemplateNotFound:themes/default/base.html」 – jwogrady

+0

或'{%extends「default/base.html」%}',除此之外我不確定如何指定模板。我不相信你可以用'extends'來使用相對路徑,但我可能是錯的。您可能還會考慮[webapp2_extra/jinja2](http://webapp-improved.appspot.com/api/webapp2_extras/jinja2.html),也許源代碼可以揭示這個問題。 –

回答

10

好吧,我想通了....

這是我學到了什麼?

  • 請勿將您的主題文件夾設置爲靜態文件夾。這是一個很大的no-no because on GAE static files are not available to the application。如果Google App Engine告訴您文件無法訪問,則可能是原因!

  • 在Jinja2中,所有文件都是相對於您分配給jinja2環境的文件夾而不是模板文件!所以,就我而言......「默認」主題文件夾是我的忍者環境的根文件夾。而不是../base.html我做base.html它工作,因爲base.html是在我告訴jinja2用來加載模板的默認文件夾。

  • 最後,如果你想讓jinja2在你的can多個文件夾中查找文件。