Digitales Produkt Landingpage - Konfigurationsanleitung

Konfigurationsanleitung

Zielgruppe: Backend-Administratoren (Backend)

Dieses Dokument beschreibt die Backend-Konfiguration des Moduls Digitales Produkt – Landingpage. Es richtet sich an Mitarbeiter, die im Backend Module für einen Shop aktivieren und konfigurieren.

Voraussetzungen

  • Das Modul DigitalProductPage muss dem Mandanten in der Modulverwaltung zugewiesen sein.

Schritt 1: Konfigurationsseite öffnen

Im Backend unter Add-Ons → Digitales Produkt – Landingpage öffnet sich die Modul-Konfiguration. Ganz oben befindet sich die Shop-Auswahl: die Konfiguration ist pro Shop, jeder Shop kann unterschiedliche Einstellungen haben.

Schritt 2: URL-Aufbau verstehen

Direkt nach dem Öffnen der Seite zeigt eine blaue Info-Box, wie eine fertige Landingpage-URL aussieht:

wide760/page/{prefix}/{name}]]>
  • {prefix} ist die öffentliche Benutzer-ID (siehe Schritt 4).

  • {name} ist der Name der Landingpage, wird vom Shop-Benutzer selbst gewählt.

Im unteren Bereich der Box wird ein Live-Beispiel mit den aktuell ausgewählten Einstellungen gerendert. Sobald in den Feldern unten etwas geändert wird, aktualisiert sich das Beispiel sofort – so kann vor dem Speichern geprüft werden, was die Einstellungen konkret bewirken.

Schritt 3: Modul für Shop aktivieren

Feld

Beschreibung

Modul für Shop aktivieren

Schaltet das Modul für den ausgewählten Shop ein. Erst danach erscheint im Shop der Verwaltungs-Menüpunkt für Shop-Benutzer und die öffentlichen Landingpage-URLs werden erreichbar.

Maximale Anzahl Landingpages pro Benutzer

Standard ist 1. Solange der Wert auf 1 steht, wird dem Shop-Benutzer im Frontend keine Mehrfach-Verwaltung angezeigt – er sieht nur seine eine Landingpage. Ab 2 erscheinen Anlegen-/Löschen-Schaltflächen. Hartes Limit: 10. Höhere Werte werden vom Server automatisch auf 10 reduziert, auch wenn das HTML-Limit umgangen wird.

Schritt 4: Prefix-Strategie wählen

Die wichtigste Entscheidung. Sie bestimmt, wie der {prefix} in der URL gebildet wird.

Option A: Automatisch generierte, nicht erratbare ID (Empfehlung)

Das System erzeugt für jeden Shop-Benutzer einmalig eine 26-stellige ULID. Diese ID:

  • ist garantiert eindeutig pro Shop,

  • ist nicht aus der internen Datenbank-ID ableitbar,

  • ist nicht enumerierbar (man kann nicht durch Hochzählen weitere Benutzer finden),

  • erfordert kein konfiguriertes Pflichtfeld am Benutzer.

Beispiel: /page/01HV2XKQP4MNRST8WQZJ6BYDE/pizzeria-venezia

Wann verwenden? Im Zweifelsfall immer. Sicher per Default.

Option B: Aus einem Benutzerfeld ableiten (opt-in)

Statt einer ULID wird der Wert eines Benutzerfelds (z.B. customer_user_kundennummer) URL-tauglich normalisiert und als Prefix benutzt. Vorteil: sprechender URL. Nachteile: erratbar (sequentielle Kundennummern!), kann doppelt vorkommen, kann leer sein.

Beispiel: /page/854121/pizzeria-venezia

Wann verwenden? Nur wenn der Kunde ausdrücklich wünscht, dass z.B. seine Kundennummer in der URL erscheint, und er das Enumerations-Risiko akzeptiert. In allen anderen Fällen Option A.

Wird Option B gewählt, erscheint zusätzlich das Feld „Benutzerfeld für die öffentliche Benutzer-ID" mit allen verfügbaren SSO-Benutzerfeldern zur Auswahl.

Schritt 5: Hinweis-Panel beachten

Sobald in Option B ein Feld ausgewählt wird, prüft das System sofort und live drei Dinge:

  1. Pflichtfeld? – Ist das gewählte Feld im Shop als Pflichtfeld konfiguriert? Wenn nicht, kann es Benutzer ohne ausgefüllten Wert geben → kein Prefix möglich.

  2. Eindeutig? – Gibt es im Shop bestehende Benutzer, bei denen dasselbe Feld doppelt vorkommt? Diese Benutzer würden sich denselben URL-Prefix teilen.

  3. Vollständig befüllt? – Gibt es Benutzer, bei denen das Feld leer ist? Diese bekommen noch keine Landingpage-URL.

