Edgewall Software

Changes between Initial Version and Version 2 of Ticket #10226


Ignore:
Timestamp:
Jun 17, 2011, 12:13:41 AM (13 years ago)
Author:
Remy Blank
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #10226 – Description

    initial v2  
    66PROBLEM
    77
    8 Currently, we are able to extend Trac at the response/template stream processing level only. At the response processing level, we are able to introduce custom ITemplateStreamFilterS, however, none of these have the power of actually introducing new directives to the Genshi template engine. As such, they will not be evaluated during rendering of the template, but instead will have to process all of the generated stream multiple times. In the end, this will lead to minor to massive performance decrease depending on the number of filters in your system.
     8Currently, we are able to extend Trac at the response/template stream processing level only. At the response processing level, we are able to introduce custom `ITemplateStreamFilter`s, however, none of these have the power of actually introducing new directives to the Genshi template engine. As such, they will not be evaluated during rendering of the template, but instead will have to process all of the generated stream multiple times. In the end, this will lead to minor to massive performance decrease depending on the number of filters in your system.
    99
    1010Of course, one can still implement custom Python macros that will be evaluated during request processing, however, these will not provide for the power inherent to custom directives. Besides that, these macros are not be Trac components and thus they cannot participate in the overall benefits provided by Trac's component system.
     
    1515I would like to propose that we add an extension point for plugging in additional directive factories that would provide extra functionality at the template level.
    1616
    17 This will require a new entry point, say, ITemplateDirectiveProvider.
     17This will require a new entry point, say, `ITemplateDirectiveProvider`.
    1818
    1919The interface is simple, it basically requires a single method:
    20 
     20{{{#!python
    2121get_template_directives()
    22 
    23 which will return both the namespace and a factory derived from DirectiveFactory as a tuple, or multiple such tuples in case that it provides multiple namespaces and directives belonging to these namespaces.
     22}}}
     23which will return both the namespace and a factory derived from `DirectiveFactory` as a tuple, or multiple such tuples in case that it provides multiple namespaces and directives belonging to these namespaces.
    2424
    2525Example:
    26 
    27 class !MyDirectivesProvider(Component):
     26{{{#!python
     27class MyDirectivesProvider(Component):
    2828     implements(ITemplateDirectiveProvider)
    2929
    3030     def get_template_directives():
    31           yield ('!http://some.namespace.here', !MyDirectiveFactory())
    32 
    33 It will also require a slight modification to trac.web.chrome which will a) query for any extensions to the extension point, e.g.
    34 
     31          yield ('http://some.namespace.here', MyDirectiveFactory())
     32}}}
     33It will also require a slight modification to `trac.web.chrome` which will a) query for any extensions to the extension point, e.g.
     34{{{#!python
    3535   directive_providers = ExtensionPoint(ITemplateDirectiveProvider)
    36  
     36}}}
    3737and, b) will add the directives and the namespaces provided by those plugins upon load of a given template in
    38 
     38{{{#!python
    3939   def load_template(...):
    4040       ...
     
    4242             for namespace, factory in provider.get_template_directives():
    4343                 template.add_directives(namespace, factory)
    44 
     44}}}
    4545
    4646RATIONALE
    4747
    48 While the ITemplateStreamFilter still has its purpose as a post processing mechanism at the markup stream level, by introducing new template level directives, one can easily introduce much more complex concepts into Trac, that will be executed and evaluated during template processing.
     48While the `ITemplateStreamFilter` still has its purpose as a post processing mechanism at the markup stream level, by introducing new template level directives, one can easily introduce much more complex concepts into Trac, that will be executed and evaluated during template processing.
    4949Subsequently, processing these custom directives will be a one time operation while Genshi processes the event stream internally.
    5050
    5151For a more sophisticated example of what can be done by introducing custom directives to the Genshi template, see for example the proposal for portlets over at [wiki:TracDev/Proposals/PortalTrac].
    5252
    53 There, you have the IPortlet extension point, which in turn is evaluated by a template directive <p:portlet ... />. The component extending upon IPortlet is able to implement arbitrary extension points and thus can serve both as a content provider for template rendering purposes, and it also can serve as an IRequestHandler etc.
     53There, you have the `IPortlet` extension point, which in turn is evaluated by a template directive `<p:portlet ... />`. The component extending upon `IPortlet` is able to implement arbitrary extension points and thus can serve both as a content provider for template rendering purposes, and it also can serve as an `IRequestHandler` etc.