| # -*- coding: utf-8 -*- |
| """ |
| jinja.plugin |
| ~~~~~~~~~~~~ |
| |
| Support for the `GeneralTemplateInterface`__ and the Buffet interface. |
| |
| Do not use this module on your own. We don't recommend those interfaces! |
| If you are able to, you should really use Jinja without those abstraction |
| layers. |
| |
| __ http://trac.pocoo.org/wiki/GeneralTemplateInterface |
| |
| :copyright: 2007 by Armin Ronacher. |
| :license: BSD, see LICENSE for more details. |
| """ |
| from warnings import warn |
| from jinja.environment import Environment |
| from jinja.loaders import FunctionLoader, FileSystemLoader, PackageLoader |
| from jinja.exceptions import TemplateNotFound |
| |
| |
| class BuffetPlugin(object): |
| """ |
| Implements the Jinja buffet plugin. Well. It works for pylons and should |
| work for TurboGears too if their plugin system would work. |
| """ |
| |
| def __init__(self, extra_vars_func=None, options=None): |
| if 'jinja.environment' in options: |
| self.env = options['jinja.environment'] |
| else: |
| opt = {} |
| for key, value in options.iteritems(): |
| if key.startswith('jinja.') and key != 'jinja.extension': |
| opt[key[6:]] = value |
| loader_func = opt.pop('loader_func', None) |
| getmtime_func = opt.pop('getmtime_func', None) |
| use_memcache = opt.pop('use_memcache', False) |
| memcache_size = opt.pop('memcache_size', 40) |
| cache_folder = opt.pop('cache_folder', None) |
| auto_reload = opt.pop('auto_reload', True) |
| if 'searchpath' in opt: |
| opt['loader'] = FileSystemLoader(opt.pop('searchpath'), |
| use_memcache, memcache_size, |
| cache_folder, auto_reload) |
| elif 'package' in opt: |
| opt['loader'] = PackageLoader(opt.pop('package'), |
| opt.pop('package_path', ''), |
| use_memcache, memcache_size, |
| cache_folder, auto_reload) |
| elif loader_func is not None: |
| opt['loader'] = FunctionLoader(loader_func, getmtime_func, |
| use_memcache, memcache_size, |
| cache_folder, auto_reload) |
| self.env = Environment(**opt) |
| |
| self.extra_vars_func = extra_vars_func |
| self.extension = options.pop('jinja.extension', 'html') |
| |
| def load_template(self, templatename, template_string=None): |
| if template_string is not None: |
| return self.env.from_string(template_string) |
| if templatename.startswith('!'): |
| jinja_name = templatename[1:] |
| else: |
| jinja_name = templatename.replace('.', '/') + '.' + self.extension |
| return self.env.get_template(jinja_name) |
| |
| def render(self, info, format='html', fragment=False, template=None): |
| if isinstance(template, basestring): |
| template = self.load_template(template) |
| if self.extra_vars_func: |
| info.update(self.extra_vars_func()) |
| return template.render(info) |
| |
| |
| def jinja_plugin_factory(options): |
| """ |
| Basic implementation of the `GeneralTemplateInterface`. |
| |
| Supports ``loader_func`` and ``getmtime_func``, as well as |
| string and file loading but ignores ``mode`` since it's a |
| text based template engine. |
| |
| All options passed to this function are forwarded to the |
| jinja environment. Exceptions are the following keys: |
| |
| =================== ================================================= |
| ``environment`` If this is provided it must be the only |
| configuration value and it's used as jinja |
| environment. |
| ``searchpath`` If provided a new file system loader with this |
| search path is instanciated. |
| ``package`` Name of the python package containing the |
| templates. If this and ``package_path`` is |
| defined a `PackageLoader` is used. |
| ``package_path`` Path to the templates inside of a package. |
| ``loader_func`` Function that takes the name of the template to |
| load. If it returns a string or unicode object |
| it's used to load a template. If the return |
| value is None it's considered missing. |
| ``getmtime_func`` Function used to check if templates requires |
| reloading. Has to return the UNIX timestamp of |
| the last template change or 0 if this template |
| does not exist or requires updates at any cost. |
| ``use_memcache`` Set this to ``True`` to enable memory caching. |
| This is usually a good idea in production mode, |
| but disable it during development since it won't |
| reload template changes automatically. |
| This only works in persistent environments like |
| FastCGI. |
| ``memcache_size`` Number of template instance you want to cache. |
| Defaults to ``40``. |
| ``cache_folder`` Set this to an existing directory to enable |
| caching of templates on the file system. Note |
| that this only affects templates transformed |
| into python code. Default is ``None`` which means |
| that caching is disabled. |
| ``auto_reload`` Set this to `False` for a slightly better |
| performance. In that case of `getmtime_func` |
| not being provided this won't have an effect. |
| =================== ================================================= |
| """ |
| warn(DeprecationWarning('general plugin interface implementation ' |
| 'deprecated because not an accepted ' |
| 'standard.')) |
| |
| if 'environment' in options: |
| env = options['environment'] |
| if not len(options) == 1: |
| raise TypeError('if environment provided no other ' |
| 'arguments are allowed') |
| else: |
| loader_func = options.pop('loader_func', None) |
| getmtime_func = options.pop('getmtime_func', None) |
| use_memcache = options.pop('use_memcache', False) |
| memcache_size = options.pop('memcache_size', 40) |
| cache_folder = options.pop('cache_folder', None) |
| auto_reload = options.pop('auto_reload', True) |
| if 'searchpath' in options: |
| options['loader'] = FileSystemLoader(options.pop('searchpath'), |
| use_memcache, memcache_size, |
| cache_folder, auto_reload) |
| elif 'package' in options: |
| options['loader'] = PackageLoader(options.pop('package'), |
| options.pop('package_path', ''), |
| use_memcache, memcache_size, |
| cache_folder, auto_reload) |
| elif loader_func is not None: |
| options['loader'] = FunctionLoader(loader_func, getmtime_func, |
| use_memcache, memcache_size, |
| cache_folder, auto_reload) |
| env = Environment(**options) |
| |
| def render_function(template, values, options): |
| if options.get('is_string'): |
| tmpl = env.from_string(template) |
| else: |
| try: |
| tmpl = env.get_template(template) |
| except TemplateNotFound: |
| return |
| return tmpl.render(**values) |
| |
| return render_function |