summaryrefslogtreecommitdiff
path: root/repoze/bfg/view.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-12-09 00:34:50 +0000
committerChris McDonough <chrism@agendaless.com>2009-12-09 00:34:50 +0000
commit8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9 (patch)
treeb0525c11e88c5adf6c233c09d7e9318429d54265 /repoze/bfg/view.py
parentf46de3bb0a9d2c9823aa3221fd28d80aed65b719 (diff)
downloadpyramid-8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9.tar.gz
pyramid-8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9.tar.bz2
pyramid-8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9.zip
- General documentation freshening which takes imperative
configuration into account in more places and uses glossary references more liberally.
Diffstat (limited to 'repoze/bfg/view.py')
-rw-r--r--repoze/bfg/view.py196
1 files changed, 111 insertions, 85 deletions
diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py
index d682d762b..e5b271262 100644
--- a/repoze/bfg/view.py
+++ b/repoze/bfg/view.py
@@ -50,14 +50,15 @@ deprecated('NotFound',
_marker = object()
def render_view_to_response(context, request, name='', secure=True):
- """ Render the view named ``name`` against the specified
- ``context`` and ``request`` to an object implementing
- ``repoze.bfg.interfaces.IResponse`` or ``None`` if no such view
- exists. This function will return ``None`` if a corresponding
- view cannot be found. If ``secure`` is ``True``, and the view is
- protected by a permission, the permission will be checked before
- calling the view function. If the permission check disallows view
- execution (based on the current security policy), a
+ """ Render the view with the :term:`view name` ``name`` against
+ the specified ``context`` and ``request`` and return a
+ :term:`response` object or ``None`` if no such view exists.
+
+ This function will return ``None`` if a corresponding view cannot
+ be found. If ``secure`` is ``True``, and the view is protected by
+ a permission, the permission will be checked before calling the
+ view function. If the permission check disallows view execution
+ (based on the current security policy), a
``repoze.bfg.exceptions.Forbidden`` exception will be raised; its
``args`` attribute explains why the view access was disallowed.
If ``secure`` is ``False``, no permission checking is done."""
@@ -83,18 +84,20 @@ def render_view_to_response(context, request, name='', secure=True):
def render_view_to_iterable(context, request, name='', secure=True):
""" Render the view named ``name`` against the specified
``context`` and ``request``, and return an iterable representing
- the view response's ``app_iter`` (see the interface named
- ``repoze.bfg.interfaces.IResponse``). This function will return
- ``None`` if a corresponding view cannot be found. Additionally,
- this function will raise a ``ValueError`` if a view function is
- found and called but the view does not return an object which
- implements ``repoze.bfg.interfaces.IResponse``. You can usually
+ the view response's ``app_iter`` (see :ref:`the_response`).
+
+ This function will return ``None`` if a corresponding view cannot
+ be found. Additionally, this function will raise a ``ValueError``
+ if a view function is found and called but the view function's
+ result does not have an ``app_iter`` attribute. You can usually
get the string representation of the return value of this function
by calling ``''.join(iterable)``, or just use ``render_view``
- instead. If ``secure`` is ``True``, and the view is protected by
- a permission, the permission will be checked before calling the
- view function. If the permission check disallows view execution
- (based on the current security policy), a
+ instead.
+
+ If ``secure`` is ``True``, and the view is protected by a
+ permission, the permission will be checked before the view
+ function is invoked. If the permission check disallows view
+ execution (based on the current :term:`authentication policy`), a
``repoze.bfg.exceptions.Forbidden`` exception will be raised; its
``args`` attribute explains why the view access was disallowed.
If ``secure`` is ``False``, no permission checking is done."""
@@ -106,16 +109,16 @@ def render_view_to_iterable(context, request, name='', secure=True):
def render_view(context, request, name='', secure=True):
""" Render the view named ``name`` against the specified
``context`` and ``request``, and unwind the the view response's
- ``app_iter`` (see the interface named
- ``repoze.bfg.interfaces.IResponse``) into a single string. This
+ ``app_iter`` (see :ref:`the_response`) into a single string. This
function will return ``None`` if a corresponding view cannot be
found. Additionally, this function will raise a ``ValueError`` if
a view function is found and called but the view does not return
an object which implements ``repoze.bfg.interfaces.IResponse``.
+
If ``secure`` is ``True``, and the view is protected by a
- permission, the permission will be checked before calling the view
- function. If the permission check disallows view execution (based
- on the current security policy), a
+ permission, the permission will be checked before the view is
+ invoked. If the permission check disallows view execution (based
+ on the current :term:`authorization policy`), a
``repoze.bfg.exceptions.Forbidden`` exception will be raised; its
``args`` attribute explains why the view access was disallowed.
If ``secure`` is ``False``, no permission checking is done."""
@@ -125,11 +128,12 @@ def render_view(context, request, name='', secure=True):
return ''.join(iterable)
def is_response(ob):
- """ Return True if ``ob`` implements the
- ``repoze.bfg.interfaces.IResponse`` interface, False if not. Note
- that this isn't actually a true Zope interface check, it's a
- duck-typing check, as response objects are not obligated to
- actually implement a Zope interface."""
+ """ Return ``True`` if ``ob`` implements the interface implied by
+ :ref:`the_response`. ``False`` if not.
+
+ .. note:: this isn't a true interface check (in Zope terms), it's a
+ duck-typing check, as response objects are not obligated to
+ actually implement a Zope interface."""
# response objects aren't obligated to implement a Zope interface,
# so we do it the hard way
if ( hasattr(ob, 'app_iter') and hasattr(ob, 'headerlist') and
@@ -141,39 +145,40 @@ def is_response(ob):
return False
class static(object):
- """ An instance of this class is a callable which can act as a BFG
- view; this view will serve static files from a directory on disk
- based on the ``root_dir`` you provide to its constructor.
+ """ An instance of this class is a callable which can act as a
+ :mod:`repoze.bfg` :term:`view callable`; this view will serve
+ static files from a directory on disk based on the ``root_dir``
+ you provide to its constructor.
The directory may contain subdirectories (recursively); the static
view implementation will descend into these directories as
necessary based on the components of the URL in order to resolve a
path into a response.
- You may pass an absolute or relative filesystem path to the
- directory containing static files directory to the constructor as
- the ``root_dir`` argument.
-
- If the path is relative, and the ``package`` argument is ``None``,
- it will be considered relative to the directory in which the
- Python file which calls ``static`` resides. If the ``package``
- name argument is provided, and a relative ``root_dir`` is
- provided, the ``root_dir`` will be considered relative to the
- Python package specified by ``package_name`` (a dotted path to a
- Python package).
-
- ``cache_max_age`` influences the Expires and Max-Age response
- headers returned by the view (default is 3600 seconds or five
- minutes). ``level`` influences how relative directories are
- resolved (the number of hops in the call stack), not used very
- often.
-
- .. note:: If the ``root_dir`` is relative to a package, the BFG
- ``resource`` ZCML directive can be used to override resources
- within the named ``root_dir`` package-relative directory.
- However, if the ``root_dir`` is absolute, the ``resource``
- directive will not be able to override the resources it
- contains.
+ You may pass an absolute or relative filesystem path or a
+ :term:`resource specification` representing the directory
+ containing static files as the ``root_dir`` argument to this
+ class' constructor.
+
+ If the ``root_dir`` path is relative, and the ``package_name``
+ argument is ``None``, ``root_dir`` will be considered relative to
+ the directory in which the Python file which *calls* ``static``
+ resides. If the ``package_name`` name argument is provided, and a
+ relative ``root_dir`` is provided, the ``root_dir`` will be
+ considered relative to the Python :term:`package` specified by
+ ``package_name`` (a dotted path to a Python package).
+
+ ``cache_max_age`` influences the ``Expires`` and ``Max-Age``
+ response headers returned by the view (default is 3600 seconds or
+ five minutes).
+
+ .. note:: If the ``root_dir`` is relative to a :term:`package`, or
+ is a :term:`resource specification` the BFG ``resource`` ZCML
+ directive or :term:`Configurator` method can be used to
+ override resources within the named ``root_dir``
+ package-relative directory. However, if the ``root_dir`` is
+ absolute, the ``resource`` directive will not be able to
+ override the resources it contains.
"""
def __init__(self, root_dir, cache_max_age=3600, package_name=None):
# package_name is for bw compat; it is preferred to pass in a
@@ -200,31 +205,41 @@ class static(object):
return request_copy.get_response(self.app)
class bfg_view(object):
- """ Function or class decorator which allows Python code to make
- view registrations instead of using ZCML for the same purpose.
+ """ A function, class or method :term:`decorator` which allows a
+ developer to create view registrations nearer to a :term:`view
+ callable` definition than use of :term:`ZCML` or :term:`imperative
+ configuration` to do the same.
- E.g. in the module ``views.py``::
+ For example, this code in a module ``views.py``::
- from models import IMyModel
- from repoze.bfg.interfaces import IRequest
+ from models import MyModel
- @bfg_view(name='my_view', request_type=IRequest, for_=IMyModel,
- permission='read', route_name='site1'))
+ @bfg_view(name='my_view', for_=MyModel, permission='read',
+ route_name='site1')
def my_view(context, request):
- return render_template_to_response('templates/my.pt')
+ return 'OK'
+
+ Might replace the following call to the ``add_view`` method of a
+ :term:`Configurator`::
+
+ import views
+ import models
+ config.add_view(views.my_view, for_=models.MyModel, name='my_view',
+ permission='read', 'route_name='site1')
- Equates to the ZCML::
+ Or might relpace the following ZCML ``view`` declaration::
<view
- for='.models.IMyModel'
+ for='.models.MyModel'
view='.views.my_view'
name='my_view'
permission='read'
route_name='site1'
/>
- The following arguments are supported: ``for_``, ``permission``,
- ``name``, ``request_type``, ``route_name``, ``request_method``,
+ The following arguments are supported as arguments to
+ ``bfg_view``: ``for_``, ``permission``, ``name``,
+ ``request_type``, ``route_name``, ``request_method``,
``request_param``, ``containment``, ``xhr``, ``accept``,
``header`` and ``path_info``.
@@ -251,10 +266,10 @@ class bfg_view(object):
``repoze.bfg.interfaces.IRequest`` is used, implying the standard
request interface type.
- If ``route_name`` is not supplied, the view declaration is
+ If ``route_name`` is not supplied, the view configuration is
considered to be made against a URL that doesn't match any defined
:term:`route`. The use of a ``route_name`` is an advanced
- feature, useful only if you're using :term:`url dispatch`.
+ feature, useful only if you're also using :term:`url dispatch`.
If ``request_method`` is not supplied, this view will match a
request with any HTTP ``REQUEST_METHOD``
@@ -276,10 +291,11 @@ class bfg_view(object):
current request.
If ``containment`` is not supplied, this view will be called when
- the context of the request has any location lineage. If
- ``containment`` *is* supplied, it must be a class or :term:`interface`,
- denoting that the view 'matches' the current request only if any graph
- lineage node possesses this class or interface.
+ the context of the request has any (or no) :term:`lineage`. If
+ ``containment`` *is* supplied, it must be a class or
+ :term:`interface`, denoting that the view 'matches' the current
+ request only if any graph :term:`lineage` node possesses this
+ class or interface.
If ``xhr`` is specified, it must be a boolean value. If the value
is ``True``, the view will only be invoked if the request's
@@ -314,12 +330,10 @@ class bfg_view(object):
...
Such a registration implies that the view name will be
- ``my_view``, registered for models with the
- ``zope.interface.Interface`` interface, using no permission,
- registered against requests which implement the default IRequest
- interface when no urldispatch route matches, with any
- REQUEST_METHOD, any set of request.params values, in any lineage
- containment.
+ ``my_view``, registered for any :term:`context` object, using no
+ permission, registered against all non-URL-dispatch-based
+ requests, with any ``REQUEST_METHOD``, any set of request.params
+ values, without respect to any object in the :term:`lineage`.
The ``bfg_view`` decorator can also be used as a class decorator
in Python 2.6 and better (Python 2.5 and below do not support
@@ -336,8 +350,8 @@ class bfg_view(object):
def __call__(self):
return Response('hello from %s!' % self.context)
- In Python 2.5 and below, the bfg_view decorator can still be used
- against a class, although not in decorator form::
+ In Python 2.5 and below, the ``bfg_view`` decorator can still be
+ used against a class, although not in decorator form::
from webob import Response
from repoze.bfg.view import bfg_view
@@ -399,10 +413,16 @@ class bfg_view(object):
method decorator is new in :mod:`repoze.bfg` version
1.1.
- To make use of any bfg_view declaration, you *must* insert the
- following boilerplate into your application registry's ZCML::
+ To make use of any bfg_view declaration, you must perform a
+ :term:`scan`. To do so, either insert the following boilerplate
+ into your application registry's ZCML::
<scan package="."/>
+
+ Or, if you don't use ZCML, use the ``scan`` method of a
+ :term:`Configurator`::
+
+ config.scan()
"""
def __init__(self, name='', request_type=None, for_=None, permission=None,
route_name=None, request_method=None, request_param=None,
@@ -486,12 +506,18 @@ def append_slash_notfound_view(context, request):
data information (turning it into a GET), so you shouldn't rely on
this to redirect POST requests.
- Add the following to your application's ``configure.zcml`` to use
- this view as the Not Found view::
+ If you use ZCML, add the following to your application's
+ ``configure.zcml`` to use this view as the Not Found view::
<notfound
view="repoze.bfg.view.append_slash_notfound_view"/>
+ Or use the ``notfound`` method of a :term:`Configurator` if you
+ don't use ZCML::
+
+ from repoze.bfg.view import append_slash_notfound_view
+ config.notfound(append_slash_notfound_view)
+
See also :ref:`changing_the_notfound_view`.
.. note:: This function is new as of :mod:`repoze.bfg` version 1.1.