From a7e625785f65c41e5a6dc017b31bd0d74821474e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 31 May 2011 14:40:05 -0400 Subject: the canonical import location for HTTP exceptions/responses is now pyramid.response --- docs/narr/urldispatch.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 5df1eb3af..e5228b81e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -917,7 +917,7 @@ the application's startup configuration, adding the following stanza: :linenos: config.add_view('pyramid.view.append_slash_notfound_view', - context='pyramid.exceptions.NotFound') + context='pyramid.response.HTTPNotFound') 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 @@ -945,14 +945,14 @@ view as the first argument to its constructor. For instance: .. code-block:: python :linenos: - from pyramid.exceptions import NotFound + from pyramid.response import HTTPNotFound from pyramid.view import AppendSlashNotFoundViewFactory def notfound_view(context, request): return HTTPNotFound('It aint there, stop trying!') custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view) - config.add_view(custom_append_slash, context=NotFound) + config.add_view(custom_append_slash, context=HTTPNotFound) The ``notfound_view`` supplied must adhere to the two-argument view callable calling convention of ``(context, request)`` (``context`` will be the -- cgit v1.2.3 From 99edc51a3b05309c7f5d98ff96289ec51b1d7660 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 11 Jun 2011 05:35:27 -0400 Subject: - Pyramid now expects Response objects to have a __call__ method which implements the WSGI application interface instead of the three webob attrs status, headerlist and app_iter. Backwards compatibility exists for code which returns response objects that do not have a __call__. - pyramid.response.Response is no longer an exception (and therefore cannot be raised in order to generate a response). - Changed my mind about moving stuff from pyramid.httpexceptions to pyramid.response. The stuff I moved over has been moved back to pyramid.httpexceptions. --- docs/narr/urldispatch.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index e5228b81e..f94ed3ba8 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -917,7 +917,7 @@ the application's startup configuration, adding the following stanza: :linenos: config.add_view('pyramid.view.append_slash_notfound_view', - context='pyramid.response.HTTPNotFound') + context='pyramid.httpexceptions.HTTPNotFound') 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 @@ -945,7 +945,7 @@ view as the first argument to its constructor. For instance: .. code-block:: python :linenos: - from pyramid.response import HTTPNotFound + from pyramid.httpexceptions import HTTPNotFound from pyramid.view import AppendSlashNotFoundViewFactory def notfound_view(context, request): -- cgit v1.2.3 From 9e7162eb7f584e8afdbc2f04846d0d7e1fcf676c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 7 Jul 2011 02:02:48 -0500 Subject: Updated proutes and pviews docs. --- docs/narr/urldispatch.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index f94ed3ba8..51a840b8d 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1084,16 +1084,17 @@ Displaying All Application Routes You can use the ``paster proutes`` command in a terminal window to print a summary of routes related to your application. Much like the ``paster pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` -command accepts two arguments. The first argument to ``proutes`` is the path -to your application's ``.ini`` file. The second is the ``app`` section name -inside the ``.ini`` file which points to your application. +command accepts one argument with the format ``config_file#section_name``. +The ``config_file`` is the path to your application's ``.ini`` file, +and ``section_name`` is the ``app`` section name inside the ``.ini`` file +which points to your application. For example: .. code-block:: text :linenos: - [chrism@thinko MyProject]$ ../bin/paster proutes development.ini MyProject + [chrism@thinko MyProject]$ ../bin/paster proutes development.ini#MyProject Name Pattern View ---- ------- ---- home / -- cgit v1.2.3 From 7278cf91ea041222f3af814d19e3d1c2f0536ba0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:28:09 -0400 Subject: remove deprecated mechanism to associate views with routes; add description of scan mechanism --- docs/narr/urldispatch.rst | 113 ++++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 79 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 51a840b8d..8e2d240fa 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -12,10 +12,10 @@ 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. -:term:`URL dispatch` is one of two ways to perform :term:`resource -location` in :app:`Pyramid`; the other way is using :term:`traversal`. -If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls -back to :term:`traversal` to handle the :term:`request`. +:term:`URL dispatch` is one of two ways to perform :term:`resource location` +in :app:`Pyramid`; the other way is to use :term:`traversal`. If no route is +matched using :term:`URL dispatch`, :app:`Pyramid` falls back to +:term:`traversal` to handle the :term:`request`. It is the responsibility of the :term:`resource location` subsystem (i.e., :term:`URL dispatch` or :term:`traversal`) to find the resource @@ -67,8 +67,8 @@ attributes. .. _config-add-route: -Configuring a Route via The ``add_route`` Configurator Method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Configuring a Route to Match a View +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :meth:`pyramid.config.Configurator.add_route` method adds a single :term:`route configuration` to the :term:`application registry`. Here's an @@ -84,90 +84,45 @@ example: config.add_route('myroute', '/prefix/{one}/{two}') config.add_view(myview, route_name='myroute') -.. versionchanged:: 1.0a4 - Prior to 1.0a4, routes allow for a marker starting with a ``:``, for - example ``/prefix/:one/:two``. This style is now deprecated - in favor of ``{}`` usage which allows for additional functionality. +When a :term:`view callable` added to the configuration by way of +:meth:`~pyramid.config.Configurator.add_view` bcomes associated with a route +via its ``route_name`` predicate, that view callable will always be found +and invoked when the associated route pattern matches during a request. -.. index:: - single: route configuration; view callable - -.. _add_route_view_config: - -Route Configuration That Names a View Callable -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. warning:: This section describes a feature which has been deprecated in - Pyramid 1.1 and higher. In order to reduce confusion and documentation - burden, passing view-related parameters to - :meth:`~pyramid.config.Configurator.add_route` is deprecated. - - In versions earlier than 1.1, a view was permitted to be connected to a - route using a set of ``view*`` parameters passed to the - :meth:`~pyramid.config.Configurator.add_route`. This was a shorthand - which replaced the need to perform a subsequent call to - :meth:`~pyramid.config.Configurator.add_view` as described in - :ref:`config-add-route`. For example, it was valid (and often recommended) - to do: - - .. code-block:: python +More commonly, you will not use any ``add_view`` statements in your project's +"setup" code, instead only using ``add_route`` statements using a +:term:`scan` for to associate view callables with routes. For example, if +this is a portion of your project's ``__init__.py``: - config.add_route('home', '/', view='mypackage.views.myview', - view_renderer='some/renderer.pt') - - Instead of the equivalent: - - .. code-block:: python - - config.add_route('home', '/') - config.add_view('mypackage.views.myview', route_name='home') - renderer='some/renderer.pt') - - Passing ``view*`` arguments to ``add_route`` as shown in the first - example above is now deprecated in favor of connecting a view to a - predefined route via :meth:`~pyramid.config.Configurator.add_view` using - the route's ``route_name`` parameter, as shown in the second example - above. +.. code-block:: python - A deprecation warning is now issued when any view-related parameter is - passed to ``Configurator.add_route``. The recommended way to associate a - view with a route is documented in :ref:`config-add-route`. + # in your project's __init__.py (mypackage.__init__) -When a route configuration declaration names a ``view`` attribute, the value -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. + config.add_route('myroute', '/prefix/{one}/{two}') + config.scan('mypackage') -Here's an example route configuration that references a view callable: +Note that we don't call :meth:`~pyramid.config.Configurator.add_view` in this +setup code. However, the above :term:`scan` execution +``config.scan('mypackage')`` will pick up all :term:`configuration +decoration`, including any objects decorated with the +:class:`pyramid.view.view_config` decorator in the ``mypackage`` Python +pakage. For example, if you have a ``views.py`` in your package, a scan will +pick up any of its configuration decorators, so we can add one there that +that references ``myroute`` as a ``route_name`` parameter: .. code-block:: python - :linenos: - - # "config" below is presumed to be an instance of the - # pyramid.config.Configurator class; "myview" is assumed - # to be a "view callable" function - from myproject.views import myview - config.add_route('myroute', '/prefix/{one}/{two}', view=myview) - -You can also pass a :term:`dotted Python name` as the ``view`` argument -rather than an actual callable: -.. code-block:: python - :linenos: + # in your project's views.py module (mypackage.views) - # "config" below is presumed to be an instance of the - # pyramid.config.Configurator class; "myview" is assumed - # to be a "view callable" function - config.add_route('myroute', '/prefix/{one}/{two}', - view='myproject.views.myview') + from pyramid.view import view_config + from pyramid.response import Response -When a route configuration names a ``view`` attribute, the :term:`view -callable` named as that ``view`` attribute will always be found and invoked -when the associated route pattern matches during a request. + @view_config(route_name='myroute') + def myview(request): + return Response('OK) -See :meth:`pyramid.config.Configurator.add_route` for a description of -view-related arguments. +THe above combination of ``add_route`` and ``scan`` is completely equivalent +to using the previous combination of ``add_route`` and ``add_view``. .. index:: single: route path pattern syntax -- cgit v1.2.3 From 321e34669f0b9119894cd1ee8c115361deba29f6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:33:56 -0400 Subject: remove references to add_route view-related configuration --- docs/narr/urldispatch.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 8e2d240fa..779a884fb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -394,13 +394,14 @@ the associated route to be considered a match during the route matching process. Examples of route predicate arguments are ``pattern``, ``xhr``, and ``request_method``. -Other arguments are view configuration related arguments. These only have an -effect when the route configuration names a ``view``. These arguments have -been deprecated as of :app:`Pyramid` 1.1 (see :ref:`add_route_view_config`). - Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. +.. warning:: Some arguments are view-configuration related arguments, such as + ``view_renderer``. These only have an effect when the route configuration + names a ``view`` and these arguments have been deprecated as of + :app:`Pyramid` 1.1. + .. _custom_route_predicates: Custom Route Predicates -- cgit v1.2.3 From e4770d391bd87c5d6164affb1a2f79b77b35b58b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:36:12 -0400 Subject: fix sample --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 779a884fb..52311682e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -119,7 +119,7 @@ that references ``myroute`` as a ``route_name`` parameter: @view_config(route_name='myroute') def myview(request): - return Response('OK) + return Response('OK') THe above combination of ``add_route`` and ``scan`` is completely equivalent to using the previous combination of ``add_route`` and ``add_view``. -- cgit v1.2.3 From ae4c577d12a16396b45515e81415b2b16f8e93e8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 13 Jul 2011 20:48:38 -0400 Subject: move all paster commands to a separate chapter --- docs/narr/urldispatch.rst | 43 +++---------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 52311682e..b0a7009e3 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1028,46 +1028,9 @@ which you started the application from. For example: See :ref:`environment_chapter` for more information about how, and where to set these values. -.. index:: - pair: routes; printing - single: paster proutes - -.. _displaying_application_routes: - -Displaying All Application Routes ---------------------------------- - -You can use the ``paster proutes`` command in a terminal window to print a -summary of routes related to your application. Much like the ``paster -pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` -command accepts one argument with the format ``config_file#section_name``. -The ``config_file`` is the path to your application's ``.ini`` file, -and ``section_name`` is the ``app`` section name inside the ``.ini`` file -which points to your application. - -For example: - -.. code-block:: text - :linenos: - - [chrism@thinko MyProject]$ ../bin/paster proutes development.ini#MyProject - Name Pattern View - ---- ------- ---- - home / - home2 / - another /another None - static/ static/*subpath - catchall /*subpath - -``paster proutes`` generates a table. The table has three columns: a Name -name column, a Pattern column, and a View column. The items listed in the -Name column are route names, the items listen in the Pattern column are route -patterns, and the items listed in the View column are representations of the -view callable that will be invoked when a request matches the associated -route pattern. The view column may show ``None`` if no associated view -callable could be found. If no routes are configured within your -application, nothing will be printed to the console when ``paster proutes`` -is executed. +You can also use the ``paster proutes`` command to see a display of all the +routes configured in your application; for more information, see +:ref:`displaying_application_routes`. Route View Callable Registration and Lookup Details --------------------------------------------------- -- cgit v1.2.3 From 6ce1e0cf1a141767ee0aca70786c15dd993347c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 06:10:38 -0400 Subject: add more index markers --- docs/narr/urldispatch.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index b0a7009e3..a25f47690 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -50,6 +50,9 @@ a context object). But ironically, using URL dispatch (instead of terms of "resources" entirely, because it allows you to directly map a :term:`view callable` to a route. +.. index:: + single: route configuration + Route Configuration ------------------- @@ -381,6 +384,9 @@ a separate :term:`ACL`, as documented in combine URL dispatch with :term:`traversal` as documented within :ref:`hybrid_chapter`. +.. index:: + single: route configuration arguments + Route Configuration Arguments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -402,6 +408,9 @@ neither predicates nor view configuration information. names a ``view`` and these arguments have been deprecated as of :app:`Pyramid` 1.1. +.. index:: + single: route predicates (custom) + .. _custom_route_predicates: Custom Route Predicates @@ -534,6 +543,9 @@ that the year match argument is '2010' if and only if the route name is See also :class:`pyramid.interfaces.IRoute` for more API documentation about route objects. +.. index:: + single: route matching + Route Matching -------------- @@ -745,6 +757,9 @@ representing a :term:`SQLAlchemy` model. single: matching the root URL single: root url (matching) +.. index:: + pair: matching; root URL + Matching the Root URL --------------------- @@ -914,6 +929,9 @@ The ``notfound_view`` supplied must adhere to the two-argument view callable calling convention of ``(context, request)`` (``context`` will be the exception object). +.. index:: + single: cleaning up after request + .. _cleaning_up_after_a_request: Cleaning Up After a Request @@ -997,6 +1015,9 @@ our sample ``Article`` factory class is not very ambitious. .. note:: See :ref:`security_chapter` for more information about :app:`Pyramid` security and ACLs. +.. index:: + pair: debugging; route matching + .. _debug_routematch_section: Debugging Route Matching @@ -1032,6 +1053,9 @@ You can also use the ``paster proutes`` command to see a display of all the routes configured in your application; for more information, see :ref:`displaying_application_routes`. +.. index:: + pair: route; view callable lookup details + Route View Callable Registration and Lookup Details --------------------------------------------------- -- cgit v1.2.3 From 8cb68208d42899b50025418812bb339f578d553f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 07:16:14 -0400 Subject: - Reordered chapters in narrative section for better new user friendliness. - Added more indexing markers to sections in documentation. --- docs/narr/urldispatch.rst | 123 ++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 70 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a25f47690..0598cd4f2 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -6,28 +6,12 @@ URL Dispatch ============ -:term:`URL dispatch` provides a simple way to map URLs to :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. - -:term:`URL dispatch` is one of two ways to perform :term:`resource location` -in :app:`Pyramid`; the other way is to use :term:`traversal`. If no route is -matched using :term:`URL dispatch`, :app:`Pyramid` falls back to -:term:`traversal` to handle the :term:`request`. - -It is the responsibility of the :term:`resource location` subsystem -(i.e., :term:`URL dispatch` or :term:`traversal`) to find the resource -object that is the :term:`context` of the :term:`request`. Once the -:term:`context` is determined, :term:`view lookup` is then responsible -for finding and invoking a :term:`view callable`. A view callable is a -specific bit of code, defined in your application, that receives the -:term:`request` and returns a :term:`response` object. - -Where appropriate, we will describe how view lookup interacts with -:term:`resource location`. The :ref:`view_config_chapter` chapter describes -the details of :term:`view lookup`. +:term:`URL dispatch` provides a simple way to map URLs to :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. A +view callable is a specific bit of code, defined in your application, that +receives the :term:`request` and returns a :term:`response` object. High-Level Operational Overview ------------------------------- @@ -37,18 +21,11 @@ If route configuration is present in an application, the :app:`Pyramid` matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request`, -:app:`Pyramid` will invoke :term:`view lookup` using a :term:`context` -resource generated by the route match. +:app:`Pyramid` will invoke :term:`view lookup` to find a matching view. -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. +If no route pattern in the route map matches the information in the +:term:`request` provided in your application, :app:`Pyramid` will fail over +to using :term:`traversal` to perform resource location and view lookup. .. index:: single: route configuration @@ -89,8 +66,8 @@ example: When a :term:`view callable` added to the configuration by way of :meth:`~pyramid.config.Configurator.add_view` bcomes associated with a route -via its ``route_name`` predicate, that view callable will always be found -and invoked when the associated route pattern matches during a request. +via its ``route_name`` predicate, that view callable will always be found and +invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's "setup" code, instead only using ``add_route`` statements using a @@ -323,12 +300,11 @@ Route Declaration Ordering Route configuration declarations are evaluated in a specific order when a request enters the system. As a result, the order of route configuration -declarations is very important. - -The order that routes declarations are evaluated is the order in which they -are added to the application at startup time. This is unlike -:term:`traversal`, which depends on emergent behavior which happens as a -result of traversing a resource tree. +declarations is very important. The order that routes declarations are +evaluated is the order in which they are added to the application at startup +time. (This is unlike a different way of mapping URLs to code that +:app:`Pyramid` provides, named :term:`traversal`, which does not depend on +pattern ordering). For routes added via the :mod:`~pyramid.config.Configurator.add_route` method, the order that routes are evaluated is the order in which they are added to @@ -551,27 +527,30 @@ Route Matching 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. +against a URL path pattern. ``PATH_INFO`` represents the path portion of the +URL that was requested. The way that :app:`Pyramid` does this is very simple. When a request enters the system, for each route configuration declaration present in the system, -:app:`Pyramid` checks the ``PATH_INFO`` against the pattern declared. - -If any route matches, the route matching process stops. The :term:`request` -is decorated with a special :term:`interface` which describes it as a "route -request", the :term:`context` resource is generated, and the context and the -resulting request are handed off to :term:`view lookup`. During view lookup, -if a :term:`view callable` associated with the matched route is found, that -view is called. +:app:`Pyramid` checks the request's ``PATH_INFO`` against the pattern +declared. This checking happens in the order that the routes were declared +via :meth:`pyramid.config.Configurator.add_route`. When a route configuration is declared, it may contain :term:`route predicate` arguments. All route predicates associated with a route declaration must be ``True`` for the route configuration to be used for a -given request. - -If any predicate in the set of :term:`route predicate` arguments provided to -a route configuration returns ``False``, that route is skipped and route -matching continues through the ordered set of routes. +given request during a check. If any predicate in the set of :term:`route +predicate` arguments provided to a route configuration returns ``False`` +during a check, that route is skipped and route matching continues through +the ordered set of routes. + +If any route matches, the route matching process stops and the :term:`view +lookup` subsystem takes over to find the most reasonable view callable for +the matched route. Most often, there's only one view that will match (a view +configured with a ``route_name`` argument matching the matched route). To +gain a better understanding of how routes and views are associated in a real +application, you can use the ``paster pviews`` command, as documented in +:ref:`displaying_matching_views`. If no route matches after all route patterns are exhausted, :app:`Pyramid` falls back to :term:`traversal` to do :term:`resource location` and @@ -1083,24 +1062,28 @@ when the route pattern is matched during a request. To do so: object is decorated with the route-specific interface. - The fact that the request is decorated with a route-specific interface - causes the view lookup machinery to always use the view callable registered - using that interface by the route configuration to service requests that - match the route pattern. - -In this way, we supply a shortcut to the developer. Under the hood, the -:term:`resource location` and :term:`view lookup` subsystems provided by -:app:`Pyramid` are still being utilized, but in a way which does not require -a developer to understand either of them in detail. It also means that we -can allow a developer to combine :term:`URL dispatch` and :term:`traversal` -in various exceptional cases as documented in :ref:`hybrid_chapter`. - -To gain a better understanding of how routes and views are associated in a -real application, you can use the ``paster pviews`` command, as documented -in :ref:`displaying_matching_views`. + causes the :term:`view lookup` machinery to always use the view callable + registered using that interface by the route configuration to service + requests that match the route pattern. + +As we can see from the above description, technically, URL dispatch doesn't +actually map a URL pattern directly to a view callable. Instead, URL +dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` +:term:`resource location` subsystem (i.e., :term:`URL dispatch` or +:term:`traversal`) finds a :term:`resource` object that is the +:term:`context` of a :term:`request`. Once the :term:`context` is determined, +a separate subsystem named :term:`view lookup` is then responsible for +finding and invoking a :term:`view callable` based on information available +in the context and the request. When URL dispatch is used, the resource +location and view lookup subsystems provided by :app:`Pyramid` are still +being utilized, but in a way which does not require a developer to understand +either of them in detail. + +If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back +to :term:`traversal` to handle the :term:`request`. References ---------- A tutorial showing how :term:`URL dispatch` can be used to create a :app:`Pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`. - -- cgit v1.2.3 From 875ded31e7fdd0c85d1c91458248581b9dd729d7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 30 Jul 2011 01:50:24 -0600 Subject: Updated all of the docs to reflect the new pyramid.* settings prefix. --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 0598cd4f2..61c9770c6 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1005,7 +1005,7 @@ Debugging Route Matching It's useful to be able to take a peek under the hood when requests that enter your application arent matching your routes as you expect them to. To debug route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or the -``debug_routematch`` configuration file setting (set either to ``true``). +``pyramid.debug_routematch`` configuration file setting (set either to ``true``). Details of the route matching decision for a particular request to the :app:`Pyramid` application will be printed to the ``stderr`` of the console which you started the application from. For example: -- cgit v1.2.3 From 83bf91aed8495cc42023e276a0e811445f98407d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 10 Aug 2011 21:24:14 -0400 Subject: - Added a ``route_prefix`` argument to the ``pyramid.config.Configurator.include`` method. This argument allows you to compose URL dispatch applications together. See the section entitled "Using a Route Prefix to Compose Applications" in the "URL Dispatch" narrative documentation chapter. - Added a section entitled "Using a Route Prefix to Compose Applications" to the "URL Dispatch" narrative documentation chapter. --- docs/narr/urldispatch.rst | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 61c9770c6..c0197743b 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1082,6 +1082,96 @@ either of them in detail. If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back to :term:`traversal` to handle the :term:`request`. +.. _route_prefix: + +Using a Route Prefix to Compose Applications +-------------------------------------------- + +.. note:: This feature is new as of :app:`Pyramid` 1.2. + +The :meth:`pyramid.config.Configurator.include` method allows configuration +statements to be included from separate files. See +:ref:`building_an_extensible_app` for information about this method. Using +:meth:`pyramid.config.Configurator.include` allows you to build your +application from small and potentially reusable components. + +The :meth:`pyramid.config.Configurator.include` method accepts an argument +named ``route_prefix`` which can be useful to authors of URL-dispatch-based +applications. If ``route_prefix`` is supplied to the include method, it must +be a string. This string represents a route prefix that will be prepended to +all route patterns added by the *included* configuration. Any calls to +:meth:`pyramid.config.Configurator.add_route` within the included callable +will have their pattern prefixed with the value of ``route_prefix``. This can +be used to help mount a set of routes at a different location than the +included callable's author intended while still maintaining the same route +names. For example: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def users_include(config): + config.add_route('show_users', '/show') + + def main(global_config, **settings): + config = Configurator() + config.include(users_include, route_prefix='/users') + +In the above configuration, the ``show_users`` route will have an effective +route pattern of ``/users/show``, instead of ``/show`` because the +``route_prefix`` argument will be prepended to the pattern. The route will +then only match if the URL path is ``/users/show``, and when the +:func:`pyramid.url.route_url` function is called with the route name +``show_users``, it will generate a URL with that same path. + +Route prefixes are recursive, so if a callable executed via an include itself +turns around and includes another callable, the second-level route prefix +will be prepended with the first: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def timing_include(config): + config.add_route('show_times', /times') + + def users_include(config): + config.add_route('show_users', '/show') + config.include(timing_include, route_prefix='/timing') + + def main(global_config, **settings): + config = Configurator() + config.include(users_include, route_prefix='/users') + +In the above configuration, the ``show_users`` route will still have an +effective route pattern of ``/users/show``. The ``show_times`` route +however, will have an effective pattern of ``/users/timing/show_times``. + +Route prefixes have no impact on the requirement that the set of route +*names* in any given Pyramid configuration must be entirely unique. If you +compose your URL dispatch application out of many small subapplications using +:meth:`pyramid.config.Configurator.include`, it's wise to use a dotted name +for your route names, so they'll be unlikely to conflict with other packages +that may be added in the future. For example: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def timing_include(config): + config.add_route('timing.show_times', /times') + + def users_include(config): + config.add_route('users.show_users', '/show') + config.include(timing_include, route_prefix='/timing') + + def main(global_config, **settings): + config = Configurator() + config.include(users_include, route_prefix='/users') + References ---------- -- cgit v1.2.3 From fb90f0166728af40142ed9a31039d26ca3f97c73 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 14 Aug 2011 04:58:34 -0400 Subject: - The ``route_url``, ``route_path``, ``resource_url``, ``static_url``, and ``current_route_url`` functions in the ``pyramid.url`` package now delegate to a method on the request they've been passed, instead of the other way around. The pyramid.request.Request object now inherits from a mixin named pyramid.url.URLMethodsMixin to make this possible, and all url/path generation logic is embedded in this mixin. - Narrative and API documentation which used the ``route_url``, ``route_path``, ``resource_url``, ``static_url``, and ``current_route_url`` functions in the ``pyramid.url`` package have now been changed to use eponymous methods of the request instead. --- docs/narr/urldispatch.rst | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c0197743b..00d36cc76 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -765,20 +765,19 @@ Or provide the literal string ``/`` as the pattern: Generating Route URLs --------------------- -Use the :func:`pyramid.url.route_url` function to generate URLs based on -route patterns. For example, if you've configured a route with the ``name`` -"foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. +Use the :meth:`pyramid.request.Request.route_url` method to generate URLs +based on route patterns. For example, if you've configured a route with the +``name`` "foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. .. ignore-next-block .. code-block:: python :linenos: - from pyramid.url import route_url - url = route_url('foo', request, a='1', b='2', c='3') + url = request.route_url('foo', 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:`~pyramid.url.route_url` API documentation for more +See the :meth:`~pyramid.request.Request.route_url` API documentation for more information. .. index:: @@ -1122,8 +1121,8 @@ In the above configuration, the ``show_users`` route will have an effective route pattern of ``/users/show``, instead of ``/show`` because the ``route_prefix`` argument will be prepended to the pattern. The route will then only match if the URL path is ``/users/show``, and when the -:func:`pyramid.url.route_url` function is called with the route name -``show_users``, it will generate a URL with that same path. +:meth:`pyramid.request.Request.route_url` function is called with the route +name ``show_users``, it will generate a URL with that same path. Route prefixes are recursive, so if a callable executed via an include itself turns around and includes another callable, the second-level route prefix -- cgit v1.2.3 From b37b97bb67eedced5c6a2e0fec718594b5d41878 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Sep 2011 17:58:34 -0400 Subject: move unrelated request cleanup to webob.rest; reorder urldispatch chapter from most-important-concept-to-least --- docs/narr/urldispatch.rst | 592 +++++++++++++++++++++------------------------- 1 file changed, 273 insertions(+), 319 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 00d36cc76..0ec440f4d 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -323,43 +323,6 @@ matched. This is because the match ordering will always match ``members/{def}`` first; the route configuration with ``members/abc`` will never be evaluated. -.. index:: - single: route factory - -.. _route_factories: - -Route Factories -~~~~~~~~~~~~~~~ - -A "route" configuration declaration can mention a "factory". When that route -matches a request, and a factory is attached to a route, the :term:`root -factory` passed at startup time to the :term:`Configurator` is ignored; -instead the factory associated with the route is used to generate a -:term:`root` object. This object will usually be used as the :term:`context` -resource of the view callable ultimately found via :term:`view lookup`. - -.. code-block:: python - :linenos: - - config.add_route('abc', '/abc', - factory='myproject.resources.root_factory') - config.add_view('myproject.views.theview', route_name='abc') - -The factory can either be a Python object or a :term:`dotted Python name` (a -string) which points to such a Python object, as it is above. - -In this way, each route can use a different factory, making it possible to -supply a different :term:`context` resource object to the view related to -each particular route. - -Supplying a different resource factory for each route is useful when you're -trying to use a :app:`Pyramid` :term:`authorization policy` to provide -declarative, "context sensitive" security checks; each resource can maintain -a separate :term:`ACL`, as documented in -:ref:`using_security_with_urldispatch`. It is also useful when you wish to -combine URL dispatch with :term:`traversal` as documented within -:ref:`hybrid_chapter`. - .. index:: single: route configuration arguments @@ -384,141 +347,6 @@ neither predicates nor view configuration information. names a ``view`` and these arguments have been deprecated as of :app:`Pyramid` 1.1. -.. index:: - single: route predicates (custom) - -.. _custom_route_predicates: - -Custom Route Predicates -~~~~~~~~~~~~~~~~~~~~~~~ - -Each of the predicate callables fed to the ``custom_predicates`` argument of -:meth:`~pyramid.config.Configurator.add_route` 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 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:`pyramid.interfaces.IRoute` for the API of such a route object). - -``info['match']`` is useful when predicates need access to the route match. -For example: - -.. code-block:: python - :linenos: - - def any_of(segment_name, *allowed): - def predicate(info, request): - if info['match'][segment_name] in allowed: - return True - return predicate - - num_one_two_or_three = any_of('num', 'one', 'two', 'three') - - config.add_route('route_to_num', '/{num}', - custom_predicates=(num_one_two_or_three,)) - -The above ``any_of`` function generates a predicate which ensures that the -match value named ``segment_name`` is in the set of allowable values -represented by ``allowed``. We use this ``any_of`` function to generate a -predicate function named ``num_one_two_or_three``, which ensures that the -``num`` segment is one of the values ``one``, ``two``, or ``three`` , and use -the result as a custom predicate by feeding it inside a tuple to the -``custom_predicates`` argument to -:meth:`~pyramid.config.Configurator.add_route`. - -A custom route predicate may also *modify* the ``match`` dictionary. For -instance, a predicate might do some type conversion of values: - -.. code-block:: python - :linenos: - - def integers(*segment_names): - def predicate(info, request): - match = info['match'] - for segment_name in segment_names: - try: - match[segment_name] = int(match[segment_name]) - except (TypeError, ValueError): - pass - return True - return predicate - - ymd_to_int = integers('year', 'month', 'day') - - config.add_route('ymd', '/{year}/{month}/{day}', - custom_predicates=(ymd_to_int,)) - -Note that a conversion predicate is still a predicate so it must return -``True`` or ``False``; a predicate that does *only* conversion, such as the -one we demonstrate above should unconditionally return ``True``. - -To avoid the try/except uncertainty, the route pattern can contain regular -expressions specifying requirements for that marker. For instance: - -.. code-block:: python - :linenos: - - def integers(*segment_names): - def predicate(info, request): - match = info['match'] - for segment_name in segment_names: - match[segment_name] = int(match[segment_name]) - return True - return predicate - - ymd_to_int = integers('year', 'month', 'day') - - config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', - custom_predicates=(ymd_to_int,)) - -Now the try/except is no longer needed because the route will not match at -all unless these markers match ``\d+`` which requires them to be valid digits -for an ``int`` type conversion. - -The ``match`` dictionary passed within ``info`` to each predicate attached to -a route will be the same dictionary. Therefore, when registering a custom -predicate which modifies the ``match`` dict, the code registering the -predicate should usually arrange for the predicate to be the *last* custom -predicate in the custom predicate list. Otherwise, custom predicates which -fire subsequent to the predicate which performs the ``match`` modification -will receive the *modified* match dictionary. - -.. warning:: - - It is a poor idea to rely on ordering of custom predicates to build a - conversion pipeline, where one predicate depends on the side effect of - another. For instance, it's a poor idea to register two custom - predicates, one which handles conversion of a value to an int, the next - which handles conversion of that integer to some custom object. Just do - all that in a single custom predicate. - -The ``route`` object in the ``info`` dict is an object that has two useful -attributes: ``name`` and ``pattern``. The ``name`` attribute is the route -name. The ``pattern`` attribute is the route pattern. An example of using -the route in a set of route predicates: - -.. code-block:: python - :linenos: - - def twenty_ten(info, request): - if info['route'].name in ('ymd', 'ym', 'y'): - return info['match']['year'] == '2010' - - config.add_route('y', '/{year}', custom_predicates=(twenty_ten,)) - config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,)) - config.add_route('ymd', '/{year}/{month}/{day}', - custom_predicates=(twenty_ten,)) - -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:`pyramid.interfaces.IRoute` for more API documentation about -route objects. - .. index:: single: route matching @@ -732,11 +560,11 @@ request in its ``__init__``. For example: In a more complicated application, this root factory might be a class representing a :term:`SQLAlchemy` model. +See :ref:`route_factories` for more details about how to use route factories. + .. index:: single: matching the root URL single: root url (matching) - -.. index:: pair: matching; root URL Matching the Root URL @@ -907,92 +735,6 @@ The ``notfound_view`` supplied must adhere to the two-argument view callable calling convention of ``(context, request)`` (``context`` will be the exception object). -.. index:: - single: cleaning up after request - -.. _cleaning_up_after_a_request: - -Cleaning Up After a Request ---------------------------- - -Sometimes it's required that some cleanup be performed at the end of a -request when a database connection is involved. - -For example, let's say you have a ``mypackage`` :app:`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.__init__`` module: - -.. ignore-next-block -.. code-block:: python - :linenos: - - from mypackage.models import DBSession - - from pyramid.events import subscriber - from pyramid.events import NewRequest - - def cleanup_callback(request): - DBSession.remove() - - @subscriber(NewRequest) - def add_cleanup_callback(event): - event.request.add_finished_callback(cleanup_callback) - -Registering the ``cleanup_callback`` finished callback at the start of a -request (by causing the ``add_cleanup_callback`` to receive a -:class:`pyramid.events.NewRequest` event at the start of each request) will -cause the DBSession to be removed whenever request processing has ended. -Note that in the example above, for the :class:`pyramid.events.subscriber` -decorator to "work", the :meth:`pyramid.config.Configurator.scan` method must -be called against your ``mypackage`` package during application -initialization. - -.. note:: This is only an example. In particular, it is not necessary to - cause ``DBSession.remove`` to be called in an application generated from - any :app:`Pyramid` scaffold, 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. - -.. index:: - pair: URL dispatch; security - -.. _using_security_with_urldispatch: - -Using :app:`Pyramid` Security With URL Dispatch --------------------------------------------------- - -:app:`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 resource object. A common thing to -want to do is to attach an ``__acl__`` to the resource object dynamically for -declarative security purposes. You can use the ``factory`` argument that -points at a factory which attaches a custom ``__acl__`` to an object at its -creation time. - -Such a ``factory`` might look like so: - -.. code-block:: python - :linenos: - - class Article(object): - def __init__(self, request): - matchdict = request.matchdict - article = matchdict.get('article', None) - if article == '1': - self.__acl__ = [ (Allow, 'editor', 'view') ] - -If the route ``archives/{article}`` is matched, and the article number is -``1``, :app:`Pyramid` will generate an ``Article`` :term:`context` resource -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 matches a particular string; -our sample ``Article`` factory class is not very ambitious. - -.. note:: See :ref:`security_chapter` for more information about - :app:`Pyramid` security and ACLs. - .. index:: pair: debugging; route matching @@ -1031,68 +773,18 @@ You can also use the ``paster proutes`` command to see a display of all the routes configured in your application; for more information, see :ref:`displaying_application_routes`. -.. index:: - pair: route; view callable lookup details - -Route View Callable Registration and Lookup Details ---------------------------------------------------- - -When a request enters the system which matches the pattern of the route, the -usual result is simple: the view callable associated with the route is -invoked with the request that caused the invocation. - -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 this section. You can skip it if you're -uninterested. - -When a view is associated with a route configuration, :app:`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: +.. _route_prefix: -- A special route-specific :term:`interface` is created at startup time for - each route configuration declaration. +Using a Route Prefix to Compose Applications +-------------------------------------------- -- When an ``add_view`` statement mentions a ``route name`` attribute, a - :term:`view configuration` is registered at startup time. This view - configuration uses a route-specific interface as a :term:`request` type. +.. note:: This feature is new as of :app:`Pyramid` 1.2. -- At runtime, when a request causes any route to match, the :term:`request` - object is decorated with the route-specific interface. - -- The fact that the request is decorated with a route-specific interface - causes the :term:`view lookup` machinery to always use the view callable - registered using that interface by the route configuration to service - requests that match the route pattern. - -As we can see from the above description, technically, URL dispatch doesn't -actually map a URL pattern directly to a view callable. Instead, URL -dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` -:term:`resource location` subsystem (i.e., :term:`URL dispatch` or -:term:`traversal`) finds a :term:`resource` object that is the -:term:`context` of a :term:`request`. Once the :term:`context` is determined, -a separate subsystem named :term:`view lookup` is then responsible for -finding and invoking a :term:`view callable` based on information available -in the context and the request. When URL dispatch is used, the resource -location and view lookup subsystems provided by :app:`Pyramid` are still -being utilized, but in a way which does not require a developer to understand -either of them in detail. - -If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back -to :term:`traversal` to handle the :term:`request`. - -.. _route_prefix: - -Using a Route Prefix to Compose Applications --------------------------------------------- - -.. note:: This feature is new as of :app:`Pyramid` 1.2. - -The :meth:`pyramid.config.Configurator.include` method allows configuration -statements to be included from separate files. See -:ref:`building_an_extensible_app` for information about this method. Using -:meth:`pyramid.config.Configurator.include` allows you to build your -application from small and potentially reusable components. +The :meth:`pyramid.config.Configurator.include` method allows configuration +statements to be included from separate files. See +:ref:`building_an_extensible_app` for information about this method. Using +:meth:`pyramid.config.Configurator.include` allows you to build your +application from small and potentially reusable components. The :meth:`pyramid.config.Configurator.include` method accepts an argument named ``route_prefix`` which can be useful to authors of URL-dispatch-based @@ -1171,6 +863,268 @@ that may be added in the future. For example: config = Configurator() config.include(users_include, route_prefix='/users') +.. index:: + single: route predicates (custom) + +.. _custom_route_predicates: + +Custom Route Predicates +----------------------- + +Each of the predicate callables fed to the ``custom_predicates`` argument of +:meth:`~pyramid.config.Configurator.add_route` 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 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:`pyramid.interfaces.IRoute` for the API of such a route object). + +``info['match']`` is useful when predicates need access to the route match. +For example: + +.. code-block:: python + :linenos: + + def any_of(segment_name, *allowed): + def predicate(info, request): + if info['match'][segment_name] in allowed: + return True + return predicate + + num_one_two_or_three = any_of('num', 'one', 'two', 'three') + + config.add_route('route_to_num', '/{num}', + custom_predicates=(num_one_two_or_three,)) + +The above ``any_of`` function generates a predicate which ensures that the +match value named ``segment_name`` is in the set of allowable values +represented by ``allowed``. We use this ``any_of`` function to generate a +predicate function named ``num_one_two_or_three``, which ensures that the +``num`` segment is one of the values ``one``, ``two``, or ``three`` , and use +the result as a custom predicate by feeding it inside a tuple to the +``custom_predicates`` argument to +:meth:`~pyramid.config.Configurator.add_route`. + +A custom route predicate may also *modify* the ``match`` dictionary. For +instance, a predicate might do some type conversion of values: + +.. code-block:: python + :linenos: + + def integers(*segment_names): + def predicate(info, request): + match = info['match'] + for segment_name in segment_names: + try: + match[segment_name] = int(match[segment_name]) + except (TypeError, ValueError): + pass + return True + return predicate + + ymd_to_int = integers('year', 'month', 'day') + + config.add_route('ymd', '/{year}/{month}/{day}', + custom_predicates=(ymd_to_int,)) + +Note that a conversion predicate is still a predicate so it must return +``True`` or ``False``; a predicate that does *only* conversion, such as the +one we demonstrate above should unconditionally return ``True``. + +To avoid the try/except uncertainty, the route pattern can contain regular +expressions specifying requirements for that marker. For instance: + +.. code-block:: python + :linenos: + + def integers(*segment_names): + def predicate(info, request): + match = info['match'] + for segment_name in segment_names: + match[segment_name] = int(match[segment_name]) + return True + return predicate + + ymd_to_int = integers('year', 'month', 'day') + + config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', + custom_predicates=(ymd_to_int,)) + +Now the try/except is no longer needed because the route will not match at +all unless these markers match ``\d+`` which requires them to be valid digits +for an ``int`` type conversion. + +The ``match`` dictionary passed within ``info`` to each predicate attached to +a route will be the same dictionary. Therefore, when registering a custom +predicate which modifies the ``match`` dict, the code registering the +predicate should usually arrange for the predicate to be the *last* custom +predicate in the custom predicate list. Otherwise, custom predicates which +fire subsequent to the predicate which performs the ``match`` modification +will receive the *modified* match dictionary. + +.. warning:: + + It is a poor idea to rely on ordering of custom predicates to build a + conversion pipeline, where one predicate depends on the side effect of + another. For instance, it's a poor idea to register two custom + predicates, one which handles conversion of a value to an int, the next + which handles conversion of that integer to some custom object. Just do + all that in a single custom predicate. + +The ``route`` object in the ``info`` dict is an object that has two useful +attributes: ``name`` and ``pattern``. The ``name`` attribute is the route +name. The ``pattern`` attribute is the route pattern. An example of using +the route in a set of route predicates: + +.. code-block:: python + :linenos: + + def twenty_ten(info, request): + if info['route'].name in ('ymd', 'ym', 'y'): + return info['match']['year'] == '2010' + + config.add_route('y', '/{year}', custom_predicates=(twenty_ten,)) + config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,)) + config.add_route('ymd', '/{year}/{month}/{day}', + custom_predicates=(twenty_ten,)) + +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:`pyramid.interfaces.IRoute` for more API documentation about +route objects. + +.. index:: + single: route factory + +.. _route_factories: + +Route Factories +--------------- + +Although it is not a particular common need in basic applications, a "route" +configuration declaration can mention a "factory". When that route matches a +request, and a factory is attached to a route, the :term:`root factory` +passed at startup time to the :term:`Configurator` is ignored; instead the +factory associated with the route is used to generate a :term:`root` object. +This object will usually be used as the :term:`context` resource of the view +callable ultimately found via :term:`view lookup`. + +.. code-block:: python + :linenos: + + config.add_route('abc', '/abc', + factory='myproject.resources.root_factory') + config.add_view('myproject.views.theview', route_name='abc') + +The factory can either be a Python object or a :term:`dotted Python name` (a +string) which points to such a Python object, as it is above. + +In this way, each route can use a different factory, making it possible to +supply a different :term:`context` resource object to the view related to +each particular route. + +Supplying a different resource factory for each route is useful when you're +trying to use a :app:`Pyramid` :term:`authorization policy` to provide +declarative, "context sensitive" security checks; each resource can maintain +a separate :term:`ACL`, as documented in +:ref:`using_security_with_urldispatch`. It is also useful when you wish to +combine URL dispatch with :term:`traversal` as documented within +:ref:`hybrid_chapter`. + +.. index:: + pair: URL dispatch; security + +.. _using_security_with_urldispatch: + +Using :app:`Pyramid` Security With URL Dispatch +-------------------------------------------------- + +:app:`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 resource object. A common thing to +want to do is to attach an ``__acl__`` to the resource object dynamically for +declarative security purposes. You can use the ``factory`` argument that +points at a factory which attaches a custom ``__acl__`` to an object at its +creation time. + +Such a ``factory`` might look like so: + +.. code-block:: python + :linenos: + + class Article(object): + def __init__(self, request): + matchdict = request.matchdict + article = matchdict.get('article', None) + if article == '1': + self.__acl__ = [ (Allow, 'editor', 'view') ] + +If the route ``archives/{article}`` is matched, and the article number is +``1``, :app:`Pyramid` will generate an ``Article`` :term:`context` resource +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 matches a particular string; +our sample ``Article`` factory class is not very ambitious. + +.. note:: See :ref:`security_chapter` for more information about + :app:`Pyramid` security and ACLs. + +.. index:: + pair: route; view callable lookup details + +Route View Callable Registration and Lookup Details +--------------------------------------------------- + +When a request enters the system which matches the pattern of the route, the +usual result is simple: the view callable associated with the route is +invoked with the request that caused the invocation. + +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 this section. You can skip it if you're +uninterested. + +When a view is associated with a route configuration, :app:`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: + +- A special route-specific :term:`interface` is created at startup time for + each route configuration declaration. + +- When an ``add_view`` statement mentions a ``route name`` attribute, a + :term:`view configuration` is registered at startup time. This view + configuration uses a route-specific interface as a :term:`request` type. + +- At runtime, when a request causes any route to match, the :term:`request` + object is decorated with the route-specific interface. + +- The fact that the request is decorated with a route-specific interface + causes the :term:`view lookup` machinery to always use the view callable + registered using that interface by the route configuration to service + requests that match the route pattern. + +As we can see from the above description, technically, URL dispatch doesn't +actually map a URL pattern directly to a view callable. Instead, URL +dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` +:term:`resource location` subsystem (i.e., :term:`URL dispatch` or +:term:`traversal`) finds a :term:`resource` object that is the +:term:`context` of a :term:`request`. Once the :term:`context` is determined, +a separate subsystem named :term:`view lookup` is then responsible for +finding and invoking a :term:`view callable` based on information available +in the context and the request. When URL dispatch is used, the resource +location and view lookup subsystems provided by :app:`Pyramid` are still +being utilized, but in a way which does not require a developer to understand +either of them in detail. + +If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back +to :term:`traversal` to handle the :term:`request`. + References ---------- -- cgit v1.2.3 From bb93cbdf16ac03e354569959663d053a68685fc5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 05:56:14 -0400 Subject: add squishy whats-unique section to introduction --- docs/narr/urldispatch.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 0ec440f4d..52f6115eb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -590,6 +590,8 @@ Or provide the literal string ``/`` as the pattern: single: generating route URLs single: route URLs +.. _generating_route_urls: + Generating Route URLs --------------------- -- cgit v1.2.3 From 68a01e26af1a0a1ab448d4dad517001186d134b2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 06:09:43 -0400 Subject: more refs to root factory docs --- docs/narr/urldispatch.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 52f6115eb..ad9cc6033 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1030,6 +1030,19 @@ In this way, each route can use a different factory, making it possible to supply a different :term:`context` resource object to the view related to each particular route. +A factory must be a callable which accepts a request and returns an arbitrary +Python object. For example, the below class can be used as a factory: + +.. code-block:: python + :linenos: + + class Mine(object): + def __init__(self, request): + pass + +A route factory is actually conceptually identical to the :term:`root +factory` described at :ref:`the_resource_tree`. + Supplying a different resource factory for each route is useful when you're trying to use a :app:`Pyramid` :term:`authorization policy` to provide declarative, "context sensitive" security checks; each resource can maintain -- cgit v1.2.3 From 649ddf33537cd2a3ea2b1efc140cc74a16a81b10 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 12 Sep 2011 12:58:43 -0400 Subject: document replacement marker composition --- docs/narr/urldispatch.rst | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ad9cc6033..a6e46515f 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -138,11 +138,22 @@ replacement marker does not need to be preceded by a ``/`` character. A replacement marker is in the format ``{name}``, where this means "accept any characters up to the next slash character and use this as the ``name`` -:term:`matchdict` value." A matchdict is the dictionary representing the -dynamic parts extracted from a URL based on the routing pattern. It is -available as ``request.matchdict``. For example, the following pattern -defines one literal segment (``foo``) and two replacement markers (``baz``, -and ``bar``): +:term:`matchdict` value." + +A replacement marker in a pattern must begin with an uppercase or lowercase +ASCII letter or an underscore, and can be composed only of uppercase or +lowercase ASCII letters, underscores, and numbers. For example: ``a``, +``a_b``, ``_b``, and ``b9`` are all valid replacement marker names, but +``0a`` is not. + +.. note:: A replacement marker could not start with an underscore until + Pyramid 1.2. Previous versions required that the replacement marker start + with an uppercase or lowercase letter. + +A matchdict is the dictionary representing the dynamic parts extracted from a +URL based on the routing pattern. It is available as ``request.matchdict``. +For example, the following pattern defines one literal segment (``foo``) and +two replacement markers (``baz``, and ``bar``): .. code-block:: text -- cgit v1.2.3 From 012b9762cd0b114b6afbf2d6356554b51706804a Mon Sep 17 00:00:00 2001 From: michr Date: Fri, 23 Sep 2011 18:48:28 -0700 Subject: fixed up all the warning dealing ..note and ..warn added a hide toc for glossary to prevent warnings --- docs/narr/urldispatch.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a6e46515f..9d5229c70 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -353,7 +353,9 @@ process. Examples of route predicate arguments are ``pattern``, ``xhr``, and Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. -.. warning:: Some arguments are view-configuration related arguments, such as +.. warning:: + + Some arguments are view-configuration related arguments, such as ``view_renderer``. These only have an effect when the route configuration names a ``view`` and these arguments have been deprecated as of :app:`Pyramid` 1.1. @@ -646,7 +648,9 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. -.. note:: the ``static`` argument to +.. note:: + + the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` is new as of :app:`Pyramid` 1.1. @@ -1098,7 +1102,9 @@ permission. Obviously you can do more generic things than inspect the routes match dict to see if the ``article`` argument matches a particular string; our sample ``Article`` factory class is not very ambitious. -.. note:: See :ref:`security_chapter` for more information about +.. note:: + + See :ref:`security_chapter` for more information about :app:`Pyramid` security and ACLs. .. index:: -- cgit v1.2.3 From 52346bed8c07002f4b720b8b0889952dc1e02959 Mon Sep 17 00:00:00 2001 From: michr Date: Fri, 23 Sep 2011 19:54:35 -0700 Subject: add documenteation for the __text__ attribute for a predicate --- docs/narr/urldispatch.rst | 79 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 19 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 9d5229c70..2fcbce507 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -190,7 +190,7 @@ at the end of the segment represented by ``{name}.html`` (it only contains To capture both segments, two replacement markers can be used: .. code-block:: text - + foo/{name}.{ext} The literal path ``/foo/biz.html`` will match the above route pattern, and @@ -256,10 +256,10 @@ The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text - foo/1/2/ -> + foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':()} - foo/abc/def/a/b/c -> + foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle':(u'a', u'b', u'c')} Note that when a ``*stararg`` remainder match is matched, the value put into @@ -288,7 +288,7 @@ split by segment. Changing the regular expression used to match a marker can also capture the remainder of the URL, for example: .. code-block:: text - + foo/{baz}/{bar}{fizzle:.*} The above pattern will match these URLs, generating the following matchdicts: @@ -699,10 +699,10 @@ route with an appended slash. .. warning:: - You **should not** rely on this mechanism to redirect ``POST`` requests. - The redirect of the slash-appending not found view will turn a ``POST`` - request into a ``GET``, losing any ``POST`` data in the original - request. + You **should not** rely on this mechanism to redirect ``POST`` requests. + The redirect of the slash-appending not found view will turn a ``POST`` + request into a ``GET``, losing any ``POST`` data in the original + request. To configure the slash-appending not found view in your application, change the application's startup configuration, adding the following stanza: @@ -710,7 +710,7 @@ the application's startup configuration, adding the following stanza: .. code-block:: python :linenos: - config.add_view('pyramid.view.append_slash_notfound_view', + config.add_view('pyramid.view.append_slash_notfound_view', context='pyramid.httpexceptions.HTTPNotFound') See :ref:`view_module` and :ref:`changing_the_notfound_view` for more @@ -772,7 +772,7 @@ which you started the application from. For example: :linenos: [chrism@thinko pylonsbasic]$ PYRAMID_DEBUG_ROUTEMATCH=true \ - bin/paster serve development.ini + bin/paster serve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ @@ -813,7 +813,7 @@ will have their pattern prefixed with the value of ``route_prefix``. This can be used to help mount a set of routes at a different location than the included callable's author intended while still maintaining the same route names. For example: - + .. code-block:: python :linenos: @@ -821,7 +821,7 @@ names. For example: def users_include(config): config.add_route('show_users', '/show') - + def main(global_config, **settings): config = Configurator() config.include(users_include, route_prefix='/users') @@ -844,7 +844,7 @@ will be prepended with the first: def timing_include(config): config.add_route('show_times', /times') - + def users_include(config): config.add_route('show_users', '/show') config.include(timing_include, route_prefix='/timing') @@ -871,7 +871,7 @@ that may be added in the future. For example: def timing_include(config): config.add_route('timing.show_times', /times') - + def users_include(config): config.add_route('users.show_users', '/show') config.include(timing_include, route_prefix='/timing') @@ -913,7 +913,7 @@ For example: num_one_two_or_three = any_of('num', 'one', 'two', 'three') - config.add_route('route_to_num', '/{num}', + config.add_route('route_to_num', '/{num}', custom_predicates=(num_one_two_or_three,)) The above ``any_of`` function generates a predicate which ensures that the @@ -944,7 +944,7 @@ instance, a predicate might do some type conversion of values: ymd_to_int = integers('year', 'month', 'day') - config.add_route('ymd', '/{year}/{month}/{day}', + config.add_route('ymd', '/{year}/{month}/{day}', custom_predicates=(ymd_to_int,)) Note that a conversion predicate is still a predicate so it must return @@ -967,7 +967,7 @@ expressions specifying requirements for that marker. For instance: ymd_to_int = integers('year', 'month', 'day') - config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', + config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', custom_predicates=(ymd_to_int,)) Now the try/except is no longer needed because the route will not match at @@ -1005,13 +1005,54 @@ the route in a set of route predicates: config.add_route('y', '/{year}', custom_predicates=(twenty_ten,)) config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,)) - config.add_route('ymd', '/{year}/{month}/{day}', + config.add_route('ymd', '/{year}/{month}/{day}', custom_predicates=(twenty_ten,)) 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'. +You can also caption the predicates by setting the ``__text__`` attribute. This +will help you with the ``paster pviews`` command (see +:ref:`displaying_application_routes`) and the ``pyramid_debugtoolbar``. + +If a predicate is a class just add __text__ property in a standard manner. + +.. code-block:: python + :linenos: + + class DummyCustomPredicate1(object): + def __init__(self): + self.__text__ = 'my custom class predicate' + + class DummyCustomPredicate2(object): + __text__ = 'my custom class predicate' + +If a predicate is a method you'll need to assign it after method declaration +(see `PEP 232 `_) + +.. code-block:: python + :linenos: + + def custom_predicate(): + pass + custom_predicate.__text__ = 'my custom method predicate' + +If a predicate is a classmethod using @classmethod will not work, but you can +still easily do it by wrapping it in classmethod call. + +.. code-block:: python + :linenos: + + def classmethod_predicate(): + pass + classmethod_predicate.__text__ = 'my classmethod predicate' + classmethod_predicate = classmethod(classmethod_predicate) + +Same will work with staticmethod, just use ``staticmethod`` instead of +``classmethod``. + + See also :class:`pyramid.interfaces.IRoute` for more API documentation about route objects. @@ -1034,7 +1075,7 @@ callable ultimately found via :term:`view lookup`. .. code-block:: python :linenos: - config.add_route('abc', '/abc', + config.add_route('abc', '/abc', factory='myproject.resources.root_factory') config.add_view('myproject.views.theview', route_name='abc') -- cgit v1.2.3 From cfb2b5596b8ef366aeef3bce5b61eafc7a2f175d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 6 Oct 2011 03:05:29 -0400 Subject: remove all reference to the paster command-line utility --- docs/narr/urldispatch.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2fcbce507..9ceb20f21 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -390,7 +390,7 @@ lookup` subsystem takes over to find the most reasonable view callable for the matched route. Most often, there's only one view that will match (a view configured with a ``route_name`` argument matching the matched route). To gain a better understanding of how routes and views are associated in a real -application, you can use the ``paster pviews`` command, as documented in +application, you can use the ``pviews`` command, as documented in :ref:`displaying_matching_views`. If no route matches after all route patterns are exhausted, :app:`Pyramid` @@ -772,7 +772,7 @@ which you started the application from. For example: :linenos: [chrism@thinko pylonsbasic]$ PYRAMID_DEBUG_ROUTEMATCH=true \ - bin/paster serve development.ini + bin/pserve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ @@ -786,7 +786,7 @@ which you started the application from. For example: See :ref:`environment_chapter` for more information about how, and where to set these values. -You can also use the ``paster proutes`` command to see a display of all the +You can also use the ``proutes`` command to see a display of all the routes configured in your application; for more information, see :ref:`displaying_application_routes`. @@ -1012,8 +1012,8 @@ 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'. -You can also caption the predicates by setting the ``__text__`` attribute. This -will help you with the ``paster pviews`` command (see +You can also caption the predicates by setting the ``__text__`` +attribute. This will help you with the ``pviews`` command (see :ref:`displaying_application_routes`) and the ``pyramid_debugtoolbar``. If a predicate is a class just add __text__ property in a standard manner. -- cgit v1.2.3 From d7afdd514faa804e93f5bb8d2bb0b330c7b4c4b0 Mon Sep 17 00:00:00 2001 From: Wayne Tong Date: Wed, 12 Oct 2011 13:08:52 +0200 Subject: Edited docs/narr/urldispatch.rst via GitHub --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 9ceb20f21..c2414965c 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -65,7 +65,7 @@ example: config.add_view(myview, route_name='myroute') When a :term:`view callable` added to the configuration by way of -:meth:`~pyramid.config.Configurator.add_view` bcomes associated with a route +:meth:`~pyramid.config.Configurator.add_view` becomes associated with a route via its ``route_name`` predicate, that view callable will always be found and invoked when the associated route pattern matches during a request. -- cgit v1.2.3 From 777ca3c6feac4179b1ecec9cd50fd15ca8dbe6bb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 24 Oct 2011 00:05:14 -0500 Subject: garden --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c2414965c..35613ea1b 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -101,7 +101,7 @@ that references ``myroute`` as a ``route_name`` parameter: def myview(request): return Response('OK') -THe above combination of ``add_route`` and ``scan`` is completely equivalent +The above combination of ``add_route`` and ``scan`` is completely equivalent to using the previous combination of ``add_route`` and ``add_view``. .. index:: -- cgit v1.2.3 From a511b1423334f855e996bb06714b36aa86f861e9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 5 Jan 2012 02:41:32 -0500 Subject: fix urldispatch matching and generation to cope with various inputs --- docs/narr/urldispatch.rst | 87 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 35613ea1b..7e485f8ae 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -235,7 +235,7 @@ When matching the following URL: .. code-block:: text - foo/La%20Pe%C3%B1a + http://example.com/foo/La%20Pe%C3%B1a The matchdict will look like so (the value is URL-decoded / UTF-8 decoded): @@ -243,6 +243,50 @@ The matchdict will look like so (the value is URL-decoded / UTF-8 decoded): {'bar':u'La Pe\xf1a'} +Literal strings in the path segment should represent the *decoded* value of +the ``PATH_INFO`` provided to Pyramid. You don't want to use a URL-encoded +value or a bytestring representing the literal's UTF-8 in the pattern. For +example, rather than this: + +.. code-block:: text + + /Foo%20Bar/{baz} + +You'll want to use something like this: + +.. code-block:: text + + /Foo Bar/{baz} + +For patterns that contain "high-order" characters in its literals, you'll +want to use a Unicode value as the pattern as opposed to any URL-encoded or +UTF-8-encoded value. For example, you might be tempted to use a bytestring +pattern like this: + +.. code-block:: text + + /La Pe\xc3\xb1a/{x} + +But that probably won't match as you expect it to. You'll want to use a +Unicode value as the pattern instead rather than raw bytestring escapes. You +can use a high-order Unicode value as the pattern by using `Python source +file encoding `_ plus the "real" +character in the Unicode pattern in the source, like so: + +.. code-block:: text + + /La Peña/{x} + +Or you can ignore source file encoding and use equivalent Unicode escape +characters in the pattern. + +.. code-block:: text + + /La Pe\xf1a/{x} + +Dynamic segment names cannot contain high-order characters, so this applies +only to literals in the pattern. + If the pattern has a ``*`` in it, the name which follows it is considered a "remainder match". A remainder match *must* come at the end of the pattern. Unlike segment replacement markers, it does not need to be preceded by a @@ -612,7 +656,6 @@ Use the :meth:`pyramid.request.Request.route_url` method to generate URLs based on route patterns. For example, if you've configured a route with the ``name`` "foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. -.. ignore-next-block .. code-block:: python :linenos: @@ -620,7 +663,45 @@ based on route patterns. For example, if you've configured a route with the 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 :meth:`~pyramid.request.Request.route_url` API documentation for more + +To get only the *path* of a route, use the +:meth:`pyramid.request.Request.route_path` API instead of +:meth:`~pyramid.request.Request.route_url`. + +.. code-block:: python + + url = request.route_path('foo', a='1', b='2', c='3') + +This will return the string ``/1/2/3`` rather than a full URL. + +Note that URLs and paths generated by ``route_path`` and ``route_url`` are +always URL-quoted string types (which contain no non-ASCII characters). +Therefore, if you've added a route like so: + +.. code-block:: python + + config.add_route('la', u'/La Peña/{city}') + +And you later generate a URL using ``route_path`` or ``route_url`` like so: + +.. code-block:: python + + url = request.route_path('la', city=u'Québec') + +You will wind up with the path encoded to UTF-8 and URL quoted like so: + +.. code-block:: python + + /La%20Pe%C3%B1a/Qu%C3%A9bec + +.. note:: + + Generating URL-quoted URLs and paths is new as of Pyramid 1.3 (and Pyramid + 1.2 after 1.2.6). Previous versions generated unquoted URLs and paths + (which was broken). + +See the :meth:`~pyramid.request.Request.route_url` and +:meth:`~pyramid.request.Request.route_path` API documentation for more information. .. index:: -- cgit v1.2.3 From e3dadfd5865f58a2f816e558e8dbc636dd037197 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 5 Jan 2012 05:55:31 -0500 Subject: bring docs up to date with code --- docs/narr/urldispatch.rst | 59 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 7e485f8ae..6d9dfdd92 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -267,11 +267,12 @@ pattern like this: /La Pe\xc3\xb1a/{x} -But that probably won't match as you expect it to. You'll want to use a -Unicode value as the pattern instead rather than raw bytestring escapes. You -can use a high-order Unicode value as the pattern by using `Python source -file encoding `_ plus the "real" -character in the Unicode pattern in the source, like so: +But this will either cause an error at startup time or it won't match +properly. You'll want to use a Unicode value as the pattern instead rather +than raw bytestring escapes. You can use a high-order Unicode value as the +pattern by using `Python source file encoding +`_ plus the "real" character in the +Unicode pattern in the source, like so: .. code-block:: text @@ -664,7 +665,7 @@ based on route patterns. For example, if you've configured a route with the 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``). -To get only the *path* of a route, use the +To generate only the *path* portion of a URL from a route, use the :meth:`pyramid.request.Request.route_path` API instead of :meth:`~pyramid.request.Request.route_url`. @@ -674,8 +675,14 @@ To get only the *path* of a route, use the This will return the string ``/1/2/3`` rather than a full URL. +Replacement values passed to ``route_url`` or ``route_path`` must be Unicode +or bytestrings encoded in UTF-8. One exception to this rule exists: if +you're trying to replace a "remainder" match value (a ``*stararg`` +replacement value), the value may be a tuple containing Unicode strings or +UTF-8 strings. + Note that URLs and paths generated by ``route_path`` and ``route_url`` are -always URL-quoted string types (which contain no non-ASCII characters). +always URL-quoted string types (they contain no non-ASCII characters). Therefore, if you've added a route like so: .. code-block:: python @@ -690,19 +697,41 @@ And you later generate a URL using ``route_path`` or ``route_url`` like so: You will wind up with the path encoded to UTF-8 and URL quoted like so: -.. code-block:: python +.. code-block:: text /La%20Pe%C3%B1a/Qu%C3%A9bec -.. note:: +If you have a ``*stararg`` remainder dynamic part of your route pattern: + +.. code-block:: python + + config.add_route('abc', 'a/b/c/*foo') + +And you later generate a URL using ``route_path`` or ``route_url`` using a +*string* as the replacement value: + +.. code-block:: python + + url = request.route_path('abc', foo=u'Québec/biz') - Generating URL-quoted URLs and paths is new as of Pyramid 1.3 (and Pyramid - 1.2 after 1.2.6). Previous versions generated unquoted URLs and paths - (which was broken). +The value you pass will be URL-quoted except for embedded slashes in the +result: + +.. code-block:: text + + /a/b/c/Qu%C3%A9bec/biz + +You can get a similar result by passing a tuple composed of path elements: + +.. code-block:: python + + url = request.route_path('abc', foo=(u'Québec', u'biz')) + +Each value in the tuple will be url-quoted and joined by slashes in this case: + +.. code-block:: text -See the :meth:`~pyramid.request.Request.route_url` and -:meth:`~pyramid.request.Request.route_path` API documentation for more -information. + /a/b/c/Qu%C3%A9bec/biz .. index:: single: static routes -- cgit v1.2.3 From d01ae960c9e278bd361e2517e0fef7173549f642 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 5 Feb 2012 23:56:29 -0500 Subject: fix extra paren --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 6d9dfdd92..dfa4e629d 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -341,7 +341,7 @@ The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':()} - foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c')} + foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c'} This occurs because the default regular expression for a marker is ``[^/]+`` which will match everything up to the first ``/``, while ``{fizzle:.*}`` will -- cgit v1.2.3 From 1ceae4adac7c050e955778c71b3680edb9a3cb8c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 7 Feb 2012 10:06:52 -0600 Subject: bug in url dispatch docs --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index dfa4e629d..a7bf74786 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -340,7 +340,7 @@ The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text - foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':()} + foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':u''} foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c'} This occurs because the default regular expression for a marker is ``[^/]+`` -- cgit v1.2.3 From 0db4a157083d51251b4d3f574a1699fc76359c9d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 22 Feb 2012 15:37:50 -0500 Subject: - New API: ``pyramid.config.Configurator.add_notfound_view``. This is a wrapper for ``pyramid.Config.configurator.add_view`` which provides easy append_slash support. It should be preferred over calling ``add_view`` directly with ``context=HTTPNotFound`` as was previously recommended. - New API: ``pyramid.view.notfound_view_config``. This is a decorator constructor like ``pyramid.view.view_config`` that calls ``pyramid.config.Configurator.add_notfound_view`` when scanned. It should be preferred over using ``pyramid.view.view_config`` with ``context=HTTPNotFound`` as was previously recommended. - The older deprecated ``set_notfound_view`` Configurator method is now an alias for the new ``add_notfound_view`` Configurator method. This has the following impact: the ``context`` sent to views with a ``(context, request)`` call signature registered via the deprecated ``add_notfound_view``/``set_notfound_view`` will now be the HTTPNotFound exception object instead of the actual resource context found. Use ``request.context`` to get the actual resource context. It's also recommended to disuse ``set_notfound_view`` in favor of ``add_notfound_view``, despite the aliasing. - The API documentation for ``pyramid.view.append_slash_notfound_view`` and ``pyramid.view.AppendSlashNotFoundViewFactory`` was removed. These names still exist and are still importable, but they are no longer APIs. Use ``pyramid.config.Configurator.add_notfound_view(append_slash=True)`` or ``pyramid.view.notfound_view_config(append_slash=True)`` to get the same behavior. - The ``set_forbidden_view`` method of the Configurator was removed from the documentation. It has been deprecated since Pyramid 1.1. - The AppendSlashNotFoundViewFactory used request.path to match routes. This was wrong because request.path contains the script name, and this would cause it to fail in circumstances where the script name was not empty. It should have used request.path_info, and now does. - Updated the "Registering a Not Found View" section of the "Hooks" chapter, replacing explanations of registering a view using ``add_view`` or ``view_config`` with ones using ``add_notfound_view`` or ``notfound_view_config``. - Updated the "Redirecting to Slash-Appended Routes" section of the "URL Dispatch" chapter, replacing explanations of registering a view using ``add_view`` or ``view_config`` with ones using ``add_notfound_view`` or ``notfound_view_config`` --- docs/narr/urldispatch.rst | 141 ++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 67 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a7bf74786..7c0b437c1 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -772,95 +772,102 @@ ignored when ``static`` is ``True``. Redirecting to Slash-Appended Routes ------------------------------------ -For behavior like Django's ``APPEND_SLASH=True``, use the -:func:`~pyramid.view.append_slash_notfound_view` view as the :term:`Not Found -view` in your application. Defining this view as the :term:`Not Found view` -is a way to automatically redirect requests where the URL lacks a trailing -slash, but requires one to match the proper route. When configured, along -with at least one other route in your application, this view will be invoked -if the value of ``PATH_INFO`` does not already end in a slash, and if the -value of ``PATH_INFO`` *plus* a slash matches any route's pattern. In this -case it does an HTTP redirect to the slash-appended ``PATH_INFO``. - -Let's use an example, because this behavior is a bit magical. If the -``append_slash_notfound_view`` is configured in your application and your -route configuration looks like so: +For behavior like Django's ``APPEND_SLASH=True``, use the ``append_slash`` +argument to :meth:`pyramid.config.Configurator.add_notfound_view` or the +equivalent ``append_slash`` argument to the +:class:`pyramid.view.notfound_view_config` decorator. + +Adding ``append_slash=True`` is a way to automatically redirect requests +where the URL lacks a trailing slash, but requires one to match the proper +route. When configured, along with at least one other route in your +application, this view will be invoked if the value of ``PATH_INFO`` does not +already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash +matches any route's pattern. In this case it does an HTTP redirect to the +slash-appended ``PATH_INFO``. + +To configure the slash-appending not found view in your application, change +the application's startup configuration, adding the following stanza: .. code-block:: python :linenos: - config.add_route('noslash', 'no_slash') - config.add_route('hasslash', 'has_slash/') +Let's use an example. If the following routes are configured in your +application: + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPNotFound + + def notfound(request): + return HTTPNotFound('Not found, bro.') + + def no_slash(request): + return Response('No slash') - config.add_view('myproject.views.no_slash', route_name='noslash') - config.add_view('myproject.views.has_slash', route_name='hasslash') + def has_slash(request): + return Response('Has slash') + + def main(g, **settings): + config = Configurator() + config.add_route('noslash', 'no_slash') + config.add_route('hasslash', 'has_slash/') + config.add_view(no_slash, route_name='noslash') + config.add_view(has_slash, route_name='hasslash') + config.add_notfound_view(notfound, append_slash=True) + +If a request enters the application with the ``PATH_INFO`` value of +``/no_slash``, the first route will match and the browser will show "No +slash". However, if a request enters the application with the ``PATH_INFO`` +value of ``/no_slash/``, *no* route will match, and the slash-appending not +found view will not find a matching route with an appended slash. As a +result, the ``notfound`` view will be called and it will return a "Not found, +bro." body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash``, a route *will* be found by the slash-appending not found view. An HTTP redirect to -``/has_slash/`` will be returned to the user's browser. +``/has_slash/`` will be returned to the user's browser. As a result, the +``notfound`` view will never actually be called. -If a request enters the application with the ``PATH_INFO`` value of -``/no_slash``, the first route will match. However, if a request enters the -application with the ``PATH_INFO`` value of ``/no_slash/``, *no* route will -match, and the slash-appending not found view will *not* find a matching -route with an appended slash. - -.. warning:: - - You **should not** rely on this mechanism to redirect ``POST`` requests. - The redirect of the slash-appending not found view will turn a ``POST`` - request into a ``GET``, losing any ``POST`` data in the original - request. - -To configure the slash-appending not found view in your application, change -the application's startup configuration, adding the following stanza: +The following application uses the :class:`pyramid.view.notfound_view_config` +and :class:`pyramid.view.view_config` decorators and a :term:`scan` to do +exactly the same job: .. code-block:: python :linenos: - config.add_view('pyramid.view.append_slash_notfound_view', - context='pyramid.httpexceptions.HTTPNotFound') - -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. + from pyramid.httpexceptions import HTTPNotFound + from pyramid.view import notfound_view_config, view_config -Custom Not Found View With Slash Appended Routes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @notfound_view_config(append_slash=True) + def notfound(request): + return HTTPNotFound('Not found, bro.') -There can only be one :term:`Not Found view` in any :app:`Pyramid` -application. Even if you use :func:`~pyramid.view.append_slash_notfound_view` -as the Not Found view, :app:`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. + @view_config(route_name='noslash') + def no_slash(request): + return Response('No slash') -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:`~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:`~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: + @view_config(route_name='hasslash') + def has_slash(request): + return Response('Has slash') -.. code-block:: python - :linenos: - - from pyramid.httpexceptions import HTTPNotFound - from pyramid.view import AppendSlashNotFoundViewFactory + def main(g, **settings): + config = Configurator() + config.add_route('noslash', 'no_slash') + config.add_route('hasslash', 'has_slash/') + config.scan() - def notfound_view(context, request): - return HTTPNotFound('It aint there, stop trying!') +.. warning:: - custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view) - config.add_view(custom_append_slash, context=HTTPNotFound) + You **should not** rely on this mechanism to redirect ``POST`` requests. + The redirect of the slash-appending not found view will turn a ``POST`` + request into a ``GET``, losing any ``POST`` data in the original + request. -The ``notfound_view`` supplied must adhere to the two-argument view callable -calling convention of ``(context, request)`` (``context`` will be the -exception object). +See :ref:`view_module` and :ref:`changing_the_notfound_view` for for a more +general description of how to configure a view and/or a not found view. .. index:: pair: debugging; route matching -- cgit v1.2.3 From 81c63fee1dae8dcf12b5063f93faf0eeed54659c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 26 Feb 2012 13:36:14 -0500 Subject: make latex render again --- docs/narr/urldispatch.rst | 6 ------ 1 file changed, 6 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 7c0b437c1..f036ce94e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -785,12 +785,6 @@ already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash matches any route's pattern. In this case it does an HTTP redirect to the slash-appended ``PATH_INFO``. -To configure the slash-appending not found view in your application, change -the application's startup configuration, adding the following stanza: - -.. code-block:: python - :linenos: - Let's use an example. If the following routes are configured in your application: -- cgit v1.2.3 From ea7a26856e27f4256ec0157635b4c64197f37053 Mon Sep 17 00:00:00 2001 From: VlAleVas Date: Fri, 27 Apr 2012 16:10:13 +0300 Subject: Update docs/narr/urldispatch.rst --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index f036ce94e..acbccbdfd 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -547,7 +547,7 @@ add to your application: config.add_route('idea', 'ideas/{idea}') config.add_route('user', 'users/{user}') - config.add_route('tag', 'tags/{tags}') + config.add_route('tag', 'tags/{tag}') config.add_view('mypackage.views.idea_view', route_name='idea') config.add_view('mypackage.views.user_view', route_name='user') -- cgit v1.2.3 From 1aa978c074afce7f821634e5aa8366caa07ee437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20B=C3=BCchler?= Date: Wed, 23 May 2012 09:28:53 +0300 Subject: Fixed a few glitches in the "Using a Route Prefix to Compose Applications" section of the docs/narr/urldispatch.rst docs. --- docs/narr/urldispatch.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index acbccbdfd..ecf3d026a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -954,7 +954,7 @@ will be prepended with the first: from pyramid.config import Configurator def timing_include(config): - config.add_route('show_times', /times') + config.add_route('show_times', '/times') def users_include(config): config.add_route('show_users', '/show') @@ -966,7 +966,7 @@ will be prepended with the first: In the above configuration, the ``show_users`` route will still have an effective route pattern of ``/users/show``. The ``show_times`` route -however, will have an effective pattern of ``/users/timing/show_times``. +however, will have an effective pattern of ``/users/timing/times``. Route prefixes have no impact on the requirement that the set of route *names* in any given Pyramid configuration must be entirely unique. If you @@ -981,7 +981,7 @@ that may be added in the future. For example: from pyramid.config import Configurator def timing_include(config): - config.add_route('timing.show_times', /times') + config.add_route('timing.show_times', '/times') def users_include(config): config.add_route('users.show_users', '/show') -- cgit v1.2.3 From 76aa5150d5ba25386817d06e0777c8891c7ef3a1 Mon Sep 17 00:00:00 2001 From: Reinout van Rees Date: Sat, 22 Dec 2012 21:19:49 +0100 Subject: Typo pakage => package --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ecf3d026a..480b0e0cc 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -86,7 +86,7 @@ setup code. However, the above :term:`scan` execution ``config.scan('mypackage')`` will pick up all :term:`configuration decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python -pakage. For example, if you have a ``views.py`` in your package, a scan will +package. For example, if you have a ``views.py`` in your package, a scan will pick up any of its configuration decorators, so we can add one there that that references ``myroute`` as a ``route_name`` parameter: -- cgit v1.2.3 From 043ccddb909327106264d10ed5d413760a51770d Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 2 Jan 2013 02:22:52 +0200 Subject: eliminate other repeated words --- docs/narr/urldispatch.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 480b0e0cc..46f908b7c 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -87,7 +87,7 @@ setup code. However, the above :term:`scan` execution decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python package. For example, if you have a ``views.py`` in your package, a scan will -pick up any of its configuration decorators, so we can add one there that +pick up any of its configuration decorators, so we can add one there that references ``myroute`` as a ``route_name`` parameter: .. code-block:: python @@ -860,7 +860,7 @@ exactly the same job: request into a ``GET``, losing any ``POST`` data in the original request. -See :ref:`view_module` and :ref:`changing_the_notfound_view` for for a more +See :ref:`view_module` and :ref:`changing_the_notfound_view` for a more general description of how to configure a view and/or a not found view. .. index:: -- cgit v1.2.3 From e241c7e479b411a7f465b0a3d86021301702f8af Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 18 Jan 2013 23:58:04 +0200 Subject: make example links clickable, for convenience --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 46f908b7c..ec97bf3b2 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -38,7 +38,7 @@ application. A route has a *name*, which acts as an identifier to be used for URL generation. The name also allows developers to associate a view configuration with the route. A route also has a *pattern*, meant to match 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``). It +and port, e.g. ``/foo/bar`` in the URL ``_). It also optionally has a ``factory`` and a set of :term:`route predicate` attributes. -- cgit v1.2.3 From 479447a1ebc231096155290f918f563b884a3432 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 29 Jan 2013 01:03:37 +0200 Subject: replace 'note' with the more correct 'versionadded' directive --- docs/narr/urldispatch.rst | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ec97bf3b2..749a2d49a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -758,11 +758,8 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. -.. note:: - - the ``static`` argument to - :meth:`~pyramid.config.Configurator.add_route` is new as of :app:`Pyramid` - 1.1. +.. versionadded:: 1.1 + the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` .. index:: single: redirecting to slash-appended routes @@ -906,7 +903,7 @@ routes configured in your application; for more information, see Using a Route Prefix to Compose Applications -------------------------------------------- -.. note:: This feature is new as of :app:`Pyramid` 1.2. +.. versionadded:: 1.2 The :meth:`pyramid.config.Configurator.include` method allows configuration statements to be included from separate files. See -- cgit v1.2.3 From 2605e0cc2ad089d4f25c00a5f2c4d99ffbfa4567 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 22:57:05 +0200 Subject: grammar fixes --- docs/narr/urldispatch.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 749a2d49a..34543c4bb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -16,12 +16,12 @@ receives the :term:`request` and returns a :term:`response` object. High-Level Operational Overview ------------------------------- -If route configuration is present in an application, the :app:`Pyramid` +If a route configuration is present in an application, the :app:`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`, -:app:`Pyramid` will invoke :term:`view lookup` to find a matching view. +:app:`Pyramid` will invoke a :term:`view lookup` to find a matching view. If no route pattern in the route map matches the information in the :term:`request` provided in your application, :app:`Pyramid` will fail over @@ -71,7 +71,7 @@ invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's "setup" code, instead only using ``add_route`` statements using a -:term:`scan` for to associate view callables with routes. For example, if +:term:`scan` to associate view callables with routes. For example, if this is a portion of your project's ``__init__.py``: .. code-block:: python @@ -83,7 +83,7 @@ this is a portion of your project's ``__init__.py``: Note that we don't call :meth:`~pyramid.config.Configurator.add_view` in this setup code. However, the above :term:`scan` execution -``config.scan('mypackage')`` will pick up all :term:`configuration +``config.scan('mypackage')`` will pick up each :term:`configuration decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python package. For example, if you have a ``views.py`` in your package, a scan will -- cgit v1.2.3 From 5c9da6debe11b52975fb296be55a4dcd8c41c533 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 17 Feb 2013 22:35:32 +0200 Subject: DRY --- docs/narr/urldispatch.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 749a2d49a..6cdcd81fb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -76,8 +76,6 @@ this is a portion of your project's ``__init__.py``: .. code-block:: python - # in your project's __init__.py (mypackage.__init__) - config.add_route('myroute', '/prefix/{one}/{two}') config.scan('mypackage') -- cgit v1.2.3 From 67486e9eec17b0209aebc9b2f2220fa704f23825 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 17 Feb 2013 22:47:39 +0200 Subject: DRY --- docs/narr/urldispatch.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 6cdcd81fb..2a7adea81 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -90,8 +90,6 @@ that references ``myroute`` as a ``route_name`` parameter: .. code-block:: python - # in your project's views.py module (mypackage.views) - from pyramid.view import view_config from pyramid.response import Response -- cgit v1.2.3 From 6a2827684a13bb588b031f4ac9a6257344bb4e18 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 17 Feb 2013 22:47:53 +0200 Subject: fix grammar; shorten overlong sentence --- docs/narr/urldispatch.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 749a2d49a..7e460c885 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -70,8 +70,8 @@ via its ``route_name`` predicate, that view callable will always be found and invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's -"setup" code, instead only using ``add_route`` statements using a -:term:`scan` for to associate view callables with routes. For example, if +"setup" code. You will instead use ``add_route`` statements, and use a +:term:`scan` to associate view callables with routes. For example, if this is a portion of your project's ``__init__.py``: .. code-block:: python -- cgit v1.2.3 From 02e6877a79fe7874af5103d9e6c886d67a09eb7f Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 6 Mar 2013 00:09:54 +0200 Subject: address issues raised by Tres Seaver at #884 --- docs/narr/urldispatch.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 34543c4bb..e58d98416 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -16,12 +16,13 @@ receives the :term:`request` and returns a :term:`response` object. High-Level Operational Overview ------------------------------- -If a route configuration is present in an application, the :app:`Pyramid` +If any route configuration is present in an application, the :app:`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`, -:app:`Pyramid` will invoke a :term:`view lookup` to find a matching view. +:app:`Pyramid` will invoke the :term:`view lookup` process to find a +matching view. If no route pattern in the route map matches the information in the :term:`request` provided in your application, :app:`Pyramid` will fail over -- cgit v1.2.3 From 5d3e517aab23d7d40c6ee147ad0395855e337451 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 26 Feb 2013 22:39:54 +0200 Subject: remove a distraction --- docs/narr/urldispatch.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2a7adea81..1ae7abcbc 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -875,8 +875,7 @@ which you started the application from. For example: .. code-block:: text :linenos: - [chrism@thinko pylonsbasic]$ PYRAMID_DEBUG_ROUTEMATCH=true \ - bin/pserve development.ini + $ PYRAMID_DEBUG_ROUTEMATCH=true bin/pserve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ -- cgit v1.2.3 From 2f4bdefd18073c418ae95fe9e5a8c7b2a9d1130e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 9 Mar 2013 03:06:17 +0200 Subject: capitalize; add term role --- docs/narr/urldispatch.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2a7adea81..16af4d088 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -814,7 +814,7 @@ bro." body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash``, a route *will* be -found by the slash-appending not found view. An HTTP redirect to +found by the slash-appending :term:`Not Found View`. An HTTP redirect to ``/has_slash/`` will be returned to the user's browser. As a result, the ``notfound`` view will never actually be called. @@ -849,12 +849,12 @@ exactly the same job: .. warning:: You **should not** rely on this mechanism to redirect ``POST`` requests. - The redirect of the slash-appending not found view will turn a ``POST`` - request into a ``GET``, losing any ``POST`` data in the original + The redirect of the slash-appending :term:`Not Found View` will turn a + ``POST`` request into a ``GET``, losing any ``POST`` data in the original request. See :ref:`view_module` and :ref:`changing_the_notfound_view` for a more -general description of how to configure a view and/or a not found view. +general description of how to configure a view and/or a :term:`Not Found View`. .. index:: pair: debugging; route matching -- cgit v1.2.3 From f73f0e332658fac2583f51247dcd49bd36d63ce4 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 13 Mar 2013 23:05:17 +0200 Subject: consistency: use $VENV whenever virtualenv binaries are used --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a327e937b..181b07259 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -875,7 +875,7 @@ which you started the application from. For example: .. code-block:: text :linenos: - $ PYRAMID_DEBUG_ROUTEMATCH=true bin/pserve development.ini + $ PYRAMID_DEBUG_ROUTEMATCH=true $VENV/bin/pserve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ -- cgit v1.2.3 From 1ad8de2b9032b5a452b75274b8f908645c732e57 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 22 Mar 2013 17:24:32 +0200 Subject: remove unused ignore-next-block directive --- docs/narr/urldispatch.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 0656a1833..bcd5fff94 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -55,7 +55,6 @@ The :meth:`pyramid.config.Configurator.add_route` method adds a single :term:`route configuration` to the :term:`application registry`. Here's an example: -.. ignore-next-block .. code-block:: python # "config" below is presumed to be an instance of the -- cgit v1.2.3 From a9bd7d058ec1399927ae19c1850ec15195319403 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 2 Apr 2013 11:13:56 -0500 Subject: fix #964 --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index bcd5fff94..18cb3e4db 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1263,7 +1263,7 @@ invoked with the request that caused the invocation. 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 this section. You can skip it if you're +explain how it *does* work in this section. You can skip it if you're uninterested. When a view is associated with a route configuration, :app:`Pyramid` ensures -- cgit v1.2.3 From 866944efa58accab20abca15409803d9e13368b4 Mon Sep 17 00:00:00 2001 From: tisdall Date: Fri, 9 Aug 2013 14:56:29 -0400 Subject: "arent" to "aren't" --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 18cb3e4db..310c160c0 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -865,7 +865,7 @@ Debugging Route Matching ------------------------ It's useful to be able to take a peek under the hood when requests that enter -your application arent matching your routes as you expect them to. To debug +your application aren't matching your routes as you expect them to. To debug route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or the ``pyramid.debug_routematch`` configuration file setting (set either to ``true``). Details of the route matching decision for a particular request to the -- cgit v1.2.3 From 8866e256bf640817692cb16ec0ccc4c642a13b7d Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Sat, 17 Aug 2013 16:54:28 +0200 Subject: Document the external URL feature. --- docs/narr/urldispatch.rst | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 310c160c0..34014c9c5 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -105,6 +105,7 @@ to using the previous combination of ``add_route`` and ``add_view``. .. _route_pattern_syntax: + Route Pattern Syntax ~~~~~~~~~~~~~~~~~~~~ @@ -754,9 +755,43 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. +:ref:`External routes ` are implicitely static. + .. versionadded:: 1.1 the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` +.. _external_route_narr: + + +External Routes +--------------- + +.. versionadded:: 1.5 + +Route patterns that are valid URLs, are treated as external routes. Like +:ref:`static routes ` they are useful for URL generation +purposes only and are never considered for matching at request time. + +.. code-block:: python + :linenos: + + >>> config = Configurator() + >>> config.add_route('youtube', 'https://youtube.com/watch/{video_id}') + ... + >>> request.route_url('youtube', video_id='oHg5SJYRHA0') + >>> "https://youtube.com/watch/oHg5SJYRHA0" + +All pattern replacements and calls to +:meth:`pyramid.request.Request.route_url` will work as expected. Note that +:meth:`pyramid.request.Request.route_path` will also just return the external +URLs path part. + +.. note:: + + The external URL feature is implemented with a :term:`pregenerator` so you + cannot use both with the same route. + + .. index:: single: redirecting to slash-appended routes -- cgit v1.2.3 From 58d507156b30ac194c99527247078cc5a25cb142 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Sat, 17 Aug 2013 17:09:34 +0200 Subject: typo --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 34014c9c5..045af42eb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -755,7 +755,7 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. -:ref:`External routes ` are implicitely static. +:ref:`External routes ` are implicitly static. .. versionadded:: 1.1 the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` -- cgit v1.2.3 From 3bae69780cf5f7d8ff772adc085f3e064853f1a0 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Sat, 17 Aug 2013 17:09:36 +0200 Subject: reference the static url route feature --- docs/narr/urldispatch.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 045af42eb..8f03b1080 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -128,6 +128,10 @@ and: /{foo}/bar/baz +If a pattern is a valid URL it won't be ever matched against an incoming +request. Instead it can be useful for generating external URLs. See +:ref:`External routes ` for details. + A pattern segment (an individual item between ``/`` characters in the pattern) may either be a literal string (e.g. ``foo``) *or* it may be a replacement marker (e.g. ``{foo}``) or a certain combination of both. A -- cgit v1.2.3 From 84367e57afc0d5538e02f670834809933d9cab26 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 19 Aug 2013 22:56:54 -0500 Subject: allow pregenerator and route_prefix with external routes --- docs/narr/urldispatch.rst | 5 ----- 1 file changed, 5 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 8f03b1080..f3513624e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -790,11 +790,6 @@ All pattern replacements and calls to :meth:`pyramid.request.Request.route_path` will also just return the external URLs path part. -.. note:: - - The external URL feature is implemented with a :term:`pregenerator` so you - cannot use both with the same route. - .. index:: single: redirecting to slash-appended routes -- cgit v1.2.3 From d07d167f6dcdc5ef03e8aaca3c953e984a5a5f1a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 20 Aug 2013 10:13:55 -0400 Subject: raise ValueError instead of generating just path when _app_url is provided to request.route_url and the route has an external pattern --- docs/narr/urldispatch.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index f3513624e..62eb89348 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -785,11 +785,12 @@ purposes only and are never considered for matching at request time. >>> request.route_url('youtube', video_id='oHg5SJYRHA0') >>> "https://youtube.com/watch/oHg5SJYRHA0" -All pattern replacements and calls to -:meth:`pyramid.request.Request.route_url` will work as expected. Note that -:meth:`pyramid.request.Request.route_path` will also just return the external -URLs path part. - +Most pattern replacements and calls to +:meth:`pyramid.request.Request.route_url` will work as expected. However, calls +to :meth:`pyramid.request.Request.route_path` against external patterns will +raise an exception, and passing ``_app_url`` to +:meth:`~pyramid.request.Request.route_url` to generate a URL against a route +that has an external pattern will also raise an exception. .. index:: single: redirecting to slash-appended routes -- cgit v1.2.3 From fdf30b3bb6f47d93d2f255a09e75be0c33d54789 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 21:12:10 -0400 Subject: - Removed the ability to pass the following arguments to ``pyramid.config.Configurator.add_route``: `view``, ``view_context``. ``view_for``, ``view_permission``, ``view_renderer``, and ``view_attr``. Using these arguments had been deprecated since Pyramid 1.1. Instead of passing view-related arguments to ``add_route``, use a separate call to ``pyramid.config.Configurator.add_view`` to associate a view with a route using its ``route_name`` argument. Note that this impacts the ``pyramid.config.Configurator.add_static_view`` function too, because it delegates to ``add_route``. --- docs/narr/urldispatch.rst | 7 ------- 1 file changed, 7 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 62eb89348..61849c3c0 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -399,13 +399,6 @@ process. Examples of route predicate arguments are ``pattern``, ``xhr``, and Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. -.. warning:: - - Some arguments are view-configuration related arguments, such as - ``view_renderer``. These only have an effect when the route configuration - names a ``view`` and these arguments have been deprecated as of - :app:`Pyramid` 1.1. - .. index:: single: route matching -- cgit v1.2.3 From 392a6c7df93b67d6889680133fda0f744970d61f Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sun, 17 Nov 2013 00:11:37 +0200 Subject: Removed extra indentation from some examples (:linenos: should be indented with the same indentation as the rest of the code block) --- docs/narr/urldispatch.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 61849c3c0..96ee5758e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -492,7 +492,7 @@ The simplest route declaration which configures a route match to *directly* result in a particular view callable being invoked: .. code-block:: python - :linenos: + :linenos: config.add_route('idea', 'site/{id}') config.add_view('mypackage.views.site_view', route_name='idea') @@ -901,7 +901,7 @@ Details of the route matching decision for a particular request to the which you started the application from. For example: .. code-block:: text - :linenos: + :linenos: $ PYRAMID_DEBUG_ROUTEMATCH=true $VENV/bin/pserve development.ini Starting server in PID 13586. @@ -1060,7 +1060,7 @@ A custom route predicate may also *modify* the ``match`` dictionary. For instance, a predicate might do some type conversion of values: .. code-block:: python - :linenos: + :linenos: def integers(*segment_names): def predicate(info, request): @@ -1086,7 +1086,7 @@ To avoid the try/except uncertainty, the route pattern can contain regular expressions specifying requirements for that marker. For instance: .. code-block:: python - :linenos: + :linenos: def integers(*segment_names): def predicate(info, request): @@ -1128,7 +1128,7 @@ name. The ``pattern`` attribute is the route pattern. An example of using the route in a set of route predicates: .. code-block:: python - :linenos: + :linenos: def twenty_ten(info, request): if info['route'].name in ('ymd', 'ym', 'y'): -- cgit v1.2.3 From 2033eeb3602f330930585678aac926749b9c22f7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 10 Feb 2014 03:22:33 -0600 Subject: - Garden PR #1121 --- docs/narr/urldispatch.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 96ee5758e..87a962a9a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1183,9 +1183,10 @@ still easily do it by wrapping it in classmethod call. Same will work with staticmethod, just use ``staticmethod`` instead of ``classmethod``. +.. seealso:: -See also :class:`pyramid.interfaces.IRoute` for more API documentation about -route objects. + See also :class:`pyramid.interfaces.IRoute` for more API documentation + about route objects. .. index:: single: route factory -- cgit v1.2.3 From bb60b86feeea7cfbb531460b22ad40f211562708 Mon Sep 17 00:00:00 2001 From: Zack Marvel Date: Wed, 10 Dec 2014 01:25:11 -0500 Subject: Revise URL Dispatch documentation to use config.scan() in Examples 1, 2, and 3 In response to #600. --- docs/narr/urldispatch.rst | 57 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 87a962a9a..2fd971917 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -495,17 +495,20 @@ result in a particular view callable being invoked: :linenos: config.add_route('idea', 'site/{id}') - config.add_view('mypackage.views.site_view', route_name='idea') + config.scan() When a route configuration with a ``view`` attribute is added to the system, and an incoming request matches the *pattern* of the route configuration, the :term:`view callable` named as the ``view`` attribute of the route configuration will be invoked. -In the case of the above example, when the URL of a request matches -``/site/{id}``, the view callable at the Python dotted path name -``mypackage.views.site_view`` will be called with the request. In other -words, we've associated a view callable directly with a route pattern. +Recall that ``config.scan`` is equivalent to calling ``config.add_view``, +because the ``@view_config`` decorator in ``mypackage.views``, shown below, +maps the route name to the matching view callable. In the case of the above +example, when the URL of a request matches ``/site/{id}``, the view callable at +the Python dotted path name ``mypackage.views.site_view`` will be called with +the request. In other words, we've associated a view callable directly with a +route pattern. When the ``/site/{id}`` route pattern matches during a request, the ``site_view`` view callable is invoked with that request as its sole @@ -519,8 +522,10 @@ The ``mypackage.views`` module referred to above might look like so: .. code-block:: python :linenos: + from pyramid.view import view_config from pyramid.response import Response + @view_config(route_name='idea') def site_view(request): return Response(request.matchdict['id']) @@ -542,11 +547,30 @@ add to your application: config.add_route('idea', 'ideas/{idea}') config.add_route('user', 'users/{user}') config.add_route('tag', 'tags/{tag}') + config.scan() + +Here is an example of a corresponding ``mypackage.views`` module: - config.add_view('mypackage.views.idea_view', route_name='idea') - config.add_view('mypackage.views.user_view', route_name='user') - config.add_view('mypackage.views.tag_view', route_name='tag') +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + @view_config(route_name='idea') + def idea_view(request): + return Response(request.matchdict['id']) + + @view_config(route_name='user') + def user_view(request): + user = request.matchdict['user'] + return Response(u'The user is {}.'.format(user)) + + @view_config(route_name='tag') + def tag_view(request): + tag = request.matchdict['tag'] + return Response(u'The tag is {}.'.format(tag)) + The above configuration will allow :app:`Pyramid` to service URLs in these forms: @@ -596,7 +620,7 @@ An example of using a route with a factory: :linenos: config.add_route('idea', 'ideas/{idea}', factory='myproject.resources.Idea') - config.add_view('myproject.views.idea_view', route_name='idea') + config.scan() The above route will manufacture an ``Idea`` resource as a :term:`context`, assuming that ``mypackage.resources.Idea`` resolves to a class that accepts a @@ -610,7 +634,20 @@ request in its ``__init__``. For example: pass In a more complicated application, this root factory might be a class -representing a :term:`SQLAlchemy` model. +representing a :term:`SQLAlchemy` model. The view ``mypackage.views.idea_view`` +might look like this: + +.. code-block:: python + :linenos: + + @view_config(route_name='idea') + def idea_view(request): + idea = request.context + return Response(idea) + +Here, ``request.context`` is an instance of ``Idea``. If indeed the resource +object is a SQLAlchemy model, you do not even have to perform a query in the +view callable, since you have access to the resource via ``request.context``. See :ref:`route_factories` for more details about how to use route factories. -- cgit v1.2.3 From 3c163b212a6848c1d45916073d6a60a9020ea5c1 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 21:08:58 -0600 Subject: reword a small part to clarify what's happening with view_config --- docs/narr/urldispatch.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2fd971917..ca6a55164 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -502,9 +502,10 @@ and an incoming request matches the *pattern* of the route configuration, the :term:`view callable` named as the ``view`` attribute of the route configuration will be invoked. -Recall that ``config.scan`` is equivalent to calling ``config.add_view``, -because the ``@view_config`` decorator in ``mypackage.views``, shown below, -maps the route name to the matching view callable. In the case of the above +Recall that the ``@view_config`` is equivalent to calling ``config.add_view``, +because the ``config.scan()`` call will import ``mypackage.views``, shown +below, and execute ``config.add_view`` under the hood. Each view then maps the +route name to the matching view callable. In the case of the above example, when the URL of a request matches ``/site/{id}``, the view callable at the Python dotted path name ``mypackage.views.site_view`` will be called with the request. In other words, we've associated a view callable directly with a -- cgit v1.2.3 From 12b6f58956a50a0ad8e6d9971a0248d8f7997122 Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Sun, 15 Mar 2015 15:18:51 -0400 Subject: Allow passing a custom redirect class for appending slashes --- docs/narr/urldispatch.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ca6a55164..fa3e734fe 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -842,7 +842,9 @@ route. When configured, along with at least one other route in your application, this view will be invoked if the value of ``PATH_INFO`` does not already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash matches any route's pattern. In this case it does an HTTP redirect to the -slash-appended ``PATH_INFO``. +slash-appended ``PATH_INFO``. In addition you may pass anything that implements +:class:`pyramid.interfaces.IResponse` which will then be used in place of the +default class (:class:`pyramid.httpexceptions.HTTPFound`). Let's use an example. If the following routes are configured in your application: -- cgit v1.2.3 From 519c49c645ff72d275be6e41b05d1e3140314259 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 6 Oct 2015 21:53:54 -0700 Subject: - grammar, rewrapping --- docs/narr/urldispatch.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index fa3e734fe..a9fc8c251 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -8,7 +8,7 @@ URL Dispatch :term:`URL dispatch` provides a simple way to map URLs to :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 +checked one by one. If one of the patterns matches the path information associated with a request, a particular :term:`view callable` is invoked. A view callable is a specific bit of code, defined in your application, that receives the :term:`request` and returns a :term:`response` object. @@ -21,8 +21,8 @@ If any route configuration is present in an application, the :app:`Pyramid` matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request`, -:app:`Pyramid` will invoke the :term:`view lookup` process to find a -matching view. +:app:`Pyramid` will invoke the :term:`view lookup` process to find a matching +view. If no route pattern in the route map matches the information in the :term:`request` provided in your application, :app:`Pyramid` will fail over @@ -39,7 +39,7 @@ application. A route has a *name*, which acts as an identifier to be used for URL generation. The name also allows developers to associate a view configuration with the route. A route also has a *pattern*, meant to match against the ``PATH_INFO`` portion of a URL (the portion following the scheme -and port, e.g. ``/foo/bar`` in the URL ``_). It +and port, e.g., ``/foo/bar`` in the URL ``http://localhost:8080/foo/bar``). It also optionally has a ``factory`` and a set of :term:`route predicate` attributes. -- cgit v1.2.3 From 5b6fd0e0fc22e37053f8d612a9f0c5dbd485606c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 7 Oct 2015 17:11:52 -0700 Subject: - grammar, rewrapping --- docs/narr/urldispatch.rst | 510 +++++++++++++++++++++++----------------------- 1 file changed, 250 insertions(+), 260 deletions(-) (limited to 'docs/narr/urldispatch.rst') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a9fc8c251..c13558008 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -25,8 +25,8 @@ If any route pattern matches the information in the :term:`request`, view. If no route pattern in the route map matches the information in the -:term:`request` provided in your application, :app:`Pyramid` will fail over -to using :term:`traversal` to perform resource location and view lookup. +:term:`request` provided in your application, :app:`Pyramid` will fail over to +using :term:`traversal` to perform resource location and view lookup. .. index:: single: route configuration @@ -35,8 +35,8 @@ Route Configuration ------------------- :term:`Route configuration` is the act of adding a new :term:`route` to an -application. A route has a *name*, which acts as an identifier to be used -for URL generation. The name also allows developers to associate a view +application. A route has a *name*, which acts as an identifier to be used for +URL generation. The name also allows developers to associate a view configuration with the route. A route also has a *pattern*, meant to match 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``). It @@ -71,8 +71,8 @@ invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's "setup" code. You will instead use ``add_route`` statements, and use a -:term:`scan` to associate view callables with routes. For example, if -this is a portion of your project's ``__init__.py``: +:term:`scan` to associate view callables with routes. For example, if this is +a portion of your project's ``__init__.py``: .. code-block:: python @@ -85,8 +85,8 @@ setup code. However, the above :term:`scan` execution decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python package. For example, if you have a ``views.py`` in your package, a scan will -pick up any of its configuration decorators, so we can add one there -that references ``myroute`` as a ``route_name`` parameter: +pick up any of its configuration decorators, so we can add one there that +references ``myroute`` as a ``route_name`` parameter: .. code-block:: python @@ -97,8 +97,8 @@ that references ``myroute`` as a ``route_name`` parameter: def myview(request): return Response('OK') -The above combination of ``add_route`` and ``scan`` is completely equivalent -to using the previous combination of ``add_route`` and ``add_view``. +The above combination of ``add_route`` and ``scan`` is completely equivalent to +using the previous combination of ``add_route`` and ``add_view``. .. index:: single: route path pattern syntax @@ -109,13 +109,13 @@ to using the previous combination of ``add_route`` and ``add_view``. Route Pattern Syntax ~~~~~~~~~~~~~~~~~~~~ -The syntax of the pattern matching language used by :app:`Pyramid` URL -dispatch in the *pattern* argument is straightforward; it is close to that of -the :term:`Routes` system used by :term:`Pylons`. +The syntax of the pattern matching language used by :app:`Pyramid` URL dispatch +in the *pattern* argument is straightforward. It is close to that of the +:term:`Routes` system used by :term:`Pylons`. -The *pattern* used in route configuration may start with a slash character. -If the pattern does not start with a slash character, an implicit slash will -be prepended to it at matching time. For example, the following patterns are +The *pattern* used in route configuration may start with a slash character. If +the pattern does not start with a slash character, an implicit slash will be +prepended to it at matching time. For example, the following patterns are equivalent: .. code-block:: text @@ -128,28 +128,29 @@ and: /{foo}/bar/baz -If a pattern is a valid URL it won't be ever matched against an incoming -request. Instead it can be useful for generating external URLs. See -:ref:`External routes ` for details. +If a pattern is a valid URL it won't be matched against an incoming request. +Instead it can be useful for generating external URLs. See :ref:`External +routes ` for details. -A pattern segment (an individual item between ``/`` characters in the -pattern) may either be a literal string (e.g. ``foo``) *or* it may be a -replacement marker (e.g. ``{foo}``) or a certain combination of both. A -replacement marker does not need to be preceded by a ``/`` character. +A pattern segment (an individual item between ``/`` characters in the pattern) +may either be a literal string (e.g., ``foo``) *or* it may be a replacement +marker (e.g., ``{foo}``), or a certain combination of both. A replacement +marker does not need to be preceded by a ``/`` character. -A replacement marker is in the format ``{name}``, where this means "accept -any characters up to the next slash character and use this as the ``name`` +A replacement marker is in the format ``{name}``, where this means "accept any +characters up to the next slash character and use this as the ``name`` :term:`matchdict` value." A replacement marker in a pattern must begin with an uppercase or lowercase ASCII letter or an underscore, and can be composed only of uppercase or lowercase ASCII letters, underscores, and numbers. For example: ``a``, -``a_b``, ``_b``, and ``b9`` are all valid replacement marker names, but -``0a`` is not. +``a_b``, ``_b``, and ``b9`` are all valid replacement marker names, but ``0a`` +is not. -.. note:: A replacement marker could not start with an underscore until - Pyramid 1.2. Previous versions required that the replacement marker start - with an uppercase or lowercase letter. +.. versionchanged:: 1.2 + A replacement marker could not start with an underscore until Pyramid 1.2. + Previous versions required that the replacement marker start with an + uppercase or lowercase letter. A matchdict is the dictionary representing the dynamic parts extracted from a URL based on the routing pattern. It is available as ``request.matchdict``. @@ -174,18 +175,18 @@ It will not match the following patterns however: foo/1/2/ -> No match (trailing slash) bar/abc/def -> First segment literal mismatch -The match for a segment replacement marker in a segment will be done only up -to the first non-alphanumeric character in the segment in the pattern. So, -for instance, if this route pattern was used: +The match for a segment replacement marker in a segment will be done only up to +the first non-alphanumeric character in the segment in the pattern. So, for +instance, if this route pattern was used: .. code-block:: text foo/{name}.html -The literal path ``/foo/biz.html`` will match the above route pattern, and -the match result will be ``{'name':u'biz'}``. However, the literal path -``/foo/biz`` will not match, because it does not contain a literal ``.html`` -at the end of the segment represented by ``{name}.html`` (it only contains +The literal path ``/foo/biz.html`` will match the above route pattern, and the +match result will be ``{'name':u'biz'}``. However, the literal path +``/foo/biz`` will not match, because it does not contain a literal ``.html`` at +the end of the segment represented by ``{name}.html`` (it only contains ``biz``, not ``biz.html``). To capture both segments, two replacement markers can be used: @@ -194,28 +195,27 @@ To capture both segments, two replacement markers can be used: foo/{name}.{ext} -The literal path ``/foo/biz.html`` will match the above route pattern, and -the match result will be ``{'name': 'biz', 'ext': 'html'}``. This occurs -because there is a literal part of ``.`` (period) between the two replacement -markers ``{name}`` and ``{ext}``. +The literal path ``/foo/biz.html`` will match the above route pattern, and the +match result will be ``{'name': 'biz', 'ext': 'html'}``. This occurs because +there is a literal part of ``.`` (period) between the two replacement markers +``{name}`` and ``{ext}``. Replacement markers can optionally specify a regular expression which will be -used to decide whether a path segment should match the marker. To specify -that a replacement marker should match only a specific set of characters as -defined by a regular expression, you must use a slightly extended form of -replacement marker syntax. Within braces, the replacement marker name must -be followed by a colon, then directly thereafter, the regular expression. -The *default* regular expression associated with a replacement marker -``[^/]+`` matches one or more characters which are not a slash. For example, -under the hood, the replacement marker ``{foo}`` can more verbosely be -spelled as ``{foo:[^/]+}``. You can change this to be an arbitrary regular -expression to match an arbitrary sequence of characters, such as -``{foo:\d+}`` to match only digits. +used to decide whether a path segment should match the marker. To specify that +a replacement marker should match only a specific set of characters as defined +by a regular expression, you must use a slightly extended form of replacement +marker syntax. Within braces, the replacement marker name must be followed by +a colon, then directly thereafter, the regular expression. The *default* +regular expression associated with a replacement marker ``[^/]+`` matches one +or more characters which are not a slash. For example, under the hood, the +replacement marker ``{foo}`` can more verbosely be spelled as ``{foo:[^/]+}``. +You can change this to be an arbitrary regular expression to match an arbitrary +sequence of characters, such as ``{foo:\d+}`` to match only digits. It is possible to use two replacement markers without any literal characters between them, for instance ``/{foo}{bar}``. However, this would be a -nonsensical pattern without specifying a custom regular expression to -restrict what each marker captures. +nonsensical pattern without specifying a custom regular expression to restrict +what each marker captures. Segments must contain at least one character in order to match a segment replacement marker. For example, for the URL ``/abc/``: @@ -224,7 +224,7 @@ replacement marker. For example, for the URL ``/abc/``: - ``/{foo}/`` will match. -Note that values representing matched path segments will be url-unquoted and +Note that values representing matched path segments will be URL-unquoted and decoded from UTF-8 into Unicode within the matchdict. So for instance, the following pattern: @@ -244,9 +244,9 @@ The matchdict will look like so (the value is URL-decoded / UTF-8 decoded): {'bar':u'La Pe\xf1a'} -Literal strings in the path segment should represent the *decoded* value of -the ``PATH_INFO`` provided to Pyramid. You don't want to use a URL-encoded -value or a bytestring representing the literal's UTF-8 in the pattern. For +Literal strings in the path segment should represent the *decoded* value of the +``PATH_INFO`` provided to Pyramid. You don't want to use a URL-encoded value +or a bytestring representing the literal encoded as UTF-8 in the pattern. For example, rather than this: .. code-block:: text @@ -259,8 +259,8 @@ You'll want to use something like this: /Foo Bar/{baz} -For patterns that contain "high-order" characters in its literals, you'll -want to use a Unicode value as the pattern as opposed to any URL-encoded or +For patterns that contain "high-order" characters in its literals, you'll want +to use a Unicode value as the pattern as opposed to any URL-encoded or UTF-8-encoded value. For example, you might be tempted to use a bytestring pattern like this: @@ -268,12 +268,11 @@ pattern like this: /La Pe\xc3\xb1a/{x} -But this will either cause an error at startup time or it won't match -properly. You'll want to use a Unicode value as the pattern instead rather -than raw bytestring escapes. You can use a high-order Unicode value as the -pattern by using `Python source file encoding -`_ plus the "real" character in the -Unicode pattern in the source, like so: +But this will either cause an error at startup time or it won't match properly. +You'll want to use a Unicode value as the pattern instead rather than raw +bytestring escapes. You can use a high-order Unicode value as the pattern by +using `Python source file encoding `_ +plus the "real" character in the Unicode pattern in the source, like so: .. code-block:: text @@ -291,8 +290,8 @@ only to literals in the pattern. If the pattern has a ``*`` in it, the name which follows it is considered a "remainder match". A remainder match *must* come at the end of the pattern. -Unlike segment replacement markers, it does not need to be preceded by a -slash. For example: +Unlike segment replacement markers, it does not need to be preceded by a slash. +For example: .. code-block:: text @@ -310,7 +309,7 @@ The above pattern will match these URLs, generating the following matchdicts: Note that when a ``*stararg`` remainder match is matched, the value put into the matchdict is turned into a tuple of path segments representing the -remainder of the path. These path segments are url-unquoted and decoded from +remainder of the path. These path segments are URL-unquoted and decoded from UTF-8 into Unicode. For example, for the following pattern: .. code-block:: text @@ -357,15 +356,15 @@ Route Declaration Ordering Route configuration declarations are evaluated in a specific order when a request enters the system. As a result, the order of route configuration -declarations is very important. The order that routes declarations are +declarations is very important. The order in which route declarations are evaluated is the order in which they are added to the application at startup time. (This is unlike a different way of mapping URLs to code that :app:`Pyramid` provides, named :term:`traversal`, which does not depend on pattern ordering). For routes added via the :mod:`~pyramid.config.Configurator.add_route` method, -the order that routes are evaluated is the order in which they are added to -the configuration imperatively. +the order that routes are evaluated is the order in which they are added to the +configuration imperatively. For example, route configuration statements with the following patterns might be added in the following order: @@ -375,10 +374,9 @@ be added in the following order: members/{def} members/abc -In such a configuration, the ``members/abc`` pattern would *never* be -matched. This is because the match ordering will always match -``members/{def}`` first; the route configuration with ``members/abc`` will -never be evaluated. +In such a configuration, the ``members/abc`` pattern would *never* be matched. +This is because the match ordering will always match ``members/{def}`` first; +the route configuration with ``members/abc`` will never be evaluated. .. index:: single: route configuration arguments @@ -416,19 +414,18 @@ the system, for each route configuration declaration present in the system, declared. This checking happens in the order that the routes were declared via :meth:`pyramid.config.Configurator.add_route`. -When a route configuration is declared, it may contain :term:`route -predicate` arguments. All route predicates associated with a route -declaration must be ``True`` for the route configuration to be used for a -given request during a check. If any predicate in the set of :term:`route -predicate` arguments provided to a route configuration returns ``False`` -during a check, that route is skipped and route matching continues through -the ordered set of routes. +When a route configuration is declared, it may contain :term:`route predicate` +arguments. All route predicates associated with a route declaration must be +``True`` for the route configuration to be used for a given request during a +check. If any predicate in the set of :term:`route predicate` arguments +provided to a route configuration returns ``False`` during a check, that route +is skipped and route matching continues through the ordered set of routes. If any route matches, the route matching process stops and the :term:`view -lookup` subsystem takes over to find the most reasonable view callable for -the matched route. Most often, there's only one view that will match (a view -configured with a ``route_name`` argument matching the matched route). To -gain a better understanding of how routes and views are associated in a real +lookup` subsystem takes over to find the most reasonable view callable for the +matched route. Most often, there's only one view that will match (a view +configured with a ``route_name`` argument matching the matched route). To gain +a better understanding of how routes and views are associated in a real application, you can use the ``pviews`` command, as documented in :ref:`displaying_matching_views`. @@ -445,11 +442,10 @@ The Matchdict ~~~~~~~~~~~~~ When the URL pattern associated with a particular route configuration is -matched by a request, a dictionary named ``matchdict`` is added as an -attribute of the :term:`request` object. Thus, ``request.matchdict`` will -contain the values that match replacement patterns in the ``pattern`` -element. The keys in a matchdict will be strings. The values will be -Unicode objects. +matched by a request, a dictionary named ``matchdict`` is added as an attribute +of the :term:`request` object. Thus, ``request.matchdict`` will contain the +values that match replacement patterns in the ``pattern`` element. The keys in +a matchdict will be strings. The values will be Unicode objects. .. note:: @@ -466,10 +462,10 @@ The Matched Route 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:`~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. +attribute of the :term:`request` object. Thus, ``request.matched_route`` will +be an object implementing 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. .. note:: @@ -480,8 +476,8 @@ Routing Examples ---------------- Let's check out some examples of how route configuration statements might be -commonly declared, and what will happen if they are matched by the -information present in a request. +commonly declared, and what will happen if they are matched by the information +present in a request. .. _urldispatch_example1: @@ -505,18 +501,18 @@ configuration will be invoked. Recall that the ``@view_config`` is equivalent to calling ``config.add_view``, because the ``config.scan()`` call will import ``mypackage.views``, shown below, and execute ``config.add_view`` under the hood. Each view then maps the -route name to the matching view callable. In the case of the above -example, when the URL of a request matches ``/site/{id}``, the view callable at -the Python dotted path name ``mypackage.views.site_view`` will be called with -the request. In other words, we've associated a view callable directly with a +route name to the matching view callable. In the case of the above example, +when the URL of a request matches ``/site/{id}``, the view callable at the +Python dotted path name ``mypackage.views.site_view`` will be called with the +request. In other words, we've associated a view callable directly with a route pattern. When the ``/site/{id}`` route pattern matches during a request, the -``site_view`` view callable is invoked with that request as its sole -argument. When this route matches, a ``matchdict`` will be generated and -attached to the request as ``request.matchdict``. If the specific URL -matched is ``/site/1``, the ``matchdict`` will be a dictionary with a single -key, ``id``; the value will be the string ``'1'``, ex.: ``{'id':'1'}``. +``site_view`` view callable is invoked with that request as its sole argument. +When this route matches, a ``matchdict`` will be generated and attached to the +request as ``request.matchdict``. If the specific URL matched is ``/site/1``, +the ``matchdict`` will be a dictionary with a single key, ``id``; the value +will be the string ``'1'``, ex.: ``{'id':'1'}``. The ``mypackage.views`` module referred to above might look like so: @@ -539,8 +535,8 @@ information about views. Example 2 ~~~~~~~~~ -Below is an example of a more complicated set of route statements you might -add to your application: +Below is an example of a more complicated set of route statements you might add +to your application: .. code-block:: python :linenos: @@ -587,33 +583,32 @@ forms: and attached to the :term:`request` will consist of ``{'idea':'1'}``. - When a URL matches the pattern ``/users/{user}``, the view callable - available at the dotted Python pathname ``mypackage.views.user_view`` will - be called. For the specific URL ``/users/1``, the ``matchdict`` generated - and attached to the :term:`request` will consist of ``{'user':'1'}``. + available at the dotted Python pathname ``mypackage.views.user_view`` will be + called. For the specific URL ``/users/1``, the ``matchdict`` generated and + attached to the :term:`request` will consist of ``{'user':'1'}``. - When a URL matches the pattern ``/tags/{tag}``, the view callable available at the dotted Python pathname ``mypackage.views.tag_view`` will be called. - For the specific URL ``/tags/1``, the ``matchdict`` generated and attached - to the :term:`request` will consist of ``{'tag':'1'}``. + For the specific URL ``/tags/1``, the ``matchdict`` generated and attached to + the :term:`request` will consist of ``{'tag':'1'}``. In this example we've again associated each of our routes with a :term:`view -callable` directly. In all cases, the request, which will have a -``matchdict`` attribute detailing the information found in the URL by the -process will be passed to the view callable. +callable` directly. In all cases, the request, which will have a ``matchdict`` +attribute detailing the information found in the URL by the process will be +passed to the view callable. Example 3 ~~~~~~~~~ -The :term:`context` resource object passed in to a view found as the result -of URL dispatch will, by default, be an instance of the object returned by -the :term:`root factory` configured at startup time (the ``root_factory`` -argument to the :term:`Configurator` used to configure the application). +The :term:`context` resource object passed in to a view found as the result of +URL dispatch will, by default, be an instance of the object returned by the +:term:`root factory` configured at startup time (the ``root_factory`` argument +to the :term:`Configurator` used to configure the application). You can override this behavior by passing in a ``factory`` argument to the :meth:`~pyramid.config.Configurator.add_route` method for a particular route. -The ``factory`` should be a callable that accepts a :term:`request` and -returns an instance of a class that will be the context resource used by the -view. +The ``factory`` should be a callable that accepts a :term:`request` and returns +an instance of a class that will be the context resource used by the view. An example of using a route with a factory: @@ -685,9 +680,9 @@ Or provide the literal string ``/`` as the pattern: Generating Route URLs --------------------- -Use the :meth:`pyramid.request.Request.route_url` method to generate URLs -based on route patterns. For example, if you've configured a route with the -``name`` "foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. +Use the :meth:`pyramid.request.Request.route_url` method to generate URLs based +on route patterns. For example, if you've configured a route with the ``name`` +"foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. .. code-block:: python :linenos: @@ -707,13 +702,12 @@ To generate only the *path* portion of a URL from a route, use the This will return the string ``/1/2/3`` rather than a full URL. -Replacement values passed to ``route_url`` or ``route_path`` must be Unicode -or bytestrings encoded in UTF-8. One exception to this rule exists: if -you're trying to replace a "remainder" match value (a ``*stararg`` -replacement value), the value may be a tuple containing Unicode strings or -UTF-8 strings. +Replacement values passed to ``route_url`` or ``route_path`` must be Unicode or +bytestrings encoded in UTF-8. One exception to this rule exists: if you're +trying to replace a "remainder" match value (a ``*stararg`` replacement value), +the value may be a tuple containing Unicode strings or UTF-8 strings. -Note that URLs and paths generated by ``route_path`` and ``route_url`` are +Note that URLs and paths generated by ``route_url`` and ``route_path`` are always URL-quoted string types (they contain no non-ASCII characters). Therefore, if you've added a route like so: @@ -727,7 +721,7 @@ And you later generate a URL using ``route_path`` or ``route_url`` like so: url = request.route_path('la', city=u'Québec') -You will wind up with the path encoded to UTF-8 and URL quoted like so: +You will wind up with the path encoded to UTF-8 and URL-quoted like so: .. code-block:: text @@ -759,7 +753,7 @@ You can get a similar result by passing a tuple composed of path elements: url = request.route_path('abc', foo=(u'Québec', u'biz')) -Each value in the tuple will be url-quoted and joined by slashes in this case: +Each value in the tuple will be URL-quoted and joined by slashes in this case: .. code-block:: text @@ -793,7 +787,7 @@ ignored when ``static`` is ``True``. :ref:`External routes ` are implicitly static. .. versionadded:: 1.1 - the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` + the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route`. .. _external_route_narr: @@ -836,13 +830,13 @@ argument to :meth:`pyramid.config.Configurator.add_notfound_view` or the equivalent ``append_slash`` argument to the :class:`pyramid.view.notfound_view_config` decorator. -Adding ``append_slash=True`` is a way to automatically redirect requests -where the URL lacks a trailing slash, but requires one to match the proper -route. When configured, along with at least one other route in your -application, this view will be invoked if the value of ``PATH_INFO`` does not -already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash -matches any route's pattern. In this case it does an HTTP redirect to the -slash-appended ``PATH_INFO``. In addition you may pass anything that implements +Adding ``append_slash=True`` is a way to automatically redirect requests where +the URL lacks a trailing slash, but requires one to match the proper route. +When configured, along with at least one other route in your application, this +view will be invoked if the value of ``PATH_INFO`` does not already end in a +slash, and if the value of ``PATH_INFO`` *plus* a slash matches any route's +pattern. In this case it does an HTTP redirect to the slash-appended +``PATH_INFO``. In addition you may pass anything that implements :class:`pyramid.interfaces.IResponse` which will then be used in place of the default class (:class:`pyramid.httpexceptions.HTTPFound`). @@ -872,12 +866,11 @@ application: config.add_notfound_view(notfound, append_slash=True) If a request enters the application with the ``PATH_INFO`` value of -``/no_slash``, the first route will match and the browser will show "No -slash". However, if a request enters the application with the ``PATH_INFO`` -value of ``/no_slash/``, *no* route will match, and the slash-appending not -found view will not find a matching route with an appended slash. As a -result, the ``notfound`` view will be called and it will return a "Not found, -bro." body. +``/no_slash``, the first route will match and the browser will show "No slash". +However, if a request enters the application with the ``PATH_INFO`` value of +``/no_slash/``, *no* route will match, and the slash-appending not found view +will not find a matching route with an appended slash. As a result, the +``notfound`` view will be called and it will return a "Not found, bro." body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the @@ -934,10 +927,10 @@ Debugging Route Matching It's useful to be able to take a peek under the hood when requests that enter your application aren't matching your routes as you expect them to. To debug -route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or the -``pyramid.debug_routematch`` configuration file setting (set either to ``true``). -Details of the route matching decision for a particular request to the -:app:`Pyramid` application will be printed to the ``stderr`` of the console +route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or +the ``pyramid.debug_routematch`` configuration file setting (set either to +``true``). Details of the route matching decision for a particular request to +the :app:`Pyramid` application will be printed to the ``stderr`` of the console which you started the application from. For example: .. code-block:: text @@ -954,11 +947,11 @@ which you started the application from. For example: http://localhost:6543/static/logo.png; \ route_name: 'static/', .... -See :ref:`environment_chapter` for more information about how, and where to -set these values. +See :ref:`environment_chapter` for more information about how and where to set +these values. -You can also use the ``proutes`` command to see a display of all the -routes configured in your application; for more information, see +You can also use the ``proutes`` command to see a display of all the routes +configured in your application. For more information, see :ref:`displaying_application_routes`. .. _route_prefix: @@ -979,11 +972,11 @@ named ``route_prefix`` which can be useful to authors of URL-dispatch-based applications. If ``route_prefix`` is supplied to the include method, it must be a string. This string represents a route prefix that will be prepended to all route patterns added by the *included* configuration. Any calls to -:meth:`pyramid.config.Configurator.add_route` within the included callable -will have their pattern prefixed with the value of ``route_prefix``. This can -be used to help mount a set of routes at a different location than the -included callable's author intended while still maintaining the same route -names. For example: +:meth:`pyramid.config.Configurator.add_route` within the included callable will +have their pattern prefixed with the value of ``route_prefix``. This can be +used to help mount a set of routes at a different location than the included +callable's author intended while still maintaining the same route names. For +example: .. code-block:: python :linenos: @@ -998,15 +991,15 @@ names. For example: config.include(users_include, route_prefix='/users') In the above configuration, the ``show_users`` route will have an effective -route pattern of ``/users/show``, instead of ``/show`` because the +route pattern of ``/users/show`` instead of ``/show`` because the ``route_prefix`` argument will be prepended to the pattern. The route will then only match if the URL path is ``/users/show``, and when the :meth:`pyramid.request.Request.route_url` function is called with the route name ``show_users``, it will generate a URL with that same path. Route prefixes are recursive, so if a callable executed via an include itself -turns around and includes another callable, the second-level route prefix -will be prepended with the first: +turns around and includes another callable, the second-level route prefix will +be prepended with the first: .. code-block:: python :linenos: @@ -1025,15 +1018,15 @@ will be prepended with the first: config.include(users_include, route_prefix='/users') In the above configuration, the ``show_users`` route will still have an -effective route pattern of ``/users/show``. The ``show_times`` route -however, will have an effective pattern of ``/users/timing/times``. +effective route pattern of ``/users/show``. The ``show_times`` route, however, +will have an effective pattern of ``/users/timing/times``. -Route prefixes have no impact on the requirement that the set of route -*names* in any given Pyramid configuration must be entirely unique. If you -compose your URL dispatch application out of many small subapplications using -:meth:`pyramid.config.Configurator.include`, it's wise to use a dotted name -for your route names, so they'll be unlikely to conflict with other packages -that may be added in the future. For example: +Route prefixes have no impact on the requirement that the set of route *names* +in any given Pyramid configuration must be entirely unique. If you compose +your URL dispatch application out of many small subapplications using +:meth:`pyramid.config.Configurator.include`, it's wise to use a dotted name for +your route names so they'll be unlikely to conflict with other packages that +may be added in the future. For example: .. code-block:: python :linenos: @@ -1060,15 +1053,16 @@ Custom Route Predicates ----------------------- Each of the predicate callables fed to the ``custom_predicates`` argument of -:meth:`~pyramid.config.Configurator.add_route` 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 current +:meth:`~pyramid.config.Configurator.add_route` 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 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:`pyramid.interfaces.IRoute` for the API of such a route object). +The ``info`` dictionary has a number of contained values, including ``match`` +and ``route``. ``match`` is a dictionary which represents the arguments matched +in the URL by the route. ``route`` is an object representing the route which +was 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 match. For example: @@ -1118,9 +1112,9 @@ instance, a predicate might do some type conversion of values: config.add_route('ymd', '/{year}/{month}/{day}', custom_predicates=(ymd_to_int,)) -Note that a conversion predicate is still a predicate so it must return -``True`` or ``False``; a predicate that does *only* conversion, such as the -one we demonstrate above should unconditionally return ``True``. +Note that a conversion predicate is still a predicate, so it must return +``True`` or ``False``. A predicate that does *only* conversion, such as the one +we demonstrate above, should unconditionally return ``True``. To avoid the try/except uncertainty, the route pattern can contain regular expressions specifying requirements for that marker. For instance: @@ -1141,31 +1135,31 @@ expressions specifying requirements for that marker. For instance: config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', custom_predicates=(ymd_to_int,)) -Now the try/except is no longer needed because the route will not match at -all unless these markers match ``\d+`` which requires them to be valid digits -for an ``int`` type conversion. +Now the try/except is no longer needed because the route will not match at all +unless these markers match ``\d+`` which requires them to be valid digits for +an ``int`` type conversion. -The ``match`` dictionary passed within ``info`` to each predicate attached to -a route will be the same dictionary. Therefore, when registering a custom -predicate which modifies the ``match`` dict, the code registering the -predicate should usually arrange for the predicate to be the *last* custom -predicate in the custom predicate list. Otherwise, custom predicates which -fire subsequent to the predicate which performs the ``match`` modification -will receive the *modified* match dictionary. +The ``match`` dictionary passed within ``info`` to each predicate attached to a +route will be the same dictionary. Therefore, when registering a custom +predicate which modifies the ``match`` dict, the code registering the predicate +should usually arrange for the predicate to be the *last* custom predicate in +the custom predicate list. Otherwise, custom predicates which fire subsequent +to the predicate which performs the ``match`` modification will receive the +*modified* match dictionary. .. warning:: It is a poor idea to rely on ordering of custom predicates to build a conversion pipeline, where one predicate depends on the side effect of - another. For instance, it's a poor idea to register two custom - predicates, one which handles conversion of a value to an int, the next - which handles conversion of that integer to some custom object. Just do - all that in a single custom predicate. + another. For instance, it's a poor idea to register two custom predicates, + one which handles conversion of a value to an int, the next which handles + conversion of that integer to some custom object. Just do all that in a + single custom predicate. The ``route`` object in the ``info`` dict is an object that has two useful -attributes: ``name`` and ``pattern``. The ``name`` attribute is the route -name. The ``pattern`` attribute is the route pattern. An example of using -the route in a set of route predicates: +attributes: ``name`` and ``pattern``. The ``name`` attribute is the route name. +The ``pattern`` attribute is the route pattern. Here's an example of using the +route in a set of route predicates: .. code-block:: python :linenos: @@ -1180,14 +1174,14 @@ the route in a set of route predicates: custom_predicates=(twenty_ten,)) 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'. +that the year match argument is '2010' if and only if the route name is 'ymd', +'ym', or 'y'. -You can also caption the predicates by setting the ``__text__`` -attribute. This will help you with the ``pviews`` command (see +You can also caption the predicates by setting the ``__text__`` attribute. This +will help you with the ``pviews`` command (see :ref:`displaying_application_routes`) and the ``pyramid_debugtoolbar``. -If a predicate is a class just add __text__ property in a standard manner. +If a predicate is a class, just add ``__text__`` property in a standard manner. .. code-block:: python :linenos: @@ -1199,8 +1193,8 @@ If a predicate is a class just add __text__ property in a standard manner. class DummyCustomPredicate2(object): __text__ = 'my custom class predicate' -If a predicate is a method you'll need to assign it after method declaration -(see `PEP 232 `_) +If a predicate is a method, you'll need to assign it after method declaration +(see `PEP 232 `_). .. code-block:: python :linenos: @@ -1209,8 +1203,8 @@ If a predicate is a method you'll need to assign it after method declaration pass custom_predicate.__text__ = 'my custom method predicate' -If a predicate is a classmethod using @classmethod will not work, but you can -still easily do it by wrapping it in classmethod call. +If a predicate is a classmethod, using ``@classmethod`` will not work, but you +can still easily do it by wrapping it in a classmethod call. .. code-block:: python :linenos: @@ -1220,7 +1214,7 @@ still easily do it by wrapping it in classmethod call. classmethod_predicate.__text__ = 'my classmethod predicate' classmethod_predicate = classmethod(classmethod_predicate) -Same will work with staticmethod, just use ``staticmethod`` instead of +The same will work with ``staticmethod``, using ``staticmethod`` instead of ``classmethod``. .. seealso:: @@ -1236,10 +1230,10 @@ Same will work with staticmethod, just use ``staticmethod`` instead of Route Factories --------------- -Although it is not a particular common need in basic applications, a "route" -configuration declaration can mention a "factory". When that route matches a -request, and a factory is attached to a route, the :term:`root factory` -passed at startup time to the :term:`Configurator` is ignored; instead the +Although it is not a particularly common need in basic applications, a "route" +configuration declaration can mention a "factory". When a route matches a +request, and a factory is attached to the route, the :term:`root factory` +passed at startup time to the :term:`Configurator` is ignored. Instead the factory associated with the route is used to generate a :term:`root` object. This object will usually be used as the :term:`context` resource of the view callable ultimately found via :term:`view lookup`. @@ -1255,8 +1249,8 @@ The factory can either be a Python object or a :term:`dotted Python name` (a string) which points to such a Python object, as it is above. In this way, each route can use a different factory, making it possible to -supply a different :term:`context` resource object to the view related to -each particular route. +supply a different :term:`context` resource object to the view related to each +particular route. A factory must be a callable which accepts a request and returns an arbitrary Python object. For example, the below class can be used as a factory: @@ -1268,33 +1262,31 @@ Python object. For example, the below class can be used as a factory: def __init__(self, request): pass -A route factory is actually conceptually identical to the :term:`root -factory` described at :ref:`the_resource_tree`. +A route factory is actually conceptually identical to the :term:`root factory` +described at :ref:`the_resource_tree`. Supplying a different resource factory for each route is useful when you're trying to use a :app:`Pyramid` :term:`authorization policy` to provide -declarative, "context sensitive" security checks; each resource can maintain -a separate :term:`ACL`, as documented in -:ref:`using_security_with_urldispatch`. It is also useful when you wish to -combine URL dispatch with :term:`traversal` as documented within -:ref:`hybrid_chapter`. +declarative, "context sensitive" security checks. Each resource can maintain a +separate :term:`ACL`, as documented in :ref:`using_security_with_urldispatch`. +It is also useful when you wish to combine URL dispatch with :term:`traversal` +as documented within :ref:`hybrid_chapter`. .. index:: pair: URL dispatch; security .. _using_security_with_urldispatch: -Using :app:`Pyramid` Security With URL Dispatch --------------------------------------------------- +Using :app:`Pyramid` Security with URL Dispatch +----------------------------------------------- :app:`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 resource object. A common thing to -want to do is to attach an ``__acl__`` to the resource object dynamically for -declarative security purposes. You can use the ``factory`` argument that -points at a factory which attaches a custom ``__acl__`` to an object at its -creation time. +: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 resource object. A common thing to want to do is +to attach an ``__acl__`` to the resource object dynamically for declarative +security purposes. You can use the ``factory`` argument that points at a +factory which attaches a custom ``__acl__`` to an object at its creation time. Such a ``factory`` might look like so: @@ -1310,15 +1302,15 @@ Such a ``factory`` might look like so: If the route ``archives/{article}`` is matched, and the article number is ``1``, :app:`Pyramid` will generate an ``Article`` :term:`context` resource -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 matches a particular string; -our sample ``Article`` factory class is not very ambitious. +with an ACL on it that allows the ``editor`` principal the ``view`` permission. +Obviously you can do more generic things than inspect the route's match dict to +see if the ``article`` argument matches a particular string. Our sample +``Article`` factory class is not very ambitious. .. note:: - See :ref:`security_chapter` for more information about - :app:`Pyramid` security and ACLs. + See :ref:`security_chapter` for more information about :app:`Pyramid` + security and ACLs. .. index:: pair: route; view callable lookup details @@ -1330,10 +1322,9 @@ When a request enters the system which matches the pattern of the route, the usual result is simple: the view callable associated with the route is invoked with the request that caused the invocation. -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 this section. You can skip it if you're -uninterested. +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 this section. You can skip it if you're uninterested. When a view is associated with a route configuration, :app:`Pyramid` ensures that a :term:`view configuration` is registered that will always be found @@ -1349,26 +1340,25 @@ when the route pattern is matched during a request. To do so: - At runtime, when a request causes any route to match, the :term:`request` object is decorated with the route-specific interface. -- The fact that the request is decorated with a route-specific interface - causes the :term:`view lookup` machinery to always use the view callable - registered using that interface by the route configuration to service - requests that match the route pattern. +- The fact that the request is decorated with a route-specific interface causes + the :term:`view lookup` machinery to always use the view callable registered + using that interface by the route configuration to service requests that + match the route pattern. As we can see from the above description, technically, URL dispatch doesn't -actually map a URL pattern directly to a view callable. Instead, URL -dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` -:term:`resource location` subsystem (i.e., :term:`URL dispatch` or -:term:`traversal`) finds a :term:`resource` object that is the -:term:`context` of a :term:`request`. Once the :term:`context` is determined, -a separate subsystem named :term:`view lookup` is then responsible for -finding and invoking a :term:`view callable` based on information available -in the context and the request. When URL dispatch is used, the resource -location and view lookup subsystems provided by :app:`Pyramid` are still -being utilized, but in a way which does not require a developer to understand -either of them in detail. - -If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back -to :term:`traversal` to handle the :term:`request`. +actually map a URL pattern directly to a view callable. Instead URL dispatch +is a :term:`resource location` mechanism. A :app:`Pyramid` :term:`resource +location` subsystem (i.e., :term:`URL dispatch` or :term:`traversal`) finds a +:term:`resource` object that is the :term:`context` of a :term:`request`. Once +the :term:`context` is determined, a separate subsystem named :term:`view +lookup` is then responsible for finding and invoking a :term:`view callable` +based on information available in the context and the request. When URL +dispatch is used, the resource location and view lookup subsystems provided by +:app:`Pyramid` are still being utilized, but in a way which does not require a +developer to understand either of them in detail. + +If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back to +:term:`traversal` to handle the :term:`request`. References ---------- -- cgit v1.2.3