Extension Point : IRequestHandler
Interface | IRequestHandler | Since | 0.9 |
Module | trac.web | Source | api.py |
A IRequestHandler implementation handles web requests.
Purpose
As a web-based system, Trac naturally needs to handle web requests. The main work to implement the various different pages is delegated to IRequestHandler implementations.
Usage
Implementing the interface follows the standard guidelines found in TracDev/ComponentArchitecture and of course TracDev/PluginDevelopment.
Each IRequestHandler is called to match a web request. The first matching handler is then used to process the request.
Matching a request usually means checking the req.path_info
string (the part of the URL relative to the Trac root URL) against a specific string prefix or regular expression.
As this matching is potentially executed for each handler for each request it is somewhat performance sensitive. Avoid spending more time than absolutely necessary.
Processing a request can include basically anything. Commonly template data is prepared and returned together with a (HTML) template file name, which is then rendered and sent to the web browser.
It can also include parsing request parameters, permission checks, database queries and updates, dynamic content generation, alternative MIME types, calling external tools, adding JavaScript and CSS files, sending custom HTTP headers etc.
Using template files requires that some (but not necessarily the same) component implements ITemplateProvider appropriately.
To get the common Trac layout (with logo, navigation bars etc.) HTML templates should <xi:include href="layout.html" />
, and to actually activate a navigation bar item the IRequestHandler component should also implement INavigationContributor.
Instead of implementing IRequestHandler and handling the main part of a request, it's also possible to implement IRequestFilter or ITemplateStreamFilter to preprocess and postprocess requests or filter template streams of other request handlers.
Examples
A IRequestHandler can be occasionally useful in isolation, though usually it is accompanied by implementations of other interfaces. Hence the following example is best understood in context of the ComponentModuleExamples.
In Trac, components do not have their own page (besides the admin panel). The following example implementation changes this:
import re from trac.core import * from trac.ticket import model from trac.web import IRequestHandler class ComponentModule(Component): implements(IRequestHandler) # IRequestHandler methods def match_request(self, req): match = re.match(r'/component/(.+)$', req.path_info) if match: req.args['name'] = match.group(1) return True def process_request(self, req): name = req.args.get('name') data = {'component': model.Component(self.env, name)} return 'component.html', data, None
The accompanying component.html template (provided by an appropriate ITemplateProvider implementation):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:py="http://genshi.edgewall.org/" xmlns:i18n="http://genshi.edgewall.org/i18n"> <xi:include href="layout.html" /> <head> <title>Component $component.name</title> </head> <body> <h2>Component $component.name</h2> <p>Owner: $component.owner</p> <p>$component.description</p> </body> </html>
Available Implementations
Almost every Trac module implements IRequestHandler (and many more exist in third-party plugins).
Additional Information and References
- Epydoc API Reference
- See also ITemplateProvider, INavigationContributor, IRequestFilter, ITemplateStreamFilter
- Related tickets:
API History
- 0.9 introduced the interface.
- 0.11 added a class attribute
jquery_noconflict
that determines if jQuery should be activated in no-conflict mode. ([6715], see also #5954) - 1.1.2 added a class attribute
is_valid_default_handler
that determines if the class can be set as the[trac]
default_handler
. ([12624])