Jinja2, JavaScript and CSP

I’ve been studying Flask and Jinja2 for a while now, and I notice that all the books and tutorials I’ve found put {% block js %} after {% block body %}. This appears to violate CSP which, as I understand it, dictates that all javascript code be in external files and that the <script> tags which include those files be inside the page’s <head> block. Is it possible/safe to put my {% block js %} inside my base template’s <head> block, or am I somehow shooting myself in the foot if I do this?

Answer

If you are using your own base template, you are defining the blocks so you can arrange them any way that makes sense; in particular you can replace

{% block body %}
...
{% endblock %}

{% block js %}
{{ super() }}
<script src="{{ url_for('static', filename='js/ckeditor/ckeditor.js') }}"></script>
<script>
  CKEDITOR.replace('editor')
</script>
{% endblock %}

with the CSP-compliant version

{% block js %}
{{ super() }}
<script src="{{ url_for('static', filename='js/ckeditor/ckeditor.js') }}"></script>
<script src="{{ url_for('static', filename='js/ckinit.js') }}"></script>
{% endblock %}

{% block body %}
...

where js/ckinit.js consists of

window.addEventListener("DOMContentLoaded", init, false);

function init(){
  CKEDITOR.replace('editor');
}

Note that if you are using a template package this may not work; in particular Flask-Bootstrap’s bootstrap/base.html places {% block scripts %} between the </body> and </html> tags.