Roundup Tracker

The roundup templating system, ZPT, allows for generation of feeds from queries in just the same way HTML is generated. This is completely dynamic and can produce feeds based on search criteria, which is very useful for getting precise information from roundup.

Dynamically generating your feeds (as opposed to DetectorBasedFeedGeneration) presents some advantages:

  1. You can be as flexible as the HTML pages, so you can generate ad hoc feeds based on searches or pretty much any other criteria you or your users can think of.
  2. You can play around with the templates on a live system without affecting anyone, with the detector you can break an issue tracker's editing ability if you break the detector.
  3. You can restrict what any given user can see, so a public tracker with private issues in it as well can present different lists of changes to different users from the same feed template.

There are also drawbacks:

  1. The biggest drawback on a public site is load, every time the feed is requested the page has to be generated. So this can place a heavy load on the server if people have news readers with a very high refresh frequency (down to 5 minutes in some cases).
  2. It's harder to present information on what has changed without writing a bit of logic to put together a list of changes. This means that users might not immediately be able to see what has changed in a given issue.

To add an atom 0.3 feed to an issue tracker you can do the following:

  1. Create a file called issue.index.xml in your tracker instance's html folder and add the following to it:

    <?xml version="1.0" encoding="utf-8"?>
      <feed version="0.3" xmlns="http://purl.org/atom/ns#"
            xmlns:tal="http://xml.zope.org/namespaces/tal"
            xmlns:metal="http://xml.zope.org/namespaces/metal">
        <title>Issues - <tal:block tal:replace="config/TRACKER_NAME" /></title>
        <link rel="alternate" type="text/html" tal:content="config/TRACKER_WEB">link</link>
        <tal:block tal:omit-tag="" tal:repeat="i request/batch">
          <entry>
              <title tal:content="i/title">title</title>
              <link rel="alternate" type="text/html" tal:content="string:${config/TRACKER_WEB}issue${i/id}">link</link>
              <id tal:content="python:config.TRACKER_NAME.replace(' ', '_') + ':issue' + i.id">id</id>
              <summary mode="escaped" type="text/html" tal:content="i/history"></summary>
              <issued tal:content="i/creation">issued</issued>
              <modified tal:content="i/activity">modified</modified>
         </entry>
       </tal:block>
     </feed>
  2. Any time you want to see an atom version of either a search result of an issue listing add '&@template=index.xml' to the URL, e.g. 'http://example.com/issues/issue?@template=index.xml'.

There are a couple of gotchas you have to watch out for:

  1. You must put in the XML namespaces ('xmlns:tal="http://xml.zope.org/namespaces/tal"' and 'xmlns:metal="http://xml.zope.org/namespaces/metal"') into the XML template or else ZPT can't see the tal and metal expressions. You know it hasn't picked up on the namespaces properly when you just see your template with the tal expressions left intact when you request a page.
  2. Currently only '.xml' is recognised as XML, anything else gets passed throught the HTML processor instead of the XML processor. This might not be immediately obvious but this does lead to a couple of issues:

    1. The wrong mime type is used in the request (this can confuse some news readers, and is plain incorrect).
    2. Certain tags can't contain content in HTML pages, so in the atom example above you would get an error about the '<link>' tag.

    If you want to make roundup recognise more document types you need to register them in the python mimetypes module in roundup's 'cgi/templating.py':

    ...
    import sys, cgi, urllib, os, re, os.path, time, errno, mimetypes
    
    # Register some new types
    mimetypes.add_type("text/xml", ".rss")
    
    from roundup import hyperdb, date, rcsv
    from roundup.i18n import _
    ...

    This requires hacking roundup's code so is only useful in situations where you really, really want a particular extension. It might make more sense for things like PDF generation, or generating XML with a particular mime type (e.g. 'application/xhtml+xml' for XHTML documents).