Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 139 lines (110 sloc) 4.391 kb
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
1 # -*- coding: utf-8 -*-
2 """
3 flask.templating
4 ~~~~~~~~~~~~~~~~
5
6 Implements the bridge to Jinja2.
7
33534bb @Parkayun Happy New Year 2015
Parkayun authored
8 :copyright: (c) 2015 by Armin Ronacher.
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
9 :license: BSD, see LICENSE for more details.
10 """
a06cd0a @mitsuhiko Started work on implementing blueprint based template loading
authored
11 from jinja2 import BaseLoader, Environment as BaseEnvironment, \
12 TemplateNotFound
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
13
f34c028 @mitsuhiko Added template tests and made config a true global
authored
14 from .globals import _request_ctx_stack, _app_ctx_stack
e0712b4 @mitsuhiko Added support for signals
authored
15 from .signals import template_rendered
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
16
17
665fa2a @mitsuhiko More refactoring and moving stuff around
authored
18 def _default_template_ctx_processor():
19 """Default template context processor. Injects `request`,
20 `session` and `g`.
21 """
22 reqctx = _request_ctx_stack.top
1949c4a @mitsuhiko flask.g is now on the app context and not the request context
authored
23 appctx = _app_ctx_stack.top
24 rv = {}
25 if appctx is not None:
26 rv['g'] = appctx.g
27 if reqctx is not None:
28 rv['request'] = reqctx.request
29 rv['session'] = reqctx.session
30 return rv
665fa2a @mitsuhiko More refactoring and moving stuff around
authored
31
32
a06cd0a @mitsuhiko Started work on implementing blueprint based template loading
authored
33 class Environment(BaseEnvironment):
34 """Works like a regular Jinja2 environment but has some additional
35 knowledge of how Flask's blueprint works so that it can prepend the
36 name of the blueprint to referenced templates if necessary.
37 """
38
39 def __init__(self, app, **options):
40 if 'loader' not in options:
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
41 options['loader'] = app.create_global_jinja_loader()
a06cd0a @mitsuhiko Started work on implementing blueprint based template loading
authored
42 BaseEnvironment.__init__(self, **options)
43 self.app = app
44
45
46 class DispatchingJinjaLoader(BaseLoader):
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
47 """A loader that looks for templates in the application and all
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
48 the blueprint folders.
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
49 """
50
51 def __init__(self, app):
52 self.app = app
53
54 def get_source(self, environment, template):
bafc139 @mitsuhiko Added EXPLAIN_TEMPLATE_LOADING to help people debug templates not bei…
authored
55 explain = self.app.config['EXPLAIN_TEMPLATE_LOADING']
56 attempts = []
57 tmplrv = None
58
59 for srcobj, loader in self._iter_loaders(template):
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
60 try:
bafc139 @mitsuhiko Added EXPLAIN_TEMPLATE_LOADING to help people debug templates not bei…
authored
61 rv = loader.get_source(environment, template)
62 if tmplrv is None:
63 tmplrv = rv
64 if not explain:
65 break
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
66 except TemplateNotFound:
bafc139 @mitsuhiko Added EXPLAIN_TEMPLATE_LOADING to help people debug templates not bei…
authored
67 rv = None
68 attempts.append((loader, srcobj, rv))
69
70 if explain:
84f57b6 @mitsuhiko Fixed a relative import
authored
71 from .debughelpers import explain_template_loading_attempts
bafc139 @mitsuhiko Added EXPLAIN_TEMPLATE_LOADING to help people debug templates not bei…
authored
72 explain_template_loading_attempts(self.app, template, attempts)
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
73
bafc139 @mitsuhiko Added EXPLAIN_TEMPLATE_LOADING to help people debug templates not bei…
authored
74 if tmplrv is not None:
75 return tmplrv
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
76 raise TemplateNotFound(template)
a06cd0a @mitsuhiko Started work on implementing blueprint based template loading
authored
77
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
78 def _iter_loaders(self, template):
79 loader = self.app.jinja_loader
80 if loader is not None:
bafc139 @mitsuhiko Added EXPLAIN_TEMPLATE_LOADING to help people debug templates not bei…
authored
81 yield self.app, loader
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
82
c09a431 @mitsuhiko Record blueprint registration order.
authored
83 for blueprint in self.app.iter_blueprints():
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
84 loader = blueprint.jinja_loader
85 if loader is not None:
bafc139 @mitsuhiko Added EXPLAIN_TEMPLATE_LOADING to help people debug templates not bei…
authored
86 yield blueprint, loader
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
87
88 def list_templates(self):
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
89 result = set()
90 loader = self.app.jinja_loader
91 if loader is not None:
92 result.update(loader.list_templates())
a06cd0a @mitsuhiko Started work on implementing blueprint based template loading
authored
93
c09a431 @mitsuhiko Record blueprint registration order.
authored
94 for blueprint in self.app.iter_blueprints():
abe1378 @mitsuhiko Chnaged a bunch of behavior in blueprints for it to be more flexible.…
authored
95 loader = blueprint.jinja_loader
96 if loader is not None:
97 for template in loader.list_templates():
817b72d @mitsuhiko Removed deprecated module functionality
authored
98 result.add(template)
a06cd0a @mitsuhiko Started work on implementing blueprint based template loading
authored
99
100 return list(result)
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
101
102
e0712b4 @mitsuhiko Added support for signals
authored
103 def _render(template, context, app):
104 """Renders the template and fires the signal"""
105 rv = template.render(context)
106 template_rendered.send(app, template=template, context=context)
107 return rv
108
109
0b33693 @dmishe Allow loading template from iterable
dmishe authored
110 def render_template(template_name_or_list, **context):
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
111 """Renders a template from the template folder with the given
112 context.
113
0b33693 @dmishe Allow loading template from iterable
dmishe authored
114 :param template_name_or_list: the name of the template to be
115 rendered, or an iterable with template names
116 the first one existing will be rendered
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
117 :param context: the variables that should be available in the
118 context of the template.
119 """
f34c028 @mitsuhiko Added template tests and made config a true global
authored
120 ctx = _app_ctx_stack.top
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
121 ctx.app.update_template_context(context)
0b33693 @dmishe Allow loading template from iterable
dmishe authored
122 return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
e0712b4 @mitsuhiko Added support for signals
authored
123 context, ctx.app)
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
124
125
126 def render_template_string(source, **context):
127 """Renders a template from the given template source string
128 with the given context.
129
3159c86 @s3rvac Unify the uses of "sourcecode" vs "source code".
s3rvac authored
130 :param source: the source code of the template to be
9ecbd20 @ralphbean Update flask/templating.py
ralphbean authored
131 rendered
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
132 :param context: the variables that should be available in the
133 context of the template.
134 """
f34c028 @mitsuhiko Added template tests and made config a true global
authored
135 ctx = _app_ctx_stack.top
a3c9494 @mitsuhiko Moved templating stuff into a separate module
authored
136 ctx.app.update_template_context(context)
e0712b4 @mitsuhiko Added support for signals
authored
137 return _render(ctx.app.jinja_env.from_string(source),
138 context, ctx.app)
Something went wrong with that request. Please try again.