Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing HTML to template using Flask/Jinja2

People also ask

Does Flask support Dynamic HTML?

Using Flask Templates for Dynamic data. We have already discussed using templates in flask for storing the non-changing data, but we can also use them dynamically to show data using Jinja. Jinja is used to write python-like syntax in HTML files, which helps in using variables like functionality.

Where do I put Flask HTML templates?

html template file in a directory called templates inside your flask_app directory. Flask looks for templates in the templates directory, which is called templates , so the name is important.


To turn off autoescaping when rendering a value, use the |safe filter.

{{ something|safe }}

Only do this on data you trust, since rendering untrusted data without escaping is a cross-site scripting vulnerability.


MarkupSafe provides Jinja's autoescaping behavior. You can import Markup and use it to declare a value HTML safe from the code:

from markupsafe import Markup
value = Markup('<strong>The HTML String</strong>')

Pass that to the templates and you don't have to use the |safe filter on it.


From the Jinja docs section HTML Escaping:

When automatic escaping is enabled everything is escaped by default except for values explicitly marked as safe. Those can either be marked by the application or in the template by using the |safe filter.

Example:

 <div class="info">
   {{data.email_content|safe}}
 </div>

When you have a lot of variables that don't need escaping, you can use an autoescape override block:

{% autoescape false %}
{{ something }}
{{ something_else }}
<b>{{ something_important }}</b>
{% endautoescape %}

Some people seem to turn autoescape off which carries security risks to manipulate the string display.

If you only want to insert some linebreaks into a string and convert the linebreaks into <br />, then you could take a jinja macro like:

{% macro linebreaks_for_string( the_string ) -%}
{% if the_string %}
{% for line in the_string.split('\n') %}
<br />
{{ line }}
{% endfor %}
{% else %}
{{ the_string }}
{% endif %}
{%- endmacro %}

and in your template just call this with

{{ linebreaks_for_string( my_string_in_a_variable ) }}

Use the safe filter in your template, and then sanitize the HTML with the bleach library in your view. Using bleach, you can whitelist the HTML tags that you need to use.

This is the safest, as far as I know. I tried both the safe filter and the Markup class, and both ways allowed me to execute unwanted JavaScript. Not very safe!