- Dokument-Vorlagen-Editor: create/edit/reset document templates (admin) - Upload-Portal: public portal for Nachweis uploads via token - Onboarding: invite Destinatäre via email with multi-step wizard - Bestätigungsschreiben: preview and send confirmation letters - Email settings: SMTP configuration UI - Management command: import_veranstaltung_teilnehmer for bulk participant import Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
"""Utility für das Rendering von Dokument-Vorlagen.
|
|
|
|
Prüft zuerst die Datenbank (DokumentVorlage), fällt dann auf die Datei-Vorlage zurück.
|
|
"""
|
|
|
|
from django.template import Context, Engine, Template
|
|
from django.template.loader import render_to_string
|
|
|
|
|
|
def render_vorlage(template_name: str, context: dict, request=None) -> str:
|
|
"""Rendert eine Vorlage.
|
|
|
|
Schaut zuerst in der DB nach (DokumentVorlage), fällt auf die Datei zurück.
|
|
|
|
Args:
|
|
template_name: Template-Pfad, z.B. "pdf/bestaetigung.html"
|
|
context: Template-Kontext-Dictionary
|
|
request: Optionaler Request (für RequestContext)
|
|
|
|
Returns:
|
|
Gerenderter HTML-String
|
|
"""
|
|
from stiftung.models import DokumentVorlage
|
|
|
|
try:
|
|
vorlage = DokumentVorlage.objects.get(schluessel=template_name)
|
|
# Eigene Engine mit den Standard-Builtins, aber ohne Dateisystem-Loader
|
|
engine = Engine.get_default()
|
|
t = engine.from_string(vorlage.html_inhalt)
|
|
return t.render(Context(context))
|
|
except DokumentVorlage.DoesNotExist:
|
|
pass
|
|
|
|
# Fallback: Datei-Template
|
|
return render_to_string(template_name, context, request=request)
|
|
|
|
|
|
def get_vorlage_original(template_name: str) -> str:
|
|
"""Liest den Original-Dateiinhalt einer Vorlage (für Reset-Funktion)."""
|
|
from django.template.loaders.filesystem import Loader
|
|
from django.template import Engine
|
|
|
|
engine = Engine.get_default()
|
|
for loader in engine.template_loaders:
|
|
try:
|
|
source, _ = loader.get_contents_and_origin(template_name)
|
|
return source
|
|
except Exception:
|
|
# Try get_template_sources
|
|
try:
|
|
for origin in loader.get_template_sources(template_name):
|
|
try:
|
|
with open(origin.name, "r", encoding="utf-8") as f:
|
|
return f.read()
|
|
except OSError:
|
|
continue
|
|
except Exception:
|
|
continue
|
|
raise FileNotFoundError(f"Template-Datei nicht gefunden: {template_name}")
|