Pluggable Directives Libraries (#395)
Goals
- provide for a framework for introducing additional directives into the system, even from different namespace
- TODO existing directives may be overridden, i.e. alternate versions will simply replace existing directives from a different library
- might require some configuration by the user for choosing the correct implementation, if multiple such replacements are available
- zero configuration effort by the user
- detection of available directives libraries is via the [genshi.libraries.directives] entry point
- available directives libraries in the system will be automatically loaded by the system
- api for programmatically adding new directives libraries (similar to the current concept of pluggable DirectiveFactory's, which will be dropped once this is stable)
- extended text based templates, see WorkInProgress/PluggableDirectivesLibraries/TextTemplates
- execution order of directives must be redefined so that directives defined by third party libraries will be executed in the correct order, and if a given directive does not impose any restrictions on its execution order, then it will be executed in document order
- this allows for adding new directives to existing directive namespaces
- this seems more natural since we are not dealing with operators here and as it is also found in common programming languages where the in-source order of statements is the normally the same order that they are executed in
- refactoring of the i18n filter into a filter module and a directives library (DONE, untested)
- refactoring of the standard directives into a base module and a directives library (DONE, tested, text template will fail since it is currently under development)
Current Development State
- currently in early alpha phase (existing test cases do not break and performance is comparable to standard genshi ~ 100..200..400 ms for rendering the trac templates incl. a site.html on my local system)
More information will be made available as soon as the initial prototype is working.
Wishlist
Feel free to add your wishes for this feature. Please do not remove existing wishes from other users, extend upon them.
- see #296 for a py:element directive
- see #321 for a py:comment directive
- see #104 for a proposal on CDATA output (which could be made a directive)
- working branch to develop this in a joint effort on g.e.o. directly
Example Directives Library
This example serves as a skeleton for ongoing development. It also serves as the initial documentation for the new feature.
Example setup.py
try: from setuptools import setup, Feature from setuptools.command.bdist_egg import bdist_egg except ImportError: from distutils.core import setup Feature = None bdist_egg = None setup( name = 'GenshiSampleDirectivesLibrary', version = '1.0.0proto_proto', description = 'A sample genshi directives library', long_description = \ """""", author = 'axn-software.de, Carsten Klein', author_email = 'info@axn-software.de', license = 'BSD', url = 'http://genshi.edgewall.org/wiki/WorkInProgress/PluggableDirectivesLibraries', #download_url = 'http://genshi.edgewall.org/wiki/Download', classifiers = [ 'Development Status :: 2 - Prototype', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Text Processing :: Markup :: HTML', 'Topic :: Text Processing :: Markup :: XML' ], keywords = ['python.templating.engines'], packages = ['sample'], #test_suite = 'genshi.tests.suite', entry_points = """ [genshi.libraries.directives] genshi-sample = sample.directives_library:SampleDirectivesLibrary """ )
Example directives_library.py
from genshi.core import Markup, TEXT from genshi.template.base import TemplateSyntaxError, _apply_directives from genshi.template.default_directives_library import WhenDirective from genshi.template.directives import Directive, DirectivesLibrary NAMESPACE = "http://genshi.edgewall.org/directives/sample/" class SampleDirectivesLibrary(DirectivesLibrary): def __init__(self): DirectivesLibrary.__init__(self, [CommentDirective, #ElementDirective #CDATADirective ], default_namespace = NAMESPACE) # taken from ticket #321 comment directive patch class CommentDirective(Directive): """Implementation of the ``sample:comment`` template directive. This directive replaces the content of the element with the result of evaluating the value of the ``sample:comment`` attribute: >>> from genshi.template import MarkupTemplate >>> tmpl = MarkupTemplate('''<div xmlns:sample="http://genshi.edgewall.org/directives/sample"> ... <sample:comment>${2 + 2}</sample:comment> ... </div>''') >>> print tmpl.generate(bar='Bye') <div> <!--4--> </div> """ __slots__ = [] @classmethod def attach(cls, template, stream, value, namespaces, pos): if type(value) is not dict: raise TemplateSyntaxError('The comment directive can only be used ' 'as an element', template.filepath, *pos[1:]) return super(CommentDirective, cls).attach(template, stream, value, namespaces, pos) def __call__(self, stream, directives, ctxt, **vars): stream = list(stream) stream.insert(0, (TEXT, Markup("<!--"), (None, 1, 0))) stream.append((TEXT, Markup("-->"), (None, 1, 0))) return _apply_directives(stream, directives, ctxt, vars) @classmethod def get_execute_before(cls): return WhenDirective
Example template.html
<html xmlns:sample="http://genshi.edgewall.org/directives/sample"> <body> <sample:comment> ${1+1} </sample:comment> </body> </html>
Last modified 14 years ago
Last modified on Jun 17, 2010, 11:51:32 PM