Hi 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 T 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 Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev