Ticket #412: loader.patch
| File loader.patch, 7.0 KB (added by Christoph Zwerschke <cito@…>, 13 years ago) |
|---|
-
genshi/template/loader.py
14 14 """Template loading and caching.""" 15 15 16 16 import os 17 import sys 17 18 try: 18 19 import threading 19 20 except ImportError: … … 32 33 33 34 def __init__(self, name, search_path): 34 35 """Create the exception. 35 36 36 37 :param name: the filename of the template 37 38 :param search_path: the search path used to lookup the template 38 39 """ … … 43 44 class TemplateLoader(object): 44 45 """Responsible for loading templates from files on the specified search 45 46 path. 46 47 47 48 >>> import tempfile 48 49 >>> fd, path = tempfile.mkstemp(suffix='.html', prefix='template') 49 50 >>> os.write(fd, '<p>$var</p>') 50 51 11 51 52 >>> os.close(fd) 52 53 53 54 The template loader accepts a list of directory paths that are then used 54 55 when searching for template files, in the given order: 55 56 56 57 >>> loader = TemplateLoader([os.path.dirname(path)]) 57 58 58 59 The `load()` method first checks the template cache whether the requested 59 60 template has already been loaded. If not, it attempts to locate the 60 61 template file, and returns the corresponding `Template` object: 61 62 62 63 >>> from genshi.template import MarkupTemplate 63 64 >>> template = loader.load(os.path.basename(path)) 64 65 >>> isinstance(template, MarkupTemplate) 65 66 True 66 67 67 68 Template instances are cached: requesting a template with the same name 68 69 results in the same instance being returned: 69 70 70 71 >>> loader.load(os.path.basename(path)) is template 71 72 True 72 73 73 74 The `auto_reload` option can be used to control whether a template should 74 75 be automatically reloaded when the file it was loaded from has been 75 76 changed. Disable this automatic reloading to improve performance. 76 77 77 78 >>> os.remove(path) 78 79 """ 79 80 def __init__(self, search_path=None, auto_reload=False, 80 81 default_encoding=None, max_cache_size=25, default_class=None, 81 82 variable_lookup='strict', allow_exec=True, callback=None): 82 83 """Create the template laoder. 83 84 84 85 :param search_path: a list of absolute path names that should be 85 86 searched for template files, or a string containing 86 87 a single absolute path; alternatively, any item on … … 105 106 callback can be used for example to add any desired 106 107 filters to the template 107 108 :see: `LenientLookup`, `StrictLookup` 108 109 109 110 :note: Changed in 0.5: Added the `allow_exec` argument 110 111 """ 111 112 from genshi.template.markup import MarkupTemplate … … 142 143 143 144 def load(self, filename, relative_to=None, cls=None, encoding=None): 144 145 """Load the template with the given name. 145 146 146 147 If the `filename` parameter is relative, this method searches the 147 148 search path trying to locate a template matching the given name. If the 148 149 file name is an absolute path, the search path is ignored. 149 150 150 151 If the requested template is not found, a `TemplateNotFound` exception 151 152 is raised. Otherwise, a `Template` object is returned that represents 152 153 the parsed template. 153 154 154 155 Template instances are cached to avoid having to parse the same 155 156 template file more than once. Thus, subsequent calls of this method 156 157 with the same template file name will return the same `Template` 157 158 object (unless the ``auto_reload`` option is enabled and the file was 158 159 changed since the last parse.) 159 160 160 161 If the `relative_to` parameter is provided, the `filename` is 161 162 interpreted as being relative to that path. 162 163 163 164 :param filename: the relative path of the template file to load 164 165 :param relative_to: the filename of the template from which the new 165 166 template is being loaded, or ``None`` if the … … 226 227 else: 227 228 try: 228 229 if isabs: 229 # If the filename of either the included or the 230 # If the filename of either the included or the 230 231 # including template is absolute, make sure the 231 232 # included template gets an absolute path, too, 232 233 # so that nested includes work properly without a … … 251 252 def _instantiate(self, cls, fileobj, filepath, filename, encoding=None): 252 253 """Instantiate and return the `Template` object based on the given 253 254 class and parameters. 254 255 255 256 This function is intended for subclasses to override if they need to 256 257 implement special template instantiation logic. Code that just uses 257 258 the `TemplateLoader` should use the `load` method instead. 258 259 259 260 :param cls: the class of the template object to instantiate 260 261 :param fileobj: a readable file-like object containing the template 261 262 source … … 276 277 @staticmethod 277 278 def directory(path): 278 279 """Loader factory for loading templates from a local directory. 279 280 280 281 :param path: the path to the local directory containing the templates 281 282 :return: the loader function to load templates from the given directory 282 283 :rtype: ``function`` 283 284 """ 285 if os.path.supports_unicode_filenames and not isinstance(path, unicode): 286 encoding = sys.getfilesystemencoding() 287 if encoding: 288 path = unicode(path, encoding) 289 else: 290 path = unicode(path) 284 291 def _load_from_directory(filename): 285 292 filepath = os.path.join(path, filename) 286 293 fileobj = open(filepath, 'U') … … 293 300 @staticmethod 294 301 def package(name, path): 295 302 """Loader factory for loading templates from egg package data. 296 303 297 304 :param name: the name of the package containing the resources 298 305 :param path: the path inside the package data 299 306 :return: the loader function to load templates from the given package … … 309 316 def prefixed(**delegates): 310 317 """Factory for a load function that delegates to other loaders 311 318 depending on the prefix of the requested template path. 312 319 313 320 The prefix is stripped from the filename when passing on the load 314 321 request to the delegate. 315 322 316 323 >>> load = prefixed( 317 324 ... app1 = lambda filename: ('app1', filename, None, None), 318 325 ... app2 = lambda filename: ('app2', filename, None, None) … … 321 328 ('app1', 'app1/foo.html', None, None) 322 329 >>> print(load('app2/bar.html')) 323 330 ('app2', 'app2/bar.html', None, None) 324 331 325 332 :param delegates: mapping of path prefixes to loader functions 326 333 :return: the loader function 327 334 :rtype: ``function``
