forked from orbit-oss/flask
Started work on implementing blueprint based template loading
This commit is contained in:
parent
1446614915
commit
a06cd0a644
4 changed files with 93 additions and 22 deletions
|
|
@ -9,7 +9,8 @@
|
|||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import posixpath
|
||||
from jinja2 import BaseLoader, TemplateNotFound
|
||||
from jinja2 import BaseLoader, Environment as BaseEnvironment, \
|
||||
TemplateNotFound
|
||||
|
||||
from .globals import _request_ctx_stack
|
||||
from .signals import template_rendered
|
||||
|
|
@ -28,7 +29,25 @@ def _default_template_ctx_processor():
|
|||
)
|
||||
|
||||
|
||||
class _DispatchingJinjaLoader(BaseLoader):
|
||||
class Environment(BaseEnvironment):
|
||||
"""Works like a regular Jinja2 environment but has some additional
|
||||
knowledge of how Flask's blueprint works so that it can prepend the
|
||||
name of the blueprint to referenced templates if necessary.
|
||||
"""
|
||||
|
||||
def __init__(self, app, **options):
|
||||
if 'loader' not in options:
|
||||
options['loader'] = app.create_jinja_loader()
|
||||
BaseEnvironment.__init__(self, **options)
|
||||
self.app = app
|
||||
|
||||
def join_path(self, template, parent):
|
||||
if template and template[0] == ':':
|
||||
template = parent.split(':', 1)[0] + template
|
||||
return template
|
||||
|
||||
|
||||
class DispatchingJinjaLoader(BaseLoader):
|
||||
"""A loader that looks for templates in the application and all
|
||||
the module folders.
|
||||
"""
|
||||
|
|
@ -37,31 +56,50 @@ class _DispatchingJinjaLoader(BaseLoader):
|
|||
self.app = app
|
||||
|
||||
def get_source(self, environment, template):
|
||||
template = posixpath.normpath(template)
|
||||
if template.startswith('../'):
|
||||
raise TemplateNotFound(template)
|
||||
# newstyle template support. blueprints are explicit and no further
|
||||
# magic is involved. If the template cannot be loaded by the
|
||||
# blueprint loader it just gives up, no further steps involved.
|
||||
if ':' in template:
|
||||
blueprint_name, local_template = template.split(':', 1)
|
||||
local_template = posixpath.normpath(local_template)
|
||||
blueprint = self.app.blueprints.get(blueprint_name)
|
||||
if blueprint is None:
|
||||
raise TemplateNotFound(template)
|
||||
loader = blueprint.jinja_loader
|
||||
if loader is not None:
|
||||
return loader.get_source(environment, local_template)
|
||||
|
||||
# if modules are enabled we call into the old style template lookup
|
||||
# and try that before we go with the real deal.
|
||||
loader = None
|
||||
try:
|
||||
module, name = template.split('/', 1)
|
||||
module, name = posixpath.normpath(template).split('/', 1)
|
||||
loader = self.app.modules[module].jinja_loader
|
||||
except (ValueError, KeyError):
|
||||
except (ValueError, KeyError, TemplateNotFound):
|
||||
pass
|
||||
# if there was a module and it has a loader, try this first
|
||||
if loader is not None:
|
||||
try:
|
||||
try:
|
||||
if loader is not None:
|
||||
return loader.get_source(environment, name)
|
||||
except TemplateNotFound:
|
||||
pass
|
||||
# fall back to application loader if module failed
|
||||
except TemplateNotFound:
|
||||
pass
|
||||
|
||||
# at the very last, load templates from the environment
|
||||
return self.app.jinja_loader.get_source(environment, template)
|
||||
|
||||
def list_templates(self):
|
||||
result = self.app.jinja_loader.list_templates()
|
||||
result = set(self.app.jinja_loader.list_templates())
|
||||
|
||||
for name, module in self.app.modules.iteritems():
|
||||
if module.jinja_loader is not None:
|
||||
for template in module.jinja_loader.list_templates():
|
||||
result.append('%s/%s' % (name, template))
|
||||
return result
|
||||
result.add('%s/%s' % (name, template))
|
||||
|
||||
for name, blueprint in self.app.blueprints.iteritems():
|
||||
if blueprint.jinja_loader is not None:
|
||||
for template in blueprint.jinja_loader.list_templates():
|
||||
result.add('%s:%s' % (name, template))
|
||||
|
||||
return list(result)
|
||||
|
||||
|
||||
def _render(template, context, app):
|
||||
|
|
@ -81,6 +119,8 @@ def render_template(template_name, **context):
|
|||
"""
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.app.update_template_context(context)
|
||||
if template_name[:1] == ':':
|
||||
template_name = ctx.request.blueprint + template_name
|
||||
return _render(ctx.app.jinja_env.get_template(template_name),
|
||||
context, ctx.app)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue