Equivalent of template context in Pyramid (pylons user)
What is the equivalent of template context in Pyramid?
Does the IBeforeRender开发者_开发知识库 event in pyramid have anything to with this? I've gone through the official documentation but diffcult to understand what the IBeforeRender event is exactly.
Pyramid already provides a tmpl_context
on its Request object, so pretty simply you just have to subscribe a BeforeRender
event to add it to the renderer globals:
def add_renderer_globals(event):
event['c'] = request.tmpl_context
event['tmpl_context'] = request.tmpl_context
config.add_subscriber(add_renderer_globals, 'pyramid.events.BeforeRender')
From now on in your code when you receive a request, you can set parameters on it:
request.tmpl_context.name = 'Bob'
And subsequently your template may reference the name
variable:
${ c.name }
If instead you are hoping for some "global bag" where you can stuff variables that will be available to every template, then your question about IBeforeRender is appropriate.
from pyramid.events import subscriber
from pyramid.events import BeforeRender
@subscriber(BeforeRender)
def add_global(event):
event['name'] = 'Pyramid Developer'
There is an alternative way of adding globals when setting up the Configurator as well. You can see the full info at: http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/hooks.html#using-the-before-render-event
It seems to me, that the solutions above do not exactly copy the behavior of Pylons template context. If one renders a page request in Pylons and adds some value a
to the context c
, it is accessible in the template as c.a
. However, if one renders another request, this key/value will be dropped.
The Pyramid solutions above show another behavior. the key/value c.a
will stay in the template context. Sometimes, this is not desired. Are there any suggestions to fix this difference?
Pyramid doesn't really expose the "template context" to the developer (although it is used internally in the various template engine bindings for Pyramid).
Normally if you want to stuff something into "c" for use inside a template you simply pass it as a keyword argument to the render_to_response() call or as part of the dict that you return with a predefined renderer.
So to do something similar as http://pylonsbook.com/en/1.1/using-view-templates.html#using-the-template-context-c-global you would do:
@view_config(renderer="greeting.mako")
def index(request):
return {'name': 'Pyramid Developer'}
And greeting.mako :
<html>
<head>
<title>Greetings</title>
</head>
<body>
<h1>Greetings</h1>
<p>Hello ${name}!</p>
</body>
</html>
From Pylons magic globals section of Pyramid Cookbook:
Pylons has several magic globals that contain state data for the current request. Here are the closest Pyramid equivalents:
(...)
pylons.tmpl_context
A scratch object for request-local data, usually used to pass varables to the template. In Pyramid, you return a dict of variables and let the renderer apply them to a template. Or you can render a template yourself in view code.
If the view is a method, you can also set instance variables. The view instance is visible as
view
in templates. There are two main use cses for this. One, to set variables for the site template that would otherwise have to be in every return dict. Two, for variables that are specific to HTML rendering, when the view is registered with both an HTML renderer and a non-HTML renderer (e.g., JSON).Pyramid does have a port of "tmpl_context" at
request.tmpl_context
, which is visible in templates asc
. However, it never caught on among Pyramid-Pylons users and is no longer documented.
If you're looking for a global dictionary to conveniently pass variables back & forth between templates and views, use pyramid.request.TemplateContext
On the template page:
<%!
from pyramid.request import TemplateContext as c
c.foo = 123
%>
Then you can access the variable by importing TemplateContext in your views the same way:
from pyramid.request import TemplateContext as c
This should more or less be the equivalent of tmpl_context in pylons.
精彩评论