Edgewall Software

Version 1 (modified by Peter Suter, 13 years ago) ( diff )

Extension Point : IRequestHandler

InterfaceIRequestHandlerSince0.9
Moduletrac.webSourceapi.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

Note: See TracWiki for help on using the wiki.