1 # -*- coding: utf-8 -*-
6 Provides a class that holds runtime and parsing time options.
8 :copyright: 2007 by Armin Ronacher.
9 :license: BSD, see LICENSE for more details.
11 from jinja2.lexer import Lexer
12 from jinja2.parser import Parser
13 from jinja2.optimizer import optimize
14 from jinja2.compiler import generate
15 from jinja2.defaults import DEFAULT_FILTERS, DEFAULT_TESTS, DEFAULT_NAMESPACE
18 class Environment(object):
19 """The Jinja environment.
21 The core component of Jinja is the `Environment`. It contains
22 important shared variables like configuration, filters, tests,
27 block_start_string='{%',
28 block_end_string='%}',
29 variable_start_string='{{',
30 variable_end_string='}}',
31 comment_start_string='{#',
32 comment_end_string='#}',
34 template_charset='utf-8',
36 """Here the possible initialization parameters:
38 ========================= ============================================
39 `block_start_string` the string marking the begin of a block.
40 this defaults to ``'{%'``.
41 `block_end_string` the string marking the end of a block.
43 `variable_start_string` the string marking the begin of a print
44 statement. defaults to ``'{{'``.
45 `comment_start_string` the string marking the begin of a
46 comment. defaults to ``'{#'``.
47 `comment_end_string` the string marking the end of a comment.
49 `trim_blocks` If this is set to ``True`` the first newline
50 after a block is removed (block, not
51 variable tag!). Defaults to ``False``.
52 `template_charset` the charset of the templates.
53 `loader` the loader which should be used.
54 ========================= ============================================
57 # lexer / parser information
58 self.block_start_string = block_start_string
59 self.block_end_string = block_end_string
60 self.variable_start_string = variable_start_string
61 self.variable_end_string = variable_end_string
62 self.comment_start_string = comment_start_string
63 self.comment_end_string = comment_end_string
64 self.trim_blocks = trim_blocks
65 self.template_charset = template_charset
68 self.filters = DEFAULT_FILTERS.copy()
69 self.tests = DEFAULT_TESTS.copy()
70 self.globals = DEFAULT_NAMESPACE.copy()
72 # if no finalize function/method exists we default to unicode. The
73 # compiler check if the finalize attribute *is* unicode, if yes no
74 # finalizaion is written where it can be avoided.
75 if not hasattr(self, 'finalize'):
76 self.finalize = unicode
78 # set the loader provided
82 self.lexer = Lexer(self)
84 def parse(self, source, filename=None):
85 """Parse the sourcecode and return the abstract syntax tree. This tree
86 of nodes is used by the compiler to convert the template into
87 executable source- or bytecode.
89 parser = Parser(self, source, filename)
92 def lex(self, source, filename=None):
93 """Lex the given sourcecode and return a generator that yields tokens.
94 The stream returned is not usable for Jinja but can be used if
95 Jinja templates should be processed by other tools (for example
96 syntax highlighting etc)
98 The tuples are returned in the form ``(lineno, token, value)``.
100 return self.lexer.tokeniter(source, filename)
102 def compile(self, source, filename=None, raw=False):
103 """Compile a node or source."""
104 if isinstance(source, basestring):
105 source = self.parse(source, filename)
106 node = optimize(source, self)
107 source = generate(node, self, filename)
111 if isinstance(filename, unicode):
112 filename = filename.encode('utf-8')
113 return compile(source, filename, 'exec')
115 def join_path(self, template, parent):
116 """Join a template with the parent. By default all the lookups are
117 relative to the loader root, but if the paths should be relative this
118 function can be used to calculate the real filename."""
121 def get_template(self, name, parent=None):
122 """Load a template."""
123 if self.loader is None:
124 raise TypeError('no loader for this environment specified')
125 if parent is not None:
126 name = self.join_path(name, parent)
127 return self.loader.load(self, name)
129 def from_string(self, source, filename='<string>'):
130 """Load a template from a string."""
131 return Template(self, self.compile(source, filename))
134 class Template(object):
135 """Represents a template."""
137 def __init__(self, environment, code):
138 namespace = {'environment': environment}
139 exec code in namespace
140 self.environment = environment
141 self.root_render_func = namespace['root']
142 self.blocks = namespace['blocks']
144 def render(self, *args, **kwargs):
145 return u''.join(self.stream(*args, **kwargs))
147 def stream(self, *args, **kwargs):
148 context = dict(*args, **kwargs)
149 return self.root_render_func(context)