docs/index.rst | ●●●●● patch | view | raw | blame | history | |
docs/latexindex.rst | ●●●●● patch | view | raw | blame | history | |
docs/narr/resourcelocation.rst | ●●●●● patch | view | raw | blame | history | |
docs/narr/urldispatch.rst | ●●●●● patch | view | raw | blame | history |
docs/index.rst
@@ -39,8 +39,8 @@ narr/project narr/startup narr/resourcelocation narr/traversal narr/urldispatch narr/traversal narr/hybrid narr/views narr/handlers docs/latexindex.rst
@@ -32,8 +32,8 @@ narr/firstapp narr/project narr/resourcelocation narr/traversal narr/urldispatch narr/traversal narr/hybrid narr/views narr/handlers docs/narr/resourcelocation.rst
@@ -6,45 +6,27 @@ Resource Location and View Lookup --------------------------------- As a primary job, :app:`Pyramid` provides a mechanism to find and invoke code written by the application developer based on parameters present in the :term:`request`. :app:`Pyramid` uses two separate but cooperating subsystems to find and invoke code written by the application developer: :term:`resource location` and :term:`view lookup`. invoke :term:`view callable` code written by the application developer: :term:`resource location` and :term:`view lookup`. - A :app:`Pyramid` :term:`resource location` subsystem is given a - First, a :app:`Pyramid` :term:`resource location` subsystem is given a :term:`request`; it is responsible for finding a :term:`resource` object based on information present in the request. When a resource is found via resource location, it becomes known as the :term:`context`. - Using the context provided by :term:`resource location`, the :app:`Pyramid` :term:`view lookup` subsystem is provided with a :term:`request` and :term:`context`. It is then responsible for finding and invoking a :term:`view callable`. A view callable is a specific bit of code written and registered by the application developer which receives the - Next, using the context resource found by :term:`resource location` and the :term:`request`, :term:`view lookup` is then responsible for finding and invoking a :term:`view callable`. A view callable is a specific bit of code written and registered by the application developer which receives the :term:`request` and which returns a :term:`response`. These two subsystems are used by :app:`Pyramid` serially: first, a :term:`resource location` subsystem does its job. Then the result of context finding is passed to the :term:`view lookup` subsystem. The view lookup system finds a :term:`view callable` written by an application developer, and invokes it. A view callable returns a :term:`response`. The response is returned to the requesting user. .. sidebar:: What Good is A Resource Location Subsystem? The :term:`URL dispatch` mode of :app:`Pyramid` as well as many other web frameworks such as :term:`Pylons` or :term:`Django` actually collapse the two steps of resource location and view lookup into a single step. In these systems, a URL can map *directly* to a view callable. This makes them simpler to understand than systems which use distinct subsystems to locate a resource and find a view. However, explicitly finding a resource provides extra flexibility. For example, it makes it possible to protect your application with declarative context-sensitive instance-level :term:`authorization`, which is not well-supported in frameworks that do not provide a notion of a resource. :term:`resource location` subsystem does its job. Then the result of resource location is passed to the :term:`view lookup` subsystem. The view lookup system finds a :term:`view callable` written by an application developer, and invokes it. A view callable returns a :term:`response`. The response is returned to the requesting user. There are two separate :term:`resource location` subsystems in :app:`Pyramid`: :term:`traversal` and :term:`URL dispatch`. They can be used @@ -60,8 +42,11 @@ Should I Use Traversal or URL Dispatch for Resource Location? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Since :app:`Pyramid` provides support for both approaches, you can use either exclusively or combine them as you see fit. When you use :app:`Pyramid`, you have a choice about how you'd like to resolve URLs to code: you can use either :term:`traversal` or :term:`URL dispatch`. The choice to use traversal vs. URL dispatch is largely "religious". Since :app:`Pyramid` provides support for both approaches, you can use either exclusively or combine them as you see fit. :term:`URL dispatch` is very straightforward. When you limit your application to using URL dispatch, you know every URL that your application @@ -76,9 +61,9 @@ callable`, e.g. ``/members/{memberid}``. However, URL dispatch is not very convenient if you'd like your URLs to represent an arbitrary hierarchy. For example, if you need to infer the difference between sets of URLs such as these, where the ``document`` in the first URL represents a PDF document, and ``/stuff/page`` in the second represent an arbitrary-depth hierarchy. For example, if you need to infer the difference between sets of URLs such as these, where the ``document`` in the first URL represents a PDF document, and ``/stuff/page`` in the second represents an OpenOffice document in a "stuff" folder. .. code-block:: text @@ -88,22 +73,31 @@ It takes more pattern matching assertions to be able to make hierarchies work in URL-dispatch based systems, and some assertions just aren't possible. Essentially, URL-dispatch based systems just don't deal very well with URLs that represent arbitrary-depth hierarchies. URL-dispatch based systems just don't deal very well with URLs that represent arbitrary-depth hierarchies. But :term:`traversal` *does* work well for URLs that represent :term:`URL dispatch` tends to collapse the two steps of :term:`resource location` and :term:`view lookup` into a single step. Thus, a URL can map *directly* to a view callable. This makes URL dispatch eaiser to understand than traversal, because traversal makes you understand how :term:`resource location` works. But explicitly locating a resource provides extra flexibility. For example, it makes it possible to protect your application with declarative context-sensitive instance-level :term:`authorization`. Unlike URL dispatch, :term:`traversal` works well for URLs that represent arbitrary-depth hierarchies. Since the path segments that compose a URL are addressed separately, it becomes very easy to form URLs that represent arbitrary depth hierarchies in a system that uses traversal. When you're willing to treat your application resources as a tree that can be traversed, it also becomes easy to provide "instance-level security": you just attach a security declaration to each resource in the tree. This is not nearly as easy to do when using URL dispatch. it also becomes easy to provide "instance-level security": you just attach an :term:`ACL` security declaration to each resource in the tree. This is not nearly as easy to do when using URL dispatch. In essence, the choice to use traversal vs. URL dispatch is largely religious. Traversal dispatch probably just doesn't make any sense when you possess completely "square" data stored in a relational database because it requires the construction and maintenance of a tree and requires that the Traversal probably just doesn't make any sense when you possess completely "square" data stored in a relational database because it requires the construction and maintenance of a resource tree and requires that the developer think about mapping URLs to code in terms of traversing that tree. However, when you have a hierarchical data store, using traversal can provide significant advantages over using URL-based dispatch. We'll examine both :term:`URL dispatch` and :term:`traversal` in the next two chapters. docs/narr/urldispatch.rst
@@ -6,41 +6,16 @@ URL Dispatch ============ The URL dispatch feature of :app:`Pyramid` allows you to either augment or replace :term:`traversal` as a :term:`resource location` mechanism, allowing URL pattern matching to have the "first crack" at resolving a given URL to :term:`context` resource. Although it is a "resource-location" mechanism, ironically, using URL dispatch exclusively allows you to avoid thinking about your application in terms of resources entirely. Many applications don't need :app:`Pyramid` features -- such as context-sensitive declarative security via an :term:`authorization policy` -- that benefit from having any visible separation between :term:`resource location` and :term:`view lookup`. To this end, URL dispatch provides a handy syntax that allows you to effectively map URLs *directly* to :term:`view` code in such a way that you needn't think about your application in terms of "resource location" at all. This makes developing a :app:`Pyramid` application seem more like developing an application in a system that is "resource-free", such as :term:`Pylons` or :term:`Django`. Whether or not you care about "resources", it often makes a lot of sense to use :term:`URL dispatch` instead of :term:`traversal` in an application that has no natural data hierarchy. For instance, if all the data in your application lives in a relational database, and that relational database has no self-referencing tables that form a natural hierarchy, URL dispatch is easier to use than traversal, and is often a more natural fit for creating an application that manipulates "flat" data. :term:`URL dispatch` provides a simple way to map URLs :term:`view` code using a simple pattern matching language. An ordered set of patterns is checked one-by-one. If one of the patterns matches the path information associated with a request, a particular :term:`view callable` is invoked. If no route matches, :app:`Pyramid` falls back to trying to use :term:`traversal` to map the current request to a :term:`view callable`. The presence of calls to the :meth:`pyramid.config.Configurator.add_route` method within your application is a sign that you're using :term:`URL dispatch`. .. note:: Route configuration may also be added to the system via :term:`ZCML` (see :ref:`zcml_route_configuration`). High-Level Operational Overview ------------------------------- @@ -50,27 +25,31 @@ matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request` provided to :app:`Pyramid`, a route-specific :term:`context` resource will be generated. When this happens, :app:`Pyramid` will shortcut :term:`traversal`, and will invoke :term:`view lookup` using the context resource and view name generated by URL dispatch. If the matched route names a :term:`view callable` in its configuration, that view callable will be invoked when view lookup is performed. to :app:`Pyramid`, app:`Pyramid` will shortcut :term:`traversal`, and will invoke :term:`view lookup` using a :term:`context` resource generated by the route match. However, if no route pattern matches the information in the :term:`request` provided to :app:`Pyramid`, it will fail over to using :term:`traversal` to perform resource location and view lookup. Technically, URL dispatch is a :term:`resource location` mechanism (it finds a context object). But ironically, using URL dispatch (instead of :term:`traversal`) allows you to avoid thinking about your application in terms of "resources" entirely, because it allows you to directly map a :term:`view callable` to a route. Route Configuration ------------------- :term:`Route configuration` is the act of adding a new :term:`route` to an application. A route has a *pattern*, representing a pattern meant to match against the ``PATH_INFO`` portion of a URL, and a *name*, which is used by developers within a :app:`Pyramid` application to uniquely identify a particular route when generating a URL. It also optionally has a ``factory``, a set of :term:`route predicate` parameters, and a set of :term:`view` parameters. against the ``PATH_INFO`` portion of a URL (the portion following the scheme and port, e.g. ``/foo/bar`` in the URL ``http://localhost:8080/foo/bar``), and a *route name*, which is used by developers within a :app:`Pyramid` application to uniquely identify a particular route when generating a URL. It also optionally has a ``factory``, a set of :term:`route predicate` parameters, and a set of :term:`view` parameters. .. index:: single: add_route @@ -103,10 +82,11 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When a route configuration declaration names a ``view`` attribute, the value of the attribute will reference a :term:`view callable`. A view callable, as described in :ref:`views_chapter`, is developer-supplied code that "does stuff" as the result of a request. For more information about how to create view callables, see :ref:`views_chapter`. of the attribute will reference a :term:`view callable`. This view callable will be invoked when the route matches. A view callable, as described in :ref:`views_chapter`, is developer-supplied code that "does stuff" as the result of a request. For more information about how to create view callables, see :ref:`views_chapter`. Here's an example route configuration that references a view callable: @@ -136,6 +116,9 @@ callable` named as that ``view`` attribute will always be found and invoked when the associated route pattern matches during a request. Route View Callable Registration and Lookup Details !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! The purpose of making it possible to specify a view callable within a route configuration is to prevent developers from needing to deeply understand the details of :term:`resource location` and :term:`view lookup`. When a route @@ -146,11 +129,8 @@ For most usage, you needn't understand more than this; how it works is an implementation detail. In the interest of completeness, however, we'll explain how it *does* work in the following section. You can skip it if you're uninterested. Route View Callable Registration and Lookup Details !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! explain how it *does* work in the this section. You can skip it if you're uninterested. When a ``view`` attribute is attached to a route configuration, :app:`Pyramid` ensures that a :term:`view configuration` is registered that @@ -1257,3 +1237,7 @@ A tutorial showing how :term:`URL dispatch` can be used to create a :app:`Pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`. Route configuration may also be added to the system via :term:`ZCML` (see :ref:`zcml_route_configuration`).