Friday, March 09, 2007

Django-esque URL Resolution in Nevow

So, from the previous post on object publishing in Nevow, we had the following resources:
  • http://localhost:8080/
  • http://localhost:8080/mystuff
  • http://localhost:8080/yourstuff
We added child_* attributes and methods to the "root" class, thus defining the "mystuff" and "yourstuff" resources. But what if we want to do it like Django does it? In other words, how do we map paths in the URL to resources via regular expressions?

It's actually fairly straight-forward. All we need to do is the following:
  1. Create a tuple of patterns.
  2. Override the locateChild() method in our "root" class.
Working with and extending the examples from the previous post, we might create a patterns tuple like this:

urlPatterns = (
(r'/mystuff(.*)', MyStuffResource),
(r'/yourstuff/blog(.*)', BlogResource),
(r'/yourstuff(.*)', YourStuffResource),
Then, in SiteRoot, we could do something like the following:

    def locateChild(self, context, segments):
path = '/'.join(('',) + segments)
for regex, resource in urlPatterns:
match = re.match(regex, path)
if match:
newPath = match.groups()[0]
r = resource()
if newPath in ['', '/']:
return r, ()
newSegments = newPath.split('/')[1:]
return r.locateChild(context, newSegments)
return super(SiteRoot, self).locateChild(context, segments)
What we're doing here is interrupting the "natural" flow of Nevow's path processing. If there are more segments once we've found a match, we pass the additional segments on to the child resource's locateChild() method. If not, we have a final destination and can return the resource itself.

Here are some screenshots of this in action:

415352821 6C5Cd31031 O
415352839 64Bee68A6A O
415352871 267C96D7A0 O
415352893 73D1095E30 O

You can browse the code for this at the following links:

Technorati Tags: , , , ,


  1. Have you tried routes as well?

  2. That's actually the third planned object publishing article in this series. It's still "planned", though (i.e., not definite), as routes really doesn't fit my brain and may, in fact, not be a good match for Nevow. I will give it a shot, and if I can get it working well, I'll write that up too :-)