[ADD] Custom Static Files Storage Class

This commit is contained in:
Peter Pfeufer 2025-05-31 23:59:03 +02:00
parent a650f0730e
commit 329b3fecfb
No known key found for this signature in database
2 changed files with 96 additions and 0 deletions

View File

@ -0,0 +1,87 @@
"""
Custom static files storage for Alliance Auth.
This module defines a custom static files storage class for
Alliance Auth, named `AaManifestStaticFilesStorage`.
Using `ManifestStaticFilesStorage` will give us a hashed name for
our static files, which is useful for cache busting.
This storage class extends Django's `ManifestStaticFilesStorage` to ignore missing files,
which the original class does not handle, and log them in debug mode.
It is useful for handling cases where static files may not exist, such as when a
CSS file references a background image that is not present in the static files directory.
With debug mode enabled, it will print a message for each missing file when running `collectstatic`,
which can help identify issues with static file references during development.
"""
from django.conf import settings
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage
class AaManifestStaticFilesStorage(ManifestStaticFilesStorage):
"""
Custom static files storage that ignores missing files.
"""
def __init__(self, *args, **kwargs):
"""
Initialize the static files storage, ignoring missing files.
:param args:
:type args:
:param kwargs:
:type kwargs:
"""
self.missing_files = []
super().__init__(*args, **kwargs)
def hashed_name(self, name, *args, **kwargs):
"""
Generate a hashed name for the given static file, ignoring missing files.
Ignore missing files, e.g. non-existent background image referenced from css.
Returns the original filename if the referenced file doesn't exist.
:param name:
:type name:
:param args:
:type args:
:param kwargs:
:type kwargs:
:return:
:rtype:
"""
try:
return super().hashed_name(name, *args, **kwargs)
except ValueError as e:
if settings.DEBUG:
# In debug mode, we log the missing file message
message = e.args[0].split(" with ")[0]
self.missing_files.append(message)
# print(f'\x1b[0;30;41m{message}\x1b[0m')
return name
def post_process(self, *args, **kwargs):
"""
Post-process the static files, printing any missing files in debug mode.
:param args:
:type args:
:param kwargs:
:type kwargs:
:return:
:rtype:
"""
yield from super().post_process(*args, **kwargs)
if settings.DEBUG:
# In debug mode, print the missing files
for message in sorted(set(self.missing_files)):
print(f"\x1b[0;30;41m{message}\x1b[0m")

View File

@ -219,6 +219,15 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "allianceauth.framework.staticfiles.storage.AaManifestStaticFilesStorage",
},
}
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(PROJECT_DIR, 'static'),