Treffer werden über dem Formular in einem gelben Hinweis-Panel angezeigt – persistent, solange das Problem besteht. Der Hinweis bleibt auch nach Reload sichtbar; er verschwindet erst, wenn die Ursache behoben ist.

Wichtig: Das Panel zeigt den aktuellen Stand schon vor dem Speichern. Es reicht, das Feld auszuwählen – der Admin sieht sofort, ob die gewählte Konfiguration tragfähig ist.

Beispiel-Meldungen

wide760

Wo behebe ich das?

Meldung

Lösung

„nicht als Pflichtfeld konfiguriert"

Im Backend unter Shops → Bearbeiten → Benutzereinstellungen → Pflichteingaben für Benutzerfelder das entsprechende Feld auf „Pflicht (Ja)" stellen.

„doppelte Werte"

Über die Benutzersuche bzw. Export die Duplikate finden und bereinigen. Erst danach speichern.

„noch nicht befüllt"

Bestehende Benutzer dazu bringen, das Feld auszufüllen (z.B. erzwungenes Update beim nächsten Login).

Schritt 6: Vorschlag für den Landingpage-Namen

Optional: Über „Benutzerfeld als Vorschlag für den Landingpage-Namen" kann ein Feld ausgewählt werden, dessen Wert beim automatischen Anlegen einer Landingpage als initialer Name (Slug) vorgeschlagen wird.

Beispiel:

Einstellung

Wert

Vorschlagsfeld

customer_user_company1

Benutzer-Wert

Pizzeria Venezia GmbH

Generierter Slug

pizzeria-venezia-gmbh

Sonderzeichen, Leerzeichen und Großbuchstaben werden automatisch entfernt bzw. ersetzt. Der Shop-Benutzer kann den Slug danach jederzeit selbst ändern.

Wird kein Feld gewählt, muss der Benutzer den Namen beim ersten Aufruf der Verwaltung selbst eingeben.

Schritt 7: Wann wird eine Landingpage erzeugt?

Die Landingpage eines Shop-Benutzers wird bei Bedarf angelegt — es gibt keine separate Konfiguration mehr dafür. Auslöser sind:

  1. Erster Aufruf der Shop-Verwaltungsseite durch den Benutzer (über das Konto-Menü).

  2. Erster Aufruf des Printess-Editors für einen Artikel mit konfigurierter Printess-Feld-Zuordnung (siehe Schritt 9 unten) — die Landingpage muss vorhanden sein, damit ihre URL und ihr Name ins Personalisierungs-Formular fließen können. Greift sowohl beim normalen Editor-Aufruf als auch beim Re-Editieren einer freigegebenen Bestellung, solange das Order-Item noch nicht personalisiert wurde.

Vorteile dieses Ansatzes: keine „leeren" Landingpages für Benutzer, die das Modul nie nutzen; kein nachträglicher Backfill nötig; keine Race-Conditions mit SSO-Pflichtfeldern, die erst beim ersten Login befüllt werden.

Schritt 8: Speichern

Beim Speichern passieren mehrere Dinge:

  1. Die Einstellungen werden in customer_settings.value als JSON unter dem Schlüssel digitalProductPageModule abgelegt.

  2. Der Cache für die Sichtbarkeit des Shop-Menüpunkts wird invalidiert (<clientId>_digitalProductPageAdminMenuEnabled_<shopId>).

  3. Die Validierung läuft erneut. Treten Hinweise auf, werden sie doppelt ausgegeben:

    • als gelbes Toastr unten rechts (kann manuell weggeklickt werden),

    • als Eintrag im Notification-Center,

  4. Das Hinweis-Panel über dem Formular aktualisiert sich automatisch — wenn ein Problem gerade behoben wurde, verschwindet es; ein neues bleibt sichtbar.

Nightly Validierungs-Cronjob

Auch nach dem Speichern können neue Probleme entstehen — zum Beispiel:

  • Ein neuer Benutzer wird per SSO angelegt, das Pflichtfeld wird vom Identity-Provider nicht mitgeliefert.

  • Ein Import erzeugt zwei Benutzer mit derselben Kundennummer.

  • Der Admin entfernt versehentlich das Pflichtfeld-Flag im Shop.

Damit das nicht unbemerkt bleibt, läuft jeden Tag um 04:00 Uhr ein Cronjob.

Der Cronjob:

  1. liest alle Shops mit gespeicherten DigitalProductPage-Einstellungen,

  2. filtert auf aktive Module,

  3. ruft pro Shop dieselbe validatePrefixField()-Logik wie das Backend-Form,

  4. legt bei Treffern eine Notification (Glocke) an und benachrichtigt den technischen Ansprechpartner per Mail.

So gibt es drei aufeinanderfolgende Stufen:

Wann

Wo sichtbar

