Edgewall Software

Changes between Initial Version and Version 1 of TracDev/PluginDevelopment/ExtensionPoints/trac.web.api.IRequestHandler


Ignore:
Timestamp:
Aug 21, 2011, 9:58:03 PM (8 years ago)
Author:
Peter Suter
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • TracDev/PluginDevelopment/ExtensionPoints/trac.web.api.IRequestHandler

    v1 v1  
     1== Extension Point : ''IRequestHandler'' ==
     2
     3||'''Interface'''||''IRequestHandler''||'''Since'''||0.9||
     4||'''Module'''||''trac.web''||'''Source'''||[source:trunk/trac/web/api.py api.py]||
     5
     6A ''IRequestHandler'' implementation handles web requests.
     7
     8== Purpose ==
     9
     10As a web-based system, Trac naturally needs to [TracDev/RequestHandling handle web requests]. The main work to implement the various different pages is delegated to IRequestHandler implementations.
     11
     12== Usage ==
     13
     14Implementing the interface follows the standard guidelines found in [wiki:TracDev/ComponentArchitecture] and of course [wiki:TracDev/PluginDevelopment].
     15
     16Each IRequestHandler is called to ''match'' a web request. The first matching handler is then used to ''process'' the request.
     17
     18Matching 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.
     19
     20As this matching is potentially executed for each handler for each request it is somewhat performance sensitive. Avoid spending more time than absolutely necessary.
     21
     22Processing 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.
     23
     24It 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.
     25
     26Using template files requires that some (but not necessarily the same) component implements [../trac.web.chrome.ITemplateProvider ITemplateProvider] appropriately.
     27
     28To 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 [../trac.web.chrome.INavigationContributor INavigationContributor].
     29
     30Instead of implementing IRequestHandler and handling the main part of a request, it's also possible to implement [../trac.web.api.IRequestFilter IRequestFilter] or [../trac.web.api.ITemplateStreamFilter ITemplateStreamFilter] to preprocess and postprocess requests or filter template streams of other request handlers.
     31 
     32== Examples ==
     33
     34A 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.
     35
     36In Trac, [TicketComponent components] do not have their own page (besides the admin panel). The following example implementation changes this:
     37{{{
     38#!python
     39import re
     40
     41from trac.core import *
     42from trac.ticket import model
     43from trac.web import IRequestHandler
     44
     45class ComponentModule(Component):
     46
     47    implements(IRequestHandler)
     48   
     49    # IRequestHandler methods
     50   
     51    def match_request(self, req):
     52        match = re.match(r'/component/(.+)$', req.path_info)
     53        if match:
     54            req.args['name'] = match.group(1)
     55            return True
     56
     57    def process_request(self, req):
     58        name = req.args.get('name')
     59        data = {'component': model.Component(self.env, name)}
     60        return 'component.html', data, None
     61}}}
     62
     63The accompanying ''component.html'' template (provided by an appropriate [../trac.web.chrome.ITemplateProvider ITemplateProvider] implementation):
     64{{{#!xml
     65<!DOCTYPE html
     66    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     67    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
     68<html xmlns="http://www.w3.org/1999/xhtml"
     69      xmlns:xi="http://www.w3.org/2001/XInclude"
     70      xmlns:py="http://genshi.edgewall.org/"
     71      xmlns:i18n="http://genshi.edgewall.org/i18n">
     72  <xi:include href="layout.html" />
     73  <head>
     74    <title>Component $component.name</title>
     75  </head>
     76  <body>
     77    <h2>Component $component.name</h2>
     78    <p>Owner: $component.owner</p>
     79    <p>$component.description</p>
     80  </body>
     81</html>
     82}}}
     83
     84== Available Implementations ==
     85
     86Almost every Trac module implements IRequestHandler (and many more exist in third-party plugins).
     87
     88== Additional Information and References ==
     89
     90 * [http://www.edgewall.org/docs/trac-trunk/epydoc/trac.web.api.IRequestHandler-class.html Epydoc API Reference]
     91 * See also [../trac.web.chrome.ITemplateProvider ITemplateProvider], [../trac.web.chrome.INavigationContributor INavigationContributor], [../trac.web.api.IRequestFilter IRequestFilter], [../trac.web.api.ITemplateStreamFilter ITemplateStreamFilter]
     92 * Related tickets:
     93  * #8509 use precompiled regex for `match_request`