Edgewall Software

Version 4 (modified by Peter Suter, 8 years ago) ( diff )

Link to #6543 where a generic replacement interface is discussed

Extension Point : IAttachmentChangeListener


The IAttachmentChangeListener allows components to listen for and to react to attachment events.


Trac allows users to attach arbitrary files to e.g. tickets or wiki pages. Plugins can hook into the attachment module to trigger their own actions when attachments are added, deleted or reparented (i.e. moved to another parent resource or with a renamed parent resource).

The main purpose for this interface is to allow plugins to stay informed about the existing attachments and trigger appropriate actions elsewhere (e.g. sending notifications, starting indexing services, updating supplementary data structures etc.)

(For attachment validation and manipulation use IAttachmentManipulator instead.)


Implementing the interface follows the standard guidelines found in TracDev/ComponentArchitecture and of course TracDev/PluginDevelopment.

When a user adds a new attachment the attachment_added method is called. Similarly attachment_deleted is called when a user deletes an attachment or its parent resource, and attachment_reparented is called when a user moves an attachment to a new parent resource or renames the parent resource.


A common use case for attachments is to attach images to wiki pages. For convenience you might want to automatically append an Image macro to the wiki page. The following minimal example IAttachmentChangeListener implementation could implement such a feature:

from trac.core import Component, implements
from trac.attachment import IAttachmentChangeListener
from trac.mimeview.api import get_mimetype
from trac.wiki.model import WikiPage

class ImageAutoAppender(Component):

    def attachment_added(self, attachment):
        if attachment.parent_realm != 'wiki':
        mimetype = get_mimetype(attachment.filename)
        if not mimetype.startswith('image/'):
        page = WikiPage(self.env, attachment.parent_id)
        page.text += '[[Image(%s)]]' % (attachment.filename,)
        page.save(attachment.author, 'Auto-append image', attachment.ipnr)

    def attachment_deleted(self, attachment):

    def attachment_reparented(self, attachment, old_parent_realm, old_parent_id):

Available Implementations

Additional Information and References

API History

Note: See TracWiki for help on using the wiki.