Version 3 (modified by 10 years ago) ( diff ) | ,
---|
Extension Point : INotificationFormatter
Interface | INotificationFormatter | Since | 1.1.2 |
Module | trac.notification | Source | api.py |
The INotificationFormatter formats notification events to messages in various formats ready to be distributed.
Purpose
Trac provides an extendible and flexible notification system, that historically has sent plain text emails for ticket changes. Notifications of different event realms (e.g. wiki notifications), transports (e.g. SMS) and message formats (e.g. HTML messages) might all require different formatting logic though.
Usage
Implementing the interface follows the standard guidelines found in TracDev/ComponentArchitecture and of course TracDev/PluginDevelopment.
A simple styles()
method lists the supported MIME types for a given transport and event realm.
The format()
method formats a notification event. It receives the following parameters:
transport
: The name of the transports that should be used. (See INotificationDistributor)style
: The style that should be used. One of those returned bystyles()
.event
: Atrac.notification.api.NotificationEvent
instance describing the event about which the recipients should be notified.
It should return the formatted message. The exact return type depends on the transport.
Examples
The following example formats notifications by SMS. (The sms
library does not exist. Several commercial SMS services provide real APIs.)
from trac.core import * from trac.notification.api import INotificationFormatter class ShortTicketNotificationFormatter(Component): implements(INotificationFormatter) # INotificationFormatter methods def styles(self, transport, realm): if transport == 'sms' and realm == 'ticket': yield 'text/plain' def format(self, transport, style, event): if transport == 'sms' and event.realm == 'ticket': return "#{0} {1} by {2}" % (event.target, event.category, event.author)
Available Implementations
At first only trac.ticket.notification.TicketFormatter
is part of core Trac.
A subsequent part of this proposal would add trac.wiki.notification.WikiFormatter
.
Various other formatters will be part of th:AnnouncerPlugin.
Additional Information and References
- epydoc
- API Reference
- Related to the INotificationDistributor
- This interface originated in th:AnnouncerPlugin as
IAnnouncementFormatter
.- DONE Dropped the
alternative_style_for()
method. (The distributor can select fallbacks without this.) - DONE Dropped the
realm
parameter to theformat()
method. (Useevent.realm
instead.)
- DONE Dropped the
Open questions
Enumerate all styles?
Maybe styles()
should be changed to enumerate the supported style / transport / realm combinations as tuples:
def styles(self): yield ('text/plain', 'sms', 'ticket')
Advantage: This would give access to the list of all supported styles, without guessing the supported realms. For example a preferences panel could then create a preferred style selection UI, listing all supported styles.
Disadvantage: Formatters could not implement catch-all fallbacks that e.g. claim to support all transports. But all current Announcer formatters do just this.
Possible solutions:
- Do not allow formatters to support all transports. Is that actually even feasible? The formatter interface even states that it must be explicitly designed to work with a specific distributor.
- Require all formatters to support all transports. Remove the transports parameter. This would prevent using different formatters for different transports. (At least the return type of
format()
could then probably be defined to some standardized type.) - Allow formatters to return
None
or'*'
to support all transports. - Define the interface with two methods. One method with parameters as before; another method without parameters must list all supported styles for any transport or realm.
- Define the interface with one method, with optional parameters. If the parameters are
None
the method must list all supported styles for any transport or realm.
Similary, could some formatters want to support all realms?
The chosen solution should be simple and easy to implement correctly by plugin authors.