annotate genshi/template/loader.py @ 902:09cc3627654c experimental-inline

Sync `experimental/inline` branch with [source:trunk@1126].
author cmlenz
date Fri, 23 Apr 2010 21:08:26 +0000
parents de82830f8816
children
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 #
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
3 # Copyright (C) 2006-2010 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
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
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
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
25 __all__ = ['TemplateLoader', 'TemplateNotFound', 'directory', 'package',
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
26 'prefixed']
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
27 __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
28
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
29
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
30 class TemplateNotFound(TemplateError):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
31 """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
32
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
33 def __init__(self, name, search_path):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
34 """Create the exception.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
35
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
36 :param name: the filename of the template
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
37 :param search_path: the search path used to lookup the template
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
38 """
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
39 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
40 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
41
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
42
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
43 class TemplateLoader(object):
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
44 """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
45 path.
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
46
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
47 >>> import tempfile
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
48 >>> 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
49 >>> 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
50 11
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
51 >>> os.close(fd)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
52
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
53 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
54 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
55
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
56 >>> 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
57
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
58 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
59 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
60 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
61
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 336
diff changeset
62 >>> 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
63 >>> 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
64 >>> isinstance(template, MarkupTemplate)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
65 True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
66
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
67 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
68 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
69
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
70 >>> 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
71 True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
72
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
73 The `auto_reload` option can be used to control whether a template should
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
74 be automatically reloaded when the file it was loaded from has been
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
75 changed. Disable this automatic reloading to improve performance.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
76
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
77 >>> os.remove(path)
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
78 """
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
79 def __init__(self, search_path=None, auto_reload=False,
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
80 default_encoding=None, max_cache_size=25, default_class=None,
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
81 variable_lookup='strict', allow_exec=True, 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
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
84 :param search_path: a list of absolute path names that should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
85 searched for template files, or a string containing
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
86 a single absolute path; alternatively, any item on
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
87 the list may be a ''load function'' that is passed
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
88 a filename and returns a file-like object and some
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
89 metadata
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
90 :param auto_reload: whether to check the last modification time of
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
91 template files, and reload them if they have changed
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
92 :param default_encoding: the default encoding to assume when loading
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
93 templates; defaults to UTF-8
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
94 :param max_cache_size: the maximum number of templates to keep in the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
95 cache
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
96 :param default_class: the default `Template` subclass to use when
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
97 instantiating templates
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
98 :param variable_lookup: the variable lookup mechanism; either "strict"
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
99 (the default), "lenient", or a custom lookup
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
100 class
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
101 :param allow_exec: whether to allow Python code blocks in templates
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
102 :param callback: (optional) a callback function that is invoked after a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
103 template was initialized by this loader; the function
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
104 is passed the template object as only argument. This
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
105 callback can be used for example to add any desired
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
106 filters to the template
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
107 :see: `LenientLookup`, `StrictLookup`
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
108
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
109 :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
110 """
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 336
diff changeset
111 from genshi.template.markup import MarkupTemplate
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 336
diff changeset
112
336
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 = search_path
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
114 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
115 self.search_path = []
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
116 elif not isinstance(self.search_path, (list, tuple)):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
117 self.search_path = [self.search_path]
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
118
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
119 self.auto_reload = auto_reload
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
120 """Whether templates should be reloaded when the underlying file is
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
121 changed"""
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
122
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
123 self.default_encoding = default_encoding
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 336
diff changeset
124 self.default_class = default_class or MarkupTemplate
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
125 self.variable_lookup = variable_lookup
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
126 self.allow_exec = allow_exec
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
127 if callback is not None and not hasattr(callback, '__call__'):
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
128 raise TypeError('The "callback" parameter needs to be callable')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
129 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
130 self._cache = LRUCache(max_cache_size)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
131 self._uptodate = {}
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
132 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
133
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
134 def __getstate__(self):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
135 state = self.__dict__.copy()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
136 state['_lock'] = None
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
137 return state
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
138
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
139 def __setstate__(self, state):
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
140 self.__dict__ = state
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
141 self._lock = threading.RLock()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
142
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 336
diff changeset
143 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
144 """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
145
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
146 If the `filename` parameter is relative, this method searches the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
147 search path trying to locate a template matching the given name. If the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
148 file 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
149
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
150 If the requested template is not found, a `TemplateNotFound` exception
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
151 is raised. Otherwise, a `Template` object is returned that represents
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
152 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
153
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
154 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
155 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
156 with the same template file name will return the same `Template`
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
157 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
158 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
159
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
160 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
161 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
162
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
163 :param filename: the relative path of the template file to load
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
164 :param relative_to: the filename of the template from which the new
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
165 template is being loaded, or ``None`` if the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
166 template is being loaded directly
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
167 :param cls: the class of the template object to instantiate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
168 :param encoding: the encoding of the template to load; defaults to the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
169 ``default_encoding`` of the loader instance
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
170 :return: the loaded `Template` instance
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
171 :raises TemplateNotFound: if a template with the given name could not
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
172 be found
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
173 """
395
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 336
diff changeset
174 if cls is None:
55cf81951686 inline branch: Merged [439:479/trunk].
cmlenz
parents: 336
diff changeset
175 cls = self.default_class
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
176 search_path = self.search_path
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
177
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
178 # Make the filename relative to the template file its being loaded
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
179 # from, but only if that file is specified as a relative path, or no
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
180 # search path has been set up
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
181 if relative_to and (not search_path or not os.path.isabs(relative_to)):
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
182 filename = os.path.join(os.path.dirname(relative_to), filename)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
183
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
184 filename = os.path.normpath(filename)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
185 cachekey = filename
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
186
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
187 self._lock.acquire()
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
188 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
189 # 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
190 try:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
191 tmpl = self._cache[cachekey]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
192 if not self.auto_reload:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
193 return tmpl
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
194 uptodate = self._uptodate[cachekey]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
195 if uptodate is not None and uptodate():
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
196 return tmpl
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
197 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
198 pass
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
199
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
200 isabs = False
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
201
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
202 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
203 # 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
204 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
205 isabs = True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
206
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
207 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
208 # 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
209 # 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
210 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
211 if dirname not in search_path:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
212 search_path = list(search_path) + [dirname]
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
213 isabs = True
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
214
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
215 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
216 # 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
217 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
218
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
219 for loadfunc in search_path:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
220 if isinstance(loadfunc, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
221 loadfunc = directory(loadfunc)
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
222 try:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
223 filepath, filename, fileobj, uptodate = loadfunc(filename)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
224 except IOError:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
225 continue
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
226 else:
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
227 try:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
228 if isabs:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
229 # 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
230 # 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
231 # included template gets an absolute path, too,
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
232 # so that nested includes work properly without a
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
233 # search path
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
234 filename = filepath
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
235 tmpl = self._instantiate(cls, fileobj, filepath,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
236 filename, encoding=encoding)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
237 if self.callback:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents: 395
diff changeset
238 self.callback(tmpl)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
239 self._cache[cachekey] = tmpl
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
240 self._uptodate[cachekey] = uptodate
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
241 finally:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
242 if hasattr(fileobj, 'close'):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
243 fileobj.close()
336
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
244 return tmpl
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
245
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
246 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
247
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
248 finally:
5f2c7782cd8a Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
249 self._lock.release()
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
250
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
251 def _instantiate(self, cls, fileobj, filepath, filename, encoding=None):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
252 """Instantiate and return the `Template` object based on the given
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
253 class and parameters.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
254
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
255 This function is intended for subclasses to override if they need to
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
256 implement special template instantiation logic. Code that just uses
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
257 the `TemplateLoader` should use the `load` method instead.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
258
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
259 :param cls: the class of the template object to instantiate
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
260 :param fileobj: a readable file-like object containing the template
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
261 source
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
262 :param filepath: the absolute path to the template file
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
263 :param filename: the path to the template file relative to the search
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
264 path
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
265 :param encoding: the encoding of the template to load; defaults to the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
266 ``default_encoding`` of the loader instance
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
267 :return: the loaded `Template` instance
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
268 :rtype: `Template`
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
269 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
270 if encoding is None:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
271 encoding = self.default_encoding
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
272 return cls(fileobj, filepath=filepath, filename=filename, loader=self,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
273 encoding=encoding, lookup=self.variable_lookup,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
274 allow_exec=self.allow_exec)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
275
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 820
diff changeset
276 @staticmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
277 def directory(path):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
278 """Loader factory for loading templates from a local directory.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
279
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
280 :param path: the path to the local directory containing the templates
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
281 :return: the loader function to load templates from the given directory
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
282 :rtype: ``function``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
283 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
284 def _load_from_directory(filename):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
285 filepath = os.path.join(path, filename)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
286 fileobj = open(filepath, 'U')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
287 mtime = os.path.getmtime(filepath)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
288 def _uptodate():
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
289 return mtime == os.path.getmtime(filepath)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
290 return filepath, filename, fileobj, _uptodate
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
291 return _load_from_directory
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
292
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 820
diff changeset
293 @staticmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
294 def package(name, path):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
295 """Loader factory for loading templates from egg package data.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
296
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
297 :param name: the name of the package containing the resources
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
298 :param path: the path inside the package data
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
299 :return: the loader function to load templates from the given package
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
300 :rtype: ``function``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
301 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
302 from pkg_resources import resource_stream
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
303 def _load_from_package(filename):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
304 filepath = os.path.join(path, filename)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
305 return filepath, filename, resource_stream(name, filepath), None
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
306 return _load_from_package
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
307
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 820
diff changeset
308 @staticmethod
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
309 def prefixed(**delegates):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
310 """Factory for a load function that delegates to other loaders
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
311 depending on the prefix of the requested template path.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
312
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
313 The prefix is stripped from the filename when passing on the load
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
314 request to the delegate.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
315
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
316 >>> load = prefixed(
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
317 ... app1 = lambda filename: ('app1', filename, None, None),
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
318 ... app2 = lambda filename: ('app2', filename, None, None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
319 ... )
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
320 >>> print(load('app1/foo.html'))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
321 ('app1', 'app1/foo.html', None, None)
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
322 >>> print(load('app2/bar.html'))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
323 ('app2', 'app2/bar.html', None, None)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
324
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
325 :param delegates: mapping of path prefixes to loader functions
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
326 :return: the loader function
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
327 :rtype: ``function``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
328 """
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
329 def _dispatch_by_prefix(filename):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
330 for prefix, delegate in delegates.items():
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
331 if filename.startswith(prefix):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
332 if isinstance(delegate, basestring):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
333 delegate = directory(delegate)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
334 filepath, _, fileobj, uptodate = delegate(
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
335 filename[len(prefix):].lstrip('/\\')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
336 )
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
337 return filepath, filename, fileobj, uptodate
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 830
diff changeset
338 raise TemplateNotFound(filename, list(delegates.keys()))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
339 return _dispatch_by_prefix
830
de82830f8816 inline branch: synced with trunk@1038.
cmlenz
parents: 820
diff changeset
340
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
341
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
342 directory = TemplateLoader.directory
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
343 package = TemplateLoader.package
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
344 prefixed = TemplateLoader.prefixed
Copyright (C) 2012-2017 Edgewall Software