mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-10 20:26:48 +00:00
build: the themes ship compiled, libsass is no longer installed
A theme change compiled Bootswatch with libsass (34 MB, upstream deprecated) into two tracked files, which updates, rollbacks and new Docker containers then reset. The 27 themes now ship as static/css/themes/<theme>.min.css, built by "manage.py build_themes"; the Settings page only saves the theme name and every page links that file (zephyr when no settings are in context, as on the 500 page). libsass moves to dev/requirements.txt; a test checks that each shipped file is its theme compiled from dev/scss. The "Theme SASS Path" setting is removed, and the theme default "flaty", a typo that never applied, becomes zephyr, the theme those installs showed. The update and rollback steps restore an older version's rewritten theme files only where they are modified.
This commit is contained in:
parent
28a73519d7
commit
41468c700d
43 changed files with 315 additions and 298 deletions
|
|
@ -1,7 +1,5 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import sass
|
||||
from admin.decorators import superuser_only
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
|
|
@ -14,11 +12,8 @@ from operations.utils import BOUNDS
|
|||
from appsettings.models import AppSettings
|
||||
|
||||
|
||||
def sass_dir_in_project(value):
|
||||
"""True if the SASS_DIR value is an existing directory inside the project:
|
||||
the page lists its themes and writes wvc-main.scss into it."""
|
||||
path = (Path(settings.BASE_DIR) / value).resolve()
|
||||
return path.is_dir() and path.is_relative_to(Path(settings.BASE_DIR).resolve())
|
||||
# the themes "manage.py build_themes" compiles; base.html links the chosen one
|
||||
THEMES_DIR = Path(settings.BASE_DIR, "static", "css", "themes")
|
||||
|
||||
|
||||
@superuser_only
|
||||
|
|
@ -27,87 +22,24 @@ def appsettings(request):
|
|||
:param request:
|
||||
:return:
|
||||
"""
|
||||
main_css = "wvc-main.min.css"
|
||||
sass_dir = AppSettings.objects.get(key="SASS_DIR")
|
||||
bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
|
||||
themes_list = []
|
||||
if not sass_dir_in_project(sass_dir.value):
|
||||
messages.error(request, _("SASS directory path must be a directory inside the project: %(dir)s") % {"dir": sass_dir.value})
|
||||
else:
|
||||
try:
|
||||
themes_list = os.listdir(sass_dir.value + "/wvc-themes")
|
||||
except FileNotFoundError as err:
|
||||
messages.error(request, err)
|
||||
addlogmsg(request.user.username, "-", "", err)
|
||||
themes_list = sorted(p.name.removesuffix(".min.css") for p in THEMES_DIR.glob("*.min.css"))
|
||||
|
||||
# Bootstrap settings related with filesystems, because of that they are excluded from other settings
|
||||
# the theme has its own form; the other settings are listed one by one
|
||||
appsettings = AppSettings.objects.exclude(
|
||||
description__startswith="Bootstrap"
|
||||
).order_by("name")
|
||||
|
||||
if request.method == "POST":
|
||||
if "SASS_DIR" in request.POST:
|
||||
if not sass_dir_in_project(request.POST.get("SASS_DIR", "")):
|
||||
messages.error(
|
||||
request,
|
||||
_("SASS directory path must be a directory inside the project: %(dir)s")
|
||||
% {"dir": request.POST.get("SASS_DIR", "")},
|
||||
)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
try:
|
||||
sass_dir.value = request.POST.get("SASS_DIR", "")
|
||||
sass_dir.save()
|
||||
|
||||
msg = _("SASS directory path is changed. Now: %(dir)s") % {
|
||||
"dir": sass_dir.value
|
||||
}
|
||||
messages.success(request, msg)
|
||||
except Exception as err:
|
||||
msg = err
|
||||
messages.error(request, msg)
|
||||
|
||||
addlogmsg(request.user.username, "-", "", msg)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
if "BOOTSTRAP_THEME" in request.POST:
|
||||
theme = request.POST.get("BOOTSTRAP_THEME", "")
|
||||
# the name goes into @import paths: only the themes in SASS_DIR
|
||||
if theme not in themes_list:
|
||||
messages.error(request, _("Unknown theme: %(theme)s") % {"theme": theme})
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
scss_var = f"@import '{sass_dir.value}/wvc-themes/{theme}/variables';"
|
||||
# scss_boot = f"@import '{sass_dir.value}/bootstrap/bootstrap.scss';"
|
||||
scss_boot = f"@import '{sass_dir.value}/bootstrap-overrides.scss';"
|
||||
scss_bootswatch = (
|
||||
f"@import '{sass_dir.value}/wvc-themes/{theme}/bootswatch';"
|
||||
)
|
||||
|
||||
try:
|
||||
with open(sass_dir.value + "/wvc-main.scss", "w") as main:
|
||||
main.write(
|
||||
scss_var + "\n" + scss_boot + "\n" + scss_bootswatch + "\n"
|
||||
)
|
||||
|
||||
css_compressed = sass.compile(
|
||||
string=scss_var + "\n" + scss_boot + "\n" + scss_bootswatch,
|
||||
output_style="compressed",
|
||||
)
|
||||
with open("static/css/" + main_css, "w") as css:
|
||||
css.write(css_compressed)
|
||||
# nginx serves the collected copy; collectstatic later takes it from static/
|
||||
served = Path(settings.STATIC_ROOT or "", "css")
|
||||
if settings.STATIC_ROOT and served.is_dir():
|
||||
(served / main_css).write_text(css_compressed)
|
||||
|
||||
bootstrap_theme.value = theme
|
||||
bootstrap_theme.save()
|
||||
|
||||
msg = _("Theme is changed. Now: %(theme)s") % {"theme": theme}
|
||||
messages.success(request, msg)
|
||||
except Exception as err:
|
||||
msg = err
|
||||
messages.error(request, msg)
|
||||
|
||||
bootstrap_theme.value = theme
|
||||
bootstrap_theme.save()
|
||||
msg = _("Theme is changed. Now: %(theme)s") % {"theme": theme}
|
||||
messages.success(request, msg)
|
||||
addlogmsg(request.user.username, "-", "", msg)
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue