]>
Commit | Line | Data |
---|---|---|
e0df8241 JR |
1 | """When it comes to combining multiple controller or view functions |
2 | (however you want to call them) you need a dispatcher. A simple way | |
3 | would be applying regular expression tests on the ``PATH_INFO`` and | |
4 | calling registered callback functions that return the value then. | |
5 | ||
6 | This module implements a much more powerful system than simple regular | |
7 | expression matching because it can also convert values in the URLs and | |
8 | build URLs. | |
9 | ||
10 | Here a simple example that creates a URL map for an application with | |
11 | two subdomains (www and kb) and some URL rules: | |
12 | ||
13 | .. code-block:: python | |
14 | ||
15 | m = Map([ | |
16 | # Static URLs | |
17 | Rule('/', endpoint='static/index'), | |
18 | Rule('/about', endpoint='static/about'), | |
19 | Rule('/help', endpoint='static/help'), | |
20 | # Knowledge Base | |
21 | Subdomain('kb', [ | |
22 | Rule('/', endpoint='kb/index'), | |
23 | Rule('/browse/', endpoint='kb/browse'), | |
24 | Rule('/browse/<int:id>/', endpoint='kb/browse'), | |
25 | Rule('/browse/<int:id>/<int:page>', endpoint='kb/browse') | |
26 | ]) | |
27 | ], default_subdomain='www') | |
28 | ||
29 | If the application doesn't use subdomains it's perfectly fine to not set | |
30 | the default subdomain and not use the `Subdomain` rule factory. The | |
31 | endpoint in the rules can be anything, for example import paths or | |
32 | unique identifiers. The WSGI application can use those endpoints to get the | |
33 | handler for that URL. It doesn't have to be a string at all but it's | |
34 | recommended. | |
35 | ||
36 | Now it's possible to create a URL adapter for one of the subdomains and | |
37 | build URLs: | |
38 | ||
39 | .. code-block:: python | |
40 | ||
41 | c = m.bind('example.com') | |
42 | ||
43 | c.build("kb/browse", dict(id=42)) | |
44 | 'http://kb.example.com/browse/42/' | |
45 | ||
46 | c.build("kb/browse", dict()) | |
47 | 'http://kb.example.com/browse/' | |
48 | ||
49 | c.build("kb/browse", dict(id=42, page=3)) | |
50 | 'http://kb.example.com/browse/42/3' | |
51 | ||
52 | c.build("static/about") | |
53 | '/about' | |
54 | ||
55 | c.build("static/index", force_external=True) | |
56 | 'http://www.example.com/' | |
57 | ||
58 | c = m.bind('example.com', subdomain='kb') | |
59 | ||
60 | c.build("static/about") | |
61 | 'http://www.example.com/about' | |
62 | ||
63 | The first argument to bind is the server name *without* the subdomain. | |
64 | Per default it will assume that the script is mounted on the root, but | |
65 | often that's not the case so you can provide the real mount point as | |
66 | second argument: | |
67 | ||
68 | .. code-block:: python | |
69 | ||
70 | c = m.bind('example.com', '/applications/example') | |
71 | ||
72 | The third argument can be the subdomain, if not given the default | |
73 | subdomain is used. For more details about binding have a look at the | |
74 | documentation of the `MapAdapter`. | |
75 | ||
76 | And here is how you can match URLs: | |
77 | ||
78 | .. code-block:: python | |
79 | ||
80 | c = m.bind('example.com') | |
81 | ||
82 | c.match("/") | |
83 | ('static/index', {}) | |
84 | ||
85 | c.match("/about") | |
86 | ('static/about', {}) | |
87 | ||
88 | c = m.bind('example.com', '/', 'kb') | |
89 | ||
90 | c.match("/") | |
91 | ('kb/index', {}) | |
92 | ||
93 | c.match("/browse/42/23") | |
94 | ('kb/browse', {'id': 42, 'page': 23}) | |
95 | ||
96 | If matching fails you get a ``NotFound`` exception, if the rule thinks | |
97 | it's a good idea to redirect (for example because the URL was defined | |
98 | to have a slash at the end but the request was missing that slash) it | |
99 | will raise a ``RequestRedirect`` exception. Both are subclasses of | |
100 | ``HTTPException`` so you can use those errors as responses in the | |
101 | application. | |
102 | ||
103 | If matching succeeded but the URL rule was incompatible to the given | |
104 | method (for example there were only rules for ``GET`` and ``HEAD`` but | |
105 | routing tried to match a ``POST`` request) a ``MethodNotAllowed`` | |
106 | exception is raised. | |
107 | """ | |
108 | from .converters import AnyConverter as AnyConverter | |
109 | from .converters import BaseConverter as BaseConverter | |
110 | from .converters import FloatConverter as FloatConverter | |
111 | from .converters import IntegerConverter as IntegerConverter | |
112 | from .converters import PathConverter as PathConverter | |
113 | from .converters import UnicodeConverter as UnicodeConverter | |
114 | from .converters import UUIDConverter as UUIDConverter | |
115 | from .converters import ValidationError as ValidationError | |
116 | from .exceptions import BuildError as BuildError | |
117 | from .exceptions import NoMatch as NoMatch | |
118 | from .exceptions import RequestAliasRedirect as RequestAliasRedirect | |
119 | from .exceptions import RequestPath as RequestPath | |
120 | from .exceptions import RequestRedirect as RequestRedirect | |
121 | from .exceptions import RoutingException as RoutingException | |
122 | from .exceptions import WebsocketMismatch as WebsocketMismatch | |
123 | from .map import Map as Map | |
124 | from .map import MapAdapter as MapAdapter | |
125 | from .matcher import StateMachineMatcher as StateMachineMatcher | |
126 | from .rules import EndpointPrefix as EndpointPrefix | |
127 | from .rules import parse_converter_args as parse_converter_args | |
128 | from .rules import Rule as Rule | |
129 | from .rules import RuleFactory as RuleFactory | |
130 | from .rules import RuleTemplate as RuleTemplate | |
131 | from .rules import RuleTemplateFactory as RuleTemplateFactory | |
132 | from .rules import Subdomain as Subdomain | |
133 | from .rules import Submount as Submount |