diff options
| author | Chris McDonough <chrism@plope.com> | 2012-08-06 00:48:29 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2012-08-06 00:48:29 -0400 |
| commit | 0196b2a06ef66d2e8b33a03cc84373ab84ba44be (patch) | |
| tree | ce73c9ea253700c20dc2165dd427e38f8c3c5529 | |
| parent | 859e947aae832194e1a22905898be9ebe05b20ed (diff) | |
| download | pyramid-0196b2a06ef66d2e8b33a03cc84373ab84ba44be.tar.gz pyramid-0196b2a06ef66d2e8b33a03cc84373ab84ba44be.tar.bz2 pyramid-0196b2a06ef66d2e8b33a03cc84373ab84ba44be.zip | |
add docs for third-party view predicates
| -rw-r--r-- | CHANGES.txt | 15 | ||||
| -rw-r--r-- | docs/api/config.rst | 2 | ||||
| -rw-r--r-- | docs/glossary.rst | 6 | ||||
| -rw-r--r-- | docs/narr/hooks.rst | 94 |
4 files changed, 117 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index ecb2bf659..5e0bf0968 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -20,6 +20,21 @@ Bug Fixes Features -------- +- Third-party custom view and route predicates can now be added for use by + view authors via ``pyramid.config.Configurator.add_view_predicate`` and + ``pyramid.config.Configurator.add_route_predicate``. So, for example, + doing this:: + + config.add_view_predicate('abc', my.package.ABCPredicate) + + Might allow a view author to do this in an application that configured that + predicate:: + + @view_config(abc=1) + + See "Adding A Third Party View or Route Predicate" in the Hooks chapter for + more information. + - Custom objects can be made easily JSON-serializable in Pyramid by defining a ``__json__`` method on the object's class. This method should return values natively serializable by ``json.dumps`` (such as ints, lists, diff --git a/docs/api/config.rst b/docs/api/config.rst index cd58e74d3..bc9e067b1 100644 --- a/docs/api/config.rst +++ b/docs/api/config.rst @@ -66,6 +66,8 @@ .. automethod:: add_response_adapter .. automethod:: add_traverser .. automethod:: add_tween + .. automethod:: add_route_predicate + .. automethod:: add_view_predicate .. automethod:: set_request_factory .. automethod:: set_root_factory .. automethod:: set_session_factory diff --git a/docs/glossary.rst b/docs/glossary.rst index 45a79326f..ba3203f89 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -994,3 +994,9 @@ Glossary Aka ``gunicorn``, a fast :term:`WSGI` server that runs on UNIX under Python 2.5+ (although at the time of this writing does not support Python 3). See http://gunicorn.org/ for detailed information. + + predicate factory + A callable which is used by a third party during the registration of a + route or view predicates to extend the view and route configuration + system. See :ref:`registering_thirdparty_predicates` for more + information. diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 332805152..bdd968362 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1232,3 +1232,97 @@ Displaying Tween Ordering The ``ptweens`` command-line utility can be used to report the current implict and explicit tween chains used by an application. See :ref:`displaying_tweens`. + +.. _registering_thirdparty_predicates: + +Adding A Third Party View or Route Predicate +-------------------------------------------- + +View and route predicates used during view configuration allow you to narrow +the set of circumstances under which a view or route will match. For +example, the ``request_method`` view predicate can be used to ensure a view +callable is only invoked when the request's method is ``POST``: + +.. code-block:: python + + @view_config(request_method='POST') + def someview(request): + ... + +Likewise, a similar predicate can be used as a *route* predicate: + +.. code-block:: python + + config.add_route('name', '/foo', request_method='POST') + +Many other built-in predicates exists (``request_param``, and others). You +can add third-party predicates to the list of available predicates by using +one of :meth:`pyramid.config.Configurator.add_view_predicate` or +:meth:`pyramid.config.Configurator.add_route_predicate`. The former adds a +view predicate, the latter a route predicate. + +When using one of those APIs, you pass a *name* and a *factory* to add a +predicate during Pyramid's configuration stage. For example: + +.. code-block:: python + + config.add_view_predicate('content_type', ContentTypePredicate) + +The above example adds a new predicate named ``content_type`` to the list of +available predicates for views. This will allow the following view +configuration statement to work: + +.. code-block:: python + :linenos: + + @view_config(content_type='File') + def aview(request): ... + +The first argument to :meth:`pyramid.config.Configurator.add_view_predicate`, +the name, is a string representing the name that is expected to be passed to +``view_config`` (or its imperative analogue ``add_view``). + +The second argument is a predicate factory. A predicate factory is most +often a class with a constructor (``__init__``), a ``text`` method, a +``phash`` method and a ``__call__`` method. For example: + +.. code-block:: python + :linenos: + + class ContentTypePredicate(object): + def __init__(self, val, config): + self.val + + def text(self): + return 'content_type = %s' % (self.val,) + + phash = text + + def __call__(self, context, request): + return getattr(context, 'content_type', None) == self.val + +The constructor of a predicate factory takes two arguments: ``val`` and +``config``. The ``val`` argument will be the argument passed to +``view_config`` (or ``add_view``). In the example above, it will be the +string ``File``. The second arg, ``config`` will be the Configurator +instance at the time of configuration. + +The ``text`` method must return a string. It should be useful to describe +the behavior of the predicate in error messages. + +The ``phash`` method must return a string or a sequence of strings. It's +most often the same as ``text``, as long as ``text`` uniquely describes the +predicate's name and the value passed to the constructor. If ``text`` is +more general, or doesn't describe things that way, ``phash`` should return a +string with the name and the value serialized. The result of ``phash`` is +not seen in output anywhere, it just informs the uniqueness constraints for +view configuration. + +The ``__call__`` method of a predicate factory must accept a resource +(``context``) and a request, and must return ``True`` or ``False``. It is +the "meat" of the predicate. + +You can use the same predicate factory as both a view predicate and as a +route predicate, but you'll need to call ``add_view_predicate`` and +``add_route_predicate`` separately with the same factory. + |
