feat: add page shell, preferences and translations

Base layout with top bar, role-based menu, profile menu and phone layout; theme, language and German form of address kept in cookies; German formal, German informal and English text; Fluent avatar bundled in the image by a Node build stage; placeholder pages for the Publisher and Admin groups.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N3t4WL7bd9bdHHNjEsxzqC
This commit is contained in:
2026-10-17 21:05:40 +02:00
co-authored by Claude Sonnet 5.5
parent 3c69c2a156
commit 0dc079a8ac
34 changed files with 2132 additions and 24 deletions
+37
View File
@@ -0,0 +1,37 @@
from django.utils.translation import gettext_lazy as _
from . import menu, preferences
THEME_OPTIONS = (
("light", _("Light")),
("dark", _("Dark")),
("system", _("System")),
)
LANGUAGE_OPTIONS = (("de", "Deutsch"), ("en", "English"))
FORM_OPTIONS = (("sie", "Sie"), ("du", "du"))
def initials(name: str) -> str:
words = [w for w in name.split() if w]
if not words:
return "?"
letters = words[0][0] + (words[-1][0] if len(words) > 1 else "")
return letters.upper()
def shell(request):
"""Menu, preferences and the values the base layout needs."""
prefs = getattr(request, "preferences", preferences.Preferences())
portal_user = getattr(request, "portal_user", None)
context = {
"preferences": prefs,
"html_lang": prefs.language,
"theme_options": THEME_OPTIONS,
"language_options": LANGUAGE_OPTIONS,
"form_options": FORM_OPTIONS,
"portal_user": portal_user,
}
if portal_user is not None:
context["menu_groups"] = menu.for_user(portal_user, request.path)
context["initials"] = initials(portal_user.display_name)
return context