Commit 4b16ad80 authored by Marco Mariani's avatar Marco Mariani

jinja2: support custom delimiters

parent 24bb21d9
...@@ -58,6 +58,66 @@ And the template has been rendered:: ...@@ -58,6 +58,66 @@ And the template has been rendered::
parameters from section: [('bar', 'bar'), ('foo', '1')] parameters from section: [('bar', 'bar'), ('foo', '1')]
Rendered with slapos.recipe.template:jinja2 Rendered with slapos.recipe.template:jinja2
Custom environment
------------------
We might want to embed jinja inline templates inside jinja template files.
To this purpose, we can use two sets of delimiters, by defining our owns
instead of the default ones - {% %} {{ }} {# and #}.
Other options for controlling whitespace handling are supported as well, see
http://jinja.pocoo.org/docs/dev/api/
>>> write('buildout.cfg',
... '''
... [buildout]
... parts = template
...
... [template]
... recipe = slapos.recipe.template:jinja2
... template = foo.in
... rendered = foo
... block-start-string = [%
... block-end-string = %]
... variable-start-string = [[
... variable-end-string = ]]
... comment-start-string = /*
... comment-end-string = */
... line-statement-prefix = @@
... line-comment-prefix = //
... lstrip-blocks = True
... trim-blocks = True
... context =
... raw knight Ni!
... ''')
The template can now use [ instead of {
>>> write('foo.in',
... 'Knights who say "[[knight]]"\n'
... 'Say it again: /* embedded comment */\n'
... ' [% for i in range(5) -%][[knight]] [% endfor -%]\n'
... '// full line comment\n'
... '@@ for i in range(3)\n'
... '[[knight]]\n'
... '@@ endfor\n'
... )
We run buildout::
>>> print system(join('bin', 'buildout')),
Uninstalling template.
Installing template.
And the template has been rendered::
>>> cat('foo')
Knights who say "Ni!"
Say it again: Ni! Ni! Ni! Ni! Ni!
Ni!
Ni!
Ni!
Parameters Parameters
---------- ----------
......
...@@ -186,6 +186,37 @@ class Recipe(object): ...@@ -186,6 +186,37 @@ class Recipe(object):
if umask_value: if umask_value:
self.umask = int(umask_value, 8) self.umask = int(umask_value, 8)
self.extra_environment = dict((key, value)
for key, value in self.iter_extra_environment(options))
def iter_extra_environment(self, options):
for is_boolean, okey in [
(0, 'block-start-string'),
(0, 'block-end-string'),
(0, 'variable-start-string'),
(0, 'variable-end-string'),
(0, 'comment-start-string'),
(0, 'comment-end-string'),
(0, 'line-statement-prefix'),
(0, 'line-comment-prefix'),
(1, 'trim-blocks'),
(1, 'lstrip-blocks')]:
jkey = okey.replace('-', '_')
if jkey in options:
raise ValueError('Invalid Jinja2 environment key %s: use %s' % (jkey, okey))
if okey in options:
if is_boolean:
if options[okey].strip().lower() == 'true':
yield jkey, True
elif options[okey].strip().lower() == 'false':
yield jkey, False
else:
raise ValueError('Invalid value for boolean key %s, should be True or False' % okey)
else:
yield jkey, options[okey]
def install(self): def install(self):
# Unlink any existing file, so umask is always applied. # Unlink any existing file, so umask is always applied.
try: try:
...@@ -197,6 +228,7 @@ class Recipe(object): ...@@ -197,6 +228,7 @@ class Recipe(object):
outdir = os.path.dirname(self.rendered) outdir = os.path.dirname(self.rendered)
if outdir and not os.path.exists(outdir): if outdir and not os.path.exists(outdir):
os.makedirs(outdir) os.makedirs(outdir)
# XXX: open doesn't allow providing a filesystem mode, so use # XXX: open doesn't allow providing a filesystem mode, so use
# os.open and os.fdopen instead. # os.open and os.fdopen instead.
with os.fdopen(os.open(self.rendered, with os.fdopen(os.open(self.rendered,
...@@ -207,6 +239,7 @@ class Recipe(object): ...@@ -207,6 +239,7 @@ class Recipe(object):
extensions=self.extension_list, extensions=self.extension_list,
undefined=StrictUndefined, undefined=StrictUndefined,
loader=self.loader, loader=self.loader,
**self.extra_environment
).from_string( ).from_string(
self.get_template(), self.get_template(),
).render( ).render(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment