Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing HTML to a Jinja macro

Tags:

html

jinja2

My page has many Bootstrap modals which always have the same markup, except for the identifiers and the actual content of course.

To minimize the enormous and repetetive amount of code for these modals I want to build a Jinja macro that spits out the entire HTML markup for a modal with one simple call, e.g.:

{# macros/modal_template.jinja2 #}

{% macro print_modal(id, title, body_content) %}
  <div class="modal fade" id="{{ id }}" tabindex="-1">
    <div class="modal-dialog">
       <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
          <h4 class="modal-title">{{ title }}</h4>
        </div>
        <div class="modal-body">
          {{ body_content }}
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div>
    </div>
  </div>
{% endmacro %}


{# my_page.jinja2 #}

{% from "macros/modal_template.jinja2" import print_modal %}
<html>
<body>
  {{ print_modal("description-modal", "Description", "Lorem Ipsum") }}
</body>
</html>

So far it's pretty much a no-brainer, but image body_content isn't a plain string, but a complex HTML form or a really long text with text-styling HTML. I'm struggling to find a good solution to this problem.

The only working solution I came up with so far is to pass the content as a string and printing it with {{ body_content|safe }}, but putting complex markup into a string is ugly and uncomfortable.

Do you guys have any good ideas?

like image 451
Florian Braun Avatar asked Feb 07 '23 06:02

Florian Braun


1 Answers

A little delayed answer -- I just came across your question googling the same thing, but I figured it out:

What you can do is to utilize jinjas call/caller() functionality like so..

{% macro print_modal(id, title) %}
  <div class="modal fade" id="{{ id }}" tabindex="-1">
    <div class="modal-dialog">
       <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
          <h4 class="modal-title">{{ title }}</h4>
        </div>
        <div class="modal-body">
          {{ caller() }} <---- {# Look at me! #}
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div>
    </div>
  </div>
{% endmacro %}

and when you utilize the macro

{% call print_modal(someId, someTitle) %}
    {# whatever you put in here will be placed into the {{caller()}} line #}
    {# for example #}
    <h1>HELLO WORLD</h1> {# Will format an h1 into the caller block #}
{% endcall %}
like image 109
mclslee Avatar answered Feb 09 '23 23:02

mclslee