I'm trying to template some of my common HTML elements by passing them as Flask variables, specifically my stylesheets and scripts. For further simplification and responsiveness I'm trying to use url_for
to connect those.
In my app.py I have:
common_html = {
'navbar': '''<nav class....>''',
'scripts': '''<!-- D3 -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- Personal JS -->
<script src="{{url_for('static', filename='javascript/myjs.js')}}"></script>'''
}
@app.route('/index')
def index():
return render_template('index.html', common=common_html)
And in my HTML file:
...
<body>
<!-- Nav --!>
{{common['navbar']|safe}}
<h1>Stuff</h1>
</body>
<!-- Scripts -->
{{common['scripts']|safe}}
</html>
In browser, my navbar code loads perfectly fine, however the script tag containing the url_for statement is not run properly. It appears as is <script src="{{url_for('static', filename='javascript/myjs.js')}}"></script>
upon inspection. The script file is in the proper directory/filepath.
I've tried removing the {{}}
double brackets and messing with the different quotations used to no avail. I have memory of this method working at some point previously, but can't say for certain.
Is there a practice or way to use url_for within a block of template code or is this poor practice? Any and all help would be appreciated!
I think the reason for this is that jinja doesn't render anything inside something that's already being rendered. So because you are passing the {{ url_for() }}
inside a double brace, it will automatically escape anything in it. What you've basically done is put Jinja syntax in something that isn't evaluated by Jinja. So it actually looks like this:
{{ "{{ url_for() }}" }}
.
Remember, Jinja will just put whatever's in the first double braces onto the page (after escaping), so it doesn't render the actual value of that {{url_for()}}
. I would recommend using a base template which can then be inherited by your other pages.