I am programming a Bokeh Server Application with templates. I have added some custom CSS and JS files. But when I make some changes the files are reloaded from the cache and I cannot see the new changes. One solution is to add a variable at the end of the URL in order to load them from scratch just if there were some changes. Bokeh resources work like that.
I have added the resources as in this example so far
{% extends base %}
<!-- goes in head -->
{% block preamble %}
<link href="app/static/css/custom.min.css" rel="stylesheet">
<script type="text/javascript" src="app/static/js/custom.min.js"></script>
{% endblock %}
<!-- goes in body -->
{% block contents %}
<div> {{ embed(roots.scatter) }} </div>
<div> {{ embed(roots.line) }} </div>
{% endblock %}
Is there a builtin way to add these hashes? The result I would like to have is:
<link href="app/static/css/custom.min.css?v=f5ee62ee57a37d94c35e8f7be218e11fc63df459" rel="stylesheet">
This hash string must be added before the page is loaded to make it work well
I found this class, but it seems just for Bokeh resources
Bokeh uses Jinja2 templates but it doesn't provide any access to template variables. One of possible workarounds is to create a custom template class:
from hashlib import md5
from jinja2 import Template
from bokeh.io import save
from bokeh.models import Div
class ExtendedTemplate(Template):
def render(self, *args, **kwargs):
if 'with_hash' not in kwargs:
kwargs['with_hash'] = with_hash
return super().render(*args, **kwargs)
t = ExtendedTemplate("""\
<link href="{{ with_hash('app/static/css/custom.min.css') }}" rel="stylesheet">
""")
def with_hash(s):
with open(s, 'rb') as f:
return f'{s}?v={md5(f.read()).hexdigest()}'
save(Div(), template=t)
Note that this particular code assumes that the CSS file's path is accessible from its current working directory.