Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 552 lines (415 sloc) 22.483 kB
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
1 .. _hybrid_chapter:
2
3 Combining Traversal and URL Dispatch
4 ====================================
5
780999e @mcdonc context finding -> resource location
mcdonc authored
6 When you write most :app:`Pyramid` applications, you'll be using one or the
7 other of two available :term:`resource location` subsystems: traversal or URL
8 dispatch. However, to solve a limited set of problems, it's useful to use
9 *both* traversal and URL dispatch together within the same application.
10 :app:`Pyramid` makes this possible via *hybrid* applications.
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
11
6fd5e12 Review.
Chris McDonough authored
12 .. warning::
13
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
14 Reasoning about the behavior of a "hybrid" URL dispatch + traversal
15 application can be challenging. To successfully reason about using
16 URL dispatch and traversal together, you need to understand URL
17 pattern matching, root factories, and the :term:`traversal`
18 algorithm, and the potential interactions between them. Therefore,
19 we don't recommend creating an application that relies on hybrid
20 behavior unless you must.
21
22 A Review of Non-Hybrid Applications
23 -----------------------------------
24
25 When used according to the tutorials in its documentation
fd5ae92 @mcdonc - All references to Pyramid-the-application were changed from :mod:`p…
mcdonc authored
26 :app:`Pyramid` is a "dual-mode" framework: the tutorials explain
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
27 how to create an application in terms of using either :term:`url
28 dispatch` *or* :term:`traversal`. This chapter details how you might
29 combine these two dispatch mechanisms, but we'll review how they work
30 in isolation before trying to combine them.
588c642 Make views that do not have a route_name match when any route is used.
Chris McDonough authored
31
32 URL Dispatch Only
33 ~~~~~~~~~~~~~~~~~
34
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
35 An application that uses :term:`url dispatch` exclusively to map URLs to code
ed7ffe0 @mcdonc - Make sure deprecation warnings aren't raised when tests are run.
mcdonc authored
36 will often have statements like this within application startup
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
37 configuration:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
38
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
39 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
40 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
41
d7f2590 @mcdonc fix docs: pyramid.configuration -> pyramid.config
mcdonc authored
42 # config is an instance of pyramid.config.Configurator
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
43
a1d8c03 @mmerickel Converting docs to deprecate view parameters in config.add_route.
mmerickel authored
44 config.add_route('foobar', '{foo}/{bar}')
45 config.add_route('bazbuz', '{baz}/{buz}')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
46
a1d8c03 @mmerickel Converting docs to deprecate view parameters in config.add_route.
mmerickel authored
47 config.add_view('myproject.views.foobar', route_name='foobar')
48 config.add_view('myproject.views.bazbuz', route_name='bazbuz')
9ec2d64 Merge of andrew-docs branch.
Chris McDonough authored
49
ed7ffe0 @mcdonc - Make sure deprecation warnings aren't raised when tests are run.
mcdonc authored
50 Each :term:`route` corresponds to one or more view callables. Each view
51 callable is associated with a route by passing a ``route_name`` parameter
52 that matches its name during a call to
53 :meth:`~pyramid.config.Configurator.add_view`. When a route is matched
54 during a request, :term:`view lookup` is used to match the request to its
55 associated view callable. The presence of calls to
56 :meth:`~pyramid.config.Configurator.add_route` signify that an application is
57 using URL dispatch.
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
58
588c642 Make views that do not have a route_name match when any route is used.
Chris McDonough authored
59 Traversal Only
60 ~~~~~~~~~~~~~~
61
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
62 An application that uses only traversal will have view configuration
63 declarations that look like this:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
64
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
65 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
66 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
67
d7f2590 @mcdonc fix docs: pyramid.configuration -> pyramid.config
mcdonc authored
68 # config is an instance of pyramid.config.Configurator
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
69
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
70 config.add_view('mypackage.views.foobar', name='foobar')
71 config.add_view('mypackage.views.bazbuz', name='bazbuz')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
72
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
73 When the above configuration is applied to an application, the
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
74 ``mypackage.views.foobar`` view callable above will be called when the URL
75 ``/foobar`` is visited. Likewise, the view ``mypackage.views.bazbuz`` will
76 be called when the URL ``/bazbuz`` is visited.
9ec2d64 Merge of andrew-docs branch.
Chris McDonough authored
77
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
78 Typically, an application that uses traversal exclusively won't perform any
d7f2590 @mcdonc fix docs: pyramid.configuration -> pyramid.config
mcdonc authored
79 calls to :meth:`pyramid.config.Configurator.add_route` in its startup
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
80 code.
8c56ae4 - Added manual index entries to generated index.
Chris McDonough authored
81
6ce1e0c @mcdonc add more index markers
mcdonc authored
82 .. index::
83 single: hybrid applications
84
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
85 Hybrid Applications
86 -------------------
87
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
88 Either traversal or url dispatch alone can be used to create a
fd5ae92 @mcdonc - All references to Pyramid-the-application were changed from :mod:`p…
mcdonc authored
89 :app:`Pyramid` application. However, it is also possible to
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
90 combine the concepts of traversal and url dispatch when building an
91 application: the result is a hybrid application. In a hybrid
92 application, traversal is performed *after* a particular route has
93 matched.
94
95 A hybrid application is a lot more like a "pure" traversal-based
96 application than it is like a "pure" URL-dispatch based application.
97 But unlike in a "pure" traversal-based application, in a hybrid
98 application, :term:`traversal` is performed during a request after a
99 route has already matched. This means that the URL pattern that
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
100 represents the ``pattern`` argument of a route must match the
101 ``PATH_INFO`` of a request, and after the route pattern has matched,
780999e @mcdonc context finding -> resource location
mcdonc authored
102 most of the "normal" rules of traversal with respect to :term:`resource
103 location` and :term:`view lookup` apply.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
104
105 There are only four real differences between a purely traversal-based
106 application and a hybrid application:
107
108 - In a purely traversal based application, no routes are defined; in a
109 hybrid application, at least one route will be defined.
110
111 - In a purely traversal based application, the root object used is
cd32fc7 @caseman Add comma
caseman authored
112 global, implied by the :term:`root factory` provided at startup
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
113 time; in a hybrid application, the :term:`root` object at which
114 traversal begins may be varied on a per-route basis.
115
116 - In a purely traversal-based application, the ``PATH_INFO`` of the
117 underlying :term:`WSGI` environment is used wholesale as a traversal
118 path; in a hybrid application, the traversal path is not the entire
119 ``PATH_INFO`` string, but a portion of the URL determined by a
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
120 matching pattern in the matched route configuration's pattern.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
121
fc7e36b @cguardia more trivial fixes
cguardia authored
122 - In a purely traversal based application, view configurations which
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
123 do not mention a ``route_name`` argument are considered during
124 :term:`view lookup`; in a hybrid application, when a route is
125 matched, only view configurations which mention that route's name as
126 a ``route_name`` are considered during :term:`view lookup`.
127
128 More generally, a hybrid application *is* a traversal-based
129 application except:
130
131 - the traversal *root* is chosen based on the route configuration of
132 the route that matched instead of from the ``root_factory`` supplied
133 during application startup configuration.
134
135 - the traversal *path* is chosen based on the route configuration of
136 the route that matched rather than from the ``PATH_INFO`` of a
137 request.
138
139 - the set of views that may be chosen during :term:`view lookup` when
140 a route matches are limited to those which specifically name a
141 ``route_name`` in their configuration that is the same as the
142 matched route's ``name``.
143
144 To create a hybrid mode application, use a :term:`route configuration`
145 that implies a particular :term:`root factory` and which also includes
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
146 a ``pattern`` argument that contains a special dynamic part: either
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
147 ``*traverse`` or ``*subpath``.
148
149 The Root Object for a Route Match
150 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
151
152 A hybrid application implies that traversal is performed during a
153 request after a route has matched. Traversal, by definition, must
154 always begin at a root object. Therefore it's important to know
155 *which* root object will be traversed after a route has matched.
156
157 Figuring out which :term:`root` object results from a particular route
158 match is straightforward. When a route is matched:
159
2b6bc8a Fix (thanks to Iain Duncan).
Chris McDonough authored
160 - If the route's configuration has a ``factory`` argument which
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
161 points to a :term:`root factory` callable, that callable will be
162 called to generate a :term:`root` object.
163
2b6bc8a Fix (thanks to Iain Duncan).
Chris McDonough authored
164 - If the route's configuration does not have a ``factory``
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
165 argument, the *global* :term:`root factory` will be called to
166 generate a :term:`root` object. The global root factory is the
70acd25 @mcdonc module name contractions
mcdonc authored
167 callable implied by the ``root_factory`` argument passed to the
168 :class:`~pyramid.config.Configurator` at application
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
169 startup time.
170
171 - If a ``root_factory`` argument is not provided to the
70acd25 @mcdonc module name contractions
mcdonc authored
172 :class:`~pyramid.config.Configurator` at startup time, a
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
173 *default* root factory is used. The default root factory is used to
174 generate a root object.
175
176 .. note::
177
fc7e36b @cguardia more trivial fixes
cguardia authored
178 Root factories related to a route were explained previously within
179 :ref:`route_factories`. Both the global root factory and default
180 root factory were explained previously within
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
181 :ref:`the_resource_tree`.
9ec2d64 Merge of andrew-docs branch.
Chris McDonough authored
182
6ce1e0c @mcdonc add more index markers
mcdonc authored
183 .. index::
184 pair: hybrid applications; *traverse route pattern
185
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
186 .. _using_traverse_in_a_route_pattern:
ef8a8c8 - New argument to ``repoze.bfg.configuration.Configurator.add_route``
Chris McDonough authored
187
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
188 Using ``*traverse`` In a Route Pattern
189 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9ec2d64 Merge of andrew-docs branch.
Chris McDonough authored
190
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
191 A hybrid application most often implies the inclusion of a route
192 configuration that contains the special token ``*traverse`` at the end
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
193 of a route's pattern:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
194
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
195 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
196 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
197
df3f64a @mcdonc convert stray references to colon routing syntax to squiggly syntax
mcdonc authored
198 config.add_route('home', '{foo}/{bar}/*traverse')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
199
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
200 A ``*traverse`` token at the end of the pattern in a route's
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
201 configuration implies a "remainder" *capture* value. When it is used,
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
202 it will match the remainder of the path segments of the URL. This
203 remainder becomes the path used to perform traversal.
204
205 .. note::
206
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
207 The ``*remainder`` route pattern syntax is explained in more
208 detail within :ref:`route_pattern_syntax`.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
209
a1d8c03 @mmerickel Converting docs to deprecate view parameters in config.add_route.
mmerickel authored
210 A hybrid mode application relies more heavily on :term:`traversal` to do
211 :term:`resource location` and :term:`view lookup` than most examples indicate
212 within :ref:`urldispatch_chapter`.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
213
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
214 Because the pattern of the above route ends with ``*traverse``, when this
780999e @mcdonc context finding -> resource location
mcdonc authored
215 route configuration is matched during a request, :app:`Pyramid` will attempt
216 to use :term:`traversal` against the :term:`root` object implied by the
217 :term:`root factory` that is implied by the route's configuration. Since no
218 ``root_factory`` argument is explicitly specified for this route, this will
219 either be the *global* root factory for the application, or the *default*
220 root factory. Once :term:`traversal` has found a :term:`context` resource,
221 :term:`view lookup` will be invoked in almost exactly the same way it would
222 have been invoked in a "pure" traversal-based application.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
223
5a6b033 @caseman Clarify paragraph describing custom root factory
caseman authored
224 Let's assume there is no *global* :term:`root factory` configured in
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
225 this application. The *default* :term:`root factory` cannot be traversed:
5a6b033 @caseman Clarify paragraph describing custom root factory
caseman authored
226 it has no useful ``__getitem__`` method. So we'll need to associate
227 this route configuration with a custom root factory in order to
228 create a useful hybrid application. To that end, let's imagine that
229 we've created a root factory that looks like so in a module named
fc7e36b @cguardia more trivial fixes
cguardia authored
230 ``routes.py``:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
231
232 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
233 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
234
fb6a5ce @mcdonc model -> resource; resource -> asset
mcdonc authored
235 class Resource(object):
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
236 def __init__(self, subobjects):
237 self.subobjects = subobjects
238
239 def __getitem__(self, name):
240 return self.subobjects[name]
241
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
242 root = Resource(
243 {'a': Resource({'b': Resource({'c': Resource({})})})}
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
244 )
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
245
acc7765 - The ``__call__`` of a plugin "traverser" implementation (registered
Chris McDonough authored
246 def root_factory(request):
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
247 return root
248
fb6a5ce @mcdonc model -> resource; resource -> asset
mcdonc authored
249 Above, we've defined a (bogus) resource tree that can be traversed, and a
250 ``root_factory`` function that can be used as part of a particular route
251 configuration statement:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
252
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
253 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
254 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
255
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
256 config.add_route('home', '{foo}/{bar}/*traverse',
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
257 factory='mypackage.routes.root_factory')
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
258
fb6a5ce @mcdonc model -> resource; resource -> asset
mcdonc authored
259 The ``factory`` above points at the function we've defined. It will return
5483175 @mcdonc minor edits to cito's edits
mcdonc authored
260 an instance of the ``Resource`` class as a root object whenever this route is
261 matched. Instances of the ``Resource`` class can be used for tree traversal
262 because they have a ``__getitem__`` method that does something nominally
263 useful. Since traversal uses ``__getitem__`` to walk the resources of a
264 resource tree, using traversal against the root resource implied by our route
265 statement is a reasonable thing to do.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
266
267 .. note::
268
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
269 We could have also used our ``root_factory`` function as the
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
270 ``root_factory`` argument of the
70acd25 @mcdonc module name contractions
mcdonc authored
271 :class:`~pyramid.config.Configurator` constructor, instead
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
272 of associating it with a particular route inside the route's
273 configuration. Every hybrid route configuration that is matched but
db312f8 @mcdonc stray quote mark
mcdonc authored
274 which does *not* name a ``factory`` attribute will use the use
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
275 global ``root_factory`` function to generate a root object.
276
277 When the route configuration named ``home`` above is matched during a
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
278 request, the matchdict generated will be based on its pattern:
fb6a5ce @mcdonc model -> resource; resource -> asset
mcdonc authored
279 ``{foo}/{bar}/*traverse``. The "capture value" implied by the ``*traverse``
280 element in the pattern will be used to traverse the resource tree in order to
780999e @mcdonc context finding -> resource location
mcdonc authored
281 find a context resource, starting from the root object returned from the root
282 factory. In the above example, the :term:`root` object found will be the
283 instance named ``root`` in ``routes.py``.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
284
df3f64a @mcdonc convert stray references to colon routing syntax to squiggly syntax
mcdonc authored
285 If the URL that matched a route with the pattern ``{foo}/{bar}/*traverse``,
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
286 is ``http://example.com/one/two/a/b/c``, the traversal path used
287 against the root object will be ``a/b/c``. As a result,
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
288 :app:`Pyramid` will attempt to traverse through the edges ``'a'``,
289 ``'b'``, and ``'c'``, beginning at the root object.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
290
fb6a5ce @mcdonc model -> resource; resource -> asset
mcdonc authored
291 In our above example, this particular set of traversal steps will mean that
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
292 the :term:`context` resource of the view would be the ``Resource`` object
293 we've named ``'c'`` in our bogus resource tree and the :term:`view name`
780999e @mcdonc context finding -> resource location
mcdonc authored
294 resulting from traversal will be the empty string; if you need a refresher
295 about why this outcome is presumed, see :ref:`traversal_algorithm`.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
296
297 At this point, a suitable view callable will be found and invoked
298 using :term:`view lookup` as described in :ref:`view_configuration`,
299 but with a caveat: in order for view lookup to work, we need to define
300 a view configuration that will match when :term:`view lookup` is
301 invoked after a route matches:
302
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
303 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
304 :linenos:
305
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
306 config.add_route('home', '{foo}/{bar}/*traverse',
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
307 factory='mypackage.routes.root_factory')
308 config.add_view('mypackage.views.myview', route_name='home')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
309
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
310 Note that the above call to
70acd25 @mcdonc module name contractions
mcdonc authored
311 :meth:`~pyramid.config.Configurator.add_view` includes a ``route_name``
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
312 argument. View configurations that include a ``route_name`` argument are
313 meant to associate a particular view declaration with a route, using the
314 route's name, in order to indicate that the view should *only be invoked when
315 the route matches*.
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
316
70acd25 @mcdonc module name contractions
mcdonc authored
317 Calls to :meth:`~pyramid.config.Configurator.add_view` may pass a
4423dd1 @caseman add comma
caseman authored
318 ``route_name`` attribute, which refers to the value of an existing route's
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
319 ``name`` argument. In the above example, the route name is ``home``,
320 referring to the name of the route defined above it.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
321
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
322 The above ``mypackage.views.myview`` view callable will be invoked when:
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
323
324 - the route named "home" is matched
325
326 - the :term:`view name` resulting from traversal is the empty string.
327
780999e @mcdonc context finding -> resource location
mcdonc authored
328 - the :term:`context` resource is any object.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
329
330 It is also possible to declare alternate views that may be invoked
331 when a hybrid route is matched:
332
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
333 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
334 :linenos:
335
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
336 config.add_route('home', '{foo}/{bar}/*traverse',
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
337 factory='mypackage.routes.root_factory')
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
338 config.add_view('mypackage.views.myview', route_name='home')
339 config.add_view('mypackage.views.another_view', route_name='home',
340 name='another')
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
341
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
342 The ``add_view`` call for ``mypackage.views.another_view`` above names a
343 different view and, more importantly, a different :term:`view name`. The
344 above ``mypackage.views.another_view`` view will be invoked when:
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
345
346 - the route named "home" is matched
347
348 - the :term:`view name` resulting from traversal is ``another``.
349
780999e @mcdonc context finding -> resource location
mcdonc authored
350 - the :term:`context` resource is any object.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
351
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
352 For instance, if the URL ``http://example.com/one/two/a/another`` is provided
fb6a5ce @mcdonc model -> resource; resource -> asset
mcdonc authored
353 to an application that uses the previously mentioned resource tree, the
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
354 ``mypackage.views.another`` view callable will be called instead of the
355 ``mypackage.views.myview`` view callable because the :term:`view name` will
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
356 be ``another`` instead of the empty string.
330f7c5 Free at last, free at last, thank god almighty free at last.
Chris McDonough authored
357
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
358 More complicated matching can be composed. All arguments to *route*
359 configuration statements and *view* configuration statements are
360 supported in hybrid applications (such as :term:`predicate`
361 arguments).
362
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
363 Using the ``traverse`` Argument In a Route Definition
364 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
365
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
366 Rather than using the ``*traverse`` remainder marker in a pattern, you
367 can use the ``traverse`` argument to the
70acd25 @mcdonc module name contractions
mcdonc authored
368 :meth:`~pyramid.config.Configurator.add_route` method.
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
369
370 When you use the ``*traverse`` remainder marker, the traversal path is
371 limited to being the remainder segments of a request URL when a route
372 matches. However, when you use the ``traverse`` argument or
373 attribute, you have more control over how to compose a traversal path.
374
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
375 Here's a use of the ``traverse`` pattern in a call to
70acd25 @mcdonc module name contractions
mcdonc authored
376 :meth:`~pyramid.config.Configurator.add_route`:
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
377
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
378 .. code-block:: python
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
379 :linenos:
380
df3f64a @mcdonc convert stray references to colon routing syntax to squiggly syntax
mcdonc authored
381 config.add_route('abc', '/articles/{article}/edit',
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
382 traverse='/{article}')
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
383
384 The syntax of the ``traverse`` argument is the same as it is for
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
385 ``pattern``.
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
386
2e3f70d @Cito Some more small fixes in the narrative docu.
Cito authored
387 If, as above, the ``pattern`` provided is ``/articles/{article}/edit``,
df3f64a @mcdonc convert stray references to colon routing syntax to squiggly syntax
mcdonc authored
388 and the ``traverse`` argument provided is ``/{article}``, when a
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
389 request comes in that causes the route to match in such a way that the
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
390 ``article`` match value is ``1`` (when the request URI is
391 ``/articles/1/edit``), the traversal path will be generated as ``/1``.
392 This means that the root object's ``__getitem__`` will be called with
393 the name ``1`` during the traversal phase. If the ``1`` object
394 exists, it will become the :term:`context` of the request.
2d5bc36 @caseman make it clear this is a chapter reference
caseman authored
395 The :ref:`traversal_chapter` chapter has more information about traversal.
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
396
397 If the traversal path contains segment marker names which are not
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
398 present in the pattern argument, a runtime error will occur. The
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
399 ``traverse`` pattern should not contain segment markers that do not
400 exist in the ``path``.
401
402 Note that the ``traverse`` argument is ignored when attached to a
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
403 route that has a ``*traverse`` remainder marker in its pattern.
8e18ea4 - The ``Hybrid`` narrative chapter now contains a description of the
Chris McDonough authored
404
405 Traversal will begin at the root object implied by this route (either
406 the global root, or the object returned by the ``factory`` associated
407 with this route).
408
6ce1e0c @mcdonc add more index markers
mcdonc authored
409 .. index::
410 pair: hybrid applications; global views
411
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
412 Making Global Views Match
413 +++++++++++++++++++++++++
414
07ee3a5 @caseman Clarify paragraph explaining use_global_views
caseman authored
415 By default, only view configurations that mention a ``route_name``
416 will be found during view lookup when a route that has a ``*traverse``
417 in its pattern matches. You can allow views without a ``route_name``
418 attribute to match a route by adding the ``use_global_views`` flag to
419 the route definition. For example, the ``myproject.views.bazbuz``
420 view below will be found if the route named ``abc`` below is matched
421 and the ``PATH_INFO`` is ``/abc/bazbuz``, even though the view
422 configuration statement does not have the ``route_name="abc"``
423 attribute.
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
424
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
425 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
426 :linenos:
427
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
428 config.add_route('abc', '/abc/*traverse', use_global_views=True)
429 config.add_view('myproject.views.bazbuz', name='bazbuz')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
430
8c56ae4 - Added manual index entries to generated index.
Chris McDonough authored
431 .. index::
6ce1e0c @mcdonc add more index markers
mcdonc authored
432 pair: hybrid applications; *subpath
c5f24b2 Prep for b1
Chris McDonough authored
433 single: route subpath
434 single: subpath (route)
8c56ae4 - Added manual index entries to generated index.
Chris McDonough authored
435
3f224a5 Gardening.
Chris McDonough authored
436 .. _star_subpath:
437
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
438 Using ``*subpath`` in a Route Pattern
439 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e2062b4 Add documentation for *subpath.
Chris McDonough authored
440
ed7ffe0 @mcdonc - Make sure deprecation warnings aren't raised when tests are run.
mcdonc authored
441 There are certain extremely rare cases when you'd like to influence the
442 traversal :term:`subpath` when a route matches without actually performing
443 traversal. For instance, the :func:`pyramid.wsgi.wsgiapp2` decorator and the
56d0fe4 @mcdonc - New API class: ``pyramid.static.static_view``. This supersedes the
mcdonc authored
444 :class:`pyramid.static.static_view` helper attempt to compute ``PATH_INFO``
445 from the request's subpath when its ``use_subpath`` argument is ``True``, so
446 it's useful to be able to influence this value.
c5f24b2 Prep for b1
Chris McDonough authored
447
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
448 When ``*subpath`` exists in a pattern, no path is actually traversed,
449 but the traversal algorithm will return a :term:`subpath` list implied
450 by the capture value of ``*subpath``. You'll see this pattern most
451 commonly in route declarations that look like this:
e2062b4 Add documentation for *subpath.
Chris McDonough authored
452
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
453 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
454 :linenos:
e2062b4 Add documentation for *subpath.
Chris McDonough authored
455
56d0fe4 @mcdonc - New API class: ``pyramid.static.static_view``. This supersedes the
mcdonc authored
456 from pryamid.static import static_view
457
458 www = static_view('mypackage:static', use_subpath=True)
459
a1d8c03 @mmerickel Converting docs to deprecate view parameters in config.add_route.
mmerickel authored
460 config.add_route('static', '/static/*subpath')
56d0fe4 @mcdonc - New API class: ``pyramid.static.static_view``. This supersedes the
mcdonc authored
461 config.add_view(www, route_name='static')
e2062b4 Add documentation for *subpath.
Chris McDonough authored
462
56d0fe4 @mcdonc - New API class: ``pyramid.static.static_view``. This supersedes the
mcdonc authored
463 ``mypackage.views.www`` is an instance of
464 :class:`pyramid.static.static_view`. This effectively tells the static
465 helper to traverse everything in the subpath as a filename.
e2062b4 Add documentation for *subpath.
Chris McDonough authored
466
6ce1e0c @mcdonc add more index markers
mcdonc authored
467 .. index::
468 pair: hybrid applications; corner cases
469
330f7c5 Free at last, free at last, thank god almighty free at last.
Chris McDonough authored
470 Corner Cases
471 ------------
62cd249 Add (painful) explanation of weak-binding route view context registra…
Chris McDonough authored
472
330f7c5 Free at last, free at last, thank god almighty free at last.
Chris McDonough authored
473 A number of corner case "gotchas" exist when using a hybrid
474 application. We'll detail them here.
62cd249 Add (painful) explanation of weak-binding route view context registra…
Chris McDonough authored
475
c5f24b2 Prep for b1
Chris McDonough authored
476 Registering a Default View for a Route That Has a ``view`` Attribute
588c642 Make views that do not have a route_name match when any route is used.
Chris McDonough authored
477 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
478
ed7ffe0 @mcdonc - Make sure deprecation warnings aren't raised when tests are run.
mcdonc authored
479 .. warning:: As of :app:`Pyramid` 1.1 this section is slated to be removed in
480 a later documentation release because the the ability to add views
481 directly to the :term:`route configuration` by passing a ``view`` argument
482 to ``add_route`` has been deprecated.
a1d8c03 @mmerickel Converting docs to deprecate view parameters in config.add_route.
mmerickel authored
483
c5f24b2 Prep for b1
Chris McDonough authored
484 It is an error to provide *both* a ``view`` argument to a :term:`route
485 configuration` *and* a :term:`view configuration` which names a
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
486 ``route_name`` that has no ``name`` value or the empty ``name`` value. For
ed7ffe0 @mcdonc - Make sure deprecation warnings aren't raised when tests are run.
mcdonc authored
487 example, this pair of declarations will generate a conflict error at startup
488 time.
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
489
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
490 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
491 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
492
df3f64a @mcdonc convert stray references to colon routing syntax to squiggly syntax
mcdonc authored
493 config.add_route('home', '{foo}/{bar}/*traverse',
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
494 view='myproject.views.home')
495 config.add_view('myproject.views.another', route_name='home')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
496
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
497 This is because the ``view`` argument to the
70acd25 @mcdonc module name contractions
mcdonc authored
498 :meth:`~pyramid.config.Configurator.add_route` above is an *implicit*
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
499 default view when that route matches. ``add_route`` calls don't *need* to
500 supply a view attribute. For example, this ``add_route`` call:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
501
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
502 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
503 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
504
df3f64a @mcdonc convert stray references to colon routing syntax to squiggly syntax
mcdonc authored
505 config.add_route('home', '{foo}/{bar}/*traverse',
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
506 view='myproject.views.home')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
507
508 Can also be spelled like so:
509
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
510 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
511 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
512
df3f64a @mcdonc convert stray references to colon routing syntax to squiggly syntax
mcdonc authored
513 config.add_route('home', '{foo}/{bar}/*traverse')
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
514 config.add_view('myproject.views.home', route_name='home')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
515
ed7ffe0 @mcdonc - Make sure deprecation warnings aren't raised when tests are run.
mcdonc authored
516 The two spellings are logically equivalent. In fact, the former is just a
517 syntactical shortcut for the latter.
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
518
37ba0d8 @caseman Fix typo
caseman authored
519 Binding Extra Views Against a Route Configuration that Doesn't Have a ``*traverse`` Element In Its Pattern
74409d1 - The ``repoze.bfg.urldispatch.Route`` constructor (not an API) now
Chris McDonough authored
520 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
588c642 Make views that do not have a route_name match when any route is used.
Chris McDonough authored
521
ef921f9 @caseman Use a colon instead of a period
caseman authored
522 Here's another corner case that just makes no sense:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
523
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
524 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
525 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
526
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
527 config.add_route('abc', '/abc', view='myproject.views.abc')
528 config.add_view('myproject.views.bazbuz', name='bazbuz',
529 route_name='abc')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
530
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
531 The above view declaration is useless, because it will never be matched when
532 the route it references has matched. Only the view associated with the route
533 itself (``myproject.views.abc``) will ever be invoked when the route matches,
534 because the default view is always invoked when a route matches and when no
535 post-match traversal is performed.
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
536
36255b3 @caseman non-useless => useful
caseman authored
537 To make the above view declaration useful, the special ``*traverse``
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
538 token must end the route's pattern. For example:
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
539
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
540 .. code-block:: python
b538144 Make the hybrid chapter represent reality.
Chris McDonough authored
541 :linenos:
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
542
c7c40b9 @mcdonc de-zcml-ify various chapters and move ZCML to the declarative chapter
mcdonc authored
543 config.add_route('abc', '/abc/*traverse', view='myproject.views.abc')
544 config.add_view('myproject.views.bazbuz', name='bazbuz',
545 route_name='abc')
57ec0ec - Added a (fairly sad) "Combining Traversal and URL Dispatch" chapter
Chris McDonough authored
546
0860706 @caseman XXX Add an example of when views would be invoked by the 'useful' con…
caseman authored
547 With the above configuration, the ``myproject.views.bazbuz`` view will
548 be invoked when the request URI is ``/abc/bazbuz``, assuming there is
549 no object contained by the root object with the key ``bazbuz``. A
550 different request URI, such as ``/abc/foo/bar``, would invoke the
551 default ``myproject.views.abc`` view.
Something went wrong with that request. Please try again.