annotate genshi/template/loader.py @ 770:c290dc5a6813 stable-0.5.x

Ported [894] and [895] back to 0.5.x branch.
author cmlenz
date Tue, 01 Jul 2008 10:42:57 +0000
parents e922f7190eea
children e01c9ad52f09
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 #
719
4bc6741b2811 Fix copyright years.
cmlenz
parents: 714
diff changeset
3 # Copyright (C) 2006-2008 Edgewall Software
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
4 # All rights reserved.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
5 #
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
9 #
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
13
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
14 """Template loading and caching."""
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
15
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
16 import os
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
17 try:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
18 import threading
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
19 except ImportError:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
20 import dummy_threading as threading
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
21
400
e29a94b3ba0c Renamed `genshi.template.core` to `genshi.template.base`, mainly to avoid confusion with `genshi.core`.
cmlenz
parents: 363
diff changeset
22 from genshi.template.base import TemplateError
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
23 from genshi.util import LRUCache
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
24
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
25 __all__ = ['TemplateLoader', 'TemplateNotFound']
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
26 __docformat__ = 'restructuredtext en'
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
27
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
28
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
29 class TemplateNotFound(TemplateError):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
30 """Exception raised when a specific template file could not be found."""
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
31
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
32 def __init__(self, name, search_path):
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
33 """Create the exception.
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
34
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
35 :param name: the filename of the template
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
36 :param search_path: the search path used to lookup the template
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
37 """
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
38 TemplateError.__init__(self, 'Template "%s" not found' % name)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
39 self.search_path = search_path
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
40
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
41
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
42 class TemplateLoader(object):
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
43 """Responsible for loading templates from files on the specified search
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
44 path.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
45
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
46 >>> import tempfile
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
47 >>> fd, path = tempfile.mkstemp(suffix='.html', prefix='template')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
48 >>> os.write(fd, '<p>$var</p>')
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
49 11
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
50 >>> os.close(fd)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
51
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
52 The template loader accepts a list of directory paths that are then used
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
53 when searching for template files, in the given order:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
54
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
55 >>> loader = TemplateLoader([os.path.dirname(path)])
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
56
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
57 The `load()` method first checks the template cache whether the requested
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
58 template has already been loaded. If not, it attempts to locate the
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
59 template file, and returns the corresponding `Template` object:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
60
363
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
61 >>> from genshi.template import MarkupTemplate
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
62 >>> template = loader.load(os.path.basename(path))
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
63 >>> isinstance(template, MarkupTemplate)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
64 True
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
65
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
66 Template instances are cached: requesting a template with the same name
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
67 results in the same instance being returned:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
68
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
69 >>> loader.load(os.path.basename(path)) is template
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
70 True
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
71
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
72 The `auto_reload` option can be used to control whether a template should
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
73 be automatically reloaded when the file it was loaded from has been
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
74 changed. Disable this automatic reloading to improve performance.
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
75
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
76 >>> os.remove(path)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
77 """
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
78 def __init__(self, search_path=None, auto_reload=False,
439
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
79 default_encoding=None, max_cache_size=25, default_class=None,
606
37ff75bb4301 Changed the default error handling mode to "strict".
cmlenz
parents: 590
diff changeset
80 variable_lookup='strict', allow_exec=True, callback=None):
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
81 """Create the template laoder.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
82
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
83 :param search_path: a list of absolute path names that should be
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
84 searched for template files, or a string containing
696
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
85 a single absolute path; alternatively, any item on
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
86 the list may be a ''load function'' that is passed
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
87 a filename and returns a file-like object and some
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
88 metadata
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
89 :param auto_reload: whether to check the last modification time of
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
90 template files, and reload them if they have changed
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
91 :param default_encoding: the default encoding to assume when loading
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
92 templates; defaults to UTF-8
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
93 :param max_cache_size: the maximum number of templates to keep in the
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
94 cache
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
95 :param default_class: the default `Template` subclass to use when
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
96 instantiating templates
606
37ff75bb4301 Changed the default error handling mode to "strict".
cmlenz
parents: 590
diff changeset
97 :param variable_lookup: the variable lookup mechanism; either "strict"
37ff75bb4301 Changed the default error handling mode to "strict".
cmlenz
parents: 590
diff changeset
98 (the default), "lenient", or a custom lookup
442
97544725bb7f Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 439
diff changeset
99 class
545
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
100 :param allow_exec: whether to allow Python code blocks in templates
439
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
101 :param callback: (optional) a callback function that is invoked after a
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
102 template was initialized by this loader; the function
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
103 is passed the template object as only argument. This
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
104 callback can be used for example to add any desired
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
105 filters to the template
442
97544725bb7f Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 439
diff changeset
106 :see: `LenientLookup`, `StrictLookup`
545
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
107
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
108 :note: Changed in 0.5: Added the `allow_exec` argument
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
109 """
363
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
110 from genshi.template.markup import MarkupTemplate
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
111
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
112 self.search_path = search_path
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
113 if self.search_path is None:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
114 self.search_path = []
696
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
115 elif not isinstance(self.search_path, (list, tuple)):
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
116 self.search_path = [self.search_path]
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
117
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
118 self.auto_reload = auto_reload
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
119 """Whether templates should be reloaded when the underlying file is
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
120 changed"""
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
121
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
122 self.default_encoding = default_encoding
363
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
123 self.default_class = default_class or MarkupTemplate
442
97544725bb7f Back out [510] and instead implement configurable error handling modes. The default is the old 0.3.x behaviour, but more strict error handling is available as an option.
cmlenz
parents: 439
diff changeset
124 self.variable_lookup = variable_lookup
545
619340e2d805 Support for Python code blocks in templates can now be disabled. Closes #123.
cmlenz
parents: 442
diff changeset
125 self.allow_exec = allow_exec
439
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
126 if callback is not None and not callable(callback):
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
127 raise TypeError('The "callback" parameter needs to be callable')
9f11c745fac9 Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
cmlenz
parents: 435
diff changeset
128 self.callback = callback
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
129 self._cache = LRUCache(max_cache_size)
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
130 self._uptodate = {}
548
1cc1afc39176 Implement static includes, which improves performance a bit when auto reloading is disabled.
cmlenz
parents: 545
diff changeset
131 self._lock = threading.RLock()
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
132
363
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
133 def load(self, filename, relative_to=None, cls=None, encoding=None):
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
134 """Load the template with the given name.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
135
696
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
136 If the `filename` parameter is relative, this method searches the
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
137 search path trying to locate a template matching the given name. If the
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
138 file name is an absolute path, the search path is ignored.
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
139
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
140 If the requested template is not found, a `TemplateNotFound` exception
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
141 is raised. Otherwise, a `Template` object is returned that represents
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
142 the parsed template.
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
143
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
144 Template instances are cached to avoid having to parse the same
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
145 template file more than once. Thus, subsequent calls of this method
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
146 with the same template file name will return the same `Template`
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
147 object (unless the ``auto_reload`` option is enabled and the file was
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
148 changed since the last parse.)
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
149
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
150 If the `relative_to` parameter is provided, the `filename` is
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
151 interpreted as being relative to that path.
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
152
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
153 :param filename: the relative path of the template file to load
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
154 :param relative_to: the filename of the template from which the new
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
155 template is being loaded, or ``None`` if the
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
156 template is being loaded directly
425
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
157 :param cls: the class of the template object to instantiate
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
158 :param encoding: the encoding of the template to load; defaults to the
073640758a42 Try to use proper reStructuredText for docstrings throughout.
cmlenz
parents: 408
diff changeset
159 ``default_encoding`` of the loader instance
435
be39660919a5 More API doc enhancements.
cmlenz
parents: 425
diff changeset
160 :return: the loaded `Template` instance
695
ed5044d318ed The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents: 606
diff changeset
161 :raises TemplateNotFound: if a template with the given name could not
ed5044d318ed The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents: 606
diff changeset
162 be found
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
163 """
363
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
164 if cls is None:
37e4b4bb0b53 Parse template includes at parse time to avoid some runtime overhead.
cmlenz
parents: 336
diff changeset
165 cls = self.default_class
770
c290dc5a6813 Ported [894] and [895] back to 0.5.x branch.
cmlenz
parents: 721
diff changeset
166 search_path = self.search_path
c290dc5a6813 Ported [894] and [895] back to 0.5.x branch.
cmlenz
parents: 721
diff changeset
167
c290dc5a6813 Ported [894] and [895] back to 0.5.x branch.
cmlenz
parents: 721
diff changeset
168 # Make the filename relative to the template file its being loaded
c290dc5a6813 Ported [894] and [895] back to 0.5.x branch.
cmlenz
parents: 721
diff changeset
169 # from, but only if that file is specified as a relative path, or no
c290dc5a6813 Ported [894] and [895] back to 0.5.x branch.
cmlenz
parents: 721
diff changeset
170 # search path has been set up
c290dc5a6813 Ported [894] and [895] back to 0.5.x branch.
cmlenz
parents: 721
diff changeset
171 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
172 filename = os.path.join(os.path.dirname(relative_to), filename)
770
c290dc5a6813 Ported [894] and [895] back to 0.5.x branch.
cmlenz
parents: 721
diff changeset
173
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
174 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
175 cachekey = filename
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
176
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
177 self._lock.acquire()
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
178 try:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
179 # 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
180 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
181 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
182 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
183 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
184 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
185 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
186 return tmpl
721
e922f7190eea Properly wrap exceptions we want to catch.
jruigrok
parents: 719
diff changeset
187 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
188 pass
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
189
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
190 isabs = False
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
191
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
192 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
193 # 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
194 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
195 isabs = True
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
196
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
197 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
198 # 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
199 # 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
200 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
201 if dirname not in search_path:
697
3d3c322ca978 Fix for #205.
cmlenz
parents: 696
diff changeset
202 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
203 isabs = True
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
204
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
205 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
206 # 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
207 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
208
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
209 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
210 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
211 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
212 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
213 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
214 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
215 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
216 else:
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
217 try:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
218 if isabs:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
219 # 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
220 # 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
221 # 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
222 # 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
223 # 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
224 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
225 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
226 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
227 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
228 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
229 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
230 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
231 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
232 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
233 fileobj.close()
336
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
234 return tmpl
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
235
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
236 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
237
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
238 finally:
7763f7aec949 Refactoring: `genshi.template` is now a package, it was getting way to crowded in that file.
cmlenz
parents:
diff changeset
239 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
240
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
241 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
242 """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
243 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
244
ed5044d318ed The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents: 606
diff changeset
245 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
246 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
247 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
248
ed5044d318ed The `TemplateLoader` class now provides an `instantiate()` method that can be overridden by subclasses to implement advanced template instantiation logic. Fixes #204.
cmlenz
parents: 606
diff changeset
249 :param 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
250 :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
251 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
252 :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
253 :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
254 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
255 :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
256 ``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
257 :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
258 :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
259 """
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 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
261 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
262 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
263 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
264 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
265
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
266 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
267 """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
268
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
269 :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
270 :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
271 :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
272 """
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
273 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
274 filepath = os.path.join(path, filename)
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
275 fileobj = open(filepath, 'U')
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
276 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
277 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
278 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
279 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
280 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
281 directory = staticmethod(directory)
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
282
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 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
284 """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
285
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
286 :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
287 :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
288 :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
289 :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
290 """
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
291 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
292 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
293 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
294 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
295 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
296 package = staticmethod(package)
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
297
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
298 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
299 """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
300 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
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 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
303 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
304
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
305 >>> load = prefixed(
698
408ab81767c7 Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch.
cmlenz
parents: 697
diff changeset
306 ... 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
307 ... 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
308 ... )
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 >>> 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
310 ('app1', 'app1/foo.html', None, None)
696
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
311 >>> 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
312 ('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
313
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
314 :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
315 :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
316 :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
317 """
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
318 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
319 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
320 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
321 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
322 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
323 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
324 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
325 )
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
326 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
327 raise TemplateNotFound(filename, delegates.keys())
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
328 return _dispatch_by_prefix
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
329 prefixed = staticmethod(prefixed)
66eead58c120 More flexible template loader allowing for loading from package data and dispatching to different template directories based on path prefix. Can be easily extended for using custom template loading. Closes #182.
cmlenz
parents: 695
diff changeset
330
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 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
332 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
333 prefixed = TemplateLoader.prefixed
Copyright (C) 2012-2017 Edgewall Software