Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exposing global data and functions in Pyramid and Jinja 2 templating

I have a base template for when a user is logged in, and on that base template, I need to add user specific options in a drop down menu. This drop down menu with options must be constant across all handlers, i.e., any time the base template is invoked (extended) with a child template.

Other than performing the necessary DB query, assigning the query results to a variable, and passing that variable to every handler (there are many), how can I consolidate this into one query and one variable, which gets passed directly to the base template? I am using jinja2 templates as well.

I would hate to do something so cumbersome in exchange for something far more simple and maintainable.

Any ideas? Thanks.


EDIT

So I still haven't found anything that's exactly what I'm looking for; however, I decided to at least make some headway in the interim. So, I made a custom decorator that takes a view's returned dict() and appends the appropriate data to it. For example:

def get_base_data(func):
    def wrapper(request):
        d = func(request)
        user_id = request.user.id  # used in query
        contact_group_data = ContactGroups.query.filter(...criteria...).all()
        d['contact_group_data'] = contact_group_data
        return d
    return wrapper

Now, I can at least decorate each method very concisely and simply by putting:

@view_config(...)
@get_base_data
def my_handler(request):
    pass  # rest of code...
like image 638
Friendly King Avatar asked Oct 24 '13 22:10

Friendly King


People also ask

What is the difference between Jinja and Jinja2?

Jinja, also commonly referred to as "Jinja2" to specify the newest release version, is a Python template engine used to create HTML, XML or other markup formats that are returned to the user via an HTTP response.


1 Answers

This is one of most inobvious things in Pyramid and took a while to find for me, too.

You can modify the global template context in BeforeRender event.

http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/hooks.html#using-the-before-render-event

Alternatively, you could use class based views, inherit all your views from one base view class which has get_base_data(), then the class instance is passed to the template context to all your views and then you could extract the data with {{ view.get_base_data }}.

http://ruslanspivak.com/2012/03/02/class-based-views-in-pyramid/

I vouch for the latter approach as it is more beautiful, predictable and easier to maintain engineering wise.

like image 54
Mikko Ohtamaa Avatar answered Oct 21 '22 17:10

Mikko Ohtamaa