Map と Rule と EndpointPrefix と Submount。

Django の url ディスパッチャと似ているようで似ていない。正規表現は使いません。
そのかわりディスパッチャ時の型変換をカスタム出来ます、これはそのうち。

from werkzeug.routing import Rule, Map, EndpointPrefix, Submount

url_map = Map([
  Rule('/', endpoint='index'),
  EndpointPrefix('blog/', [
    Submount('/blog', [
      Rule('/', endpoint='index'),
      Rule('/entry/<entry_slug>', endpoint='entry_detail'),
      Rule('/entry/<entry_id>', endpoint='entry_detail'),
      Submount('/archive', [
        Rule('/<int:year>/', endpoint='archive_year'),
        Rule('/<int:year>/<int:month>/', endpoint='archive_month'),
        Rule('/<int:year>/<int:month>/<int:day>/', endpoint='archive_day'),
        Rule('/<int:year>/<int:month>/<int:day>/<int:entry_id>', endpoint='archive_detail'),
      ]),
    ]),
  ])
])

import unittest

class TestUrlMap(unittest.TestCase):
  def setUp(self):
    self.urls = url_map.bind('example.com', '/')

  def test_urls(self):
    self.assertEqual(self.urls.match('/'), ('index', {}))
    self.assertEqual(self.urls.match('/blog/'), ('blog/index', {}))
    self.assertEqual(self.urls.match('/blog/entry/pyspa-disc-5'),
        ('blog/entry_detail', {'entry_slug': 'pyspa-disc-5'}))
    self.assertEqual(self.urls.match('/blog/archive/2009/'),
        ('blog/archive_year', {'year': 2009}))
    self.assertEqual(self.urls.match('/blog/archive/2009/01/'),
        ('blog/archive_month', {'year': 2009, 'month': 1}))
    self.assertEqual(self.urls.match('/blog/archive/2009/01/01/'),
        ('blog/archive_day', {'year': 2009, 'month': 1, 'day': 1}))
    self.assertEqual(self.urls.match('/blog/archive/2009/01/01/100'),
        ('blog/archive_detail',
          {'year': 2009, 'month': 1, 'day': 1, 'entry_id': 100}))

  def tearDown(self):
    pass

if __name__ == '__main__':
  unittest.main()