How do you render a variable as html using flask? - python

Using flask, I'm passing in a list of dictionaries to one of the pages. One of the variables contains html text (ex:var x = <h1>hello</h1>). How would I get it to display as hello rather than just print out "<h1>hello</h1>"? Here's my code so far (post.description has the html variable; It's equal to <h1>hello</h1>):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{% for post in posts %}
<p>{{post.title}}<p>
{{post.description}}
{% endfor %}
</body>
</html>

You can use safe to render the HTML code with Jinja.
Example: {{ post.description | safe }}

Related

Django: Inject a string variable from Views.py with HTML and Django template tags into HTML file

So this is my issue: I have a Python string that contains both HTML and Django Template Tags and want to inject it into a base HTML file when I go to that page. Although, when I go to the page, all the HTML renders, but the Django Template Tags do not, and are treated literally as strings?
Here is a simplified example of the issue:
Views.py
def page(request, code):
html = {
'code': code
'html': """<p>Hello world {{ code }}</p> <script src="{% static 'appName/javascript_code_example.js' %}"></script>"""
}
return render(request, 'base.html', html)
base.html
{% load static %}
...
{{ html | safe }}
...
And all I will see when I run the app on my local machine with python3 manage.py runserver and go to the URL that renders base.html is Hello world {{ code }}, and the Javascript code is not executed. Instead of {{ code }} I'd like to see the actual value of the 'code' key in the html dictionary in the Views.py file.
If my base.html file is as follows:
{% load static %}
...
<p>Hello world {{ code }}</p>
<script src="{% static 'appName/javascript_code_example.js' %}"></script>
...
Then the Javascript will be enabled and I will see Hello world value_of_code_variable on the screen.
you have to load the python script that has the template library functions.
Also, Why are you rendering a string into html as opposed to creating an html template? (html file with template syntax)?
The Django template engine will not render (parse) template code inside injected strings. For this to happen, you have to manually render the template code by either:
instantiating a Template object and passing the resulting string to your base.html,
or ideally by moving the value of your html context variable to a template file, and using render_to_string().
If you decide to go for the last one, you should definitely consider using the include template tag in your base.html (instead of manually rendering using render_to_string()), as it reduces the amount of manual work and is the preferred way of rendering template code inside another template.
You can use file writing to do this task.
Make a newfile.html in templates folder and you can do thusly
Views.py
html_tag = "{% extends \"yourapp/base.html\"%}"+"{% block content %}"
html_tag +="<p>Hello world {{ code }}</p> <script src=\"{% static \"appName/javascript_code_example.js\" %}\"></script>"
html_tag +="{% endblock content %}"
html_file = open('yourapp/templates/yourapp/newfile.html', "w")
html_file.write(html_tag)
html_file.close()
html = {
'code': code
}
return render(request, r'yourapp\newfile.html', html)
In base.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>Your base code</p>
<!--The part of code you want to retrieve from views.py file-->
{% block content %}{% endblock content %}
</body>
</html>

Jinja2 not working in newsletter.html

I have this function which gets data from an API and then uses Jinja2 to insert this data into an HTML file. I want this data to show up in my newsletter.html and be sent as an email. Everything works fine apart from
this happening:
Here are some relevant snippets:
Getting the data as list and templating with Jinja:
# movie_finder.py
movie_list = []
for item in now_playing['results']:
if genre_id in item['genre_ids']:
movie_list.append(item['original_title'])
print movie_list
# Create jinja2 environment
try:
env = Environment(loader=PackageLoader('movie_finder', 'templates'))
template = env.get_template('newsletter.html')
rend = template.render(info=movie_list)
print "Templating successful"
except:
print "Templating fail"
return "Templating fail"
find_movies_with_genre(API_KEY, 878)
In the script that sends the email (which otherwise works fine), I simply do:
from scifi_finder import find_movies_with_genre
Template:
<!-- Newsletter template by https://github.com/derekpunsalan/-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width"/>
<!-- For development, pass document through inliner -->
<link rel="stylesheet" href="css/simple.css">
<style type="text/css">
output print movie_list:
[u'Thor: Ragnarok', u'Blade Runner 2049', u'War for the Planet of the Apes', u'Geostorm']
You are not passing the variables correctly when calling render(), here is what you are doing:
template.render(info=movie_list)
You are passing a variable info, yet in your template, you are referring to movie_list:
{% for item in movie_list %}
{{ item[0] }}
{{ item[1] }}
{% endfor %}
This will not work, you need to refer to the variable you are passing, personally I prefer it this way:
template.render(movie_list=movie_list)
...and in template...
{% for item in movie_list %}
{{ item[0] }}
{{ item[1] }}
{% endfor %}
...as you have it already. You could just as well use...
{% for item in info %}
{{ item[0] }}
{{ item[1] }}
{% endfor %}
...in your template and keep your function call as it is, but personally I find the first variant less confusing when I read it again weeks later.

How to handle a variable in HTML?

I have the following flask application that displays a dashboard with various buttons. Each button executes a python function. After the execution of such a function I want the application to return to the dashboard. In order to give the user a simple log I want to output some string on the html page. For that thought about a tag above the buttons on the dashboard that get filled with the respective value. How can I do that?
Flask:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def main():
return render_template('index.html')
#app.route('/something')
def do_something():
print("Hello")
return render_template('index.html', user="Successfully executed!")
if __name__ == "__main__":
app.run()
HTML:
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="UTF-8">
</head>
<title>MP Reporting</title>
</head>
<body>
<div value=user></div>
Your button
</body>
</html>
For flask template use "{{kwarg}}" i.e. in your example
<div>{{user}}</div>
will render as
<div>Successfully executed!</div>
In addition to other answers, I suggest using Flask's built-in message flashing which is simpler, and neater instead of passing variables to render_template manually. It's simple as that:
(template)
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div>{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
(flask view)
from flask import flash
flash("Successfully executed!")
You can get more information from here.
You can print variables using Jinja2.
To print out the variable user in your example add
{{ user }} in the html template.
If you send a list of items to the html you can output them by using a simple for:
{% for item in items %}
{{ item }}
{% endfor %}

Create directory of dynamically created html files. Flask

I've got a simple flask app, with a templates folder with a bunch of html files that are created by a separate program. I want to (1) serve each of these html files by hitting localhost:8888/<html_filename> and
(2) create a directory with hyperlinks to these endpoints on my main / endpoint.
Thoughts on how I could get a jinja template to create links to those endpoints? Heres what I've been thinking.
Flask App:
#app.route('/')
def index():
reports = [f_name for f_name in os.listdir("templates") if f_name.endswith(".html")]
return render_template("index.html", reports=reports)
#app.route('/<report>')
def render_report(report):
return render_template(report+'.html')
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report Directory</title>
</head>
<body>
<ul>
{% for r in reports %}
<li>
{{ r }}
</li>
{% endfor %}
</ul>
</body>
</html>
Off the top of my head and not tested in any way define a route along the lines of the following:
#route("/<string:slug>/", methods=['GET'])
def page(self, slug):
if slug_exists_as_a_html_file(slug):
return render_template(slug)
abort(404)
The function (or inline it) )slug_exists_as_a_html_file needs to return True if the slug matches a valid html template file, otherwise false.
To generate your report listing use something like :
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report Directory</title>
</head>
<body>
<ul>
{% for r in reports %}
<li>
{{ r }}
</li>
{% endfor %}
</ul>
</body>
</html>

Flask and AngularJs [duplicate]

This question already has answers here:
Is it possible to use AngularJS with the Jinja2 template engine?
(2 answers)
Closed 6 years ago.
I am trying to implement AngularJs to my flask project. In my app.py I have this code to render a test site:
#app.route('/test/')
def test():
return render_template('test.html')
And in the test.html I have this:
<!DOCTYPE html>
<html lang="en" data-ng-app>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<title>Flask-Triangle - Tutorial</title>
</head>
<body>
<label>Name:</label>
<input type="text" data-ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{ yourName }}!</h1>
</body>
</html>
When I type in the input field nothing is happen..
I have checked that the angular.min.js is correctly loaded.
Is there something I have to do in app.py to get this work?
Flask uses jinja as its templating language which also uses {{ variable }}
so when flask renders the templates {{ yourname }} just becomes an empty string since yourname is not a context variable in the current render
to fix this you can use flask-triangle
http://flask-triangle.readthedocs.org/en/develop/tutorial/part1.html
which provides a template filter
{{ yourname | angular }} that will ensure the template is rendered correct for angular
you could also use escaped brackets inside the brackets (but this is much uglier I think)
{{ '{{ yourname }}' }}
Another way to fix this is that you can wrap the entire test.html contents with {% raw %} at the top, and {% endraw %} at the bottom. This will tell jinja not to do anything special in this. This way would only be good if you are not planning on using jinja at all. Using this would also make it a bit nicer to write with, as you no longer have to add in the fixes that Joran Beasley suggested.
Example:
{% raw %}
<!DOCTYPE html>
<html>
<head>
<!-- HEADER STUFF -->
</head>
<body>
<!-- Normal AngularJS code and syntax -->
</body>
</html>
{% endraw %}

Categories