-
Notifications
You must be signed in to change notification settings - Fork 130
/
template_utils.py
90 lines (82 loc) · 3.46 KB
/
template_utils.py
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
# Copyright 2013, Big Switch Networks, Inc.
#
# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
# the following special exception:
#
# LOXI Exception
#
# As a special exception to the terms of the EPL, you may distribute libraries
# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
# that copyright and licensing notices generated by LoxiGen are not altered or removed
# from the LoxiGen Libraries and the notice provided below is (i) included in
# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
# documentation for the LoxiGen Libraries, if distributed in binary form.
#
# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
#
# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
# a copy of the EPL at:
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# EPL for the specific language governing permissions and limitations
# under the EPL.
import os
import sys
import tenjin
""" @brief utilities for rendering templates
"""
def render_template(out, name, path, context, prefix = None):
"""
Render a template using tenjin.
out: a file-like object
name: name of the template
path: array of directories to search for the template
context: dictionary of variables to pass to the template
prefix: optional prefix to use for embedding (for other languages than python)
"""
pp = [ tenjin.PrefixedLinePreprocessor(prefix=prefix) if prefix else tenjin.PrefixedLinePreprocessor() ] # support "::" syntax
template_globals = { "to_str": str, "escape": str } # disable HTML escaping
engine = TemplateEngine(path=path, pp=pp)
out.write(engine.render(name, context, template_globals))
def render_static(out, name, path):
"""
Write out a static template.
out: a file-like object
name: name of the template
path: array of directories to search for the template
"""
# Reuse the tenjin logic for finding the template
template_filename = tenjin.FileSystemLoader().find(name, path)
if not template_filename:
raise ValueError("template %s not found" % name)
with open(template_filename) as infile:
out.write(infile.read())
class TemplateEngine(tenjin.Engine):
def include(self, template_name, **kwargs):
"""
Tenjin has an issue with nested includes that use the same local variable
names, because it uses the same context dict for each level of nesting.
The fix is to copy the context.
"""
frame = sys._getframe(1)
locals = frame.f_locals
globals = frame.f_globals
context = locals["_context"].copy()
context.update(kwargs)
template = self.get_template(template_name, context, globals)
return template.render(context, globals, _buf=locals["_buf"])
def open_output(install_dir, name):
"""
Open an output file for writing
'name' may include slashes. Subdirectories will be automatically created.
"""
print(("Writing %s to %s" % (name, install_dir)))
path = os.path.join(install_dir, name)
dirpath = os.path.dirname(path)
if not os.path.exists(dirpath):
os.makedirs(dirpath)
return open(path, "w")