summaryrefslogtreecommitdiff
path: root/docs/narr/hybrid.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-11-03 23:11:07 -0400
committerChris McDonough <chrism@plope.com>2010-11-03 23:11:07 -0400
commitc7c40b9b3b3c0008185f1a44a2aba4f95f29abd0 (patch)
tree839bf0a16a3add905e58dc037703ce400f1fa43e /docs/narr/hybrid.rst
parent108698b020c4b360c180ab3faa6f11e45a51439c (diff)
downloadpyramid-c7c40b9b3b3c0008185f1a44a2aba4f95f29abd0.tar.gz
pyramid-c7c40b9b3b3c0008185f1a44a2aba4f95f29abd0.tar.bz2
pyramid-c7c40b9b3b3c0008185f1a44a2aba4f95f29abd0.zip
de-zcml-ify various chapters and move ZCML to the declarative chapter
Diffstat (limited to 'docs/narr/hybrid.rst')
-rw-r--r--docs/narr/hybrid.rst314
1 files changed, 113 insertions, 201 deletions
diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst
index cdac3642a..24ae63059 100644
--- a/docs/narr/hybrid.rst
+++ b/docs/narr/hybrid.rst
@@ -33,33 +33,24 @@ in isolation before trying to combine them.
URL Dispatch Only
~~~~~~~~~~~~~~~~~
-An application that uses :term:`url dispatch` exclusively to map URLs
-to code will often have declarations like this within :term:`ZCML`:
+An application that uses :term:`url dispatch` exclusively to map URLs to code
+will often have statements like this within your application startup
+configuration:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar"
- name="foobar"
- view=".views.foobar"
- />
+ # config is an instance of pyramid.configuration.Configurator
- <route
- pattern=":baz/:buz"
- name="bazbuz"
- view=".views.bazbuz"
- />
+ config.add_route('foobar', ':foo/:bar', view='myproject.views.foobar')
+ config.add_route('bazbuz', ':baz/:buz', view='myproject.views.bazbuz')
Each :term:`route` typically corresponds to a single view callable,
and when that route is matched during a request, the view callable
named by the ``view`` attribute is invoked.
-Typically, an application that uses only URL dispatch won't perform
-any configuration in ZCML that includes a ``<view>`` declaration and
-won't have any calls to
-:meth:`pyramid.configuration.Configurator.add_view` in its startup
-code.
+Typically, an application that uses only URL dispatch won't perform any calls
+to :meth:`pyramid.configuration.Configurator.add_view` in its startup code.
Traversal Only
~~~~~~~~~~~~~~
@@ -67,28 +58,22 @@ Traversal Only
An application that uses only traversal will have view configuration
declarations that look like this:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <view
- name="foobar"
- view=".views.foobar"
- />
+ # config is an instance of pyramid.configuration.Configurator
- <view
- name="bazbuz"
- view=".views.bazbuz"
- />
+ config.add_view('mypackage.views.foobar', name='foobar')
+ config.add_view('mypackage.views.bazbuz', name='bazbuz')
When the above configuration is applied to an application, the
-``.views.foobar`` view callable above will be called when the URL
-``/foobar`` is visited. Likewise, the view ``.views.bazbuz`` will be
-called when the URL ``/bazbuz`` is visited.
+``mypackage.views.foobar`` view callable above will be called when the URL
+``/foobar`` is visited. Likewise, the view ``mypackage.views.bazbuz`` will
+be called when the URL ``/bazbuz`` is visited.
-An application that uses :term:`traversal` exclusively to map URLs to
-code usually won't have any ZCML ``<route>`` declarations nor will it
-make any calls to the
-:meth:`pyramid.configuration.Configurator.add_route` method.
+Typically, an application that uses traversal exclusively won't perform any
+calls to :meth:`pyramid.configuration.Configurator.add_route` in its startup
+code.
Hybrid Applications
-------------------
@@ -197,13 +182,10 @@ A hybrid application most often implies the inclusion of a route
configuration that contains the special token ``*traverse`` at the end
of a route's pattern:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar/*traverse"
- name="home"
- />
+ config.add_route('home', ':foo/:bar/*traverse')
A ``*traverse`` token at the end of the pattern in a route's
configuration implies a "remainder" *capture* value. When it is used,
@@ -215,13 +197,12 @@ remainder becomes the path used to perform traversal.
The ``*remainder`` route pattern syntax is explained in more
detail within :ref:`route_pattern_syntax`.
-Note that unlike the examples provided within
-:ref:`urldispatch_chapter`, the ``<route>`` configuration named
-previously does not name a ``view`` attribute. This is because a
-hybrid mode application relies on :term:`traversal` to do
-:term:`context finding` and :term:`view lookup` instead of invariably
-invoking a specific view callable named directly within the matched
-route's configuration.
+Note that unlike the examples provided within :ref:`urldispatch_chapter`, the
+``add_route`` configuration statement named previously does not pass a
+``view`` argument. This is because a hybrid mode application relies on
+:term:`traversal` to do :term:`context finding` and :term:`view lookup`
+instead of invariably invoking a specific view callable named directly within
+the matched route's configuration.
Because the pattern of the above route ends with ``*traverse``, when this
route configuration is matched during a request, :mod:`pyramid`
@@ -259,14 +240,11 @@ Above, we've defined a (bogus) graph here that can be traversed, and a
``root_factory`` function that can be used as part of a particular
route configuration statement:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar/*traverse"
- name="home"
- factory=".routes.root_factory"
- />
+ config.add_route('home', ':foo/:bar/*traverse',
+ factory='mypackage.routes.root_factory')
The ``factory`` above points at the function we've defined. It
will return an instance of the ``Traversable`` class as a root object
@@ -315,32 +293,26 @@ but with a caveat: in order for view lookup to work, we need to define
a view configuration that will match when :term:`view lookup` is
invoked after a route matches:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar/*traverse"
- name="home"
- factory=".routes.root_factory"
- />
-
- <view
- route_name="home"
- view=".views.myview"
- />
+ config.add_route('home', ':foo/:bar/*traverse',
+ factory='mypackage.routes.root_factory')
+ config.add_view('mypackage.views.myview', route_name='home')
-Note that the above ``view`` declaration includes a ``route_name``
-argument. Views that include a ``route_name`` argument are meant to
-associate a particular view declaration with a route, using the
-route's name, in order to indicate that the view should *only be
-invoked when the route matches*.
+Note that the above call to
+:meth:`pyramid.configuration.Configurator.add_view` includes a ``route_name``
+argument. View configurations that include a ``route_name`` argument are
+meant to associate a particular view declaration with a route, using the
+route's name, in order to indicate that the view should *only be invoked when
+the route matches*.
-View configurations may have a ``route_name`` attribute which refers
-to the value of the ``<route>`` declaration's ``name`` attribute. In
-the above example, the route name is ``home``, referring to the name
-of the route defined above it.
+Calls to :meth:`pyramid.configuration.Configurator.add_view` may pass a
+``route_name`` attribute which refers to the value of an existing route's
+``name`` argument. In the above example, the route name is ``home``,
+referring to the name of the route defined above it.
-The above ``.views.myview`` view will be invoked when:
+The above ``mypackage.views.myview`` view callable will be invoked when:
- the route named "home" is matched
@@ -351,29 +323,18 @@ The above ``.views.myview`` view will be invoked when:
It is also possible to declare alternate views that may be invoked
when a hybrid route is matched:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar/*traverse"
- name="home"
- factory=".routes.root_factory"
- />
+ config.add_route('home', ':foo/:bar/*traverse',
+ factory='mypackage.routes.root_factory')
+ config.add_view('mypackage.views.myview', name='home')
+ config.add_view('mypackage.views.another_view', name='another',
+ route_name='home')
- <view
- route_name="home"
- view=".views.myview"
- />
-
- <view
- route_name="home"
- name="another"
- view=".views.another_view"
- />
-
-The ``view`` declaration for ``.views.another_view`` above names a
-different view and, more importantly, a different :term:`view name`.
-The above ``.views.another_view`` view will be invoked when:
+The ``add_view`` call for ``mypackage.views.another_view`` above names a
+different view and, more importantly, a different :term:`view name`. The
+above ``mypackage.views.another_view`` view will be invoked when:
- the route named "home" is matched
@@ -381,10 +342,10 @@ The above ``.views.another_view`` view will be invoked when:
- the :term:`context` is any object.
-For instance, if the URL ``http://example.com/one/two/a/another`` is
-provided to an application that uses the previously mentioned object
-graph, the ``.views.another`` view callable will be called instead of
-the ``.views.myview`` view callable because the :term:`view name` will
+For instance, if the URL ``http://example.com/one/two/a/another`` is provided
+to an application that uses the previously mentioned object graph, the
+``mypackage.views.another`` view callable will be called instead of the
+``mypackage.views.myview`` view callable because the :term:`view name` will
be ``another`` instead of the empty string.
More complicated matching can be composed. All arguments to *route*
@@ -397,26 +358,21 @@ Using the ``traverse`` Argument In a Route Definition
Rather than using the ``*traverse`` remainder marker in a pattern, you
can use the ``traverse`` argument to the
-:meth:`pyramid.configuration.Configurator.add_route`` method or the
-``traverse`` attribute of the :ref:`route_directive` ZCML directive.
-(either method is equivalent).
+:meth:`pyramid.configuration.Configurator.add_route`` method.
When you use the ``*traverse`` remainder marker, the traversal path is
limited to being the remainder segments of a request URL when a route
matches. However, when you use the ``traverse`` argument or
attribute, you have more control over how to compose a traversal path.
-Here's a use of the ``traverse`` pattern in a ZCML ``route``
-declaration:
+Here's a use of the ``traverse`` pattern in a call to
+:meth:`pyramid.configuration.Configurator.add_route`:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- name="abc"
- pattern="/articles/:article/edit"
- traverse="/articles/:article"
- />
+ config.add_route('abc', '/articles/:article/edit',
+ traverse='/articles/:article')
The syntax of the ``traverse`` argument is the same as it is for
``pattern``.
@@ -446,28 +402,20 @@ with this route).
Making Global Views Match
+++++++++++++++++++++++++
-By default, view configurations that don't mention a ``route_name``
-will be not found by view lookup when a route that mentions a
-``*traverse`` in its pattern matches. You can make these match forcibly
-by adding the ``use_global_views`` flag to the route definition. For
-example, the ``views.bazbuz`` view below will be found if the route
-named ``abc`` below is matched and the ``PATH_INFO`` is
-``/abc/bazbuz``, even though the view configuration statement does not
-have the ``route_name="abc"`` attribute.
+By default, view configurations that don't mention a ``route_name`` will be
+not found by view lookup when a route that mentions a ``*traverse`` in its
+pattern matches. You can make these match forcibly by adding the
+``use_global_views`` flag to the route definition. For example, the
+``myproject.views.bazbuz`` view below will be found if the route named
+``abc`` below is matched and the ``PATH_INFO`` is ``/abc/bazbuz``, even
+though the view configuration statement does not have the
+``route_name="abc"`` attribute.
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern="/abc/*traverse"
- name="abc"
- use_global_views="True"
- />
-
- <view
- name="bazbuz"
- view=".views.bazbuz"
- />
+ config.add_route('abc', '/abc/*traverse', use_global_views=True)
+ config.add_view('myproject.views.bazbuz', name='bazbuz')
.. index::
single: route subpath
@@ -491,18 +439,15 @@ but the traversal algorithm will return a :term:`subpath` list implied
by the capture value of ``*subpath``. You'll see this pattern most
commonly in route declarations that look like this:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern="/static/*subpath"
- name="static"
- view=".views.static_view"
- />
+ config.add_route('static', '/static/*subpath',
+ view='mypackage.views.static_view')
-Where ``.views.static_view`` is an instance of
-:class:`pyramid.view.static`. This effectively tells the static
-helper to traverse everything in the subpath as a filename.
+Where ``mypackage.views.static_view`` is an instance of
+:class:`pyramid.view.static`. This effectively tells the static helper to
+traverse everything in the subpath as a filename.
Corner Cases
------------
@@ -515,52 +460,35 @@ Registering a Default View for a Route That Has a ``view`` Attribute
It is an error to provide *both* a ``view`` argument to a :term:`route
configuration` *and* a :term:`view configuration` which names a
-``route_name`` that has no ``name`` value or the empty ``name`` value.
-For example, this pair of route/view ZCML declarations will generate a
-"conflict" error at startup time.
+``route_name`` that has no ``name`` value or the empty ``name`` value. For
+example, this pair of declarations will generate a "conflict" error at
+startup time.
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar/*traverse"
- name="home"
- view=".views.home"
- />
-
- <view
- route_name="home"
- view=".views.another"
- />
+ config.add_route('home', ':foo/:bar/*traverse',
+ view='myproject.views.home')
+ config.add_view('myproject.views.another', route_name='home')
-This is because the ``view`` attribute of the ``<route>`` statement
-above is an *implicit* default view when that route matches.
-``<route>`` declarations don't *need* to supply a view attribute. For
-example, this ``<route>`` statement:
+This is because the ``view`` argument to the
+:meth:`pyramid.configuration.Configurator.add_route` above is an *implicit*
+default view when that route matches. ``add_route`` calls don't *need* to
+supply a view attribute. For example, this ``add_route`` call:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar/*traverse"
- name="home"
- view=".views.home"
- />
+ config.add_route('home', ':foo/:bar/*traverse',
+ view='myproject.views.home')
Can also be spelled like so:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern=":foo/:bar/*traverse"
- name="home"
- />
-
- <view
- route_name="home"
- view=".views.home"
- />
+ config.add_route('home', ':foo/:bar/*traverse')
+ config.add_view('myproject.views.home', route_name='home')
The two spellings are logically equivalent. In fact, the former is
just a syntactical shortcut for the latter.
@@ -570,42 +498,26 @@ Binding Extra Views Against a Route Configuration that Doesn't Have a ``*travers
Here's another corner case that just makes no sense.
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern="/abc"
- name="abc"
- view=".views.abc"
- />
+ config.add_route('abc', '/abc', view='myproject.views.abc')
+ config.add_view('myproject.views.bazbuz', name='bazbuz',
+ route_name='abc')
- <view
- name="bazbuz"
- view=".views.bazbuz"
- route_name="abc"
- />
+The above view declaration is useless, because it will never be matched when
+the route it references has matched. Only the view associated with the route
+itself (``myproject.views.abc``) will ever be invoked when the route matches,
+because the default view is always invoked when a route matches and when no
+post-match traversal is performed.
-The above ``<view>`` declaration is useless, because it will never be
-matched when the route it references has matched. Only the view
-associated with the route itself (``.views.abc``) will ever be invoked
-when the route matches, because the default view is always invoked
-when a route matches and when no post-match traversal is performed.
+To make the above view declaration non-useless, the special ``*traverse``
+token must end the route's pattern. For example:
-To make the above ``<view>`` declaration non-useless, the special
-``*traverse`` token must end the route's pattern. For example:
-
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <route
- pattern="/abc/*traverse"
- name="abc"
- view=".views.abc"
- />
-
- <view
- name="bazbuz"
- view=".views.bazbuz"
- route_name="abc"
- />
+ config.add_route('abc', '/abc/*traverse', view='myproject.views.abc')
+ config.add_view('myproject.views.bazbuz', name='bazbuz',
+ route_name='abc')