introduce django compressor

This commit is contained in:
Tobias Brunner 2025-07-15 18:24:28 +02:00
parent 67e1b4cab1
commit a4a0fa4f8b
No known key found for this signature in database
7 changed files with 121 additions and 2 deletions

1
.gitignore vendored
View file

@ -15,3 +15,4 @@ wheels/
media/
deployment/secret.yaml
*.json
static/

View file

@ -35,6 +35,6 @@ RUN uv sync --frozen \
&& chgrp -R 0 /app \
&& chmod -R g=u /app \
&& chmod g+w /app/config/caddy/Caddyfile \
&& SECRET_KEY= python -m hub collectstatic --noinput
&& SECRET_KEY=dummy python -m hub build_assets --force
CMD ["/usr/local/bin/runhub.sh"]

View file

@ -0,0 +1,32 @@
from django.core.management.base import BaseCommand
from django.core.management import call_command
class Command(BaseCommand):
help = "Build and compress static assets for production"
def add_arguments(self, parser):
parser.add_argument(
"--force",
action="store_true",
help="Force compression even if files exist",
)
def handle(self, *args, **options):
self.stdout.write("Building static assets...")
# Compress CSS and JS files
self.stdout.write("Compressing CSS and JavaScript...")
call_command(
"compress",
force=options.get("force", False),
verbosity=options.get("verbosity", 1),
)
# Collect all static files
self.stdout.write("Collecting static files...")
call_command(
"collectstatic", interactive=False, verbosity=options.get("verbosity", 1)
)
self.stdout.write(self.style.SUCCESS("Successfully built static assets"))

View file

@ -1,12 +1,36 @@
{% extends 'base.html' %}
{% load static %}
{% load compress %}
{% load contact_tags %}
{% load json_ld_tags %}
{% block title %}Managed {{ offering.service.name }} on {{ offering.cloud_provider.name }}{% endblock %}
{% block extra_js %}
<script defer src="{% static "js/price-calculator.js" %}"></script>
{% if debug %}
<!-- Development: Load individual modules for easier debugging -->
<script defer src="{% static 'js/price-calculator.js' %}"></script>
{% else %}
<!-- Production: Load compressed bundle -->
{% compress js %}
<script src="{% static 'js/price-calculator/dom-manager.js' %}"></script>
<script src="{% static 'js/price-calculator/pricing-data-manager.js' %}"></script>
<script src="{% static 'js/price-calculator/plan-manager.js' %}"></script>
<script src="{% static 'js/price-calculator/addon-manager.js' %}"></script>
<script src="{% static 'js/price-calculator/ui-manager.js' %}"></script>
<script src="{% static 'js/price-calculator/order-manager.js' %}"></script>
<script src="{% static 'js/price-calculator/price-calculator.js' %}"></script>
<script>
// Initialize calculator when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
// Check if we're on a page that needs the price calculator
if (document.getElementById('cpuRange')) {
window.priceCalculator = new PriceCalculator();
}
});
</script>
{% endcompress %}
{% endif %}
<link rel="stylesheet" type="text/css" href='{% static "css/price-calculator.css" %}'>
{% json_ld_structured_data %}

View file

@ -76,6 +76,7 @@ INSTALLED_APPS = [
"django.contrib.staticfiles",
"django.contrib.sitemaps",
# 3rd party
"compressor",
"django_prose_editor",
"rest_framework",
"schema_viewer",
@ -186,6 +187,25 @@ USE_TZ = True
STATIC_URL = "static/"
STATIC_ROOT = env.path("STATIC_ROOT", default=BASE_DIR / "static")
# Static files configuration
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
"compressor.finders.CompressorFinder",
]
# Django Compressor settings
COMPRESS_ENABLED = True
COMPRESS_OFFLINE = True # Compress during build, not runtime
COMPRESS_CSS_FILTERS = [
"compressor.filters.css_default.CssAbsoluteFilter",
"compressor.filters.cssmin.rCSSMinFilter",
]
COMPRESS_JS_FILTERS = [
"compressor.filters.jsmin.rJSMinFilter",
]
COMPRESS_OUTPUT_DIR = "CACHE"
# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field

View file

