to modify this dict. For more details see :ref:`global-namespace`.
For valid object names have a look at :ref:`identifier-naming`.
+ .. attribute:: code_generator_class
+
+ The class used for code generation. This should not be changed
+ in most cases, unless you need to modify the Python code a
+ template compiles to.
+
.. automethod:: overlay([options])
.. method:: undefined([hint, obj, name, exc])
"""Generate the python source for a node tree."""
if not isinstance(node, nodes.Template):
raise TypeError('Can\'t compile non template nodes')
- generator = CodeGenerator(environment, name, filename, stream, defer_init)
+ generator = environment.code_generator_class(environment, name, filename,
+ stream, defer_init)
generator.visit(node)
if stream is None:
return generator.stream.getvalue()
from jinja2.parser import Parser
from jinja2.nodes import EvalContext
from jinja2.optimizer import optimize
-from jinja2.compiler import generate
+from jinja2.compiler import generate, CodeGenerator
from jinja2.runtime import Undefined, new_context
from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \
TemplatesNotFound, TemplateRuntimeError
exception_handler = None
exception_formatter = None
+ #: the class that is used for code generation. See
+ #: :class:`~jinja2.compiler.CodeGenerator` for more information.
+ code_generator_class = CodeGenerator
+
def __init__(self,
block_start_string=BLOCK_START_STRING,
block_end_string=BLOCK_END_STRING,
from jinja2 import Environment, Undefined, DebugUndefined, \
StrictUndefined, UndefinedError, meta, \
is_undefined, Template, DictLoader, make_logging_undefined
+from jinja2.compiler import CodeGenerator
from jinja2.utils import Cycler
assert e.message == "'int object' has no attribute 'upper'"
else:
assert False, 'expected exception'
+
+
+@pytest.mark.api
+@pytest.mark.lowlevel
+class TestLowLevel():
+
+ def test_custom_code_generator(self):
+ class CustomCodeGenerator(CodeGenerator):
+ def visit_Const(self, node, frame=None):
+ # This method is pure nonsense, but works fine for testing...
+ if node.value == 'foo':
+ self.write(repr('bar'))
+ else:
+ super(CustomCodeGenerator, self).visit_Const(node, frame)
+
+ class CustomEnvironment(Environment):
+ code_generator_class = CustomCodeGenerator
+
+ env = CustomEnvironment()
+ tmpl = env.from_string('{% set foo = "foo" %}{{ foo }}')
+ assert tmpl.render() == 'bar'