diff options
| author | Steve Piercy <web@stevepiercy.com> | 2015-10-07 17:12:56 -0700 |
|---|---|---|
| committer | Steve Piercy <web@stevepiercy.com> | 2015-10-07 17:12:56 -0700 |
| commit | ccffdf29fffec7a8f9493a0ee04497ba84464bac (patch) | |
| tree | 31e8739d98f3e5ebc437319fb262479f400d108e | |
| parent | 9b0f79b58f2a924234545af4b8c4830b8b335b8f (diff) | |
| parent | 5b6fd0e0fc22e37053f8d612a9f0c5dbd485606c (diff) | |
| download | pyramid-ccffdf29fffec7a8f9493a0ee04497ba84464bac.tar.gz pyramid-ccffdf29fffec7a8f9493a0ee04497ba84464bac.tar.bz2 pyramid-ccffdf29fffec7a8f9493a0ee04497ba84464bac.zip | |
Merge pull request #1932 from stevepiercy/master
grammar, wrapping
| -rw-r--r-- | docs/narr/urldispatch.rst | 518 |
1 files changed, 254 insertions, 264 deletions
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index fa3e734fe..c13558008 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,12 +21,12 @@ 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 -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,11 +35,11 @@ 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 +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. @@ -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 <external_route_narr>` 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 <external_route_narr>` 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 -<http://www.python.org/dev/peps/pep-0263/>`_ 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 <http://www.python.org/dev/peps/pep-0263/>`_ +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 <external_route_narr>` 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 <http://www.python.org/dev/peps/pep-0232/>`_) +If a predicate is a method, you'll need to assign it after method declaration +(see `PEP 232 <http://www.python.org/dev/peps/pep-0232/>`_). .. 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 ---------- |
