1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# -*- coding: utf-8 -*-
"""
flask.templating
~~~~~~~~~~~~~~~~
Implements the bridge to Jinja2.
:copyright: (c) 2010 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
import posixpath
from jinja2 import BaseLoader, TemplateNotFound
from .globals import _request_ctx_stack
from .signals import template_rendered
def _default_template_ctx_processor():
"""Default template context processor. Injects `request`,
`session` and `g`.
"""
reqctx = _request_ctx_stack.top
return dict(
config=reqctx.app.config,
request=reqctx.request,
session=reqctx.session,
g=reqctx.g
)
class _DispatchingJinjaLoader(BaseLoader):
"""A loader that looks for templates in the application and all
the module folders.
"""
def __init__(self, app):
self.app = app
def get_source(self, environment, template):
template = posixpath.normpath(template)
if template.startswith('../'):
raise TemplateNotFound(template)
loader = None
try:
module, name = template.split('/', 1)
loader = self.app.modules[module].jinja_loader
except (ValueError, KeyError):
pass
# if there was a module and it has a loader, try this first
if loader is not None:
try:
return loader.get_source(environment, name)
except TemplateNotFound:
pass
# fall back to application loader if module failed
return self.app.jinja_loader.get_source(environment, template)
def list_templates(self):
result = 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
def _render(template, context, app):
"""Renders the template and fires the signal"""
rv = template.render(context)
template_rendered.send(app, template=template, context=context)
return rv
def render_template(template_name, **context):
"""Renders a template from the template folder with the given
context.
:param template_name: the name of the template to be rendered
:param context: the variables that should be available in the
context of the template.
"""
ctx = _request_ctx_stack.top
ctx.app.update_template_context(context)
return _render(ctx.app.jinja_env.get_template(template_name),
context, ctx.app)
def render_template_string(source, **context):
"""Renders a template from the given template source string
with the given context.
:param template_name: the sourcecode of the template to be
rendered
:param context: the variables that should be available in the
context of the template.
"""
ctx = _request_ctx_stack.top
ctx.app.update_template_context(context)
return _render(ctx.app.jinja_env.from_string(source),
context, ctx.app)
|