I know this is old but wanted to share my own hacky solution, which is to change how the Dash-specific tags are marked, render the HTML file using Jinja’s template loader, and then re.sub
to insert the proper Dash-tag delimiters.
Step 1.
In my base.html (parent) and index.html (child template) files, create my own markup to delineate the Dash-specific tags, e.g. {%app_entry%}
to{~%app_entry%~}
If you don’t do this, Jinja will throw an error like:
File "templates/index.jinja.html", line 7, in template
{%app_entry%}
^^^^^^^^^^^^^^^^^^
jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'app_entry'.
Step 2a.
(note: I copied this template loading code from ChatGPT, feel free to ignore if it’s just AI crap instead of actual jinja2 best practice!)
In my app.py
, I create a helper function named load_jinja_index_page
.
The first part of this function uses jinja2.Environment
and jinja2.FileSystemLoader
to load my template files and process them
_env = jinja_env(loader=jinja_loader(searchpath="./templates"))
template = _env.get_template("index.jinja.html")
jinja_html = template.render()
Step 2b.
After using template.render()
to create a jinja-acceptable HTML string, we use re.sub
to convert all instances of ~%
back to %
. That cleaned string is what my load_jinja_index_page
function returns
dash_html = re.sub(r"~%", "%", jinja_html)
All together
After that, all you need to do is give that rendered HTML string to app.index_string
. This is what my app.py
looks like:
from dash import Dash, html
from jinja2 import Environment as jinja_env, FileSystemLoader as jinja_loader
import re
def load_jinja_index_page() -> str:
_env = jinja_env(loader=jinja_loader(searchpath="./templates"))
template = _env.get_template("index.jinja.html")
jinja_html = template.render()
# jinja throws an error at dash-specific tags like {% app_entry %},
# so in the html files, the dash tags are set with {~% dash_tag ~%}
dash_html = re.sub(r"~%", "%", jinja_html)
return dash_html
app = Dash()
app.index_string = load_jinja_index_page()
app.layout = [
html.H1(children="""Hello World!"""),
]
if __name__ == "__main__":
app.run(debug=True)