Edgewall Software

Changes between Version 6 and Version 7 of TracPluggableModules


Ignore:
Timestamp:
Nov 20, 2004, 11:59:50 AM (18 years ago)
Author:
cboos@…
Comment:

Contribute idea: link to TracObjectModelProposal , module configurability and Client interfaces

Legend:

Unmodified
Added
Removed
Modified
  • TracPluggableModules

    v6 v7  
    6969 * contribute functionality to other modules
    7070 * provide hooks so that other modules can contribute to its functionality
     71
     72=== By using Function Hooks ===
    7173
    7274The supporting model for such cooperation between modules should be functions defined by the contributing plug-in, and called by the plug-in to which we contribute. For example, let's assume the timeline module documents the following hook functions (or ''extension points'' in Eclipse jargon):
     
    102104This is probably just the price to pay for a cleaner architecture, but optimizations may be possible.
    103105
     106=== By using ExtensionPoint Interfaces ===
     107
     108Alternatively, a Module could define one or
     109several client interfaces (all ExtensionPoint
     110subclasses), and the other modules could provide zero,
     111one or more implementations for this Client interface.
     112
     113This approach would provide both clarity and flexibility
     114(if not even a simpler programming model) than the
     115''hook functions'' approach.
     116
     117See a more detailed description below
     118'''Your Ideas Wanted / Modules and Configurability'''
     119
     120
    104121== Other Aspects of Plug-Ins ==
    105122
     
    115132--ChristopherLenz
    116133
     134=== Trac Modules and Trac Objects ===
     135
     136The approach of Pluggable Module described here
     137would be complementary to the Trac Objects idea
     138described here: TracObjectModelProposal.
     139
     140--ChristianBoos
     141
     142=== Modules and Configurability ===
     143
     144In some cases, one would like to have a fine control
     145on how a module works. I'll take an example.
     146The Timeline module interacts with the Ticket module.
     147The latter provide several timeline entries to be
     148displayed by the former, as well as specific filters
     149for composing the filter panel.
     150
     151But let's say I would be interested in having
     152the Ticket Contributions displayed (See #187 and my
     153patch at #890), whereas others wouldn't want this
     154option to be available. How to solve this?
     155 * Subclassing the Ticket module?
     156   (For the ''hook function approach'': not very
     157   flexible, what if there are multiple optional
     158   features)
     159 * A configuration flag for the Ticket module?
     160   (This would be more flexible, but, well, would be
     161   spaghetti code in the end!)
     162 * Have the Ticket module provide a (configurable) list
     163   of !TimelineEventProvider objects (the, or one of the
     164   ExtensionPoint interface that the Timeline module
     165   would offer)?
     166
     167The last idea seems the most interesting.
     168The Timeline module expects that the
     169other modules will provide zero or more
     170!TimelineEventProvider object.
     171
     172The Ticket module would implement all of the following subclasses of !TimelineEventProvider class:
     173 * !NewAndCloseTicketsInTimeline
     174 * !ReopenedTicketsInTimeline
     175 * !TicketContributionsInTimeline
     176
     177After being configured (either from the {{{trac.ini}}}
     178file, or any other mean, even dynamically!),
     179the Ticket module could decide which instances of
     180these subclasses will be given to the Timeline instance.
     181
     182The !TimelineEventProvider and ExtensionPoint could be
     183defined as:
     184{{{
     185#!python
     186class ExtensionPoint:
     187    def module(self):
     188        """The module providing this client for the timeline"""
     189        pass
     190    ...
     191
     192class TimelineEventProvider(ExtensionPoint):
     193    def query_string(self):
     194        """The SQL fragment which provides:
     195 * time: the timestamp of the event
     196 * idata: the unique identifier for this event
     197 * ... and so on
     198"""
     199        pass
     200
     201    def render_item(self,item):
     202        """Populate the item dictionary with hdf data"""
     203        pass
     204    ...
     205}}}
     206
     207--ChristianBoos
    117208
    118209