Skip to content

Commit 5b7190b

Browse files
authored
Merge pull request #71 from janheini/hash-static-files
Invalidate HTTP cache by appending md5sum to static files
2 parents a313943 + 2e32e38 commit 5b7190b

1 file changed

Lines changed: 61 additions & 12 deletions

File tree

flamingo/core/plugins/static.py

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,69 @@
1+
import hashlib
12
import os
23

34

45
class Static:
6+
def _iter_static_files(self, context):
7+
for static_dir in context.templating_engine.find_static_dirs():
8+
for dirpath, _dirnames, filenames in os.walk(static_dir):
9+
for filename in filenames:
10+
yield (static_dir, dirpath, filename)
11+
12+
def templating_engine_setup(self, context, templating_engine):
13+
"""Add a Jinja2 filter that appends md5sum to static files as a query parameter
14+
15+
Adding the checksum as a query parameter invalidates any HTTP caching when the file
16+
contents change.
17+
18+
Usage Example:
19+
<link rel="stylesheet" href="{{ static_file('theme/static/css/style.css') }}" type="text/css" />
20+
21+
Will be rendered as
22+
<link rel="stylesheet" href="/static/css/style.css?<md5sum>" type="text/css" />
23+
"""
24+
25+
self.static_files_map = {}
26+
27+
for static_dir, dirpath, filename in self._iter_static_files(context):
28+
source = os.path.join(dirpath, filename)
29+
30+
href = os.path.join(
31+
"/",
32+
os.path.relpath(
33+
context.settings.STATIC_ROOT,
34+
context.settings.OUTPUT_ROOT,
35+
),
36+
os.path.relpath(dirpath, static_dir),
37+
filename,
38+
)
39+
40+
with open(source, "rb") as file:
41+
md5 = hashlib.file_digest(file, hashlib.md5).hexdigest()
42+
43+
self.static_files_map[source] = {
44+
"href": href,
45+
"md5": md5,
46+
}
47+
48+
def static_file(source: str):
49+
return "?".join(
50+
(
51+
self.static_files_map[source]["href"],
52+
self.static_files_map[source]["md5"],
53+
)
54+
)
55+
56+
templating_engine.env.globals["static_file"] = static_file
57+
558
def post_build(self, context):
659
if context.settings.CONTENT_PATHS:
760
return
861

9-
for static_dir in context.templating_engine.find_static_dirs():
10-
for root, _dirs, files in os.walk(static_dir):
11-
for f in files:
12-
source = os.path.join(root, f)
13-
14-
destination = os.path.join(
15-
context.settings.STATIC_ROOT,
16-
os.path.relpath(root, static_dir),
17-
f,
18-
)
19-
20-
context.cp(source=source, destination=destination)
62+
for static_dir, dirpath, filename in self._iter_static_files(context):
63+
source = os.path.join(dirpath, filename)
64+
destination = os.path.join(
65+
context.settings.STATIC_ROOT,
66+
os.path.relpath(dirpath, static_dir),
67+
filename,
68+
)
69+
context.cp(source=source, destination=destination)

0 commit comments

Comments
 (0)