Django-esque URL Resolution in Nevow

Posted on March 09, 2007 by oubiwann


Blog post image

So, from the previous post on object publishing in Nevow, we had the following resources:

  • http://localhost:8080/
  • http://localhost:8080/m ystuff
  • 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, ()
else:
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: , , , ,

Author oubiwann
Date March 09, 2007
Time 02:04:08
Category
Tags
Line Count 1
Word Count 382
Character Count 5091

Comments?
This blog doesn't use standard (embedded) comments; however, since the site is hosted on Github, if there is something you'd like to share, please do so by opening a "comment" ticket!