blob: 1db02928099c55af2ebafe6dd73e6d5309a99782 [file] [log] [blame]
Andreas Wundsamc94e08c2013-11-15 13:37:59 -08001# Copyright 2013, Big Switch Networks, Inc.
2#
3# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4# the following special exception:
5#
6# LOXI Exception
7#
8# As a special exception to the terms of the EPL, you may distribute libraries
9# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10# that copyright and licensing notices generated by LoxiGen are not altered or removed
11# from the LoxiGen Libraries and the notice provided below is (i) included in
12# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13# documentation for the LoxiGen Libraries, if distributed in binary form.
14#
15# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16#
17# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18# a copy of the EPL at:
19#
20# http://www.eclipse.org/legal/epl-v10.html
21#
22# Unless required by applicable law or agreed to in writing, software
23# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25# EPL for the specific language governing permissions and limitations
26# under the EPL.
27
28import os
29import sys
30
31import tenjin
32
33""" @brief utilities for rendering templates
34"""
35
36def render_template(out, name, path, context, prefix = None):
37 """
38 Render a template using tenjin.
39 out: a file-like object
40 name: name of the template
41 path: array of directories to search for the template
42 context: dictionary of variables to pass to the template
43 prefix: optional prefix to use for embedding (for other languages than python)
44 """
45 pp = [ tenjin.PrefixedLinePreprocessor(prefix=prefix) if prefix else tenjin.PrefixedLinePreprocessor() ] # support "::" syntax
46 template_globals = { "to_str": str, "escape": str } # disable HTML escaping
47 engine = TemplateEngine(path=path, pp=pp)
48 out.write(engine.render(name, context, template_globals))
49
50def render_static(out, name, path):
51 """
52 Write out a static template.
53 out: a file-like object
54 name: name of the template
55 path: array of directories to search for the template
56 """
57 # Reuse the tenjin logic for finding the template
58 template_filename = tenjin.FileSystemLoader().find(name, path)
59 if not template_filename:
60 raise ValueError("template %s not found" % name)
61 with open(template_filename) as infile:
62 out.write(infile.read())
63
64class TemplateEngine(tenjin.Engine):
65 def include(self, template_name, **kwargs):
66 """
67 Tenjin has an issue with nested includes that use the same local variable
68 names, because it uses the same context dict for each level of nesting.
69 The fix is to copy the context.
70 """
71 frame = sys._getframe(1)
72 locals = frame.f_locals
73 globals = frame.f_globals
74 context = locals["_context"].copy()
75 context.update(kwargs)
76 template = self.get_template(template_name, context, globals)
77 return template.render(context, globals, _buf=locals["_buf"])
78
79def open_output(install_dir, name):
80 """
81 Open an output file for writing
82
83 'name' may include slashes. Subdirectories will be automatically created.
84 """
85 print "Writing %s" % name
86 path = os.path.join(install_dir, name)
87 dirpath = os.path.dirname(path)
88 if not os.path.exists(dirpath):
89 os.makedirs(dirpath)
90 return open(path, "w")