summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/narr/security.rst2
-rw-r--r--docs/narr/templates.rst42
-rw-r--r--docs/narr/views.rst109
3 files changed, 126 insertions, 27 deletions
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index 36c0b618a..e12ae9883 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -1,3 +1,5 @@
+.. _security_chapter:
+
Security
========
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index c67bee81b..f414596b8 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -16,21 +16,39 @@ specification. While :term:`z3c.pt` doesn't implement the *METAL*
specification (feature or drawback, depending on your viewpoint), it
is significantly faster.
-Given a template named ``foo.html`` in a directory in your application
-named "templates", you can render the template in a view via::
+Given that there is a template named ``foo.html`` in a directory in
+your application named ``templates``, you can render the template from
+a view like so::
from repoze.bfg.template import render_template_to_response
- return render_template_to_response('templates/foo.html', foo=1, bar=2)
-You associate a view with a URL by adding information to your ZCML.
-
-.. sourcecode:: xml
-
- <bfg:view
- for=".models.IMapping"
- view=".views.contents_view"
- name="contents.html"
- />
+ def sample_view(context, request)
+ return render_template_to_response('templates/foo.html', foo=1, bar=2)
+
+The first argument to ``render_template_to_response`` shown above (and
+its sister function ``render_template``, not shown, which just returns
+a string body) is the template *path*. Above, the path
+``templates/foo.html`` is *relative*. Relative to what, you ask?
+Relative to the directory in which the ``views.py`` file which names
+it lives, which is usually the :mod:`repoze.bfg` application's
+:term:`package` directory.
+
+``render_template_to_response`` always renders a :term:`z3c.pt`
+template, and always returns a Response object which has a *status
+code* of ``200 OK`` and a *content-type* of ``text-html``. If you
+need more control over the status code and content-type, use the
+``render_template`` function instead, which also renders a z3c.pt
+template but returns a string instead of a Response. You can use
+the string manually as a response body::
+
+ from repoze.bfg.template import render_template
+ from webob import Response
+
+ def sample_view(context, request)
+ result = render_template('templates/foo.html', foo=1, bar=2)
+ response = Response(result)
+ response.content_type = 'text/plain'
+ return response
:mod:`repoze.bfg` loads the template and keeps it in memory between
requests. This means that modifications to the ZPT require a restart
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index a2a0c79ca..33e80caf7 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -1,35 +1,33 @@
Views
=====
-A view is a callable which is invoked when a request enters your
-application. :mod:`repoze.bfg's` primary job is to find and call a
-view when a request reaches it. The view's return value must
-implement the :term:`WebOb` ``Response`` object interface.
+A :term:`view` is a callable which is invoked when a request enters
+your application. :mod:`repoze.bfg's` primary job is to find and call
+a view when a :term:`request` reaches it. The view's return value
+must implement the :term:`WebOb` ``Response`` object interface.
Defining a View as a Function
-----------------------------
The easiest way to define a view is to create a function that accepts
-two arguments: *context*, and *request*. For example, this is a hello
-world view implemented as a function::
+two arguments: :term:`context`, and :term:`request`. For example,
+this is a hello world view implemented as a function::
def hello_world(context, request):
from webob import Response
return Response('Hello world!')
-View Arguments
---------------
+The :term:`context` and :term:`request` arguments can be defined as
+follows:
-:term:`context`
+context
- An instance of a model found via graph traversal.
+ An instance of a model found via graph :term:`traversal` or
+ :term:`URL dispatch`.
-:term:`request`
+request
- A WebOb request object representing the current request.
-
-Response Construction
----------------------
+ A WebOb request object representing the current WSGI request.
A view must return an object that implements the :term:`WebOb`
``Response`` interface. The easiest way to return something that
@@ -58,4 +56,85 @@ If a view happens to return something to the :mod:`repoze.bfg`
publisher that does not implement this interface, the publisher will
raise an error.
+Mapping Views to URLs
+----------------------
+
+You must associate a view with a URL by adding information to your
+:term:`application registry` via :term:`ZCML` in your
+``configure.zcml`` file using a ``bfg:view`` declaration.
+
+.. sourcecode:: xml
+
+ <bfg:view
+ for=".models.IHello"
+ view=".views.hello_world"
+ name="hello.html"
+ />
+
+The above maps the ``.views.hello_world`` view function to
+:term:`context` objects which implement the ``.models.IHello``
+interface when the *view name* is ``hello.html``.
+
+Note that values prefixed with a period (``.``)for the ``for`` and
+``view`` attributes of a ``bfg:view`` (such as those above) mean
+"relative to the Python package directory in which this :term:`ZCML`
+file is stored". So if the above ``bfg:view`` declaration was made
+inside a ``configure.zcml`` file that lived in the ``hello`` package,
+you could replace the relative ``.models.IHello`` with the absolute
+``hello.models.IHello``; likewise you could replace the relative
+``.views.hello_world`` with the absolute ``hello.views.hello_world``.
+Either the relative or absolute form is functionally equivalent. It's
+often useful to use the relative form, in case your package's name
+changes. It's also shorter to type.
+
+You can also declare a *default view* for a model type:
+
+.. sourcecode:: xml
+
+ <bfg:view
+ for=".models.IHello"
+ view=".views.hello_world"
+ />
+
+A *default view* has no ``name`` attribute. When a :term:`context` is
+traversed and there is no *view name* in the request, the *default
+view* is the view that is used.
+
+You can also declare that a view is good for any model type by using
+the special ``*`` character in the ``for`` attribute:
+
+.. sourcecode:: xml
+
+ <bfg:view
+ for="*"
+ view=".views.hello_world"
+ name="hello.html"
+ />
+
+This indicates that when :mod:`repoze.bfg` identifies that the *view
+name* is ``hello.html`` against *any* :term:`context`, this view will
+be called.
+
+View Security
+-------------
+
+If a :term:`security policy` is active, any :term:`permission`
+attached to a ``bfg:view`` declaration will be consulted to ensure
+that the currently authenticated user possesses that permission
+against the context before the view function is actually called.
+Here's an example of specifying a permission in a ``bfg:view``
+declaration:
+
+.. sourcecode:: xml
+
+ <bfg:view
+ for=".models.IBlog"
+ view=".views.add_entry"
+ name="add.html"
+ permission="add"
+ />
+
+When a security policy is enabled, this view will be protected with
+the ``add`` permission. See the :ref:`security_chapter` chapter to
+find out how to turn on a security policy.