Mercurial > genshi > genshi-test
annotate genshi/template/loader.py @ 935:705727288d7e
Merge r1143 from py3k:
add support for python 3 to remaining genshi.template components:
* minor changes to track encoding=None API change in core genshi modules.
* genshi/template/directives:
* slightly odd syntax changes to make the 2to3 .next() fixer pick up *stream.next()
* minor test fix for change in behaviour of division (/) in Python 3.
* genshi/template/loader:
* add 'b' to file modes to ensure it's loaded as bytes in Python 3.
* use not isinstance(s, unicode) instead of isinstance(s, str) since the former is correctly converted by 2to3.
author | hodgestar |
---|---|
date | Fri, 18 Mar 2011 09:17:52 +0000 |
parents | 85e4678337cf |
children |
rev | line source |
---|---|
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
2 # |
897 | 3 # Copyright (C) 2006-2010 Edgewall Software |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
4 # All rights reserved. |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
5 # |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
6 # This software is licensed as described in the file COPYING, which |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
7 # you should have received as part of this distribution. The terms |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
8 # are also available at http://genshi.edgewall.org/wiki/License. |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
9 # |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
10 # This software consists of voluntary contributions made by many |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
11 # individuals. For the exact contribution history, see the revision |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
12 # history and logs, available at http://genshi.edgewall.org/log/. |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
13 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
14 """Template loading and caching.""" |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
15 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
16 import os |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
17 try: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
18 import threading |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
19 except ImportError: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
20 import dummy_threading as threading |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
21 |
400
8dd0d34a9fb7
Renamed `genshi.template.core` to `genshi.template.base`, mainly to avoid confusion with `genshi.core`.
cmlenz
parents:
363
diff
changeset
|
22 from genshi.template.base import TemplateError |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
23 from genshi.util import LRUCache |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
24 |
773
b555a6769c5b
Export the template loader factory functions from the `loader` module.
cmlenz
parents:
769
diff
changeset
|
25 __all__ = ['TemplateLoader', 'TemplateNotFound', 'directory', 'package', |
b555a6769c5b
Export the template loader factory functions from the `loader` module.
cmlenz
parents:
769
diff
changeset
|
26 'prefixed'] |
425
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
27 __docformat__ = 'restructuredtext en' |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
28 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
29 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
30 class TemplateNotFound(TemplateError): |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
31 """Exception raised when a specific template file could not be found.""" |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
32 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
33 def __init__(self, name, search_path): |
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
39 TemplateError.__init__(self, 'Template "%s" not found' % name) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
40 self.search_path = search_path |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
41 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
42 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
43 class TemplateLoader(object): |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
44 """Responsible for loading templates from files on the specified search |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
45 path. |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
46 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
47 >>> import tempfile |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
48 >>> fd, path = tempfile.mkstemp(suffix='.html', prefix='template') |
935 | 49 >>> os.write(fd, u'<p>$var</p>'.encode('utf-8')) |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
50 11 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
51 >>> os.close(fd) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
52 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
53 The template loader accepts a list of directory paths that are then used |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
54 when searching for template files, in the given order: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
55 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
56 >>> loader = TemplateLoader([os.path.dirname(path)]) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
57 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
58 The `load()` method first checks the template cache whether the requested |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
59 template has already been loaded. If not, it attempts to locate the |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
60 template file, and returns the corresponding `Template` object: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
61 |
363
caf7b68ab5dc
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
62 >>> from genshi.template import MarkupTemplate |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
63 >>> template = loader.load(os.path.basename(path)) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
64 >>> isinstance(template, MarkupTemplate) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
65 True |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
66 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
67 Template instances are cached: requesting a template with the same name |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
68 results in the same instance being returned: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
69 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
70 >>> loader.load(os.path.basename(path)) is template |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
71 True |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
72 |
548
c2e039c7e439
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 |
c2e039c7e439
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 |
c2e039c7e439
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. |
c2e039c7e439
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
76 |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
77 >>> os.remove(path) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
78 """ |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
79 def __init__(self, search_path=None, auto_reload=False, |
439
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
80 default_encoding=None, max_cache_size=25, default_class=None, |
606
9ada030ad986
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
81 variable_lookup='strict', allow_exec=True, callback=None): |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
82 """Create the template laoder. |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
83 |
425
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
84 :param search_path: a list of absolute path names that should be |
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
85 searched for template files, or a string containing |
696
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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
5b248708bbed
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 |
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
91 template files, and reload them if they have changed |
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
92 :param default_encoding: the default encoding to assume when loading |
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
93 templates; defaults to UTF-8 |
5b248708bbed
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 |
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
95 cache |
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
96 :param default_class: the default `Template` subclass to use when |
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
97 instantiating templates |
606
9ada030ad986
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
98 :param variable_lookup: the variable lookup mechanism; either "strict" |
9ada030ad986
Changed the default error handling mode to "strict".
cmlenz
parents:
590
diff
changeset
|
99 (the default), "lenient", or a custom lookup |
442
ff7c72b52fb2
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
439
diff
changeset
|
100 class |
545
6e21c89d9255
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
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
102 :param callback: (optional) a callback function that is invoked after a |
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
103 template was initialized by this loader; the function |
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
104 is passed the template object as only argument. This |
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
105 callback can be used for example to add any desired |
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
106 filters to the template |
442
ff7c72b52fb2
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
439
diff
changeset
|
107 :see: `LenientLookup`, `StrictLookup` |
545
6e21c89d9255
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
108 |
6e21c89d9255
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
110 """ |
363
caf7b68ab5dc
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
111 from genshi.template.markup import MarkupTemplate |
caf7b68ab5dc
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
112 |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
113 self.search_path = search_path |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
114 if self.search_path is None: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
115 self.search_path = [] |
696
87b8e23610d4
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
117 self.search_path = [self.search_path] |
548
c2e039c7e439
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
118 |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
119 self.auto_reload = auto_reload |
548
c2e039c7e439
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 |
c2e039c7e439
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
121 changed""" |
c2e039c7e439
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
122 |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
123 self.default_encoding = default_encoding |
363
caf7b68ab5dc
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
ff7c72b52fb2
Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents:
439
diff
changeset
|
125 self.variable_lookup = variable_lookup |
545
6e21c89d9255
Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents:
442
diff
changeset
|
126 self.allow_exec = allow_exec |
793 | 127 if callback is not None and not hasattr(callback, '__call__'): |
439
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
128 raise TypeError('The "callback" parameter needs to be callable') |
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
129 self.callback = callback |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
130 self._cache = LRUCache(max_cache_size) |
714
7e6496bde18a
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
c2e039c7e439
Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents:
545
diff
changeset
|
132 self._lock = threading.RLock() |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
133 |
876
52d7d6b7b6c1
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): |
52d7d6b7b6c1
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() |
52d7d6b7b6c1
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 |
52d7d6b7b6c1
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 |
52d7d6b7b6c1
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 |
52d7d6b7b6c1
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): |
52d7d6b7b6c1
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 |
52d7d6b7b6c1
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() |
52d7d6b7b6c1
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
caf7b68ab5dc
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
144 """Load the template with the given name. |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
145 |
696
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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
5f2c7782cd8a
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
153 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
154 Template instances are cached to avoid having to parse the same |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
155 template file more than once. Thus, subsequent calls of this method |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
156 with the same template file name will return the same `Template` |
425
5b248708bbed
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
158 changed since the last parse.) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
159 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
160 If the `relative_to` parameter is provided, the `filename` is |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
161 interpreted as being relative to that path. |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
162 |
425
5b248708bbed
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 |
5b248708bbed
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
5b248708bbed
Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents:
408
diff
changeset
|
167 :param cls: the class of the template object to instantiate |
5b248708bbed
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 |
5b248708bbed
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
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
173 """ |
363
caf7b68ab5dc
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
174 if cls is None: |
caf7b68ab5dc
Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents:
336
diff
changeset
|
175 cls = self.default_class |
769
834e8fd2d822
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 |
834e8fd2d822
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 |
834e8fd2d822
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 |
834e8fd2d822
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 |
834e8fd2d822
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 |
834e8fd2d822
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
182 filename = os.path.join(os.path.dirname(relative_to), filename) |
769
834e8fd2d822
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
184 filename = os.path.normpath(filename) |
699
1f08da62e8fd
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
186 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
187 self._lock.acquire() |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
188 try: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
189 # First check the cache to avoid reparsing the same file |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
190 try: |
699
1f08da62e8fd
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
87b8e23610d4
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: |
87b8e23610d4
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
7e6496bde18a
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] |
7e6496bde18a
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
5f2c7782cd8a
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
198 pass |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
199 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
200 isabs = False |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
201 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
202 if os.path.isabs(filename): |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
203 # Bypass the search path if the requested filename is absolute |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
204 search_path = [os.path.dirname(filename)] |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
205 isabs = True |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
206 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
207 elif relative_to and os.path.isabs(relative_to): |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
208 # Make sure that the directory containing the including |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
209 # template is on the search path |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
210 dirname = os.path.dirname(relative_to) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
211 if dirname not in search_path: |
697 | 212 search_path = list(search_path) + [dirname] |
336
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
213 isabs = True |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
214 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
215 elif not search_path: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
216 # Uh oh, don't know where to look for the template |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
217 raise TemplateError('Search path for templates not configured') |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
218 |
696
87b8e23610d4
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: |
87b8e23610d4
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
654e1d1b3953
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
222 try: |
714
7e6496bde18a
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
87b8e23610d4
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: |
87b8e23610d4
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 |
87b8e23610d4
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
227 try: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
228 if isabs: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
229 # If the filename of either the included or the |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
230 # including template is absolute, make sure the |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
231 # included template gets an absolute path, too, |
696
87b8e23610d4
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
233 # search path |
714
7e6496bde18a
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 |
7e6496bde18a
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, |
7e6496bde18a
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
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
237 if self.callback: |
b84c11a49ad2
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents:
435
diff
changeset
|
238 self.callback(tmpl) |
699
1f08da62e8fd
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
7e6496bde18a
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
241 finally: |
696
87b8e23610d4
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'): |
87b8e23610d4
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
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
244 return tmpl |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
245 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
246 raise TemplateNotFound(filename, search_path) |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
247 |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
248 finally: |
5f2c7782cd8a
Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff
changeset
|
249 self._lock.release() |
695
3d11d6b1d3d4
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
7e6496bde18a
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
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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. |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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. |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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
7e6496bde18a
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 |
7e6496bde18a
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 |
7e6496bde18a
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
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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 |
3d11d6b1d3d4
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` |
3d11d6b1d3d4
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 """ |
3d11d6b1d3d4
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: |
3d11d6b1d3d4
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
7e6496bde18a
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
3d11d6b1d3d4
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, |
3d11d6b1d3d4
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
87b8e23610d4
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
ce5ad2d540b3
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
87b8e23610d4
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): |
87b8e23610d4
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. |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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`` |
87b8e23610d4
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 """ |
87b8e23610d4
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): |
87b8e23610d4
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) |
935 | 286 fileobj = open(filepath, 'rbU') |
714
7e6496bde18a
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) |
7e6496bde18a
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(): |
7e6496bde18a
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) |
7e6496bde18a
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
87b8e23610d4
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 |
87b8e23610d4
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
ce5ad2d540b3
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
87b8e23610d4
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): |
87b8e23610d4
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. |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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`` |
87b8e23610d4
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 """ |
87b8e23610d4
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 |
87b8e23610d4
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): |
87b8e23610d4
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
7e6496bde18a
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
87b8e23610d4
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 |
87b8e23610d4
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
ce5ad2d540b3
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
87b8e23610d4
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): |
87b8e23610d4
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 |
87b8e23610d4
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. |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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. |
87b8e23610d4
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 |
87b8e23610d4
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
654e1d1b3953
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), |
654e1d1b3953
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
87b8e23610d4
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
4376010bb97e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
822
diff
changeset
|
320 >>> print(load('app1/foo.html')) |
714
7e6496bde18a
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
4376010bb97e
Convert a bunch of print statements to py3k compatible syntax.
cmlenz
parents:
822
diff
changeset
|
322 >>> print(load('app2/bar.html')) |
714
7e6496bde18a
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) |
7e6496bde18a
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
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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`` |
87b8e23610d4
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 """ |
87b8e23610d4
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): |
87b8e23610d4
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(): |
87b8e23610d4
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): |
87b8e23610d4
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
654e1d1b3953
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
7e6496bde18a
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
654e1d1b3953
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('/\\') |
654e1d1b3953
Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents:
697
diff
changeset
|
336 ) |
714
7e6496bde18a
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
0d9e87c6cf6e
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
87b8e23610d4
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
ce5ad2d540b3
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
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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 |
87b8e23610d4
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 |