使用Google App Engine和&amp ;;的TemplateNotFound(模板) Jinja2的

时间:2012-06-01 08:31:58

标签: google-app-engine jinja2

我在使用Jinja2的Google App Engine上收到TemplateNotFound错误(下面是完整的堆栈跟踪。)

我期望看到的是带有传递给index.html模板文件的“greet”变量的index.html。我不明白的是,当TraceBack中index.html的路径正确时,为什么我得到模板未找到错误。

我尝试过的......

  • 通过在模板路径中取出“os.path.dirname( file )”来尝试相对路径。
  • 使用“template”而不是主题作为目录名。

这是我的代码。

的app.yaml

application: codemywayout
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:

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

- url: /static/([^/]+)/(.*)
  static_files: template/\1/static/\2
  upload: static/.*

- 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

admin.py

from google.appengine.ext import db
import webapp2
import jinja2
import os
import fix_path
import config


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

class BlogPost(db.Model):
    title = db.StringProperty()
    body = db.StringProperty()

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

class BaseHandler(webapp2.RequestHandler):
    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))

class AdminHandler(BaseHandler):
    def get(self):
        greet = "hello"
        template_vals = {
            'greet': greet
        }
        self.render_to_response("index.html", template_vals)

config.py

# Name of the blog
blog_name = 'My Blog'

# Selects the theme to use. Theme names correspond to directories under
# the 'themes' directory, containing templates and static content.
theme = 'default'

# Defines the URL organization to use for blog postings. Valid substitutions:
#   slug - the identifier for the post, derived from the title
#   year - the year the post was published in
#   month - the month the post was published in
#   day - the day the post was published in

# URL Options
#   post_path_format = '/%(year)d/%(month)02d/%(slug)s'
post_path_format = '/%(slug)s'

回溯

Traceback (most recent call last):
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1536, in __call__
    rv = self.handle_exception(request, response, e)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "C:\Users\john\webdev\google\lib\webapp2\webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "C:\Users\john\webdev\workspace\codemywayout\admin.py", line 49, in get
    self.render_to_response("index.html", template_vals)
  File "C:\Users\john\webdev\workspace\codemywayout\admin.py", line 34, in render_to_response
    template_vals, theme))
  File "C:\Users\john\webdev\workspace\codemywayout\admin.py", line 14, in render_template
    return env.get_template(template_path, template_vals or {})
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\environment.py", line 719, in get_template
    return self._load_template(name, self.make_globals(globals))
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\environment.py", line 693, in _load_template
    template = self.loader.load(self, name, globals)
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\loaders.py", line 115, in load
    source, filename, uptodate = self.get_source(environment, name)
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\loaders.py", line 162, in get_source
    pieces = split_template_path(template)
  File "C:\Users\john\webdev\google\lib\jinja2\jinja2\loaders.py", line 33, in split_template_path
    raise TemplateNotFound(template)
TemplateNotFound: C:\Users\john\webdev\workspace\codemywayout\themes\default\admin\index.html

2 个答案:

答案 0 :(得分:1)

我希望您不要尝试从与静态文件相同的路径加载Jinja模板

static_files:template / \ 1 / static / \ 2

由于您的应用无法访问该路径。

我会尝试记录Jinja尝试加载模板的路径,以帮助您了解加载模板的位置。

答案 1 :(得分:0)

如果你看一下C:\ Users \ john \ webdev \ google \ lib \ jinja2 \ jinja2 \ loaders.py第33行,你可以设置一个pdb断点import pdb; pdb.set_trace( ),看看发生了什么。

我在Mac上使用SDK源代码发布,但如果您的代码与我看到的相同,那就是:

def split_template_path(template):
    """Split a path into segments and perform a sanity check.  If it detects
    '..' in the path it will raise a `TemplateNotFound` error.
    """
    pieces = []
    for piece in template.split('/'):
        if path.sep in piece \
           or (path.altsep and path.altsep in piece) or \
           piece == path.pardir:
            raise TemplateNotFound(template)
        elif piece and piece != '.':
            pieces.append(piece)
    return pieces

请注意for piece in template.split('/')分隔在'/'而不是path.sep的位置。我怀疑你的输入是C:\ Path \ to \ file.html,在这种情况下,piece是整个路径,adn path.sep(\ on windows)确实是一块,这给出了TemplateNotFound错误。

而不是template_name = os.path.join("admin", template_name)你可以尝试template_name = 'admin/%s' % template_name,不要在template_path中包含template_name,并将template_name而不是template_path传递给env.get_template(template_name, template_vals or {}),因为loaders.py第162行表示它在寻找template_path中的template_name

您修改但未经测试的代码看起来像

from google.appengine.ext import db
import webapp2
import jinja2
import os
import fix_path
import config


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))
    return env.get_template(template_name, template_vals or {})

class BlogPost(db.Model):
    title = db.StringProperty()
    body = db.StringProperty()

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

class BaseHandler(webapp2.RequestHandler):
    def render_to_response(self, template_name, \
            template_vals=None, theme=None):
        template_name = "admin/%s" % template_name
        self.response.out.write(render_template(template_name,\
            template_vals, theme))

class AdminHandler(BaseHandler):
    def get(self):
        greet = "hello"
        template_vals = {
            'greet': greet
        }
        self.render_to_response("index.html", template_vals)