Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/websdk/genshi/template/plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'websdk/genshi/template/plugin.py')
-rw-r--r--websdk/genshi/template/plugin.py176
1 files changed, 176 insertions, 0 deletions
diff --git a/websdk/genshi/template/plugin.py b/websdk/genshi/template/plugin.py
new file mode 100644
index 0000000..70d56af
--- /dev/null
+++ b/websdk/genshi/template/plugin.py
@@ -0,0 +1,176 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2006-2009 Edgewall Software
+# Copyright (C) 2006 Matthew Good
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://genshi.edgewall.org/wiki/License.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For the exact contribution history, see the revision
+# history and logs, available at http://genshi.edgewall.org/log/.
+
+"""Basic support for the template engine plugin API used by TurboGears and
+CherryPy/Buffet.
+"""
+
+from genshi.input import ET, HTML, XML
+from genshi.output import DocType
+from genshi.template.base import Template
+from genshi.template.loader import TemplateLoader
+from genshi.template.markup import MarkupTemplate
+from genshi.template.text import TextTemplate, NewTextTemplate
+
+__all__ = ['ConfigurationError', 'AbstractTemplateEnginePlugin',
+ 'MarkupTemplateEnginePlugin', 'TextTemplateEnginePlugin']
+__docformat__ = 'restructuredtext en'
+
+
+class ConfigurationError(ValueError):
+ """Exception raised when invalid plugin options are encountered."""
+
+
+class AbstractTemplateEnginePlugin(object):
+ """Implementation of the plugin API."""
+
+ template_class = None
+ extension = None
+
+ def __init__(self, extra_vars_func=None, options=None):
+ self.get_extra_vars = extra_vars_func
+ if options is None:
+ options = {}
+ self.options = options
+
+ self.default_encoding = options.get('genshi.default_encoding', 'utf-8')
+ auto_reload = options.get('genshi.auto_reload', '1')
+ if isinstance(auto_reload, basestring):
+ auto_reload = auto_reload.lower() in ('1', 'on', 'yes', 'true')
+ search_path = [p for p in
+ options.get('genshi.search_path', '').split(':') if p]
+ self.use_package_naming = not search_path
+ try:
+ max_cache_size = int(options.get('genshi.max_cache_size', 25))
+ except ValueError:
+ raise ConfigurationError('Invalid value for max_cache_size: "%s"' %
+ options.get('genshi.max_cache_size'))
+
+ loader_callback = options.get('genshi.loader_callback', None)
+ if loader_callback and not hasattr(loader_callback, '__call__'):
+ raise ConfigurationError('loader callback must be a function')
+
+ lookup_errors = options.get('genshi.lookup_errors', 'strict')
+ if lookup_errors not in ('lenient', 'strict'):
+ raise ConfigurationError('Unknown lookup errors mode "%s"' %
+ lookup_errors)
+
+ try:
+ allow_exec = bool(options.get('genshi.allow_exec', True))
+ except ValueError:
+ raise ConfigurationError('Invalid value for allow_exec "%s"' %
+ options.get('genshi.allow_exec'))
+
+ self.loader = TemplateLoader([p for p in search_path if p],
+ auto_reload=auto_reload,
+ max_cache_size=max_cache_size,
+ default_class=self.template_class,
+ variable_lookup=lookup_errors,
+ allow_exec=allow_exec,
+ callback=loader_callback)
+
+ def load_template(self, templatename, template_string=None):
+ """Find a template specified in python 'dot' notation, or load one from
+ a string.
+ """
+ if template_string is not None:
+ return self.template_class(template_string)
+
+ if self.use_package_naming:
+ divider = templatename.rfind('.')
+ if divider >= 0:
+ from pkg_resources import resource_filename
+ package = templatename[:divider]
+ basename = templatename[divider + 1:] + self.extension
+ templatename = resource_filename(package, basename)
+
+ return self.loader.load(templatename)
+
+ def _get_render_options(self, format=None, fragment=False):
+ if format is None:
+ format = self.default_format
+ kwargs = {'method': format}
+ if self.default_encoding:
+ kwargs['encoding'] = self.default_encoding
+ return kwargs
+
+ def render(self, info, format=None, fragment=False, template=None):
+ """Render the template to a string using the provided info."""
+ kwargs = self._get_render_options(format=format, fragment=fragment)
+ return self.transform(info, template).render(**kwargs)
+
+ def transform(self, info, template):
+ """Render the output to an event stream."""
+ if not isinstance(template, Template):
+ template = self.load_template(template)
+ return template.generate(**info)
+
+
+class MarkupTemplateEnginePlugin(AbstractTemplateEnginePlugin):
+ """Implementation of the plugin API for markup templates."""
+
+ template_class = MarkupTemplate
+ extension = '.html'
+
+ def __init__(self, extra_vars_func=None, options=None):
+ AbstractTemplateEnginePlugin.__init__(self, extra_vars_func, options)
+
+ default_doctype = self.options.get('genshi.default_doctype')
+ if default_doctype:
+ doctype = DocType.get(default_doctype)
+ if doctype is None:
+ raise ConfigurationError('Unknown doctype %r' % default_doctype)
+ self.default_doctype = doctype
+ else:
+ self.default_doctype = None
+
+ format = self.options.get('genshi.default_format', 'html').lower()
+ if format not in ('html', 'xhtml', 'xml', 'text'):
+ raise ConfigurationError('Unknown output format %r' % format)
+ self.default_format = format
+
+ def _get_render_options(self, format=None, fragment=False):
+ kwargs = super(MarkupTemplateEnginePlugin,
+ self)._get_render_options(format, fragment)
+ if self.default_doctype and not fragment:
+ kwargs['doctype'] = self.default_doctype
+ return kwargs
+
+ def transform(self, info, template):
+ """Render the output to an event stream."""
+ data = {'ET': ET, 'HTML': HTML, 'XML': XML}
+ if self.get_extra_vars:
+ data.update(self.get_extra_vars())
+ data.update(info)
+ return super(MarkupTemplateEnginePlugin, self).transform(data, template)
+
+
+class TextTemplateEnginePlugin(AbstractTemplateEnginePlugin):
+ """Implementation of the plugin API for text templates."""
+
+ template_class = TextTemplate
+ extension = '.txt'
+ default_format = 'text'
+
+ def __init__(self, extra_vars_func=None, options=None):
+ if options is None:
+ options = {}
+
+ new_syntax = options.get('genshi.new_text_syntax')
+ if isinstance(new_syntax, basestring):
+ new_syntax = new_syntax.lower() in ('1', 'on', 'yes', 'true')
+ if new_syntax:
+ self.template_class = NewTextTemplate
+
+ AbstractTemplateEnginePlugin.__init__(self, extra_vars_func, options)