Extension Point : ITicketManipulator
Interface | ITicketManipulator | Since | 0.10 |
Module | trac.ticket.api | Source | api.py |
The ITicketManipulator can manipulate and validate tickets before saving.
Purpose
The Trac ticketing system is extendable by plugins. These plugins might add additional fields or introduce new restrictions on existing fields. They might want to automatically manage some fields. Any such ticket manipulations or validations can be added by implementing the ITicketManipulator interface.
Usage
Implementing the interface follows the standard guidelines found in TracDev/ComponentArchitecture and of course TracDev/PluginDevelopment.
The validate_ticket
method is called when a user creates or modifies a ticket. Returning a list of messages rejects the (changed) ticket, returning []
accepts it.
Note that the validate_ticket
method can also be used to manipulate the ticket's fields before they are saved.
Note that the validate_ticket
method is also called during preview. Check if 'submit' in req.args
or 'preview' in req.args
to determine if the validated ticket is getting saved or just previewed.
Since 1.3.2, validate_comment
is called when appending or editing a ticket comment. The method is optional, and therefore only invoked when the method is present on the class implementing ITicketManipulator
. Check for 'edit_comment' in req.args
or 'preview_comment' in req.args
to determine if the ticket comment edit is being submitted or previewed.
Note that the previous values of a changed ticket can be accessed in ticket._old
. (See #10495.)
The prepare_ticket
method should always be implemented as an empty dummy method for compatibility reasons:
def prepare_ticket(self, req, ticket, fields, actions): pass
Examples
One might want to maintain a wiki page with the MostFrequentDuplicates. One could take this idea further and implement a minimal example ITicketManipulator implementation that warns about tickets already listed there:
import re from trac.core import Component, implements from trac.ticket.api import ITicketManipulator class MostFrequentDuplicates(Component): implements(ITicketManipulator) def prepare_ticket(self, req, ticket, fields, actions): pass def validate_ticket(self, req, ticket): for id, summary in self.mostfrequentduplicates: if summary == ticket['summary'] and int(id) != ticket['id']: return [(None, "Duplicate of ticket #%s" % id)] return [] _page_name = 'MostFrequentDuplicates' _duplicate_re = re.compile(r" - #(\d*): '''(.*)'''") @cached def mostfrequentduplicates(self, db): """List of (id, summary) values.""" from trac.wiki.model import WikiPage duplicates = [] content = WikiPage(self.env, MostFrequentDuplicates._page_name, db=db).text for line in content.split('\n'): m = re.match(MostFrequentDuplicates._duplicate_re, line) if m: duplicates.append(m.groups()) return duplicates
- comment:1:ticket:10384 Contains an example that makes milestone a required field.
Available Implementations
- SpamFilter: Reject ticket changes that contain spam
- th:InputfieldTrapPlugin: Rejects spam with a hidden input field.
- th:MathCaptchaPlugin: Rejects spam with math question CAPTCHA.
- th:TracTicketValidatorPlugin: Rejects invalid (configurable) fields.
- th:BlackMagicTicketTweaksPlugin: Rejects ticket changes to disabled or hidden fields.
- th:SensitiveTicketsPlugin: Rejects anonymous sensitive tickets.
- th:ChildTicketsPlugin: Rejects invalid child/parent ticket relations.
- th:MasterTicketsPlugin: Rejects closing a ticket that is blocked.
- th:RemoteTicketPlugin: Rejects closing a ticket that is blocked.
- th:TracDupPlugin: Rejects changes to the duplicate ticket management fields.
- th:DateFieldPlugin: Rejects tickets with invalid dates.
- th:TimingAndEstimationPlugin: Rejects invalid hours and estimatedhours fields.
- th:TracHoursPlugin: Changes ticket comments that mention hours to link to a special hours management page.
- th:BudgetingPlugin: Rejects tickets with invalid budgeting fields.
- th:EpochFieldPlugin: Converts epoch fields.
- th:ImageTracPlugin: Rejects tickets with invalid images.
- th:TracStoryPointsPlugin: Rejects tickets with invalid storypoints and completed fields.
- th:GeoTicketPlugin: Updates a ticket's geolocation fields.
Additional Information and References
- epydoc
- API Reference
- See trac.ticket.api.ITicketChangeListener
- See trac.ticket.api.ITicketActionController
- See trac.attachment.IAttachmentManipulator, trac.wiki.api.IWikiPageManipulator
- Related tickets:
- ticket system component
- #3029 Initial implementation.
- #10125 Discusses unused
prepare_ticket
method- comment:15:ticket:10125 and following discuss ideas for fundamental refactoring
- #6879 Discusses relation to ticket fields changed by the workflow and ITicketActionController
- #6634 Discusses validation messages containing markup (e.g. links).
- Archived mailing list discussions:
- Example illustrating the original idea for
prepare_ticket_for_render
. This would not work now.
- Example illustrating the original idea for