Persistenz

Beim Tippen im Form

Hinweis-Panel

Solange das Problem besteht

Beim Speichern

Toast + Notification + Mail

Bis manuell weggeklickt / archiviert

Nightly Cron

Notification + Mail

Bis behoben

Printess-Feld-Zuordnung pro Artikel

Damit aus der Personalisierung ein Landingpage-Name, ein Tab-Name und optional ein Header-Medium wird, können am Artikel vier Printess-Formularfelder zugeordnet werden. Im Backend unter Artikel → Bearbeiten → Tab „Grundeinstellungen" erscheint der Block „Digital-Landingpage: Printess-Feld-Zuordnung" sobald für den Mandanten DigitalProductPage und Printess beide aktiv sind und im Artikel ein Printess-Template ausgewählt wurde.

Die vier Felder

Setting

Inhalt im Editor

Verwendung

Printess-Feld für die Landingpage-URL

Wird beim Öffnen mit <https://<shop>>/page/{öffentliche Benutzer-ID}/ vorbefüllt. Im Printess-Template als nicht editierbar konfigurieren.

Reine Anzeige für den Benutzer; verändert nichts.

Printess-Feld für den Landingpage-Namen

Editierbar. Beim Öffnen mit dem aktuellen Namen (Slug) der (ggf. neu angelegten) Default-Landingpage vorbefüllt.

Wird beim erstellter Bestellung (nach Freigaben) ausgelesen: weicht der Wert vom aktuellen Namen (Slug) ab, wird die Landingpage automatisch umbenannt (alter Slug wird zur Historie und löst eine Weiterleitung aus). Bei Slug-Kollision (Name bereits vergeben oder in fremder Historie reserviert) wird der Rename übersprungen und ein Warnung geloggt.

Printess-Feld für den Tab-Namen

Editierbar. Beim Öffnen leer.

Wird beim erstellter Bestellung (nach Freigaben) als neuer Tab unterhalb der Landingpage angelegt. Bei Nachbestellungen wird der alte Tab per Soft-Delete abgelöst und ein neuer Tab mit dem aktuellen Inhalt erstellt. Bei Slug-Kollision mit einem bestehenden Tab bekommt der neue Tab ein Datums-Suffix (z.B. mittag-new-2026-04-15-143200) — der Shop-Benutzer kann den alten Tab anschließend in der Verwaltung per Ein-Klick-Aktion ersetzen.

Printess-Feld für das Header-Medium

Editierbar. Beim Öffnen leer. Typischerweise ein Freitext-Feld, das im Printess-Template an einen Bild- oder Video-Picker gekoppelt ist.

