root/galaxy-central/eggs/Mako-0.2.5-py2.6.egg/mako/template.py @ 3

リビジョン 3, 12.0 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# template.py
2# Copyright (C) 2006, 2007, 2008, 2009 Michael Bayer mike_mp@zzzcomputing.com
3#
4# This module is part of Mako and is released under
5# the MIT License: http://www.opensource.org/licenses/mit-license.php
6
7"""provides the Template class, a facade for parsing, generating and executing template strings,
8as well as template runtime operations."""
9
10from mako.lexer import Lexer
11from mako import codegen
12from mako import runtime, util, exceptions
13import imp, os, re, shutil, stat, sys, tempfile, time, types, weakref
14
15   
16class Template(object):
17    """a compiled template"""
18    def __init__(self, text=None, filename=None, uri=None, format_exceptions=False, error_handler=None,
19        lookup=None, output_encoding=None, encoding_errors='strict', module_directory=None, cache_type=None,
20        cache_dir=None, cache_url=None, module_filename=None, input_encoding=None, disable_unicode=False, default_filters=None,
21        buffer_filters=[], imports=None, preprocessor=None, cache_enabled=True):
22        """construct a new Template instance using either literal template text, or a previously loaded template module
23       
24        text - textual template source, or None if a module is to be provided
25       
26        uri - the uri of this template, or some identifying string. defaults to the
27        full filename given, or "memory:(hex id of this Template)" if no filename
28       
29        filename - filename of the source template, if any
30       
31        format_exceptions - catch exceptions and format them into an error display template
32        """
33       
34        if uri:
35            self.module_id = re.sub(r'\W', "_", uri)
36            self.uri = uri
37        elif filename:
38            self.module_id = re.sub(r'\W', "_", filename)
39            self.uri = filename
40        else:
41            self.module_id = "memory:" + hex(id(self))
42            self.uri = self.module_id
43       
44        self.input_encoding = input_encoding
45        self.output_encoding = output_encoding
46        self.encoding_errors = encoding_errors
47        self.disable_unicode = disable_unicode
48        if default_filters is None:
49            if self.disable_unicode:
50                self.default_filters = ['str']
51            else:
52                self.default_filters = ['unicode']
53        else:
54            self.default_filters = default_filters
55        self.buffer_filters = buffer_filters
56           
57        self.imports = imports
58        self.preprocessor = preprocessor
59       
60        # if plain text, compile code in memory only
61        if text is not None:
62            (code, module) = _compile_text(self, text, filename)
63            self._code = code
64            self._source = text
65            ModuleInfo(module, None, self, filename, code, text)
66        elif filename is not None:
67            # if template filename and a module directory, load
68            # a filesystem-based module file, generating if needed
69            if module_filename is not None:
70                path = module_filename
71            elif module_directory is not None:
72                u = self.uri
73                if u[0] == '/':
74                    u = u[1:]
75                path = os.path.abspath(os.path.join(module_directory.replace('/', os.path.sep), u + ".py"))
76            else:
77                path = None   
78            if path is not None:
79                util.verify_directory(os.path.dirname(path))
80                filemtime = os.stat(filename)[stat.ST_MTIME]
81                if not os.path.exists(path) or os.stat(path)[stat.ST_MTIME] < filemtime:
82                    _compile_module_file(self, file(filename).read(), filename, path)
83                module = imp.load_source(self.module_id, path, file(path))
84                del sys.modules[self.module_id]
85                if module._magic_number != codegen.MAGIC_NUMBER:
86                    _compile_module_file(self, file(filename).read(), filename, path)
87                    module = imp.load_source(self.module_id, path, file(path))
88                    del sys.modules[self.module_id]
89                ModuleInfo(module, path, self, filename, None, None)
90            else:
91                # template filename and no module directory, compile code
92                # in memory
93                (code, module) = _compile_text(self, file(filename).read(), filename)
94                self._source = None
95                self._code = code
96                ModuleInfo(module, None, self, filename, code, None)
97        else:
98            raise exceptions.RuntimeException("Template requires text or filename")
99
100        self.module = module
101        self.filename = filename
102        self.callable_ = self.module.render_body
103        self.format_exceptions = format_exceptions
104        self.error_handler = error_handler
105        self.lookup = lookup
106        self.cache_type = cache_type
107        self.cache_dir = cache_dir
108        self.cache_url = cache_url
109        self.cache_enabled = cache_enabled
110
111    def source(self):
112        """return the template source code for this Template."""
113        return _get_module_info_from_callable(self.callable_).source
114    source = property(source)
115   
116    def code(self):
117        """return the module source code for this Template"""
118        return _get_module_info_from_callable(self.callable_).code
119    code = property(code)
120   
121    def cache(self):
122        return self.module._template_cache
123    cache = property(cache)
124   
125    def render(self, *args, **data):
126        """render the output of this template as a string.
127       
128        if the template specifies an output encoding, the string will be encoded accordingly, else the output
129        is raw (raw output uses cStringIO and can't handle multibyte characters).
130        a Context object is created corresponding to the given data.  Arguments that are explictly
131        declared by this template's internal rendering method are also pulled from the given *args, **data
132        members."""
133        return runtime._render(self, self.callable_, args, data)
134   
135    def render_unicode(self, *args, **data):
136        """render the output of this template as a unicode object."""
137       
138        return runtime._render(self, self.callable_, args, data, as_unicode=True)
139       
140    def render_context(self, context, *args, **kwargs):
141        """render this Template with the given context. 
142       
143        the data is written to the context's buffer."""
144        if getattr(context, '_with_template', None) is None:
145            context._with_template = self
146        runtime._render_context(self, self.callable_, context, *args, **kwargs)
147   
148    def has_def(self, name):
149        return hasattr(self.module, "render_%s" % name)
150       
151    def get_def(self, name):
152        """return a def of this template as an individual Template of its own."""
153        return DefTemplate(self, getattr(self.module, "render_%s" % name))
154
155    def _get_def_callable(self, name):
156        return getattr(self.module, "render_%s" % name)
157   
158    def last_modified(self):
159        return self.module._modified_time   
160    last_modified = property(last_modified)
161   
162class ModuleTemplate(Template):
163    """A Template which is constructed given an existing Python module.
164   
165        e.g.::
166       
167        t = Template("this is a template")
168        f = file("mymodule.py", "w")
169        f.write(t.code)
170        f.close()
171       
172        import mymodule
173       
174        t = ModuleTemplate(mymodule)
175        print t.render()
176   
177    """
178   
179    def __init__(self, module,
180        module_filename=None,
181        template=None, template_filename=None,
182        module_source=None, template_source=None,
183        output_encoding=None, encoding_errors='strict', disable_unicode=False, format_exceptions=False,
184        error_handler=None, lookup=None, cache_type=None, cache_dir=None, cache_url=None, cache_enabled=True
185    ):
186        self.module_id = re.sub(r'\W', "_", module._template_uri)
187        self.uri = module._template_uri
188        self.input_encoding = module._source_encoding
189        self.output_encoding = output_encoding
190        self.encoding_errors = encoding_errors
191        self.disable_unicode = disable_unicode
192        self.module = module
193        self.filename = template_filename
194        ModuleInfo(module, module_filename, self, template_filename, module_source, template_source)
195       
196        self.callable_ = self.module.render_body
197        self.format_exceptions = format_exceptions
198        self.error_handler = error_handler
199        self.lookup = lookup
200        self.cache_type = cache_type
201        self.cache_dir = cache_dir
202        self.cache_url = cache_url
203        self.cache_enabled = cache_enabled
204       
205class DefTemplate(Template):
206    """a Template which represents a callable def in a parent template."""
207    def __init__(self, parent, callable_):
208        self.parent = parent
209        self.callable_ = callable_
210        self.output_encoding = parent.output_encoding
211        self.module = parent.module
212        self.encoding_errors = parent.encoding_errors
213        self.format_exceptions = parent.format_exceptions
214        self.error_handler = parent.error_handler
215        self.lookup = parent.lookup
216
217    def get_def(self, name):
218        return self.parent.get_def(name)
219
220class ModuleInfo(object):
221    """stores information about a module currently loaded into memory,
222    provides reverse lookups of template source, module source code based on
223    a module's identifier."""
224    _modules = weakref.WeakValueDictionary()
225
226    def __init__(self, module, module_filename, template, template_filename, module_source, template_source):
227        self.module = module
228        self.module_filename = module_filename
229        self.template_filename = template_filename
230        self.module_source = module_source
231        self.template_source = template_source
232        self._modules[module.__name__] = template._mmarker = self
233        if module_filename:
234            self._modules[module_filename] = self
235    def _get_code(self):
236        if self.module_source is not None:
237            return self.module_source
238        else:
239            return file(self.module_filename).read()
240    code = property(_get_code)
241    def _get_source(self):
242        if self.template_source is not None:
243            if self.module._source_encoding and not isinstance(self.template_source, unicode):
244                return self.template_source.decode(self.module._source_encoding)
245            else:
246                return self.template_source
247        else:
248            if self.module._source_encoding:
249                return file(self.template_filename).read().decode(self.module._source_encoding)
250            else:
251                return file(self.template_filename).read()
252    source = property(_get_source)
253       
254def _compile_text(template, text, filename):
255    identifier = template.module_id
256    lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor)
257    node = lexer.parse()
258    source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_unicode=not template.disable_unicode)
259    #print source
260    cid = identifier
261    if isinstance(cid, unicode):
262        cid = cid.encode()
263    module = types.ModuleType(cid)
264    code = compile(source, cid, 'exec')
265    exec code in module.__dict__, module.__dict__
266    return (source, module)
267
268def _compile_module_file(template, text, filename, outputpath):
269    identifier = template.module_id
270    lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor)
271    node = lexer.parse()
272    source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_unicode=not template.disable_unicode)
273    (dest, name) = tempfile.mkstemp()
274    os.write(dest, source)
275    os.close(dest)
276    shutil.move(name, outputpath)
277
278def _get_module_info_from_callable(callable_):
279    return _get_module_info(callable_.func_globals['__name__'])
280   
281def _get_module_info(filename):
282    return ModuleInfo._modules[filename]
283       
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。