I am not too sure about making this the default 'view' implementation
or at least we need to retain the existing the simpler view directive.

I many cases I am/need to identify the template used much later in the
process, so for me baking the template
name in the view directive is certainly not what I want


On Mon, Sep 14, 2009 at 1:59 AM, Chris Rossi <ch...@archimedeanco.com> wrote:
> This looks reasonable.  I think it would also be reasonable to just make
> this the standard 'view' functionality, since afaict the current
> functionality is a subset of this.
> Chris
> On Sun, Sep 13, 2009 at 12:57 PM, Chris McDonough <chr...@plope.com> wrote:
>> Here's some sci fi I wrote up about a "page" ZCML directive.  As Tim
>> Hoffman
>> suggested, maybe the fact that the "page" is passed into the template
>> would
>> give us enough "pull" capability to avoid any of the other hacks I
>> proposed to
>> push global names into every rendered template.
>> Note that the "view" directive could probably eventually be changed to do
>> everything that the "page" directive I describe below does.
>> Comments appreciated.
>> repoze.bfg.page README
>> ======================
>> ``repoze.bfg.page`` is a package which adds a ``page`` ZCML directive
>> to the set of directives that may be used under BFG.  You might use a
>> ``page`` directive in places where you would otherwise use the
>> built-in repoze.bfg ``view`` directive.  Defining a ``page`` directive
>> effectively creates a single BFG view "under the hood", and owns
>> attributes similar to those of a view directive.  However, the
>> ``page`` directive differs from the BFG ``view`` directive in a number
>> of important ways:
>> - The ``page`` directive allows you to associate a *template* with the
>>   page being defined.  The machinery behind the ``page`` directive is
>>   capable of rendering an associated template, unlike a view, which
>>   must find and render a template itself.
>> - A ``page`` directive, like a BFG ``view`` directive, points at a
>>   callable which accepts two arguments: ``context`` and ``request``.
>>   This callable must return a Response object *or* a Python
>>   dictionary.  This is unlike a BFG ``view`` callable, which always
>>   returns a Response object (and must never return a dictionary).
>>   The ``callable`` which a ``page`` directive points at may optionally
>>   be a class.  If the page directive's ``callable`` attribute points
>>   at a class, that class must have an ``__init__`` method that accepts
>>   two arguments: ``context`` and ``request``.  That class must further
>>   define a ``__call__`` method which accepts no arguments and which
>>   returns a dictionary or a Response object.
>>   If the page callable returns a Python dictionary, the ``template``
>>   named within the directive will be passed the dictionary as its
>>   keyword arguments, and the ``page`` implementation will return the
>>   resulting rendered template in a response to the user.  The callable
>>   object (whatever object was used to define the page ``callable``)
>>   will be automatically inserted into the set of keyword arguments
>>   passed to the template as ``page``.  If the callable object was a
>>   class, an instance of that class will be inserted into the keyword
>>   arguments as ``page``.
>>   If the ``callable`` associated with a ``page`` directive returns a
>>   Response object (an object with the attributes ``status``,
>>   ``headerlist`` and ``app_iter``), any template associated with the
>>   ``page`` declaration is ignored, and the response is passed back to
>>   BFG.  For example, if your page callable returns an ``HTTPFound``
>>   response, no template rendering will be performed::
>>     from webob.exc import HTTPFound
>>     return HTTPFound(location='http://example.com') # templating avoided
>> Here's an example of a page directive which acts as a default view::
>>   <page
>>    template="templates/my_template.pt"
>>    callable=".pages.my_page"
>>    />
>> The ``template`` attribute is optional.  If one is not named, and the
>> callable returns a dictionary, an error will be thrown at rendering
>> time.
>> Special ZCML Attributes
>> -----------------------
>> The directive accepts attributes other than ``template`` and ``callable``.
>> attr
>>   ``repoze.bfg.page`` defaults to using the ``__call__`` method of the
>>   page callable to obtain a response dictionary.  The ``attr`` value
>>   allows you to vary that method name.  For example, if your class had
>>   a method named ``index`` and you wanted to use this method instead
>>   of ``__call__``, you'd say ``attr="index"`` in the page ZCML
>>   definition.  This is most useful when the page definition is a
>>   class.
>> for
>>   A Python dotted-path name representing the Python class that the
>>   :term:`context` must be an instance of, *or* the :term:`interface`
>>   that the :term:`context` must provide in order for this view to be
>>   found and called.
>> name
>>   The *view name*.  Read and understand :ref:`traversal_chapter` to
>>   understand the concept of a view name.
>> permission
>>   The name of a *permission* that the user must possess in order to
>>   call the view.  See :ref:`view_security_section` for more
>>   information about view security and permissions.
>> request_method
>>   This value can either be one of the strings 'GET', 'POST', 'PUT',
>>   'DELETE', or 'HEAD' representing an HTTP ``REQUEST_METHOD``.  A view
>>   declaration with this attribute ensures that the view will only be
>>   called when the request's ``method`` (aka ``REQUEST_METHOD``) string
>>   matches the supplied value.
>> request_param
>>   This value can be any string.  A view declaration with this
>>   attribute ensures that the view will only be called when the request
>>   has a key in the ``request.params`` dictionary (an HTTP ``GET`` or
>>   ``POST`` variable) that has a name which matches the supplied value.
>>   If the value supplied to the attribute has a ``=`` sign in it,
>>   e.g. ``request_params="foo=123"``, then the key (``foo``) must both
>>   exist in the ``request.params`` dictionary, and the value must match
>>   the right hand side of the expression (``123``) for the view to
>>   "match" the current request.
>> containment
>>   This value should be a Python dotted-path string representing the
>>   class that a graph traversal parent object of the :term:`context`
>>   must be an instance of (or :term:`interface` that a parent object
>>   must provide) in order for this view to be found and called.  Your
>>   models must be "location-aware" to use this feature.  See
>>   :ref:`location_aware` for more information about location-awareness.
>> route_name
>>   *This attribute services an advanced feature that isn't often used
>>   unless you want to perform traversal *after* a route has matched.*
>>   This value must match the ``name`` of a ``<route>`` declaration (see
>>   :ref:`urldispatch_chapter`) that must match before this view will be
>>   called.  The ``<route>`` declaration specified by ``route_name`` must
>>   exist in ZCML before the view that names the route
>>   (XML-ordering-wise) .  Note that the ``<route>`` declaration
>>   referred to by ``route_name`` usually has a ``*traverse`` token in
>>   the value of its ``path`` attribute, representing a part of the path
>>   that will be used by traversal against the result of the route's
>>   :term:`root factory`.  See :ref:`hybrid_chapter` for more
>>   information on using this advanced feature.
>> request_type
>>   This value should be a Python dotted-path string representing the
>>   :term:`interface` that the :term:`request` must have in order for
>>   this view to be found and called.  See
>>   :ref:`view_request_types_section` for more information about request
>>   types.  For backwards compatibility with :mod:`repoze.bfg` version
>>   1.0, this value may also be an HTTP ``REQUEST_METHOD`` string, e.g.
>>   ('GET', 'HEAD', 'PUT', 'POST', or 'DELETE').  Passing request method
>>   strings as a ``request_type`` is deprecated.  Use the
>>   ``request_method`` attribute instead for maximum forward
>>   compatibility.
>> Special Keyword Names When A Callable Returns A Dictionary
>> ----------------------------------------------------------
>> Several keyword names in a dictionary return value of a page callable
>> are treated specially by the page implementation.  These values are
>> passed through to the template during rendering, but they also
>> influence the response returned to the user separate from any template
>> rendering.  Page callables should set these values into the dictionary
>> they return to influence response attributes.
>> content_type
>>   Defines the content-type of the resulting response,
>>   e.g. ``text/xml``.
>> headerlist
>>   A sequence of tuples describing cookie values that should be set in
>>   the response, e.g. ``[('Set-Cookie', 'abc=123'), ('X-My-Header',
>>   'foo')]``.
>> status
>>   A WSGI-style status code (e.g. ``200 OK``) describing the status of
>>   the response.
>> charset
>>   The character set (e.g. ``UTF-8``) of the response.
>> cache_for
>>   A value in seconds which will influence ``Cache-Control`` and
>>   ``Expires`` headers in the returned response.  The same can also be
>>   achieved by returning various values in the headerlist, this is
>>   purely a convenience.
>> Default Template Filename Extension Mappings
>> --------------------------------------------
>> A file extension mapping is used to determine which templating system
>> renderer to use to render any given template.  By default, a single
>> filename-extension-to-renderer mapping is used: any template name with
>> a filename extension of ".pt" is assumed to be rendered via a
>> Chameleon ZPT template.
>> By default, if a template renderer cannot be recognized by its
>> extension, it will be assumed that a Chameleon text renderer should be
>> used to render the template.
>> Adding and Overriding Template Filename Extension Mappings
>> ----------------------------------------------------------
>> Additonal declarations can be made which override a default
>> file-extension-to-renderer mapping or add a new
>> file-extension-to-renderer mapping.  This is accomplished via one or
>> more separate ZCML directives.
>> For example, to add Jinja2 rendering (after installing the
>> repoze.bfg.jinja2" package), whereby filenames that end in ``.jinja``
>> are rendered by the Jinja2 renderer::
>>   <utility provides="repoze.bfg.page.IPageRenderer"
>>            name=".jinja"
>>            component="repoze.bfg.jinja2.render_template_to_response"/>
>> To override the default mapping in which files with a ``.pt``
>> extension are rendered via a Chameleon ZPT page template renderer, use
>> a variation on the following::
>>   <utility provides="repoze.bfg.page.IPageRenderer"
>>            name=".pt"
>>            component="my.package.pt_renderer"/>
>> By default, when a template extension is unrecognized, the Chameleon
>> text templating engine is assumed.  You can override the default
>> renderer by creating an ``IPageRenderer`` utility which has no
>> ``name``::
>>   <utility provides="repoze.bfg.page.IPageRenderer"
>>            component="my.package.default_renderer"/>
>> The ``component`` named within any of these directives must be a
>> callable which accepts the following arguments: ``(template_name,
>> request, **kw)``.  It must return a Response object.
>> _______________________________________________
>> Repoze-dev mailing list
>> Repoze-dev@lists.repoze.org
>> http://lists.repoze.org/listinfo/repoze-dev
> _______________________________________________
> Repoze-dev mailing list
> Repoze-dev@lists.repoze.org
> http://lists.repoze.org/listinfo/repoze-dev
Repoze-dev mailing list

Reply via email to