13

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.

sidewinder
  • 2,253
  • 6
  • 21
  • 33

6 Answers6

11

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 }
Michael Merickel
  • 22,500
  • 3
  • 47
  • 66
  • `Request.tmpl_context` is no longer documented and it's already visible in templates as `c` – see my [answer](http://stackoverflow.com/a/35443664/95735). – Piotr Dobrogost Feb 16 '16 at 21:52
6

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

Piotr Dobrogost
  • 38,049
  • 34
  • 218
  • 341
Rocky Burt
  • 401
  • 3
  • 7
2

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?

Fynn
  • 4,389
  • 2
  • 28
  • 62
  • Yes, instead of using **global** event `BeforeRender` pass request specific variables to renderer or use them while rendering your response directly. *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.* – from [Pylons magic globals](http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/pylons/request.html#pylons-magic-globals) section of *Pyramid Cookbook*. – Piotr Dobrogost Feb 16 '16 at 22:29
1

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>
Rocky Burt
  • 401
  • 3
  • 7
0

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 as c. However, it never caught on among Pyramid-Pylons users and is no longer documented.

Piotr Dobrogost
  • 38,049
  • 34
  • 218
  • 341
-1

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.

Kyle Liu
  • 618
  • 6
  • 9