I want to insert follium map into the jinja template.
run.py
from flask import Flask, render_template
app = Flask(__name__)
@app.rou
A different solution using iframe and render_template
<iframe class="map", src="/get_map" width="1100" height="600"></iframe>
Plus python flask code
# a hack going on here as web servers are caching folium generated template
# randomly move to a new name and then use render_template
@app.route('/get_map')
def get_map():
r = int(random.triangular(0,100))
t = "templates/map_{i}.html"
for i in range(0,100):
f = t.format(i=i)
if os.path.exists(f):
os.remove(f)
f = t.format(i=r)
shutil.copy("templates/map.html", f)
r = make_response(render_template(os.path.split(f)[1]))
r.cache_control.max_age = 0
r.cache_control.no_cache = True
r.cache_control.no_store = True
r.cache_control.must_revalidate = True
r.cache_control.proxy_revalidate = True
return r
Without the copy to a random filename before rendering httpd (on AWS beanstalk) / flask debug environment was not picking up new instance of folium html template. cache_control is not needed but was part of what I trialed to come to a solution. Clearly this solution is not thread safe
Maybe it can be the solution. First we save a Folium map as an html file on templates folder. Then we create a Flask route to render another html file. On that html file, we create an iframe element that call our map.
Here is the file structure:
proectApp
├── app.py
└── templates
├── index.html
└── map.html
Folium map file (map.html) will be created automatically from my app.py. On app.py I'll create 2 main route: the first one is the home route which will render index.html & create map.html. Then the other is to render folium map (map.html). Here are the codes:
app.py
from flask import Flask, render_template
import folium
app = Flask(__name__)
@app.route('/')
def index():
start_coords = (-6.1753924, 106.8271528)
folium_map = folium.Map(
location=start_coords,
zoom_start=17
)
folium_map.save('templates/map.html')
return render_template('index.html')
@app.route('/map')
def map():
return render_template('7_map.html')
if __name__ == '__main__':
app.run(debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Folium Map</title>
</head>
<body>
<h1>Render Folium on Flask
You could save your generated html with folium_map.save('templates/map.html')
. Then you can use jinja2 to {% include "map.html" %}
. The generated html does not render a map when wrapped in div tags as indicated, if encapsulation is necessary consider using iframes or custom folium templates.
file structure
myapp
├── run.py
└── templates
├── index.html
└── layout.html
run.py
from flask import Flask, render_template
import folium
app = Flask(__name__)
@app.route('/')
def index():
start_coords = (46.9540700, 142.7360300)
folium_map = folium.Map(location=start_coords, zoom_start=14)
folium_map.save('templates/map.html')
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
layout.html
<!DOCTYPE HTML>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<header>{% block head %}{% endblock %}</header>
{% block body %}{% endblock %}
</body>
</html>
index.html
{% extends "layout.html" %}
{% block title %} Test {% endblock %}
{% block head %} {{ super() }} {% endblock %}
{% block body %}
{% include "map.html" %}
{% endblock %}