= 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 [wiki: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 === {{{ #!python 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 === {{{ #!python 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('''
... ${2 + 2} ...
''') >>> print tmpl.generate(bar='Bye')
""" __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))) return _apply_directives(stream, directives, ctxt, vars) @classmethod def get_execute_before(cls): return WhenDirective }}} === Example template.html === {{{ #!genshi ${1+1} }}}