@ -7,6 +7,7 @@ requires-python = ">=3.13"
dependencies = [
"django>=5.2",
"django-admin-sortable2>=2.2.4",
"django-compressor>=4.5.1",
"django-import-export>=4.3.7",
"django-jazzmin>=3.0.1",
"django-nested-admin>=4.1.1",

41
uv.lock generated
View file

@ -81,6 +81,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/66/c3/e804b1f04546c1060e566f35177c346590820a95bfb981d1f6360b419437/django_admin_sortable2-2.2.4-py3-none-any.whl", hash = "sha256:406c5b6d6e84ad982cc6e53c3f34b5db5f0a3f34891126af90c9fb2c372f53d5", size = 90816, upload-time = "2024-11-15T09:43:13.665Z" },
]
[[package]]
name = "django-appconf"
version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
]
sdist = { url = "https://files.pythonhosted.org/packages/61/a9/dcf95ff3fa0620b6818fc02276fbbb8926e7f286039b6d015e56e8b7af39/django-appconf-1.1.0.tar.gz", hash = "sha256:9fcead372f82a0f21ee189434e7ae9c007cbb29af1118c18251720f3d06243e4", size = 15986, upload-time = "2025-02-13T16:09:40.258Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/62/9e/f3a899991e4aaae4b69c1aa187ba4a32e34742475c91eb13010ee7fbe9db/django_appconf-1.1.0-py3-none-any.whl", hash = "sha256:7abd5a163ff57557f216e84d3ce9dac36c37ffce1ab9a044d3d53b7c943dd10f", size = 6389, upload-time = "2025-02-13T16:09:39.133Z" },
]
[[package]]
name = "django-browser-reload"
version = "1.17.0"
@ -103,6 +115,21 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/48/90/01755e4a42558b763f7021e9369aa6aa94c2ede7313deed56cb7483834ab/django_cache_url-3.4.5-py2.py3-none-any.whl", hash = "sha256:5f350759978483ab85dc0e3e17b3d53eed3394a28148f6bf0f53d11d0feb5b3c", size = 4760, upload-time = "2023-12-04T17:19:44.355Z" },
]
[[package]]
name = "django-compressor"
version = "4.5.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
{ name = "django-appconf" },
{ name = "rcssmin" },
{ name = "rjsmin" },
]
sdist = { url = "https://files.pythonhosted.org/packages/15/30/a9994277ae05082ba5df22c5678a87082253a034927c8d9915c3bf3b8c36/django_compressor-4.5.1.tar.gz", hash = "sha256:c1d8a48a2ee4d8b7f23c411eb9c97e2d88db18a18ba1c9e8178d5f5b8366a822", size = 124734, upload-time = "2024-07-22T09:56:47.554Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/00/d9/ac374a1f7a432230cdf4d2ffbe957fd0d4d5d6426bf4d5c17f382b0801c4/django_compressor-4.5.1-py2.py3-none-any.whl", hash = "sha256:87741edee4e7f24f3e0b8072d94a990cfb010cb2ca7cc443944da8e193cdea65", size = 145465, upload-time = "2024-07-22T09:56:45.822Z" },
]
[[package]]
name = "django-import-export"
version = "4.3.7"
@ -351,6 +378,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
]
[[package]]
name = "rcssmin"
version = "1.1.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ef/26/f38d49c21d933e3e4320ed31c6025c381dbd973e9936edd0af52ce521534/rcssmin-1.1.2.tar.gz", hash = "sha256:bc75eb75bd6d345c0c51fd80fc487ddd6f9fd409dd7861b3fe98dee85018e1e9", size = 582213, upload-time = "2023-10-03T19:57:48.536Z" }
[[package]]
name = "rjsmin"
version = "1.2.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f0/1c/c0355e8b8b8aca9c0d43519d2a7c473940deae0297ff8544eff359d7f715/rjsmin-1.2.2.tar.gz", hash = "sha256:8c1bcd821143fecf23242012b55e13610840a839cd467b358f16359010d62dae", size = 420634, upload-time = "2023-10-05T07:19:30.857Z" }
[[package]]
name = "servala-fe"
version = "0.1.0"
@ -358,6 +397,7 @@ source = { virtual = "." }
dependencies = [
{ name = "django" },
{ name = "django-admin-sortable2" },
{ name = "django-compressor" },
{ name = "django-import-export" },
{ name = "django-jazzmin" },
{ name = "django-nested-admin" },
@ -381,6 +421,7 @@ requires-dist = [
{ name = "django", specifier = ">=5.2" },
{ name = "django-admin-sortable2", specifier = ">=2.2.4" },
{ name = "django-browser-reload", marker = "extra == 'dev'", specifier = "~=1.13" },
{ name = "django-compressor", specifier = ">=4.5.1" },
{ name = "django-import-export", specifier = ">=4.3.7" },
{ name = "django-jazzmin", specifier = ">=3.0.1" },
{ name = "django-nested-admin", specifier = ">=4.1.1" },