# LehrerApp Templating ## PDF-Import im TemplateDesigner Der Menüpunkt **Einfügen → PDF als Vorlage importieren** rekonstruiert einseitige PDF-Vorlagen. Der präzisere Modus verwendet ein leeres Template zusammen mit einem ausgefüllten Beispiel und ermittelt variable Textbereiche über einen toleranten Geometrie-Diff. Mit nur einem PDF werden Datum, Zahlen und typische Adressbereiche lokal heuristisch vorerkannt. PdfPig extrahiert Text, Bounding-Box, Schriftgröße und verfügbare Schriftmerkmale. Die optionale KI-Klassifikation erhält ausschließlich diese strukturierte Zwischenrepräsentation und darf nur Placeholder-Namen, Typ, Gruppierung und Konfidenz liefern. Koordinaten werden nicht an die KI delegiert. Das gerasterte PDF bleibt als Hintergrund erhalten; erkannte variable Bereiche werden deterministisch mit einem weißen Asset maskiert und anschließend als `TEXT` oder `TEXTBOX` eingefügt. Der Nutzer prüft alle Vorschläge im Importdialog und muss die Übernahme ausdrücklich bestätigen. Das Paket wird dabei noch nicht gespeichert. Die serverseitige Klassifikation liegt in `ai-backend/pdf-template.php` und verwendet denselben Login-, Bearer-Token-, Guthaben- und Abrechnungsmechanismus wie die übrigen KI-Funktionen. Das Passwort wird vom eigenständigen Designer nicht gespeichert. Tabellen-/Chart-Erkennung und die automatische Rekonstruktion mehrseitiger Vorlagen sind bewusst nicht Teil von v1. ## Mehrseitiger Fließtext `TEXTBOX` bleibt ein absolut positionierter Bereich mit fester Höhe. Für Texte unbekannter Länge steht `FLOWBOX` mit derselben Syntax zur Verfügung: ```text PAGE 210 297 mm FLOWBOX 20 45 170 232 $Klassenbucheintraege size=11 ``` Der Inhalt wird innerhalb dieses Bereichs umbrochen und bei Bedarf auf beliebig vielen Seiten fortgesetzt. Pro Layout ist höchstens eine `FLOWBOX` zulässig. Das optionale Manifestfeld `continuationLayoutFile` verweist auf ein zweites Layout im Paket, das ab Seite 2 verwendet wird. Damit können Folgeseiten beispielsweise einen kleineren Briefkopf oder einen eigenen Hintergrund haben. Haupt- und Folgeseitenlayout müssen dieselbe Seitengröße besitzen; ihre `FLOWBOX` muss aus technischen Gründen dieselbe Position und Größe haben. Ohne Folgeseitenlayout werden die statischen Elemente der ersten Seite auf jeder erzeugten Seite wiederholt. ## Konstante Platzhalter und Hervorhebung Ein Platzhalter kann seinen Wert vollständig im Vorlagenpaket tragen. `IsConstant=true` bewirkt, dass `ConstantValue` beim Rendern immer verwendet wird; ein gleichnamiger Wert aus dem externen `ITemplateDataProvider` wird bewusst ignoriert. Damit eignen sich Konstanten besonders für lange Textbausteine in `TEXTBOX`, rechtliche Hinweise oder wiederkehrende Fußtexte. ```csharp new PlaceholderDefinition( "Datenschutzhinweis", PlaceholderType.Multiline, IsConstant: true, ConstantValue: "Dieser längere Text wird im Paket gespeichert.", Bold: true, Italic: false, Underline: false); ``` Konstante Werte werden für `Text`, `Multiline`, `Date` und `Number` unterstützt. Die Eigenschaften `Bold`, `Italic` und `Underline` wirken, wenn der Platzhalter direkt von einem `TEXT`- oder `TEXTBOX`-Element referenziert wird. In der Layout-DSL kann Unterstreichung außerdem direkt mit `underline=true` gesetzt werden. Konstante Text- und Multiline-Werte unterstützen zusätzlich abschnittsweise Hervorhebung und eingebettete externe Platzhalter: ```text Sehr geehrte Familie [b]${Student.LastName}[/b], bitte geben Sie die [u]unterschriebene Erklärung[/u] bis [i]Freitag[/i] zurück. ``` Unterstützt werden `[b]…[/b]`, `[i]…[/i]` und `[u]…[/u]`, auch verschachtelt. Die Klammerform `${Name}` ist in Fließtext vorzuziehen; `${Datum|dd.MM.yyyy}` erlaubt zusätzlich ein Format. Eingebettete Platzhalter müssen im Manifest als externe Platzhalter deklariert sein. Ihre gelieferten Werte werden immer als reiner Text behandelt und können deshalb kein Markup einschleusen. Mit `\[`, `\$` und `\\` lassen sich die Steuerzeichen wörtlich ausgeben. ## Freie Paketmetadaten Jedes neu gespeicherte `.lavorlage`-Paket enthält eine lesbare `metadata.txt`. Pro Zeile steht ein frei wählbares Schlüssel-Wert-Paar; leere Zeilen und mit `#` beginnende Kommentare werden beim Einlesen ignoriert: ```text language=de-DE report-type=parent-letter school-year=2026/27 ``` Werte dürfen ein weiteres `=` enthalten. Schlüssel sind ohne Beachtung der Groß-/Kleinschreibung eindeutig und Werte bleiben einzeilig. Der Loader stellt sie der Anwendung direkt über `loadedTemplate.Manifest.Metadata` zur Verfügung. Bestehende Pakete ohne `metadata.txt` werden weiterhin mit einer leeren Metadatensammlung geladen. Die empfohlenen Standardschlüssel stehen zusätzlich als `TemplateMetadataKeys.Language` und `TemplateMetadataKeys.ReportType` bereit. ## Bildskalierung `IMG` unterstützt neben dem festen Begrenzungsrahmen eine optionale prozentuale Skalierung: ```text IMG logo.png 15 15 30 12 scale=50% ``` Der Rahmen von `30 × 12` Layout-Einheiten wird dabei auf `15 × 6` skaliert. `x` und `y` bleiben unverändert. Das Bild wird mit erhaltenem Seitenverhältnis in diesen Rahmen eingepasst. Ohne `scale` gilt wie bisher `100%`. Zulässig sind Werte größer als `0` bis einschließlich `1000%`. ## Wiederverwendbare Ausgangsvorlagen Der TemplateDesigner verwaltet lokale Ausgangsvorlagen im Benutzerprofil. Eine Ausgangsvorlage ist weiterhin ein normales `.lavorlage`-Paket und kann deshalb importiert oder exportiert werden. - **Bearbeiten** öffnet die Ausgangsvorlage mit ihrer stabilen ID. Erneutes Speichern aktualisiert sie. - **Als neues Projekt** kopiert Layout, Platzhalter und sämtliche Assets, vergibt aber eine neue ID. - **Duplizieren** erzeugt eine weitere unabhängige Ausgangsvorlage. - **Vorschau** rendert die Vorlage mit typgerechten Beispieldaten, ohne das aktuelle Projekt zu ändern. Die Bibliothek liegt unter `LehrerApp/TemplateDesigner/starter-templates` im plattformspezifischen Anwendungsdatenverzeichnis und wird nicht in das LehrerApp-Repository oder Release eingebettet. ## Visueller Koordinateneditor Die QuestPDF-Vorschau dient gleichzeitig als maßstabsgetreue Zeichenfläche. Der Designer bildet das tatsächlich sichtbare Seitenrechteck unabhängig von Zoom und freien Rändern auf die `PAGE`- Koordinaten ab: ```text dslX = (mausX - seitenrandLinks) / angezeigteSeitenbreite * pageWidth dslY = (mausY - seitenrandOben) / angezeigteSeitenhöhe * pageHeight ``` Im Messmodus übernimmt ein Klick `x/y`; ein aufgezogener Bereich übernimmt zusätzlich Breite und Höhe ins Elementformular. Im Bearbeitungsmodus lassen sich vorhandene Elemente verschieben und - außer einzeiligem `TEXT` - am rechten unteren Anfasser skalieren. Rasterfang und Pfeiltasten sind für Feinkorrekturen verfügbar. Änderungen werden in die ursprüngliche DSL-Zeile zurückgeschrieben, wobei Inhalte, Platzhalter, Formatangaben und Attribute erhalten bleiben.