diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/narr/security.rst | 2 | ||||
| -rw-r--r-- | docs/narr/templates.rst | 42 | ||||
| -rw-r--r-- | docs/narr/views.rst | 109 |
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. |
