From fec0f0614c69dc7382fba367f8269479e2682058 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 25 Oct 2010 18:47:29 -0400 Subject: convert narrative docs to Pyramid --- docs/narr/urldispatch.rst | 117 ++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 61 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 62a588187..6e7c82f56 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -6,7 +6,7 @@ URL Dispatch ============ -The URL dispatch feature of :mod:`repoze.bfg` allows you to either +The URL dispatch feature of :mod:`pyramid` allows you to either augment or replace :term:`traversal` as a :term:`context finding` mechanism, allowing URL pattern matching to have the "first crack" at resolving a given URL to :term:`context` and :term:`view name`. @@ -15,14 +15,14 @@ Although it is a "context-finding" mechanism, ironically, using URL dispatch exclusively allows you to avoid thinking about your application in terms of "contexts" and "view names" entirely. -Many applications don't need :mod:`repoze.bfg` features -- such as +Many applications don't need :mod:`pyramid` features -- such as declarative security via an :term:`authorization policy` -- that benefit from having any visible separation between :term:`context finding` 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 "context finding" at all. This makes developing -a :mod:`repoze.bfg` application seem more like developing an +a :mod:`pyramid` application seem more like developing an application in a system that is "context-free", such as :term:`Pylons` or :term:`Django`. @@ -37,7 +37,7 @@ data. The presence of :ref:`route_directive` statements in a :term:`ZCML` file used by your application or the presence of calls to the -:meth:`repoze.bfg.configuration.Configurator.add_route` method in +:meth:`pyramid.configuration.Configurator.add_route` method in imperative configuration within your application is a sign that you're using :term:`URL dispatch`. @@ -45,20 +45,20 @@ High-Level Operational Overview ------------------------------- If route configuration is present in an application, the -:mod:`repoze.bfg` :term:`Router` checks every incoming request against +:mod:`pyramid` :term:`Router` checks every incoming request against an ordered set of URL matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request` -provided to :mod:`repoze.bfg`, a route-specific :term:`context` and +provided to :mod:`pyramid`, a route-specific :term:`context` and :term:`view name` will be generated. In this circumstance, -:mod:`repoze.bfg` will shortcut :term:`traversal`, and will invoke +:mod:`pyramid` will shortcut :term:`traversal`, and will invoke :term:`view lookup` using the context 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. However, if no route pattern matches the information in the -:term:`request` provided to :mod:`repoze.bfg`, it will fail over to +:term:`request` provided to :mod:`pyramid`, it will fail over to using :term:`traversal` to perform context finding and view lookup. Route Configuration @@ -67,7 +67,7 @@ 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 :mod:`repoze.bfg` +*name*, which is used by developers within a :mod:`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. @@ -81,7 +81,7 @@ configuration` or via :term:`ZCML`. Both are completely equivalent. Configuring a Route Imperatively via The ``add_route`` Configurator Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The :meth:`repoze.bfg.configuration.Configurator.add_route` method +The :meth:`pyramid.configuration.Configurator.add_route` method adds a single :term:`route configuration` to the :term:`application registry`. Here's an example: @@ -89,7 +89,7 @@ registry`. Here's an example: .. code-block:: python # "config" below is presumed to be an instance of the - # repoze.bfg.configuration.Configurator class; "myview" is assumed + # pyramid.configuration.Configurator class; "myview" is assumed # to be a "view callable" function from views import myview config.add_route('myroute', '/prefix/:one/:two', view=myview) @@ -101,7 +101,7 @@ Configuring a Route via ZCML ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Instead of using the imperative -:meth:`repoze.bfg.configuration.Configurator.add_route` method to add +:meth:`pyramid.configuration.Configurator.add_route` method to add a new route, you can alternately use :term:`ZCML`. For example, the following :term:`ZCML declaration` causes a route to be added to the application. @@ -174,7 +174,7 @@ Route View Callable Registration and Lookup Details !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! When a ``view`` attribute is attached to a route configuration, -:mod:`repoze.bfg` ensures that a :term:`view configuration` is +:mod:`pyramid` ensures that a :term:`view configuration` is registered that will always be found when the route pattern is matched during a request. To do so: @@ -196,8 +196,8 @@ during a request. To do so: to service requests that match the route pattern. In this way, we supply a shortcut to the developer. Under the hood, -:mod:`repoze.bfg` still consumes the :term:`context finding` and -:term:`view lookup` subsystems provided by :mod:`repoze.bfg`, but in a +:mod:`pyramid` still consumes the :term:`context finding` and +:term:`view lookup` subsystems provided by :mod:`pyramid`, but in a way which does not require that a developer understand either of them if he doesn't want or need to. It also means that we can allow a developer to combine :term:`URL dispatch` and :term:`traversal` in @@ -211,7 +211,7 @@ various exceptional cases as documented in :ref:`hybrid_chapter`. Route Pattern Syntax ~~~~~~~~~~~~~~~~~~~~ -The syntax of the pattern matching language used by :mod:`repoze.bfg` +The syntax of the pattern matching language used by :mod:`pyramid` URL dispatch in the *pattern* argument is straightforward; it is close to that of the :term:`Routes` system used by :term:`Pylons`. @@ -368,7 +368,7 @@ a result of traversing a graph. The order that routes are evaluated when they are defined via :term:`ZCML` is the order in which they appear in the ZCML relative to each other. For routes added via the -:mod:`repoze.bfg.configuration.Configurator.add_route` method, the +:mod:`pyramid.configuration.Configurator.add_route` method, the order that routes are evaluated is the order in which they are added to the configuration imperatively. @@ -415,7 +415,7 @@ possible to supply a different :term:`context` object to the view related to each particular route. Supplying a different context for each route is useful when you're -trying to use a :mod:`repoze.bfg` :term:`authorization policy` to +trying to use a :mod:`pyramid` :term:`authorization policy` to provide declarative "context-sensitive" security checks; each context can maintain a separate :term:`ACL`, as in :ref:`using_security_with_urldispatch`. It is also useful when you @@ -449,7 +449,7 @@ represent neither predicates nor view configuration information. ``factory`` A Python object (often a function or a class) or a :term:`dotted Python name` to such an object that will generate a - :mod:`repoze.bfg` :term:`context` object when this route + :mod:`pyramid` :term:`context` object when this route matches. For example, ``mypackage.models.MyFactoryClass``. If this argument is not specified, the traversal root factory will be used. @@ -496,7 +496,7 @@ represent neither predicates nor view configuration information. about the syntax of route paths. If the path doesn't match the current URL, route matching continues. - .. note:: In :mod:`repoze.bfg` 1.2 and prior, this argument existed + .. note:: In earlier releases of this framework, this argument existed as ``path``. ``path`` continues to work as an alias for ``pattern``. @@ -648,7 +648,7 @@ Custom Route Predicates ~~~~~~~~~~~~~~~~~~~~~~~ Each of the predicate callables fed to the ``custom_predicates`` -argument of :meth:`repoze.bfg.configuration.Configurator.add_route` or +argument of :meth:`pyramid.configuration.Configurator.add_route` or the ``custom_predicates`` ZCML attribute must be a callable accepting two arguments. The first argument passed to a custom predicate is a dictionary conventionally named ``info``. The second argument is the @@ -657,7 +657,7 @@ current :term:`request` object. The ``info`` dictionary has a number of contained values: ``match`` is a dictionary: it represents the arguments matched in the URL by the route. ``route`` is an object representing the route which was -matched (see :class:`repoze.bfg.interfaces.IRoute` for the API of such +matched (see :class:`pyramid.interfaces.IRoute` for the API of such a route object). ``info['match']`` is useful when predicates need access to the route @@ -750,7 +750,7 @@ The above predicate, when added to a number of route configurations ensures that the year match argument is '2010' if and only if the route name is 'ymd', 'ym', or 'y'. -See also :class:`repoze.bfg.interfaces.IRoute` for more API +See also :class:`pyramid.interfaces.IRoute` for more API documentation about a route object. Route Matching @@ -760,9 +760,9 @@ The main purpose of route configuration is to match (or not match) the ``PATH_INFO`` present in the WSGI environment provided during a request against a URL path pattern. -The way that :mod:`repoze.bfg` does this is very simple. When a +The way that :mod:`pyramid` does this is very simple. When a request enters the system, for each route configuration declaration -present in the system, :mod:`repoze.bfg` checks the ``PATH_INFO`` +present in the system, :mod:`pyramid` checks the ``PATH_INFO`` against the pattern declared. If any route matches, the route matching process stops. The @@ -785,7 +785,7 @@ skipped and route matching continues through the ordered set of routes. If no route matches after all route patterns are exhausted, -:mod:`repoze.bfg` falls back to :term:`traversal` to do :term:`context +:mod:`pyramid` falls back to :term:`traversal` to do :term:`context finding` and :term:`view lookup`. .. index:: @@ -816,7 +816,7 @@ When the URL pattern associated with a particular route configuration is matched by a request, an object named ``matched_route`` is added as an attribute of the :term:`request` object. Thus, ``request.matched_route`` will be an object implementing the -:class:`repoze.bfg.interfaces.IRoute` interface which matched the +:class:`pyramid.interfaces.IRoute` interface which matched the request. The most useful attribute of the route object is ``name``, which is the name of the route that matched. @@ -909,7 +909,7 @@ might add to your application: view="mypackage.views.tag_view" /> -The above configuration will allow :mod:`repoze.bfg` to service URLs +The above configuration will allow :mod:`pyramid` to service URLs in these forms: .. code-block:: text @@ -1059,7 +1059,7 @@ Or provide the literal string ``/`` as the pattern: Generating Route URLs --------------------- -Use the :func:`repoze.bfg.url.route_url` function to generate URLs +Use the :func:`pyramid.url.route_url` function to generate URLs based on route patterns. For example, if you've configured a route in ZCML with the ``name`` "foo" and the ``pattern`` ":a/:b/:c", you might do this. @@ -1068,13 +1068,13 @@ do this. .. code-block:: python :linenos: - from repoze.bfg.url import route_url + from pyramid.url import route_url url = route_url('foo', request, a='1', b='2', c='3') This would return something like the string ``http://example.com/1/2/3`` (at least if the current protocol and hostname implied ``http:/example.com``). See the -:func:`repoze.bfg.url.route_url` API documentation for more +:func:`pyramid.url.route_url` API documentation for more information. .. index:: @@ -1086,7 +1086,7 @@ Redirecting to Slash-Appended Routes ------------------------------------ For behavior like Django's ``APPEND_SLASH=True``, use the -:func:`repoze.bfg.view.append_slash_notfound_view` view as the +:func:`pyramid.view.append_slash_notfound_view` view as the :term:`Not Found view` in your application. When this view is the Not Found view (indicating that no view was found), and any routes have been defined in the configuration of your application, if the value of @@ -1134,51 +1134,49 @@ stanza: :linenos: -Or use the :meth:`repoze.bfg.configuration.Configurator.add_view` +Or use the :meth:`pyramid.configuration.Configurator.add_view` method if you don't use ZCML: .. code-block:: python :linenos: - from repoze.bfg.exceptions import NotFound - from repoze.bfg.view import append_slash_notfound_view + from pyramid.exceptions import NotFound + from pyramid.view import append_slash_notfound_view config.add_view(append_slash_notfound_view, context=NotFound) See :ref:`view_module` and :ref:`changing_the_notfound_view` for more information about the slash-appending not found view and for a more general description of how to configure a not found view. -.. note:: This feature is new as of :mod:`repoze.bfg` 1.1. - Custom Not Found View With Slash Appended Routes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There can only be one :term:`Not Found view` in any :mod:`repoze.bfg` +There can only be one :term:`Not Found view` in any :mod:`pyramid` application. Even if you use -:func:`repoze.bfg.view.append_slash_notfound_view` as the Not Found -view, :mod:`repoze.bfg` still must generate a ``404 Not Found`` +:func:`pyramid.view.append_slash_notfound_view` as the Not Found +view, :mod:`pyramid` still must generate a ``404 Not Found`` response when it cannot redirect to a slash-appended URL; this not found response will be visible to site users. If you don't care what this 404 response looks like, and only you need redirections to slash-appended route URLs, you may use the -:func:`repoze.bfg.view.append_slash_notfound_view` object as the Not +:func:`pyramid.view.append_slash_notfound_view` object as the Not Found view as described above. However, if you wish to use a *custom* notfound view callable when a URL cannot be redirected to a slash-appended URL, you may wish to use an instance of the -:class:`repoze.bfg.view.AppendSlashNotFoundViewFactory` class as the +:class:`pyramid.view.AppendSlashNotFoundViewFactory` class as the Not Found view, supplying a :term:`view callable` to be used as the custom notfound view as the first argument to its constructor. For instance: .. code-block:: python - from repoze.bfg.exceptions import NotFound - from repoze.bfg.view import AppendSlashNotFoundViewFactory + from pyramid.exceptions import NotFound + from pyramid.view import AppendSlashNotFoundViewFactory def notfound_view(context, request): return HTTPNotFound('It aint there, stop trying!') @@ -1190,9 +1188,6 @@ The ``notfound_view`` supplied must adhere to the two-argument view callable calling convention of ``(context, request)`` (``context`` will be the exception object). -.. note:: The :class:`repoze.bfg.view.AppendSlashNotFoundViewFactory` - class is new as of BFG 1.3. - .. _cleaning_up_after_a_request: Cleaning Up After a Request @@ -1211,7 +1206,7 @@ Instead of putting this cleanup logic in the root factory, however, you can cause a subscriber to be fired when a new request is detected; the subscriber can do this work. -For example, let's say you have a ``mypackage`` :mod:`repoze.bfg` +For example, let's say you have a ``mypackage`` :mod:`pyramid` application package that uses SQLAlchemy, and you'd like the current SQLAlchemy database session to be removed after each request. Put the following in the ``mypackage.run`` module: @@ -1236,7 +1231,7 @@ Then in the ``configure.zcml`` of your package, inject the following: .. code-block:: xml - Or, if you don't use ZCML, but you do use a :term:`scan` add a @@ -1244,8 +1239,8 @@ subscriber decorator: .. code-block:: python - from repoze.bfg.events import subscriber - from repoze.bfg.interfaces import INewRequest + from pyramid.events import subscriber + from pyramid.interfaces import INewRequest @subscriber(INewRequest) def handle_teardown(event): @@ -1257,8 +1252,8 @@ method of a :term:`Configurator`. .. code-block:: python - from repoze.bfg.interfaces import INewRequest - from repoze.bfg.configuration imoport Configurator + from pyramid.interfaces import INewRequest + from pyramid.configuration imoport Configurator def handle_teardown(event): environ = event.request.environ @@ -1274,7 +1269,7 @@ is destroyed (usually at the end of every request). .. note:: This is only an example. In particular, it is not necessary to cause ``DBSession.remove`` to be called as the result of an event listener in an application generated from any - :mod:`repoze.bfg` paster template, because these all use the + :mod:`pyramid` paster template, because these all use the ``repoze.tm2`` middleware. The cleanup done by ``DBSession.remove`` is unnecessary when ``repoze.tm2`` middleware is in the WSGI pipeline. @@ -1284,10 +1279,10 @@ is destroyed (usually at the end of every request). .. _using_security_with_urldispatch: -Using :mod:`repoze.bfg` Security With URL Dispatch +Using :mod:`pyramid` Security With URL Dispatch -------------------------------------------------- -:mod:`repoze.bfg` provides its own security framework which consults an +:mod:`pyramid` provides its own security framework which consults an :term:`authorization policy` before allowing any application code to be called. This framework operates in terms of an access control list, which is stored as an ``__acl__`` attribute of a context object. @@ -1309,7 +1304,7 @@ Such a ``factory`` might look like so: self.__acl__ = [ (Allow, 'editor', 'view') ] If the route ``archives/:article`` is matched, and the article number -is ``1``, :mod:`repoze.bfg` will generate an ``Article`` +is ``1``, :mod:`pyramid` will generate an ``Article`` :term:`context` with an ACL on it that allows the ``editor`` principal the ``view`` permission. Obviously you can do more generic things than inspect the routes match dict to see if the ``article`` argument @@ -1317,11 +1312,11 @@ matches a particular string; our sample ``Article`` factory class is not very ambitious. .. note:: See :ref:`security_chapter` for more information about - :mod:`repoze.bfg` security and ACLs. + :mod:`pyramid` security and ACLs. References ---------- A tutorial showing how :term:`URL dispatch` can be used to create a -:mod:`repoze.bfg` application exists in :ref:`bfg_sql_wiki_tutorial`. +:mod:`pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`. -- cgit v1.2.3