CherryPy Project Download

RoutesUrlMatching: tut11_routes.py

Line 
1 """
2 Tutorial - Routes
3
4 In this tutorial, we will try to see what can be done with routes and what can't (at least with Routes 1.8).
5 We are going to create a very simple application customized for each user.
6 """
7
8 import cherrypy
9
10 class Profile(object):
11
12     def __init__(self):
13         self. users = {
14             'marc' : {'id': 1, 'email': 'marc@test.com', 'interests': ['knitting', 'coding', 'beer drinking']},
15             'paul' : {'id': 2, 'email': 'paul@test.com', 'interests': ['kitty hunting', 'throwing rocks at children']}
16         }
17
18     def interests(self, user, id=None):
19         user = user.lower()
20         if user in self.users.keys():
21             if id is not None and 0 <= int(id) < len(self.users[user]['interests']):
22                 return user + "'s interests: " + self.users[user]['interests'][int(id)]
23             if id is None:
24                 return user + "'s interests: " + str(self.users[user]['interests'])
25         return user + " does not exist. Or the id specified is not valid."
26    
27     def home(self, user, field=None):
28         user = user.lower()
29         if field not in ['email', 'interests']:
30             field = None
31         if user in self.users.keys():
32             if field is not None and field in self.users[user].keys():
33                 return user + "'s " + field + ": " + str(self.users[user][field])
34             else:
35                 res = ""
36                 for field in self.users[user].keys():
37                     res += user+ "'s " + field + ": " + str(self.users[user][field]) + "<br/>"
38                 return res
39         return user + " does not exist"
40
41
42
43 # getting the Routes dispatcher
44 d = cherrypy.dispatch.RoutesDispatcher()
45 root = Profile()
46
47 # here is the standard way of doing things with routes
48 # thanks to "URL Minimization", uri like
49 # /interests/marc
50 # /interests/marc/2
51 # are both matched by the same route.
52
53 #d.connect('second route', '/interests/:user/:id', controller=root, action='interests', id=0)
54 #d.connect('first route', '/home/:user/:field', controller=root, action='home', field=None)
55
56 # but what happens when you want to do prettier uri ?
57 # let's assume that your app is user centered.
58 # Having all url starting with the user name is by far nicer
59 # /marc/interests is more attractive than /interests/marc
60 # moreover, it would be very nice to be able to access "home" through /marc and not /marc/home
61 # the intuitive way of doing so is the following:
62 # d.connect('interests', '/:user/interests/:id', controller=root, action='interests', id=0)
63 # d.connect('home', '/:user/:field', controller=root, action='home', field=None)
64 # Note that the order is very important here, as Routes stops at the first route matched.
65 # but as you can see, accessing /marc does not display marc's home but the page you would expect to get at /marc/interests/0
66
67 # Although it should not be this way, the url minimization in routes makes this possible
68 # For further detail, look at Routes' doc. It has to do with minization and implicit values of variables
69 # The only solution is forget minimization and only use explicit routes.
70 # To do so, 2 things must be done:
71 # first of all, not doing things like 'field=None'
72 # second of all, disabling implicit routes
73 # the default form for a route is /:controller/:action/:id
74 # you can just do d.connect('/:controller/:action/:id') and Routes will interpret it as using the 'action' method on the specified controller with id as parameter (id = None if not specified)
75 # As you can see, there is some implicit minimization here
76 # However, this is not possible with Routes 1.8 (the one provided with a standard cherrypy3 installation)
77
78 # About classic minimization:
79 # If you want to be sure that no minimization is done, you must disable it (and of course use only explicit routes)
80 # You have to upgrade to at least Routes 1.9 to do this
81 # easy_install -U routes
82 # Moreover, with minimization disabled, you have to specify routes for each type of URL
83 # You can't do /:user/:field anymore with field default to None
84 # You have to specify /:user and /:user/:field
85 # This way everything is explicit and works fine
86
87 m = d.mapper
88 m.explicit = True # no implicit values for routes
89 m.minimization = False # no minimization (Routes > 1.9 only !)
90 d.connect('interests-1', '/:user/interests', controller=root, action='interests')
91 d.connect('interests-2', '/:user/interests/:id', controller=root, action='interests')
92 d.connect('home-1', '/:user', controller=root, action='home')
93 d.connect('home-2', '/:user/:field', controller=root, action='home', field=None)
94
95
96 # setting the dispatcher into the CherryPy config
97 conf = {'/' : {'request.dispatch' : d}}
98 # note that since the dispatcher handles the matching url/method
99 # we do not need to specify the root of the application anymore
100 cherrypy.tree.mount(root=None, config=conf)
101 cherrypy.server.quickstart()
102 cherrypy.engine.start()

Hosted by WebFaction

Log in as guest/cherrypy to create/edit wiki pages