Skip to content

Getting TracRedirect to work with Trac 0.11rc1

I’m a big fan of Trac, and I use it for project management when I’m given the choice. It has a few issues, but nothing a little plugin magic can’t fix. On of my favorite plugins is TracRedirect, which allows me to make one page point to another and make the browser redirect there, so “Customers” points to “Customer”, and I can be lazy when I’m typing other pages and use whichever one makes the most sense.

But TracRedirect does not play nice with the latest version of Trac, 0.11. In fact, it makes 0.11 die. This is bad.

I don’t really know Python. I mean, I can get by, but I don’t really know it. So the prospect of patching some code for a plugin in a language I don’t know for a project whose code I’ve never seen is at once intimidating and exciting. The reason I’m a programmer is because the exciting won, and I fumbled around until I got it working. The diff between the latest svn code and my own is after the jump; it’s mostly just updating IWikiMacroProvider to take the new args 0.11 passes its way, but there’s another little fix to include the redirect stylesheet using the new method, as the old method didn’t seem to work reliably.

--- 3245)
+++ copy)
@@ -47,6 +47,7 @@
 import re
 from trac.core import Component, implements
 from import WikiSystem, IWikiMacroProvider
+from trac.web.api import IRequestFilter
 from import ITemplateProvider, INavigationContributor, add_stylesheet
 from import Formatter
 from trac.util import Markup
@@ -80,19 +81,20 @@

 class Redirect(Component):

-    implements(IWikiMacroProvider, ITemplateProvider, INavigationContributor)
+    implements(IWikiMacroProvider, ITemplateProvider, INavigationContributor, IRequestFilter)

     # IWikiMacroProvider methods
-    def execute(self, req, args):
+    def execute(self, formatter, name, args):
         Main routine of the wiki macro.
+        req = formatter.context.req
         preview = req.args.get('preview', '')
         shouldRedirect = req.args.get('redirect', 'yes') == 'yes' and (not preview)
         curpage = req.args.get('page', '') or 'WikiStart'

         out = StringIO()
-        link, missing = RedirectFormatter(self.env, req).format(args)
+        link, missing = RedirectFormatter(self.env, formatter.context).format(args)

         if link and not missing:
             out.write('<div class="system-message">')
@@ -133,8 +135,8 @@
     def get_macros(self):
         yield 'redirect'

-    def render_macro(self, req, name, args):
-        return self.execute(req, args)
+    def expand_macro(self, formatter, name, args):
+        return self.execute(req, formatter, name, args)

     def get_macro_description(self, name):
         from inspect import getdoc, getmodule
@@ -156,7 +158,6 @@
         return 'redirectedfrom'

     def get_navigation_items(self, req):
-        add_stylesheet(req, 'redirect/css/redirect.css')
         redirectedfrom = req.args.get('redirectedfrom', '')
         if redirectedfrom:
             yield 'metanav', 'redirectedfrom',\
@@ -164,3 +165,11 @@
                          '(<a href="%s">hide</a>)</span>',
                 + '?redirect=no', redirectedfrom,
                          req.base_path + req.path_info)
+    # IRequestFilter methods
+    def pre_process_request(self, req, handler):
+        add_stylesheet(req, 'redirect/css/redirect.css')
+        return handler
+    def post_process_request(self, req, template, content_type):
+        return(template, content_type)