Passing HTML to Template Using Flask/Jinja2

Passing HTML to template using Flask/Jinja2

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.

How to change HTML attributes using Flask and Jinja2 templates?

This kind of toggling is better handled in the front-end via JavaScript.

Using Jinja2 template means handling it in the back-end, since the Jinja2 template is only re-rendered when the there is a new request and the view updates. You don't really want to hit the server just to toggle something on the webpage.

To use JavaScript, the trick is to use JavaScript to modify the css of the table row tags.

For example, using id of the tag to modify visibility:

<script type="text/javascript">
function showHideDiv(id) {
var e = document.getElementById(id);
if(e.style.display == null || e.style.display == "none") {
e.style.display = "table-row";
} else {
e.style.display = "none";
}
}
</script>

{% for row in table %}
<tr>
<td>
<button onclick="showHideDiv('hiddable_{{row.id}}')">Show/Hide</button>
</td>
</tr>
<tr id="hiddable_{{row.id}}">
<td>
<table>
<!—- Hidden table -—>
</table>
</td>
</tr>
{% endfor %}

  1. The javascript finds tag by id and toggles the visibility for that tag.
  2. The button calls the javascript function on-click for the corresponding {{row.id}} which is # of iteration in the loop and is populated by the Jinja2 loop.
  3. The table in the same loop uses the same {{row.id}} and is thus controlled by the button in the loop.

How to render html for variables in Flask render_template

Flask turns on Jinja's autoescape feature. Quoting the manual on how to disable it:

There are three ways to accomplish that:

  1. In the Python code, wrap the HTML string in a Markup object before passing it to the template. This is in general the recommended way.

  2. Inside the template, use the |safe filter to explicitly mark a string as safe HTML ({{ myvariable|safe }})`

  3. Temporarily disable the autoescape system altogether.

flask_babel and Jinja2 How to include HTML or placeholders in translatable text?

You can mark the contents as | safe to avoid HTML being escaped:

{{ page_title | safe }}

Assuming you don't let the users insert content for other users that could work.

Another option is to use placeholders for the tags you want to insert, such as:

{{ _('The best %(start_tag)spotatoes%(end_tag)s in the world!', start_tag='<span>', end_tag='</span>') | safe }}

Passing custom python object between Jinja2 and Flask

@app.route('/event/<event>')

<event>, in this case, is a string. See the Flask quickstart for details on this. You cannot pass arbitrary objects through URLs like you are trying to do here.

Typically, you would have an ID of some kind here that you can use to look up the object, perhaps in a database. In that case, you would pass that ID into url_for() which would produce a URL like /events/123.

Then, when your event route is called, it's given the ID in the event argument. Then it's up to you to look up the right object and pass it into your template.

How to get a Python dict into an HTML template using Flask/Jinja2

The problem is that you’re iterating over iteritems(), which is an iterator of (key, value) pairs. This means that the l variable is a tuple, not a dictionary. You actually want to iterate over itervalues() instead. Update your template code as follows:

{% for l in result.itervalues() %}
<div class="link">
<a href="{{ l.url }}"> {{l.title}}</a>
<img src="{{ l.img }}" width="100" height="100">
</div>
{% endfor %}

I believe that should get you the behaviour you want.


Note that this will return the values in a random order (as iterating over a dictionary is random). If you wanted to sort by the key, you could modify the template as follows:

{% for key in result.iterkeys()|sort %}
<div class="link">
{%- set val=result[key] %}
<a href="{{ val.url }}"> {{val.title}}</a>
<img src="{{ val.img }}" width="100" height="100">
</div>
{% endfor %}

Here we iterate over the sorted keys, get the associated value, and then drop it into the template.

You could also swap out the sort filter for another filter which applies the ordering of your choice.


Here’s a minimal example that demonstrates the new template:

TEMPLATE_STR = """
{% for l in result.itervalues() %}
<div class="link">
<a href="{{ l.url }}"> {{l.title}}</a>
<img src="{{ l.img }}" width="100" height="100">
</div>
{% endfor %}
"""

from jinja2 import Template

template = Template(TEMPLATE_STR)

class democlass(object):
def getTitle(self): return "Hello world"
def getLink(self): return "google.co.uk"
def getImg(self): return "myimage.png"

class democlass2(object):
def getTitle(self): return "Foo bar"
def getLink(self): return "stackoverflow.com"
def getImg(self): return "a_photo.jpeg"

l = democlass()
m = democlass2()

dict1 = {}
dict1['l'] = { 'title': l.getTitle(), 'url': l.getLink(), 'img': l.getImg() }
dict1['m'] = { 'title': m.getTitle(), 'url': m.getLink(), 'img': m.getImg() }

print template.render(result=dict1)

Here's the HTML it returns:

<div class="link">
<a href="stackoverflow.com"> Foo bar</a>
<img src="a_photo.jpeg" width="100" height="100">
</div>

<div class="link">
<a href="google.co.uk"> Hello world</a>
<img src="myimage.png" width="100" height="100">
</div>

Flask Request to get HTML data from a template?

I managed to do this using make_response.

from flask import make_response

resp = make_response(render_template('custom_templates/basic.html'))
html = resp.get_data(as_text=True)

If you don't add as_text=True then it returns it in Bytes.



Related Topics



Leave a reply



Submit