Mercurial > genshi > mirror
annotate genshi/template/loader.py @ 966:570226c48119 trunk
Templates should be loaded as bytes -- the encoding is passed around with the source explicitly. Fixes bugs in test suite in Python 3.3.
author | hodgestar |
---|---|
date | Sat, 29 Dec 2012 19:12:14 +0000 |
parents | bef1e8701e79 |
children |
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 # |
897 | 3 # Copyright (C) 2006-2010 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 |
773
e01c9ad52f09
Export the template loader factory functions from the `loader` module.
cmlenz
parents:
769
diff
changeset
|
25 __all__ = ['TemplateLoader', 'TemplateNotFound', 'directory', 'package', |
e01c9ad52f09
Export the template loader factory functions from the `loader` module.
cmlenz
parents:
769
diff
changeset
|
26 'prefixed'] |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
27 __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
|
28 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
29 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
30 class TemplateNotFound(TemplateError): |
7763f7aec949
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.""" |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
32 |
7763f7aec949
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): |
435 | 34 """Create the exception. |
35 | |
36 :param name: the filename of the template | |
37 :param search_path: the search path used to lookup the template | |
38 """ | |
336
7763f7aec949
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) |
7763f7aec949
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 |
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
43 class TemplateLoader(object): |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
45 path. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
46 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
47 >>> import tempfile |
7763f7aec949
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') |
935 | 49 >>> os.write(fd, u'<p>$var</p>'.encode('utf-8')) |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
50 11 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
51 >>> os.close(fd) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
52 |
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
55 |
7763f7aec949
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)]) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
57 |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
61 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
62 >>> 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
|
63 >>> 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
|
64 >>> isinstance(template, MarkupTemplate) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
65 True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
66 |
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
69 |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
71 True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
72 |
548
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
73 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
|
74 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
|
75 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
|
76 |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
77 >>> os.remove(path) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
78 """ |
7763f7aec949
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, |
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
|
80 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
|
81 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
|
82 """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
|
83 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
84 :param search_path: a list of absolute path names that should be |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
85 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
|
86 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
|
87 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
|
88 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
|
89 metadata |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
90 :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
|
91 template files, and reload them if they have changed |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
92 :param default_encoding: the default encoding to assume when loading |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
93 templates; defaults to UTF-8 |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
94 :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
|
95 cache |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
96 :param default_class: the default `Template` subclass to use when |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
97 instantiating templates |
606
37ff75bb4301
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
98 :param variable_lookup: the variable lookup mechanism; either "strict" |
37ff75bb4301
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
99 (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
|
100 class |
545
619340e2d805
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
101 :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
|
102 :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
|
103 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
|
104 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
|
105 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
|
106 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
|
107 :see: `LenientLookup`, `StrictLookup` |
545
619340e2d805
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
108 |
619340e2d805
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
109 :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
|
110 """ |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
111 from genshi.template.markup import MarkupTemplate |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
112 |
336
7763f7aec949
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 |
7763f7aec949
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: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
115 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
|
116 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
|
117 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
|
118 |
336
7763f7aec949
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 |
548
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
120 """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
|
121 changed""" |
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
122 |
336
7763f7aec949
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 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
124 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
|
125 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
|
126 self.allow_exec = allow_exec |
793 | 127 if callback is not None and not hasattr(callback, '__call__'): |
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
|
128 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
|
129 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
|
130 self._cache = LRUCache(max_cache_size) |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
131 self._uptodate = {} |
548
1cc1afc39176
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
132 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
|
133 |
876
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
134 def __getstate__(self): |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
135 state = self.__dict__.copy() |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
136 state['_lock'] = None |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
137 return state |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
138 |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
139 def __setstate__(self, state): |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
140 self.__dict__ = state |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
141 self._lock = threading.RLock() |
124b57282f81
Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320.
cmlenz
parents:
854
diff
changeset
|
142 |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
143 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
|
144 """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
|
145 |
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
|
146 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
|
147 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
|
148 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
|
149 |
435 | 150 If the requested template is not found, a `TemplateNotFound` exception |
151 is raised. Otherwise, a `Template` object is returned that represents | |
152 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
|
153 |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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` |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
157 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
|
158 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
|
159 |
7763f7aec949
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 |
7763f7aec949
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. |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
162 |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
163 :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
|
164 :param relative_to: the filename of the template from which the new |
435 | 165 template is being loaded, or ``None`` if the |
166 template is being loaded directly | |
425
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
167 :param cls: the class of the template object to instantiate |
073640758a42
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
168 :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
|
169 ``default_encoding`` of the loader instance |
435 | 170 :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
|
171 :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
|
172 be found |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
173 """ |
363
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
174 if cls is None: |
37e4b4bb0b53
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
175 cls = self.default_class |
769
3a59144a35b1
Includes from templates loaded via an absolute path now include the correct file in nested directories as long if no search path has been configured. Closes #240.
cmlenz
parents:
721
diff
changeset
|
176 search_path = self.search_path |
3a59144a35b1
Includes from templates loaded via an absolute path now include the correct file in nested directories as long if no search path has been configured. Closes #240.
cmlenz
parents:
721
diff
changeset
|
177 |
3a59144a35b1
Includes from templates loaded via an absolute path now include the correct file in nested directories as long if no search path has been configured. Closes #240.
cmlenz
parents:
721
diff
changeset
|
178 # Make the filename relative to the template file its being loaded |
3a59144a35b1
Includes from templates loaded via an absolute path now include the correct file in nested directories as long if no search path has been configured. Closes #240.
cmlenz
parents:
721
diff
changeset
|
179 # from, but only if that file is specified as a relative path, or no |
3a59144a35b1
Includes from templates loaded via an absolute path now include the correct file in nested directories as long if no search path has been configured. Closes #240.
cmlenz
parents:
721
diff
changeset
|
180 # search path has been set up |
3a59144a35b1
Includes from templates loaded via an absolute path now include the correct file in nested directories as long if no search path has been configured. Closes #240.
cmlenz
parents:
721
diff
changeset
|
181 if relative_to and (not search_path or not os.path.isabs(relative_to)): |
336
7763f7aec949
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) |
769
3a59144a35b1
Includes from templates loaded via an absolute path now include the correct file in nested directories as long if no search path has been configured. Closes #240.
cmlenz
parents:
721
diff
changeset
|
183 |
336
7763f7aec949
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) |
699
cfe3b4f02d77
Fix for caching in template loader for templates included by templates loaded from an absolute path. Closes #193. Thanks to Waldemar Kornewald for the test case.
cmlenz
parents:
698
diff
changeset
|
185 cachekey = filename |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
186 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
187 self._lock.acquire() |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
188 try: |
7763f7aec949
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 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
190 try: |
699
cfe3b4f02d77
Fix for caching in template loader for templates included by templates loaded from an absolute path. Closes #193. Thanks to Waldemar Kornewald for the test case.
cmlenz
parents:
698
diff
changeset
|
191 tmpl = self._cache[cachekey] |
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
|
192 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
|
193 return tmpl |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
194 uptodate = self._uptodate[cachekey] |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
195 if uptodate is not None and uptodate(): |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
196 return tmpl |
721 | 197 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
|
198 pass |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
199 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
200 isabs = False |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
201 |
7763f7aec949
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): |
7763f7aec949
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 |
7763f7aec949
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)] |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
205 isabs = True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
206 |
7763f7aec949
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): |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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) |
7763f7aec949
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: |
697 | 212 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
|
213 isabs = True |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
214 |
7763f7aec949
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: |
7763f7aec949
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 |
7763f7aec949
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') |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
218 |
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
|
219 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
|
220 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
|
221 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
|
222 try: |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
223 filepath, filename, fileobj, uptodate = loadfunc(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
|
224 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
|
225 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
|
226 else: |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
227 try: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
228 if isabs: |
7763f7aec949
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 |
7763f7aec949
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 |
7763f7aec949
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, |
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
|
232 # 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
|
233 # search path |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
234 filename = filepath |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
235 tmpl = self._instantiate(cls, fileobj, filepath, |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
236 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
|
237 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
|
238 self.callback(tmpl) |
699
cfe3b4f02d77
Fix for caching in template loader for templates included by templates loaded from an absolute path. Closes #193. Thanks to Waldemar Kornewald for the test case.
cmlenz
parents:
698
diff
changeset
|
239 self._cache[cachekey] = tmpl |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
240 self._uptodate[cachekey] = uptodate |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
241 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
|
242 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
|
243 fileobj.close() |
336
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
244 return tmpl |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
245 |
7763f7aec949
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) |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
247 |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
248 finally: |
7763f7aec949
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
249 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
|
250 |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
251 def _instantiate(self, cls, fileobj, filepath, filename, encoding=None): |
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
|
252 """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
|
253 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
|
254 |
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 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
|
256 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
|
257 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
|
258 |
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 :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
|
260 :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
|
261 source |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
262 :param filepath: the absolute path to the template file |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
263 :param filename: the path to the template file relative to the search |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
264 path |
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
|
265 :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
|
266 ``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
|
267 :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
|
268 :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
|
269 """ |
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
|
270 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
|
271 encoding = self.default_encoding |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
272 return cls(fileobj, filepath=filepath, filename=filename, loader=self, |
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
|
273 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
|
274 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
|
275 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
793
diff
changeset
|
276 @staticmethod |
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
|
277 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
|
278 """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
|
279 |
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 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
|
281 :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
|
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 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
|
285 filepath = os.path.join(path, filename) |
966
570226c48119
Templates should be loaded as bytes -- the encoding is passed around with the source explicitly. Fixes bugs in test suite in Python 3.3.
hodgestar
parents:
955
diff
changeset
|
286 fileobj = open(filepath, 'rb') |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
287 mtime = os.path.getmtime(filepath) |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
288 def _uptodate(): |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
289 return mtime == os.path.getmtime(filepath) |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
290 return filepath, filename, fileobj, _uptodate |
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
|
291 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
|
292 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
793
diff
changeset
|
293 @staticmethod |
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
|
294 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
|
295 """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
|
296 |
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 :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
|
298 :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
|
299 :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
|
300 :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
|
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 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
|
303 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
|
304 filepath = os.path.join(path, filename) |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
305 return filepath, filename, resource_stream(name, filepath), 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 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
|
307 |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
793
diff
changeset
|
308 @staticmethod |
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
|
309 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
|
310 """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
|
311 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
|
312 |
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 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
|
314 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
|
315 |
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
|
316 >>> load = prefixed( |
698
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
317 ... 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
|
318 ... 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
|
319 ... ) |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
822
diff
changeset
|
320 >>> print(load('app1/foo.html')) |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
321 ('app1', 'app1/foo.html', None, None) |
853
f33ecf3c319e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
822
diff
changeset
|
322 >>> print(load('app2/bar.html')) |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
323 ('app2', 'app2/bar.html', None, None) |
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
324 |
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
|
325 :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
|
326 :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
|
327 :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
|
328 """ |
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
|
329 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
|
330 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
|
331 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
|
332 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
|
333 delegate = directory(delegate) |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
334 filepath, _, fileobj, uptodate = delegate( |
698
408ab81767c7
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
335 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
|
336 ) |
714
fc6d9d2a3527
The `Template` class and its subclasses, as well as the interpolation API, now take an `filepath` parameter instead of `basedir`. Closes #207. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
699
diff
changeset
|
337 return filepath, filename, fileobj, uptodate |
854
4d9bef447df9
More work on reducing the size of the diff produced by 2to3.
cmlenz
parents:
853
diff
changeset
|
338 raise TemplateNotFound(filename, list(delegates.keys())) |
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
|
339 return _dispatch_by_prefix |
822
70fddd2262f5
Get rid of some Python 2.3 legacy that's no longer needed now that 2.4 is the baseline.
cmlenz
parents:
793
diff
changeset
|
340 |
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
|
341 |
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
|
342 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
|
343 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
|
344 prefixed = TemplateLoader.prefixed |