Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a Jinja2 macro from a view callable?

I have some macros defined that are called from several templates.

For example, the Product page has a Review section that uses the macros defined in 'helpers/review.jinja2' to print each review. The 'helpers/review.jinja2' file has this two macros:

{% macro render_review(request,review) -%}
{% macro render_review_comment(request,comment) -%}

When someone submits a new review, via ajax, I want to return the rendered review in order to append the content to the Review section.

Right now, I have an intermediate template 'review/review.jinja2' that looks like this:

{% import 'helpers/review.jinja2' as review_helper %}
{{ review_helper.render_review(request,review) }}

This template is rendered from the view:

@view_config(route_name='review.add_review', renderer='review/review.jinja2')
def add_review(request):
    return dict(review=my_new_review)

But I hope there is a better way to do this. So, is it possible to render a macro defined in a template?

Thanks

like image 267
Marco Bruggmann Avatar asked Oct 07 '22 23:10

Marco Bruggmann


People also ask

How do you call a Jinja function in Python?

Using a Python function in a Jinja templateFirst we define 2 functions: 'hello_world' and 'multiply'. These functions are placed in a dictionary. After this, the render function is created. Inside this function, we use jinja_template.

What is a Jinja2 macro?

Macros within Jinja2 are essentially used like functions with Python and are great for repeating configs with identical structures (think interface configurations, ASA object-groups, etc).

How do you write a for loop in Jinja2?

Jinja2 being a templating language has no need for wide choice of loop types so we only get for loop. For loops start with {% for my_item in my_collection %} and end with {% endfor %} . This is very similar to how you'd loop over an iterable in Python.


1 Answers

The solution can actually be found in another one of Armin's projects - Flask implements a get_template_attribute method (see here for the source of the method). This points us at Jinja2's Template class, more specifically, the Template class' module attribute.

I don't know if Pyramid's default renderer for Jinja2 exposes that functionality for you, but it should be possible to create and register a custom renderer if the default one does not let you do something like this (entirely theoretical):

@view_config(route_name='review.add_review',
                renderer='helpers/review.jinja2:render_review')
def add_review(request):
    return dict(review=my_new_review)
like image 82
Sean Vieira Avatar answered Oct 16 '22 20:10

Sean Vieira