summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2008-07-17 15:54:13 +0000
committerChris McDonough <chrism@agendaless.com>2008-07-17 15:54:13 +0000
commitd6798e7775cc31e7507bccf8373fe5f77381ba51 (patch)
tree3cdeed50040f2ab90fc46793da8426f896f5d1c8 /docs
parent7dec5421d9ff145a1e401493b61f96bea795bbac (diff)
downloadpyramid-d6798e7775cc31e7507bccf8373fe5f77381ba51.tar.gz
pyramid-d6798e7775cc31e7507bccf8373fe5f77381ba51.tar.bz2
pyramid-d6798e7775cc31e7507bccf8373fe5f77381ba51.zip
Add info about views.
Diffstat (limited to 'docs')
-rw-r--r--docs/api/index.rst20
-rw-r--r--docs/index.rst1
-rw-r--r--docs/narr/introduction.rst14
-rw-r--r--docs/narr/views.rst147
4 files changed, 155 insertions, 27 deletions
diff --git a/docs/api/index.rst b/docs/api/index.rst
deleted file mode 100644
index 496afc4c6..000000000
--- a/docs/api/index.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-.. _modules:
-
-API documentation
-=================
-
-:mod:`repoze.bfg`
------------------
-
-The :mod:`repoze.bfg` package contains the code nececessary to create
-and run a web application.
-
-.. toctree::
- :maxdepth: 2
-
- push
- router
- security
- template
- view
-
diff --git a/docs/index.rst b/docs/index.rst
index bc6dbb303..3e27cccde 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -13,6 +13,7 @@ Narrative documentation in chapter form explaining how to use
:maxdepth: 2
narr/introduction
+ narr/views
API documentation
-----------------
diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst
index 91cafd503..768b9b905 100644
--- a/docs/narr/introduction.rst
+++ b/docs/narr/introduction.rst
@@ -149,15 +149,15 @@ mapply
code which dynamically ("magically") determines which arguments to
pass to a view based on environment and request parameters.
-view constructor and view
+view factory and view
- A "view constructor" is a callable which returns a view object. It
+ A "view factory" is a callable which returns a view object. It
should accept two values: context and request.
A "view" is a callable that accepts arbitrary values (mapped into it
by "mapply") and which returns a response object.
- A view constructor may *be* a view in a repoze.bfg application
+ A view factory may *be* a view in a repoze.bfg application
(e.g. it may accept "context" and "request" and return a response
object directly instead of returning a view object). This makes it
possible to support views as simple functions.
@@ -180,7 +180,7 @@ context
view registry
- A registry which maps a context and view name to a view constructor
+ A registry which maps a context and view name to a view factory
and optionally a permission.
template
@@ -278,12 +278,12 @@ code to execute:
8. Armed with the context, the view name, and the subpath, the
router performs a view lookup. It attemtps to look up a view
- constructor from the ``repoze.bfg`` view registry using the view
- name and the context. If a view constructor is found, it is
+ factory from the ``repoze.bfg`` view registry using the view
+ name and the context. If a view factory is found, it is
converted into a WSGI application: it is "wrapped in" ( aka
"adapted to") a WSGI application using mapply. The WSGI adapter
uses mapply to map request and environment variables into the
- view when it is called. If a view constructor is not found, a
+ view when it is called. If a view factory is not found, a
generic WSGI ``NotFound`` application is constructed.
In either case, the resulting WSGI application is called. The WSGI
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
new file mode 100644
index 000000000..3331794e3
--- /dev/null
+++ b/docs/narr/views.rst
@@ -0,0 +1,147 @@
+Views
+=====
+
+A view is a callable which is called when a a request enters your
+application. ``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
+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::
+
+ def hello_world(context, request):
+ from webob import Response
+ return Response('Hello world!')
+
+Defining View Factories
+-----------------------
+
+Declarations in your view registry to point at a *view factory*
+rather than pointing it at a view implemented as a function. This
+provides an additional level of convenience for some applications.
+
+A view factory, like a view implemented as a function, accepts the
+*context* and *request* arguments. But unlike a view implemented as a
+function it returns *another* callable instead of a response. The
+returned callable is then called by ``repoze.bfg``, with its arguments
+filled in "magically".
+
+The easiest way to implement a view factory is to imlement it as a
+class. Here's a hello world view factory that is implemented as a
+class::
+
+ class HelloWorld(object):
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self):
+ from webob import Response
+ return Response('Hello world!')
+
+You can also implement a view factory as a function::
+
+ def HelloWorld(context, request):
+ def hello_world():
+ from webob import Response
+ return Response('Hello world!')
+ return hello_world
+
+Using View Factories for Convenience
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+View factories aren't just makework. They exist for convenience,
+because, unlike views as functions, views that are returned via a view
+factory will have arguments "magically" mapped into them when they are
+called by the router. You can choose the arguments you'd like the
+constructed view to receive simply by mentioning each in the signature
+of the callable you return from the view factory (or the __call__ of
+the class you use as the view factory).
+
+The arguments that are available to be magically mapped into
+constructed view calls are as follows.
+
+context
+
+ The current context
+
+request
+
+ The current request
+
+environ
+
+ The current WSGI environment
+
+start_response
+
+ The current WSGI start_response callable
+
+XXX We need to decide which other elements will be mapped in from the
+request and map them in: e.g. query string/form elements, etc.
+
+This means that the ``__call__`` of the following view factory
+will have its *environ* and *start_response* arguments filled in
+magically during view call time::
+
+ def ViewFactory(object):
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self, environ, start_response):
+ msg = 'Called via %s ' % environ['PATH_INFO']
+ start_response('200 OK', ('Content-Length', len(msg))
+ return msg
+
+.. note:: If you're familiar with WSGI, you'll notice above that the
+ view factory returns a valid WSGI application. View
+ factories in ``repoze.bfg`` can return any WSGI application.
+
+View Functions Revisited
+------------------------
+
+Above we provided an example of a "view" imlemented as a function::
+
+ def hello_world(context, request):
+ from webob import Response
+ return Response('Hello world!')
+
+When ``repoze.bfg`` finds and calls this callable, has no a-priori
+knowledge that would allow it to believe that this function would
+return a response directly. It assumes that what it's calling will
+return a *view* instead of a *response*. In other words, it expects
+that everything configured in its view registry points at a view
+factory.
+
+However, there is a special case in the logic implemented in the
+``repoze.bfg`` router that says if the return value of a view
+factory is an object implementing the Response interface, use that
+object as the response, and don't try to call the object or magically
+map any arguments into it. Instead, it just passes it along to the
+upstream WSGI server.
+
+This is purely for convenience: it's useful to be able to define
+simple functions as "views" without the overhead of defining a view
+factory.
+
+View Factory Arguments
+----------------------
+
+Now that we know what view factories are, what are these *context*
+and *request* arguments that are mapped in to it?
+
+context
+
+ An instance of a model found via graph traversal.
+
+request
+
+ A WebOb request object representing the current request.
+
+
+