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)