2012-09-07 15 views
5

Uso Jinja2 con Google App Engine. Estoy intentando usar una ruta relativa para cargar base.html con mi plantilla edit.html.URL relativas con Google App Engine y Jinja2

Mi estructura de directorio del tema se ve así ...

  • raíz de la aplicación
    • temas
      • predeterminado
        • administrador
          • edit.html
        • base.html

He intentado esto en la plantilla ...

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

que devuelve esta ...

TemplateNotFound: ../base.html 

Cuando hago th es ...

{% extends "base.html" %} 

mi plantilla edit.html se carga, pero sin base.html.

¿Cómo accedo a base.html desde el directorio de edit.html?

Ahora para el código ...

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 %} 

completa Seguimiento de la pila

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

¿Qué sucede si lo haces '{% extends" themes/default/base.html "%}'? –

+0

Mismo error, pero con "TemplateNotFound: themes/default/base.html" – jwogrady

+0

O '{% extends" default/base.html "%}', aparte de que no estoy seguro de cómo podría especificar la plantilla. No creo que puedas usar rutas relativas con 'extends', pero podría estar equivocado. También puede consultar [webapp2_extra/jinja2] (http://webapp-improved.appspot.com/api/webapp2_extras/jinja2.html), tal vez la fuente podría arrojar algo de luz sobre el tema. –

Respuesta

10

Bueno, lo he descubierto ....

Aquí es lo que he aprendido ...

  • No convierta su carpeta de temas en una carpeta estática. Este es un gran no-no because on GAE static files are not available to the application. Si Google App Engine le dice que el archivo no es accesible, ¡esta puede ser la causa!

  • En Jinja2 todos los archivos son relativos a la carpeta que asigna al entorno jinja2 ... ¡no al archivo de la plantilla! Entonces, en mi caso ... la carpeta del tema "predeterminado" era la carpeta raíz de mi entorno jinja. En lugar de ../base.html hago base.html y funciona porque base.html está en la carpeta predeterminada que dije a jinja2 que use para cargar plantillas.

  • Finalmente, si quiere que jinja2 busque un archivo en varias carpetas, can.