annotate genshi/template/loader.py @ 647:5af131b37ab4 experimental-sandboxed

restricted is the new secure
author aronacher
date Wed, 26 Sep 2007 17:56:41 +0000
parents e5363d3c22d3
children c7dcd4dc240d
rev   line source
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
2 #
408
49a3bae5a8bb Update copyright year for files modified this year.
cmlenz
parents: 400
diff changeset
3 # Copyright (C) 2006-2007 Edgewall Software
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
4 # All rights reserved.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
5 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
9 #
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
13
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
14 """Template loading and caching."""
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
15
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
16 import os
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
17 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
18 import threading
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
19 except ImportError:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
20 import dummy_threading as threading
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
21
400
8dd0d34a9fb7 Renamed `genshi.template.core` to `genshi.template.base`, mainly to avoid confusion with `genshi.core`.
cmlenz
parents: 363
diff changeset
22 from genshi.template.base import TemplateError
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
23 from genshi.util import LRUCache
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
24
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
25 __all__ = ['TemplateLoader', 'TemplateNotFound']
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
26 __docformat__ = 'restructuredtext en'
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
27
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
28
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
29 class TemplateNotFound(TemplateError):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
30 """Exception raised when a specific template file could not be found."""
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
31
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
32 def __init__(self, name, search_path):
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
33 """Create the exception.
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
34
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
35 :param name: the filename of the template
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
36 :param search_path: the search path used to lookup the template
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
37 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
38 TemplateError.__init__(self, 'Template "%s" not found' % name)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
39 self.search_path = search_path
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
40
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
41
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
42 class TemplateLoader(object):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
43 """Responsible for loading templates from files on the specified search
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
44 path.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
45
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
46 >>> import tempfile
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
47 >>> fd, path = tempfile.mkstemp(suffix='.html', prefix='template')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
48 >>> os.write(fd, '<p>$var</p>')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
49 11
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
50 >>> os.close(fd)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
51
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
52 The template loader accepts a list of directory paths that are then used
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
53 when searching for template files, in the given order:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
54
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
55 >>> loader = TemplateLoader([os.path.dirname(path)])
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
56
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
57 The `load()` method first checks the template cache whether the requested
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
58 template has already been loaded. If not, it attempts to locate the
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
59 template file, and returns the corresponding `Template` object:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
60
363
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
61 >>> from genshi.template import MarkupTemplate
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
62 >>> template = loader.load(os.path.basename(path))
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
63 >>> isinstance(template, MarkupTemplate)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
64 True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
65
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
66 Template instances are cached: requesting a template with the same name
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
67 results in the same instance being returned:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
68
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
69 >>> loader.load(os.path.basename(path)) is template
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
70 True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
71
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
72 The `auto_reload` option can be used to control whether a template should
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
73 be automatically reloaded when the file it was loaded from has been
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
74 changed. Disable this automatic reloading to improve performance.
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
75
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
76 >>> os.remove(path)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
77 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
78 def __init__(self, search_path=None, auto_reload=False,
439
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
79 default_encoding=None, max_cache_size=25, default_class=None,
643
e5363d3c22d3 some more work on the sandbox
aronacher
parents: 606
diff changeset
80 variable_lookup='strict', allow_exec=True,
647
5af131b37ab4 restricted is the new secure
aronacher
parents: 643
diff changeset
81 restricted=False, callback=None):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
82 """Create the template laoder.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
83
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
84 :param search_path: a list of absolute path names that should be
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
85 searched for template files, or a string containing
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
86 a single absolute path
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
87 :param auto_reload: whether to check the last modification time of
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
88 template files, and reload them if they have changed
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
89 :param default_encoding: the default encoding to assume when loading
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
90 templates; defaults to UTF-8
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
91 :param max_cache_size: the maximum number of templates to keep in the
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
92 cache
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
93 :param default_class: the default `Template` subclass to use when
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
94 instantiating templates
606
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 590
diff changeset
95 :param variable_lookup: the variable lookup mechanism; either "strict"
9ada030ad986 Changed the default error handling mode to "strict".
cmlenz
parents: 590
diff changeset
96 (the default), "lenient", or a custom lookup
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 439
diff changeset
97 class
545
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
98 :param allow_exec: whether to allow Python code blocks in templates
647
5af131b37ab4 restricted is the new secure
aronacher
parents: 643
diff changeset
99 :param restricted: use restricted template evaluation
439
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
100 :param callback: (optional) a callback function that is invoked after a
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
101 template was initialized by this loader; the function
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
102 is passed the template object as only argument. This
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
103 callback can be used for example to add any desired
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
104 filters to the template
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 439
diff changeset
105 :see: `LenientLookup`, `StrictLookup`
545
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
106
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
107 :note: Changed in 0.5: Added the `allow_exec` argument
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
108 """
363
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
109 from genshi.template.markup import MarkupTemplate
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
110
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
111 self.search_path = search_path
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
112 if self.search_path is None:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
113 self.search_path = []
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
114 elif isinstance(self.search_path, basestring):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
115 self.search_path = [self.search_path]
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
116
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
117 self.auto_reload = auto_reload
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
118 """Whether templates should be reloaded when the underlying file is
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
119 changed"""
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
120
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
121 self.default_encoding = default_encoding
363
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
122 self.default_class = default_class or MarkupTemplate
442
ff7c72b52fb2 Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 439
diff changeset
123 self.variable_lookup = variable_lookup
545
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
124 self.allow_exec = allow_exec
647
5af131b37ab4 restricted is the new secure
aronacher
parents: 643
diff changeset
125 self.restricted = restricted
439
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
126 if callback is not None and not callable(callback):
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
127 raise TypeError('The "callback" parameter needs to be callable')
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
128 self.callback = callback
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
129 self._cache = LRUCache(max_cache_size)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
130 self._mtime = {}
548
c2e039c7e439 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
131 self._lock = threading.RLock()
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
132
363
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
133 def load(self, filename, relative_to=None, cls=None, encoding=None):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
134 """Load the template with the given name.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
135
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
136 If the `filename` parameter is relative, this method searches the search
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
137 path trying to locate a template matching the given name. If the file
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
138 name is an absolute path, the search path is ignored.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
139
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
140 If the requested template is not found, a `TemplateNotFound` exception
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
141 is raised. Otherwise, a `Template` object is returned that represents
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
142 the parsed template.
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
143
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
144 Template instances are cached to avoid having to parse the same
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
145 template file more than once. Thus, subsequent calls of this method
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
146 with the same template file name will return the same `Template`
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
147 object (unless the ``auto_reload`` option is enabled and the file was
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
148 changed since the last parse.)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
149
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
150 If the `relative_to` parameter is provided, the `filename` is
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
151 interpreted as being relative to that path.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
152
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
153 :param filename: the relative path of the template file to load
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
154 :param relative_to: the filename of the template from which the new
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
155 template is being loaded, or ``None`` if the
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
156 template is being loaded directly
425
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
157 :param cls: the class of the template object to instantiate
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
158 :param encoding: the encoding of the template to load; defaults to the
5b248708bbed Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
159 ``default_encoding`` of the loader instance
435
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
160 :return: the loaded `Template` instance
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
161 :raises TemplateNotFound: if a template with the given name could not be
7800a61eae43 More API doc enhancements.
cmlenz
parents: 425
diff changeset
162 found
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
163 """
363
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
164 if cls is None:
caf7b68ab5dc Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
165 cls = self.default_class
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
166 if encoding is None:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
167 encoding = self.default_encoding
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
168 if relative_to and not os.path.isabs(relative_to):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
169 filename = os.path.join(os.path.dirname(relative_to), filename)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
170 filename = os.path.normpath(filename)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
171
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
172 self._lock.acquire()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
173 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
174 # First check the cache to avoid reparsing the same file
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
175 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
176 tmpl = self._cache[filename]
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
177 if not self.auto_reload or \
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
178 os.path.getmtime(tmpl.filepath) == self._mtime[filename]:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
179 return tmpl
590
880b1a75d046 Fix includes so that they again raise an exception when the included template is not found and no fallback has been provided.
cmlenz
parents: 548
diff changeset
180 except KeyError, OSError:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
181 pass
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
182
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
183 search_path = self.search_path
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
184 isabs = False
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
185
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
186 if os.path.isabs(filename):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
187 # Bypass the search path if the requested filename is absolute
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
188 search_path = [os.path.dirname(filename)]
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
189 isabs = True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
190
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
191 elif relative_to and os.path.isabs(relative_to):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
192 # Make sure that the directory containing the including
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
193 # template is on the search path
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
194 dirname = os.path.dirname(relative_to)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
195 if dirname not in search_path:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
196 search_path = search_path + [dirname]
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
197 isabs = True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
198
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
199 elif not search_path:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
200 # Uh oh, don't know where to look for the template
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
201 raise TemplateError('Search path for templates not configured')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
202
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
203 for dirname in search_path:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
204 filepath = os.path.join(dirname, filename)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
205 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
206 fileobj = open(filepath, 'U')
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
207 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
208 if isabs:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
209 # If the filename of either the included or the
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
210 # including template is absolute, make sure the
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
211 # included template gets an absolute path, too,
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
212 # so that nested include work properly without a
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
213 # search path
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
214 filename = os.path.join(dirname, filename)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
215 dirname = ''
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
216 tmpl = cls(fileobj, basedir=dirname, filename=filename,
545
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
217 loader=self, encoding=encoding,
6e21c89d9255 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
218 lookup=self.variable_lookup,
643
e5363d3c22d3 some more work on the sandbox
aronacher
parents: 606
diff changeset
219 allow_exec=self.allow_exec,
647
5af131b37ab4 restricted is the new secure
aronacher
parents: 643
diff changeset
220 restricted=self.restricted)
439
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
221 if self.callback:
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
222 self.callback(tmpl)
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
223 self._cache[filename] = tmpl
b84c11a49ad2 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
224 self._mtime[filename] = os.path.getmtime(filepath)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
225 finally:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
226 fileobj.close()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
227 return tmpl
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
228 except IOError:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
229 continue
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
230
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
231 raise TemplateNotFound(filename, search_path)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
232
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
233 finally:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
234 self._lock.release()
Copyright (C) 2012-2017 Edgewall Software