Wird beim erstellter Bestellung (nach Freigaben) ausgelesen: der zurückgegebene URL-Wert wird per HEAD-Request auf image/* oder video/* geprüft und auf der Landingpage als Banner des zu diesem Bestellposition gehörenden Tabs angezeigt — überschreibt Artikel- und Shop-Defaults. Siehe Abschnitt Header-Medien konfigurieren.

Welche Printess-Felder erscheinen in der Auswahl?

Es werden nur Freitext-Formularfelder des aktuell ausgewählten Templates angeboten. Listen-Felder werden ausgeblendet, weil sie nur fest vordefinierte Werte akzeptieren und sich daher nicht für einen individuellen Namen oder eine URL eignen. Eine Info-Box oberhalb der Auswahl zeigt, wie viele Felder ausgeblendet wurden (z.B. „12 von 232 Feldern nutzbar · 220 Listen-Felder ausgeblendet").

Die Form-Felder werden von Printess abgefragt und 5 Minuten pro Shop-Template gecached. Der Cache-Status (frisch / stale / API nicht erreichbar) wird unterhalb der Selects als kleiner Hinweis angezeigt; bei totalem API-Ausfall ohne Cache fällt die Auswahl auf reine Texteingabe-Felder zurück, damit die Bearbeitung nicht blockiert.

Was passiert beim Öffnen des Editors?

  1. Modul aktiv für den Mandanten + Modul aktiv für den Shop + mindestens eines der drei Felder gemappt? Sonst passiert nichts.

  2. Hat der Shop-Benutzer noch keine Landingpage? → eine neue wird lazy angelegt (gleicher Pfad wie beim ersten Aufruf der Shop-Verwaltungsseite).

  3. Wenn es mehr als eine Landingpage gibt, wird die als Standard markierte ausgewählt.

  4. URL <https://<shop>>/page/{prefix}/ und der Name (Slug) der Landingpage werden als Initialwerte in templateFormFields an Printess übergeben.

Greift sowohl beim normalen Editor-Aufruf als auch beim Re-Editieren einer freigegebenen Bestellung, solange die Bestellposition noch nicht personalisiert wurde. Bei bereits personalisierten Bestellpositionen (Cart-Edit, Reorder, Save-Token-Load, Übernahme aus anderer Position) wird nicht überschrieben — der Kunde behält den von ihm zuvor gewählten Namen (Slug).

Koexistenz mit dem alten DigitalProduct

Wenn am selben Mandanten zusätzlich DigitalProduct aktiv ist, erscheint dessen alter Block oberhalb der DigitalProductPage-Sektion. Beide funktionieren unabhängig voneinander — pro Artikel wird typischerweise nur eines der beiden Module genutzt, die UI erzwingt das aber nicht.

Header-Medien konfigurieren

Das Hero-Medium im Block dpp-banner der öffentlichen Landingpage kann in drei Stufen gepflegt werden. Die effektive Konfiguration wird pro Tab live ermittelt — es gibt keine Persistierung auf Landing-Ebene, Änderungen an Shop- oder Artikel-Defaults wirken sofort auf alle Tabs, die keinen eigenen Printess-Return haben.

Auflösungsreihenfolge

Stufe

Wo gepflegt

Wann wirkt sie?

1. Shop-Default

Modul-Konfigurationsseite (addon/DigitalProductPage/config)

Fallback für alle Tabs dieses Shops

2. Artikel-Override

Artikel → Tab „Grundeinstellungen" → Block „Digital-Landingpage"

Für Tabs, deren Order-Item zu diesem Artikel gehört

3. Printess-Return

Im Printess-Editor über das im Artikel zugeordnete „Header-Medium"-Feld

Medientyp-Erkennung beim Speichern

Beim Speichern einer URL läuft genau einmal ein HEAD-Request mit folgenden Regeln:

Prüfung

Verhalten bei Verletzung

Nur <https://>

Abbruch mit Reason-Code insecureScheme

Host nicht in RFC-1918/Loopback/Link-Local (via DNS-Resolution auf 10/8, 172.16/12, 192.168/16, 100.64/10, 127/8, 169.254/16, ::1, fc00::/7, fe80::/10)

Reason blockedHost — SSRF-Schutz

Content-Type in Whitelist: image/jpeg, image/pjpeg, image/png, image/webp, image/avif, image/gif, video/mp4, video/webm, video/ogg

Reason unsupportedMime + Fallback auf Extension-Parse; scheitert auch das → Reason typeUnknown

HEAD-Request erreichbar (Timeout 5 s, max. 3 Redirects)

Bei Netzwerkfehler → Fallback auf Extension-Parse, sonst Reason unreachable

Fehlerausgabe:

  • Shop-Default (Modul-Konfigurationsseite): Nach dem Speichern läuft die Prüfung. Gelingt die Typ-Erkennung nicht, wird die Type-Spalte zurückgesetzt als Toast (über den Standard-Notices-Pfad) ausgegeben. Die URL bleibt gespeichert, damit der Admin sie korrigieren kann.

  • Artikel-Override: Der Save-Handler ruft die Prüfung inline auf. Bei Fehler wird die URL nicht gespeichert, ein Flash-Error-Eintrag mit der gleichen Übersetzung gesetzt.

  • Printess-Return: Fehler werden protokolliert. Das Feld bleibt ungesetzt — der Tab fällt auf Artikel/Shop zurück.

Vorschau / Rendering-Verhalten

Bedingung

Rendering

Aufgelöstes Medium mit type = image

<img src="…" fetchpriority="high" alt="…">. Für den initialen Tab wird im Head ein <link rel="preload" as="image" fetchpriority="high" …> gesetzt (Block dpp-meta-preload in base.tpl).

Aufgelöstes Medium mit type = video

<video autoplay muted loop playsinline preload="metadata" fetchpriority="high" poster="…"><source src="…"></video>. Kein <link rel="preload"> für Videos (Mobile-Datenvolumen).

Keine URL auf keiner Stufe

.dpp-banner bekommt Zusatz-Klasse dpp-banner--emptymax-height: 0 + opacity: 0 + aspect-ratio: auto → keine sichtbare Fläche, kein Layout-Shift.

Tab-Wechsel

Ersetzt <img>/<video> im data-dpp-banner-Container. Wird wieder eingeblendet, wenn sich die URL ändert.

Historie-Verhalten bei Slug-/Tab-Rename

Beim Umbenennen oder Löschen einer Landingpage bzw. eines Tabs wird der bisherige Slug immer in die zugehörige History geschrieben — unabhängig davon, ob der alte Slug jemals oeffentlich aufgerufen wurde.

Hintergrund: Eine neu angelegte Landing kann durchaus per QR-Code gedruckt werden, bevor der erste Scan passiert.

Aufräumen: Der Shop-Benutzer sieht in seiner Landingpage-Verwaltung die vollständige History inklusive Einträgen mit Zugriffszahlen und kann sie per „Freigeben"-Aktion löschen, sobald er sich sicher ist, dass keine alten QR-Codes mehr im Umlauf sind. In der Shop-UI erscheinen Null-Aufruf-Einträge mit dem Vermerk „noch nie aufgerufen" als Hilfestellung.

Relevanz für den Admin: Diese Änderung ist transparent — es gibt keine Konfigurationsoption, kein Migration-Skript und keine UI-Option. Das reine Verhalten der Release-Pipeline (beim Rename im Printess-Editor) und der Shop-Verwaltung (beim manuellen Rename) ist jetzt konsistent „immer mit History".

QR-Code-Landingpage-Auswahl im Artikel

Für Artikel, die einzig einen QR-Code auf eine bereits bestehende Landingpage drucken sollen (z.B. Visitenkarten, Flyer, Tischaufsteller), gibt es eine zusätzliche Printess-Feld-Zuordnung im Artikel — unabhängig von den oben beschriebenen vier Settings.

Wo konfigurieren?

Gleiche Stelle wie die Printess-Feld-Zuordnung: Artikel → Bearbeiten → Tab „Grundeinstellungen". Ganz unten im DPP-Block erscheint der neue Abschnitt „QR-Code: Landingpage-Auswahl" mit einem einzigen Dropdown:

Setting

Inhalt im Editor

Printess-Listenfeld für QR-URL

Wird beim Öffnen des Editors dynamisch mit allen aktiven Landing + Tab-URLs des angemeldeten Shop-Benutzers befüllt. Der Endkunde wählt eine Adresse, diese wird als Wert des Listenfelds gesetzt und vom Printess-Template als QR-Code gerendert.

Listenfeld-Filter

Dieses Dropdown bietet genau das Gegenteil der anderen DPP-Settings an: nur Printess-Listenfelder (Select-List, Tab-List, Image-List, Color-List o.ä.) sind auswählbar — Freitext-Felder sind ausgegraut mit Suffix „Freitext – nicht kompatibel". Grund: die Liste wird zur Laufzeit mit Werten befüllt; ein Freitext-Feld kann keine Dropdown-Werte aufnehmen.

Die Template-Daten kommen aus denselben Daten wie die obigen vier Felder — der Cache-Hinweis „Liste aus dem Cache, vor X abgerufen, läuft in Y ab" erscheint deshalb auch unter diesem Block.

Scope: Entkoppelt von der Landing-Personalisierung

Das QR-Setting ist bewusst unabhängig vom digitalProductPageSlugFormFieldName-Mechanismus:

  • Ein Artikel kann das QR-Feld gesetzt haben ohne eine der Prefix/Slug/SubSlug-Zuordnungen — dann triggert er keine Release-Pipeline, keine Slug-Renames, keine Tab-Creates, keine Tagged-PDFs.

  • Ein Artikel kann umgekehrt die vier Personalisierungs-Felder gesetzt haben ohne das QR-Feld — dann gibt es keinen Dropdown im Editor.

  • Beide gleichzeitig ist erlaubt, bleibt aber selten sinnvoll (Artikel, der gleichzeitig eine neue Landing per Release erzeugt und eine bestehende Landing als QR-Ziel anbietet).

Was passiert beim Öffnen des Editors?

  1. Modul aktiv für den Mandanten? Wenn nein → Hook passiert nichts.

  2. Artikel-Setting gesetzt? Wenn nein → Hook passiert nichts.

  3. Ansonsten:

    • Lazy-Create einer Default-Landing + URL-Prefix, falls der Shop-Benutzer noch keine hat (gleicher Pfad wie beim normalen DPP-Editor-Open).

    • Alle aktiven Landings + Tabs werden als {key: URL, label, meta1: URL}-Einträge gelistet. Sortierung: erst Landing-Hauptseite, dann deren Tabs in sortOrder.

    • Labels: Landing-Title (Fallback Slug); Tabs als „<Landing-Title> – <Tab-Title>".

  4. Dieser Listen-Eintrag wird dem Printess-Editor-Payload unter formFieldProperties[] angehängt.

  5. Zusätzlich wird der erste Listeneintrag als templateFormFields[]-Default gesetzt — das Dropdown ist beim ersten Editor-Öffnen also nicht leer.

Beim Re-Editieren einer bereits personalisierten Bestellung (Cart-Edit, Reorder) wird der vom Kunden zuvor gewählte Wert aus den Bestellinformationen gelesen — er behält seine Auswahl.

Dieser Eintrag erweitert die Tabelle in der Header-Medien-Section oben um einen neunten möglichen Eintrag; pro Artikel sind also bis zu neun DPP-Settings kombinierbar.

Zentraler URL-Builder

Alle Server-seitigen /page/...-URL-Emissionen laufen ueber eine zentrale Funktion:

  • ROUTE_BASE = 'page' (ohne führenden Slash — für Laravel-Route-Registration)

  • URL_PREFIX = '/page' (mit führendem Slash — für URL-Bau)

  • PDF_SEGMENT = 'pdf'

  • Statische Methoden: landingPath(), tabPath(), pdfPath(), publicUserRootUrl()

Falls das URL-Layout jemals geändert werden muss (z.B. /p/ statt /page/), genügt eine Anpassung in dieser Klasse — die Route-Definition, die Redirects. Nicht mitgezogen werden die JS-seitigen Vorschau-URLs dort muss bei einer Änderung manuell synchronisiert werden.

Release-Pipeline (Bestellabschluss)

Wenn eine Bestellposition (OrderItem) freigegeben wird, prüft der Listener, ob das Modul für den Mandanten aktiv ist und ob der Artikel eine Printess-Feld-Zuordnung hat. Falls ja, delegiert er an den Handler, der folgende Schritte ausführt:

  1. Landingpage sicherstellen — Falls der Shop-Benutzer noch keine Landingpage hat, wird sie lazy angelegt (gleicher Pfad wie beim ersten Aufruf der Shop-Verwaltungsseite).

  2. Slug-Rename — Der im Printess-Formular eingegebene Landingpage-Name wird mit dem aktuellen Slug der Default-Landingpage verglichen. Weicht er ab, wird dieser umbeannt (alter Slug → Historie → 301-Redirect).

  3. Tab-Erstellung — Der Tab-Name aus dem Printess-Formular wird als neuer Tab angelegt und mit der Bestellposition verknüpft.

  4. Nachbestellungs-Handling — Ist das Feld für eine Nachbestellung gesetzt und existiert eine aktive Verknüpfung für die Ursprungsposition, wird der alte Tab per Soft-Delete in den Papierkorb verschoben und ein neuer Tab wird angelegt.

  5. Kollisions-Suffix — Existiert bereits ein aktiver Tab mit demselben Slug, erzeugt den Tab mit einem -new-{Y-m-d-His}-Suffix. Der Shop-Benutzer sieht in der Verwaltung einen „Neuer Tab wartet"-Hinweis.

  6. Header-Medium auflösen — Ist im Artikel das Setting gesetzt, wird dessen Wert aus dem Printess-Formular gelesen, per HEAD-Request auf image/* / video/* geprüft und als {url, type}-JSON unter Bestellinformationen persistiert. Bei Detection-Fehler:Logging + Skip (Tab fällt auf Artikel-Override / Shop-Default zurück).

  7. Tagged-PDF-Job — Der Printess Job für die Screen-Version setzt taggedPdf=true, sodass die resultierende PDF ohne Ghostscript-Optimierung gespeichert wird (Tag-Struktur bleibt erhalten).

Screen-Version-PDF

Die PDF wird gespeichert. Im Gegensatz zu normalen Printess-Screen-Versionen wird keine Ghostscript-Optimierung angewendet, weil GS die PDF-Tag-Struktur (H/H1-Elemente) zerstören würde.

PrintDataController-Regenerate

Die Nachträgliche Druckdatengenerierung (Screen) unterstützt jetzt auch DPP-Artikel. Wenn kein DigitalProduct-Eintrag existiert, wird geprüft, ob eine Verknüpfung für die Bestellposition vorhanden ist, und die Screen-Version über den DPP-Pfad neu erzeugt.

Offene Punkte

  • Storno-Handling: Es existiert kein dediziertes OrderItem-Cancel-Event. Wenn eine Bestellung storniert wird, bleibt die Tab↔OrderItem-Verknüpfung bestehen.

  • Verwaiste PDFs: Ein Cron zum Aufräumen von PDFs, deren Tab gelöscht wurde, ist noch nicht implementiert.

Häufige Fragen

Wo finde ich die Modulseite?

Backend → Add-Ons → Liste der Module → Digitales Produkt – Landingpage.

Warum sehe ich die Hinweise nach dem Speichern als Toast nur kurz?

Toasts sind für transiente Quittungen gedacht. Der eigentliche persistente Indikator ist das gelbe Panel oben im Formular. Solange dort etwas steht, gibt es ein Problem; ist das Panel leer, ist alles in Ordnung.

Wo bekomme ich die Mail-Benachrichtigungen hin?

An die im Shop hinterlegte Adresse unter Shops → Bearbeiten → Technischer Ansprechpartner. Ist dort nichts hinterlegt, wird nur die Notification (Glocke) erzeugt, keine Mail verschickt.

Kann ich die ULID nachträglich gegen ein Benutzerfeld tauschen?

Technisch ja: die Prefix-Strategie umstellen und speichern. Bereits vergebene öffentliche IDs bleiben dabei aber erhalten – bestehende QR-Codes mit ULID-URLs funktionieren weiter, nur neue Benutzer bekommen den Wert aus dem Feld. Wenn alle Benutzer komplett auf die Feld-Variante umgestellt werden sollen, ist das eine manuelle Datenbank-Aktion — bitte beim PrintLounge-Support anfragen.

Gibt es ein Rate Limit auf den öffentlichen Landingpage-URLs?

Ja. Jede IP-Adresse darf maximal 45 Aufrufe pro Minute gegen die öffentlichen Landingpage-URLs machen; darüber hinaus antwortet der Server mit HTTP 429 Too Many Requests. Das Limit ist als Infrastruktur-Schutz fest eingebaut und nicht pro Shop konfigurierbar. Überschreitungen werden intern protokolliert, sodass auffällige IPs im Missbrauchsfall nachvollziehbar sind. Legitime Shop-Benutzer, die eine Landingpage öffnen und zwischen Tabs wechseln, bleiben weit unter dem Limit.

Was passiert, wenn ein Shop-Benutzer einen Tab löscht?

Der Tab wird nicht physisch gelöscht, sondern in den Papierkorb verschoben. Der bisherige Name wird intern mit einem Datums-Zusatz versehen, damit der Original-Name sofort wieder für einen neuen Tab verwendet werden kann (z.B. für eine neue Mittagskarte aus einer neuen Bestellung). Der Tab inklusive Aufrufzähler und alten Namen bleibt erhalten und kann jederzeit aus dem Papierkorb wiederhergestellt werden — beim Wiederherstellen versucht das System, den Original-Namen zurückzusetzen (klappt nur, wenn er aktuell frei ist; sonst bleibt der Zusatz, und der Benutzer benennt manuell um).

Ein endgültiges Löschen aus der Datenbank gibt es im Shop-UI nicht. Bei Bedarf ist das eine manuelle Support-Aktion.

Warum dauert die Template-Auswahl im Artikel-Editor manchmal etwas länger zu aktualisieren?

Im Backend unter Artikel bearbeiten → Printess Editor ist die Template-Auswahl 5 Minuten pro Shop zwischengespeichert. Unterhalb der Auswahl steht ein kleiner Hinweis wie „Template-Liste aus dem Cache — vor 2 Minuten abgerufen, läuft in 3 Minuten ab". Wer ein neu in Printess angelegtes Template sofort sehen will, muss also bis zu 5 Minuten warten.

Falls Printess gerade nicht erreichbar ist (z.B. auf dem Test-System ohne Outbound-Verbindung), zeigt der Hinweis stattdessen orange „Printess aktuell nicht erreichbar — Liste aus zwischengespeichertem Stand von …" und greift auf einen 7-Tage-Stale-Cache zurück, damit die Bearbeitungsmaske weiter funktioniert.

Ist das Modul kompatibel mit dem alten DigitalProduct?

Ja, beide Module sind unabhängig. Das alte DigitalProduct legt pro Bestellung eine Landingpage an, das neue DigitalProductPage arbeitet pro Benutzer. Beide können parallel aktiv sein.

Wie bekomme ich ein Banner auf die Landingpage?

In der Modul-Konfigurationsseite unter Add-Ons → Digitales Produkt – Landingpage gibt es den Abschnitt „Header-Medium (Shop-Default)" mit den Feldern „Medien-URL", „Poster-Bild" und „Alt-Text". Eine HTTPS-URL auf ein Bild oder Video dort eintragen und speichern — der Server erkennt den Medientyp automatisch und speichert das Ergebnis. Ab dann sehen alle Landingpages des Shops das Banner, solange kein Artikel- oder Printess-Override greift.

Wer nur für einzelne Artikel ein anderes Banner möchte, trägt die URL im Artikel (Tab „Grundeinstellungen") im Abschnitt „Header-Medium (Artikel-Override)" ein. Wer das Endkunden-gewählte Medium aus dem Printess-Editor übernehmen will, mappt im selben Block das Feld „Printess-Feld für das Header-Medium" auf ein dafür vorgesehenes Printess-Formularfeld.

Die Header-Medien-URL wird als „nicht erreichbar" abgewiesen, obwohl sie im Browser lädt. Warum?

Drei häufige Ursachen:

  1. Schema ist <http://> statt <https://> — das Modul akzeptiert nur HTTPS-URLs (SSRF-Härtung). Auf HTTPS wechseln und speichern.

  2. Host zeigt auf ein internes Netzwerk — die Adresse verweist auf einen nicht-öffentlichen Bereich (Loopback, internes Netz). Als Schutz gegen SSRF wird das abgelehnt; ein öffentlich erreichbarer CDN-Host muss verwendet werden.

  3. Medientyp nicht erkannt — nur gängige Bild- (JPEG, PNG, WebP, AVIF, GIF) und Video-Formate (MP4, WebM, OGG) werden akzeptiert. Generische Server-Antworten ohne passenden Content-Type werden abgewiesen; als Fallback wird die Dateiendung der URL ausgewertet.

Die konkrete Fehlerursache steht im Toast nach dem Speichern.

Was passiert, wenn die Header-Medien-URL später nicht mehr erreichbar ist?

Nichts — das Modul prüft die URL nur beim Speichern bzw. beim Bestellabschluss. Danach wird die URL nur noch im HTML ausgegeben und der Browser lädt das Bild oder Video direkt vom externen Host. Ist der Host später offline, zeigt der Browser ein defektes Bild oder lädt das Video nicht — die Landingpage selbst bleibt voll funktionsfähig. Wer das proaktiv vermeiden will, hostet die Medien in einem garantiert verfügbaren CDN.

Wie konfiguriere ich einen reinen QR-Code-Artikel?

Ein Artikel, der nur einen QR-Code auf eine bestehende Landingpage druckt (z.B. Visitenkarte, Flyer), braucht keine der vier Personalisierungs-Zuordnungen — nur das neue QR-Code-Listenfeld:

  1. Im Printess-Template des Artikels ein Listenfeld anlegen, das den QR-Code-Wert aufnimmt. Der Wert des Feldes wird vom Template als QR-Code gerendert.

  2. Im Backend unter Artikel → Bearbeiten → Tab „Grundeinstellungen" ganz unten den Abschnitt „QR-Code: Landingpage-Auswahl" öffnen.

  3. Das dort vorhandene Dropdown listet alle Listenfelder des Templates — das vorbereitete Listenfeld auswählen und Artikel speichern.

Beim Öffnen des Editors bekommt der Endkunde automatisch ein Dropdown mit allen seinen Landing- und Tab-URLs und wählt die gewünschte. Die Felder für Prefix, Landingpage-Name, Tab-Name und Header-Medium bleiben leer — der Artikel selbst ist nicht Teil der Landing-Personalisierung.

Warum erscheint das Dropdown im Editor leer, obwohl der Shop-Benutzer bereits Landingpages hat?

Drei Ursachen sind möglich:

  1. Modul nicht aktiv für den Mandanten — in der Modul-Konfiguration prüfen.

  2. QR-Code-Listenfeld im Artikel nicht gesetzt — im Artikel-Edit muss im Abschnitt „QR-Code: Landingpage-Auswahl" ein Printess-Listenfeld ausgewählt sein, das im Template existiert.

  3. Alle Landingpages inaktiv oder gelöscht — nur aktive Landingpages und aktive Tabs werden angeboten; inaktive oder im Papierkorb liegende Elemente erscheinen nicht.

Bei einem neuen Shop-Benutzer ohne bestehende Landingpage wird beim ersten Editor-Öffnen automatisch eine Default-Landingpage angelegt. Die Liste zeigt dann einen einzigen Eintrag „Hauptseite".

Alte QR-Codes funktionieren nach Umbenennung nicht mehr — wie prüfe ich, ob die Historie aktiv ist?

Beim Umbenennen oder Löschen einer Landingpage bzw. eines Tabs wird der bisherige Name immer in die Historie übernommen — auch wenn die alte Adresse nie aufgerufen wurde. Der Shop-Benutzer sieht in seiner Landingpage-Verwaltung die vollständige Historie und kann dort Einträge per „Freigeben"-Aktion entfernen. Wenn alte QR-Codes nicht mehr funktionieren, fehlt der zugehörige Historien-Eintrag — entweder wurde die Landing nie umbenannt, oder der Eintrag wurde vom Shop-Benutzer bereits freigegeben.

Ein Printess-Formularfeld fehlt in der Auswahl „Digital-Landingpage: Printess-Feld-Zuordnung" — warum?

Im Auswahlmenü für Landingpage-URL, Landingpage-Name und Tab-Name werden nur Freitext-Formularfelder des Printess-Templates angeboten. Alle anderen Feldtypen (Listenfelder, Checkboxen usw.) werden ausgeblendet, weil sie nur fest vordefinierte Werte akzeptieren und sich daher nicht für einen individuellen Namen oder eine URL eignen. Oberhalb der Auswahl zeigt eine Info-Box, wie viele Felder ausgeblendet wurden.

Ausschlaggebend ist die im Printess-Editor gewählte Feld-Art. Nur als Textbox oder mehrzeiliges Textfeld markierte Felder werden zur Auswahl angeboten. Falls ein Feld trotz Textbox-Konfiguration nicht erscheint, im Printess-Editor speichern und veröffentlichen; die Auswahl aktualisiert sich nach spätestens 5 Minuten (oder im Backend das Template einmal aus- und wieder auswählen).