| 106 | === By using ExtensionPoint Interfaces === |
| 107 | |
| 108 | Alternatively, a Module could define one or |
| 109 | several client interfaces (all ExtensionPoint |
| 110 | subclasses), and the other modules could provide zero, |
| 111 | one or more implementations for this Client interface. |
| 112 | |
| 113 | This approach would provide both clarity and flexibility |
| 114 | (if not even a simpler programming model) than the |
| 115 | ''hook functions'' approach. |
| 116 | |
| 117 | See a more detailed description below |
| 118 | '''Your Ideas Wanted / Modules and Configurability''' |
| 119 | |
| 120 | |
| 134 | === Trac Modules and Trac Objects === |
| 135 | |
| 136 | The approach of Pluggable Module described here |
| 137 | would be complementary to the Trac Objects idea |
| 138 | described here: TracObjectModelProposal. |
| 139 | |
| 140 | --ChristianBoos |
| 141 | |
| 142 | === Modules and Configurability === |
| 143 | |
| 144 | In some cases, one would like to have a fine control |
| 145 | on how a module works. I'll take an example. |
| 146 | The Timeline module interacts with the Ticket module. |
| 147 | The latter provide several timeline entries to be |
| 148 | displayed by the former, as well as specific filters |
| 149 | for composing the filter panel. |
| 150 | |
| 151 | But let's say I would be interested in having |
| 152 | the Ticket Contributions displayed (See #187 and my |
| 153 | patch at #890), whereas others wouldn't want this |
| 154 | option 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 | |
| 167 | The last idea seems the most interesting. |
| 168 | The Timeline module expects that the |
| 169 | other modules will provide zero or more |
| 170 | !TimelineEventProvider object. |
| 171 | |
| 172 | The Ticket module would implement all of the following subclasses of !TimelineEventProvider class: |
| 173 | * !NewAndCloseTicketsInTimeline |
| 174 | * !ReopenedTicketsInTimeline |
| 175 | * !TicketContributionsInTimeline |
| 176 | |
| 177 | After being configured (either from the {{{trac.ini}}} |
| 178 | file, or any other mean, even dynamically!), |
| 179 | the Ticket module could decide which instances of |
| 180 | these subclasses will be given to the Timeline instance. |
| 181 | |
| 182 | The !TimelineEventProvider and ExtensionPoint could be |
| 183 | defined as: |
| 184 | {{{ |
| 185 | #!python |
| 186 | class ExtensionPoint: |
| 187 | def module(self): |
| 188 | """The module providing this client for the timeline""" |
| 189 | pass |
| 190 | ... |
| 191 | |
| 192 | class 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 |