Mercurial > genshi > mirror
annotate genshi/template/loader.py @ 698:408ab81767c7 trunk
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
author | cmlenz |
---|---|
date | Thu, 27 Mar 2008 14:45:11 +0000 |
parents | 3d3c322ca978 |
children | cfe3b4f02d77 |
rev | line source |
---|---|
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
2 # |
408 | 3 # Copyright (C) 2006-2007 Edgewall Software |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
4 # All rights reserved. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
5 # |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
9 # |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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/. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
13 |
7763f7aec949
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.""" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
15 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
16 import os |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
17 try: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
18 import threading |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
19 except ImportError: |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
21 |
400
e29a94b3ba0c
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
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
24 |
7763f7aec949
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
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
26 __docformat__ = 'restructuredtext en' |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
27 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
28 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
29 class TemplateNotFound(TemplateError): |
7763f7aec949
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.""" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
31 |
7763f7aec949
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 | 33 """Create the exception. |
34 | |
35 :param name: the filename of the template | |
36 :param search_path: the search path used to lookup the template | |
37 """ | |
336
7763f7aec949
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) |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
40 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
41 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
42 class TemplateLoader(object): |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
44 path. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
45 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
46 >>> import tempfile |
7763f7aec949
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') |
7763f7aec949
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>') |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
49 11 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
50 >>> os.close(fd) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
51 |
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
54 |
7763f7aec949
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)]) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
56 |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
60 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
61 >>> from genshi.template import MarkupTemplate |
336
7763f7aec949
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)) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
63 >>> isinstance(template, MarkupTemplate) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
64 True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
65 |
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
68 |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
70 True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
71 |
548
1cc1afc39176
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 |
1cc1afc39176
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 |
1cc1afc39176
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. |
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
75 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
76 >>> os.remove(path) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
77 """ |
7763f7aec949
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
9f11c745fac9
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, |
606
37ff75bb4301
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
80 variable_lookup='strict', allow_exec=True, callback=None): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
81 """Create the template laoder. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
82 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
83 :param search_path: a list of absolute path names that should be |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
84 searched for template files, or a string containing |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
85 a single absolute path; alternatively, any item on |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
86 the list may be a ''load function'' that is passed |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
87 a filename and returns a file-like object and some |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
88 metadata |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
89 :param auto_reload: whether to check the last modification time of |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
90 template files, and reload them if they have changed |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
91 :param default_encoding: the default encoding to assume when loading |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
92 templates; defaults to UTF-8 |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
93 :param max_cache_size: the maximum number of templates to keep in the |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
94 cache |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
95 :param default_class: the default `Template` subclass to use when |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
96 instantiating templates |
606
37ff75bb4301
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
97 :param variable_lookup: the variable lookup mechanism; either "strict" |
37ff75bb4301
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
98 (the default), "lenient", or a custom lookup |
442
97544725bb7f
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
|
99 class |
545
619340e2d805
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
100 :param allow_exec: whether to allow Python code blocks in templates |
439
9f11c745fac9
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 :param callback: (optional) a callback function that is invoked after a |
9f11c745fac9
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 template was initialized by this loader; the function |
9f11c745fac9
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 is passed the template object as only argument. This |
9f11c745fac9
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 callback can be used for example to add any desired |
9f11c745fac9
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
|
105 filters to the template |
442
97544725bb7f
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
|
106 :see: `LenientLookup`, `StrictLookup` |
545
619340e2d805
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
107 |
619340e2d805
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
108 :note: Changed in 0.5: Added the `allow_exec` argument |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
109 """ |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
110 from genshi.template.markup import MarkupTemplate |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
111 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
112 self.search_path = search_path |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
113 if self.search_path is None: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
114 self.search_path = [] |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
115 elif not isinstance(self.search_path, (list, tuple)): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
116 self.search_path = [self.search_path] |
548
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
117 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
118 self.auto_reload = auto_reload |
548
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
119 """Whether templates should be reloaded when the underlying file is |
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
120 changed""" |
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
121 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
122 self.default_encoding = default_encoding |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
123 self.default_class = default_class or MarkupTemplate |
442
97544725bb7f
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
|
124 self.variable_lookup = variable_lookup |
545
619340e2d805
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
125 self.allow_exec = allow_exec |
439
9f11c745fac9
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): |
9f11c745fac9
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') |
9f11c745fac9
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
7763f7aec949
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) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
130 self._mtime = {} |
548
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
131 self._lock = threading.RLock() |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
132 |
363
37e4b4bb0b53
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
7763f7aec949
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. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
135 |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
136 If the `filename` parameter is relative, this method searches the |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
137 search path trying to locate a template matching the given name. If the |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
138 file name is an absolute path, the search path is ignored. |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
139 |
435 | 140 If the requested template is not found, a `TemplateNotFound` exception |
141 is raised. Otherwise, a `Template` object is returned that represents | |
142 the parsed template. | |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
143 |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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
073640758a42
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
7763f7aec949
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.) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
149 |
7763f7aec949
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 |
7763f7aec949
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. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
152 |
425
073640758a42
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 |
073640758a42
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 | 155 template is being loaded, or ``None`` if the |
156 template is being loaded directly | |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
157 :param cls: the class of the template object to instantiate |
073640758a42
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 |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
159 ``default_encoding`` of the loader instance |
435 | 160 :return: the loaded `Template` instance |
695
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
161 :raises TemplateNotFound: if a template with the given name could not |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
162 be found |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
163 """ |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
164 if cls is None: |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
165 cls = self.default_class |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
166 if relative_to and not os.path.isabs(relative_to): |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
167 filename = os.path.join(os.path.dirname(relative_to), filename) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
168 filename = os.path.normpath(filename) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
169 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
170 self._lock.acquire() |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
171 try: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
172 # First check the cache to avoid reparsing the same file |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
173 try: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
174 tmpl = self._cache[filename] |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
175 if not self.auto_reload: |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
176 return tmpl |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
177 mtime = self._mtime[filename] |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
178 if mtime and mtime == os.path.getmtime(tmpl.filepath): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
179 return tmpl |
590
36b5a03534a0
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
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
181 pass |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
182 |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
184 isabs = False |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
185 |
7763f7aec949
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): |
7763f7aec949
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 |
7763f7aec949
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)] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
189 isabs = True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
190 |
7763f7aec949
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): |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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) |
7763f7aec949
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: |
697 | 196 search_path = list(search_path) + [dirname] |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
197 isabs = True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
198 |
7763f7aec949
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: |
7763f7aec949
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 |
7763f7aec949
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') |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
202 |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
203 for loadfunc in search_path: |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
204 if isinstance(loadfunc, basestring): |
698
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
205 loadfunc = directory(loadfunc) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
206 try: |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
207 dirname, filename, fileobj, mtime = loadfunc(filename) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
208 except IOError: |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
209 continue |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
210 else: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
211 try: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
212 if isabs: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
213 # If the filename of either the included or the |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
214 # including template is absolute, make sure the |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
215 # included template gets an absolute path, too, |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
216 # so that nested includes work properly without a |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
217 # search path |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
218 filename = os.path.join(dirname, filename) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
219 dirname = '' |
695
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
220 tmpl = self.instantiate(cls, fileobj, dirname, |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
221 filename, encoding=encoding) |
439
9f11c745fac9
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 if self.callback: |
9f11c745fac9
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.callback(tmpl) |
9f11c745fac9
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._cache[filename] = tmpl |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
225 self._mtime[filename] = mtime |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
226 finally: |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
227 if hasattr(fileobj, 'close'): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
228 fileobj.close() |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
229 return tmpl |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
230 |
7763f7aec949
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) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
232 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
233 finally: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
234 self._lock.release() |
695
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
235 |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
236 def instantiate(self, cls, fileobj, dirname, filename, encoding=None): |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
237 """Instantiate and return the `Template` object based on the given |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
238 class and parameters. |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
239 |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
240 This function is intended for subclasses to override if they need to |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
241 implement special template instantiation logic. Code that just uses |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
242 the `TemplateLoader` should use the `load` method instead. |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
243 |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
244 :param cls: the class of the template object to instantiate |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
245 :param fileobj: a readable file-like object containing the template |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
246 source |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
247 :param dirname: the name of the base directory containing the template |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
248 file |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
249 :param filename: the name of the template file, relative to the given |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
250 base directory |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
251 :param encoding: the encoding of the template to load; defaults to the |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
252 ``default_encoding`` of the loader instance |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
253 :return: the loaded `Template` instance |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
254 :rtype: `Template` |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
255 """ |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
256 if encoding is None: |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
257 encoding = self.default_encoding |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
258 return cls(fileobj, basedir=dirname, filename=filename, loader=self, |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
259 encoding=encoding, lookup=self.variable_lookup, |
ed5044d318ed
The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents:
606
diff
changeset
|
260 allow_exec=self.allow_exec) |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
261 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
262 def directory(path): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
263 """Loader factory for loading templates from a local directory. |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
264 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
265 :param path: the path to the local directory containing the templates |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
266 :return: the loader function to load templates from the given directory |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
267 :rtype: ``function`` |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
268 """ |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
269 def _load_from_directory(filename): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
270 filepath = os.path.join(path, filename) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
271 fileobj = open(filepath, 'U') |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
272 return path, filename, fileobj, os.path.getmtime(filepath) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
273 return _load_from_directory |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
274 directory = staticmethod(directory) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
275 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
276 def package(name, path): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
277 """Loader factory for loading templates from egg package data. |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
278 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
279 :param name: the name of the package containing the resources |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
280 :param path: the path inside the package data |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
281 :return: the loader function to load templates from the given package |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
282 :rtype: ``function`` |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
283 """ |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
284 from pkg_resources import resource_stream |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
285 def _load_from_package(filename): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
286 filepath = os.path.join(path, filename) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
287 return path, filename, resource_stream(name, filepath), None |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
288 return _load_from_package |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
289 package = staticmethod(package) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
290 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
291 def prefixed(**delegates): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
292 """Factory for a load function that delegates to other loaders |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
293 depending on the prefix of the requested template path. |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
294 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
295 The prefix is stripped from the filename when passing on the load |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
296 request to the delegate. |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
297 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
298 >>> load = prefixed( |
698
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
299 ... app1 = lambda filename: ('app1', filename, None, None), |
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
300 ... app2 = lambda filename: ('app2', filename, None, None) |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
301 ... ) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
302 >>> print load('app1/foo.html') |
698
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
303 ('', 'app1/foo.html', None, None) |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
304 >>> print load('app2/bar.html') |
698
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
305 ('', 'app2/bar.html', None, None) |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
306 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
307 :param delegates: mapping of path prefixes to loader functions |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
308 :return: the loader function |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
309 :rtype: ``function`` |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
310 """ |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
311 def _dispatch_by_prefix(filename): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
312 for prefix, delegate in delegates.items(): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
313 if filename.startswith(prefix): |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
314 if isinstance(delegate, basestring): |
698
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
315 delegate = directory(delegate) |
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
316 path, _, fileobj, mtime = delegate( |
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
317 filename[len(prefix):].lstrip('/\\') |
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
318 ) |
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
319 dirname = path[len(prefix):].rstrip('/\\') |
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
320 return dirname, filename, fileobj, mtime |
696
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
321 raise TemplateNotFound(filename, delegates.keys()) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
322 return _dispatch_by_prefix |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
323 prefixed = staticmethod(prefixed) |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
324 |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
325 directory = TemplateLoader.directory |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
326 package = TemplateLoader.package |
66eead58c120
More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents:
695
diff
changeset
|
327 prefixed = TemplateLoader.prefixed |