{{= $myProduct.description }}
``` Die Template Engine interpretiert diese Platzhalter und ersetzt sie zur Laufzeit mit den entsprechenden Werten aus dem System. ### Standard-Escaping Die WEBSALE Template-Engine verfügt über ein integriertes Standard-Escaping, das automatisch auf alle dynamisch eingebundenen Inhalte angewendet wird. Dadurch wird sichergestellt, dass HTML- oder JavaScript-Code, der z. B. in Produktdaten oder CMS-Inhalten enthalten ist, nicht interpretiert, sondern als Klartext dargestellt wird. Viele Inhalte im Shop – z. B. Produktbeschreibungen, CMS-Artikel oder andere redaktionelle Texte – enthalten HTML zur Formatierung. Damit diese Inhalte nicht unbeabsichtigt als echter HTML-Code ausgeführt werden, wird bei der Ausgabe mit `{{= ... }}` ein automatisches Escaping angewendet. **Beispiel: Standard-Escaping aktiviert** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{= $product.description }} ``` **Inhalt in den Shopdaten:** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}Super atmungsaktiv – ideal für Sport und Freizeit. Jetzt in der neuesten Generation erhältlich.
``` **Ausgabe im Browser:** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} <p><strong>Super atmungsaktiv</strong> – ideal für Sport und Freizeit. Jetzt in der <em>neuesten Generation</em> erhältlich.</p> ``` Der HTML-Code wird **nicht interpretiert**, sondern als normaler Text angezeigt. Das schützt vor unbeabsichtigter Codeausführung. Wenn Inhalte bewusst als HTML ausgegeben werden sollen – z. B. weil Produkttexte oder CMS-Inhalte HTML enthalten und korrekt gerendert werden sollen – kann das Escaping gezielt deaktiviert werden. Dazu wird statt `=` ein Ausrufezeichen `!` verwendet: ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{! $product.description }} ``` **Ausgabe im Browser:** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}Super atmungsaktiv – ideal für Sport und Freizeit. Jetzt in der neuesten Generation erhältlich.
``` Jetzt wird der HTML-Code korrekt interpretiert und gerendert. **Wichtig:** Die Deaktivierung des Escapings sollte nur bei vertrauenswürdigen Inhalten erfolgen – z. B. bei Daten aus dem eigenen Produkt-Backend oder CMS. Inhalte, die z. B. über Formulareingaben von Kunden stammen, sollten nicht ungefiltert ohne Escaping ausgegeben werden. *** ## Variablen Mit der WEBSALE Template-Sprache können die Daten ausgegeben werden, die vom Shopsystem bereitgestellt werden. Jede Seite, die von der Template Engine gerendert wird, erhält so die benötigten Daten, um die angeforderten Inhalte anzuzeigen. Diese Daten werden in sogenannten Template-Variablen gespeichert. Alle Template-Variablen können über die Template-Sprache mit einem `$` gefolgt vom Variablennamen aufgerufen werden. Variablennamen können frei vergeben werden. Es gibt auch System-Variablen, die mit `$ws` beginnen und deren Namen vorgeben sind, z.B. `$wsProduct`, `$wsCategory` etc. Eine vollständige Übersicht der WEBSALE System-Variablen und mehr Informationen zu den Variablen allgemein finden Sie [hier](/frontend/referenz/variablen). ### Variablen setzen & verwenden **Beispiel: Neue Variable** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{ var $myProduct = $wsProduct.load('1234') }} ``` Neue Variablen werden immer mit dem **var-Keyword** definiert. In diesem Beispiel lädt die Funktion `$wsProduct.load('1234')` die Produktdaten des Produkts mit der Artikelnummer `1234`. Diese werden in der Variable `$myProduct` gespeichert und können später verwendet werden. **Beispiel: Verwendung der Variablen** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{ var $myProduct = $wsProduct.load('1234') }}{{= $myProduct.description }}
Preis: {{= $myProduct.price }} €
``` Einmal definierte Variablen können an beliebigen Stellen im Template genutzt werden. In diesem Fall: * Die Produktdaten werden in `$myProduct` gespeichert. * Der Produktname, die Beschreibung und der Preis werden dynamisch in das Template eingefügt. **Beispiel: Verschachtelte Variable** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{ var $myProduct = $wsProduct.load('1234') }}Diese Kategorie ist aktiv.
{{ /if }} ``` Variablen, die innerhalb von Bereichsanweisungen definiert werden, existieren nur innerhalb dieses Bereichs: ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{ foreach $myProduct in $wsCategory.loadProducts('5678') }}{{= $myProduct.price }} €
{{ /foreach }}{{= $myProduct.name }}
-> $myProduct ist außerhalb der Schleife nicht gültig ``` *** ## Modifiers (Modifikatoren) Manchmal reicht es nicht aus, den Inhalt einer Variable einfach nur auszugeben – der Wert muss vorher verändern oder angepasst werden. Genau dafür gibt es die **Modifiers**. **Modifiers** können auf alle Variablen angewendet werden, um deren Inhalt zu verändern. Dazu hängen sie einfach ein `|` (Pipe-Zeichen) und den Modifiernamen an die entsprechende Variable an. Zusätzliche Parameter werden mit `:` hinzugefügt. **Beispiel: Kürzen der Produktbeschreibung** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{= $myProduct.description|truncate:120 }} ``` In diesem Beispiel wird der Modifikator `truncate` auf die Produktbeschreibung angewendet. Dieser kürzt den Text auf eine maximale Länge von 120 Zeichen. **Beispiele: Mehrere Modifikatoren auf eine Variable anwenden** Sie können auch mehrere Modifikatoren hintereinander auf eine Variable anwenden. Diese werden in der Reihenfolge verarbeitet, in der sie angegeben werden. Eine vollständige Liste aller Modifiers sowie deren Beschreibung finden Sie in der [Übersicht der Modifikatoren.](/frontend/referenz/modifiers) *** ## Bedingungen (Conditions) Die WEBSALE `{if}`-Bedingungen erlauben die selbe Flexibilität wie in PHP oder Javascript, bis auf ein paar Erweiterungen für die Template-Engine. Jedes `{if}` muss mit einem `{/if}` kombiniert sein. `{else}` und `{elseif}` sind ebenfalls erlaubt. Alle gängigen PHP Vergleichsoperatoren und Funktionen, wie `||`, `or`, `&&`, `and`, `is_array()`, etc. sind erlaubt. Mit den WEBSALE `{if}`-Bedingungen können Sie die Ausgabe in der Storefront abhängig von bestimmten Bedingungen variieren. Um zu entscheiden, was ausgegeben wird, können Sie eine **Bedingung** definieren, die eine Variable überprüft. Eine einfache Bedingung wird durch einen `{if}-`Block dargestellt, der eine Prüfung enthält. Dieser Block wird nur dann ausgeführt, wenn die Prüfung wahr (true) ist. **Beispiel:** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{ if $myProduct.description }} {{= $myPproduct.description }} {{ else }} {{= $myProduct.custom.shortdescr }} {{ /if }} ``` In diesem Beispiel prüfen wir, ob die Variable `$myProduct.description` Inhalt besitzt. Wenn ja, wird ihr Inhalt ausgegeben. Ist das nicht der Fall, wird der alternative Inhalt im **else**-Block gerendert. Hier verwenden die Kurzbeschreibung. Zusätzlich zu `if` und `else` können auch komplexere Bedingungen definiert, indem `{elseif}` hinzugefügt wird. Dadurch können mehrere Prüfungen in einer einzigen Bedingung kombiniert werden. **Beispiel: Begrüßung des Besuchers im Onlineshop** * Es wird eine persönliche Begrüßung angezeigt, wenn sich ein Bestandskunde eingeloggt. * Es wird eine andere Begrüßung angezeigt, wenn sich ein Neukunde eingeloggt. * Für alle nicht eingeloggte Besucher wird eine allgemeine Nachricht angezeigt. ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{ if $wsAccount.isLoggedIn }}Willkommen zurück, {{= $wsAccount.name }}!
{{ elseif $wsAccount.isLoggedIn.newUser }}Willkommen in unserem Onlineshop, {{= $wsAccount.name }}
{{ else }}Willkommen! Registrieren Sie sich.
{{ /if }} ``` **Beispiel: Komplexe Bedingungen mit Operatoren, z.B. für den Lagerbestand** Sie können unterschiedliche Operatoren verwenden, um komplexe Bedingungen zu erstellen, z. B.: * `>` oder `<` für Vergleiche der Stückzahl eines Produktes ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} {{ if $myProduct.stock > 0 }}Dieses Produkt ist verfügbar.
{{ else }}Dieses Produkt nicht verfügbar.
{{ /if }} ``` Eine vollständige Übersicht der verfügbaren Operatoren und deren Verwendung finden Sie in der [Dokumentation der Bedingungen (Conditions)](/frontend/referenz/conditions). *** ## Loops (Schleifen) Schleifen ermöglichen es, durch ein Array zu iterieren, das mehrere Datensätze (z. B. Produkte) enthält, und automatisch Inhalte für jeden einzelnen Datensatz zu generieren. Damit können Sie wiederholende Strukturen wie Produktlisten, Bildergalerien oder ähnliche Inhalte effizient erstellen. Eine `foreach`-Schleife wird mit dem Tag `{{ foreach }}` geöffnet und mit `{{ /foreach }}` geschlossen. Der Name der Schleife (die sogenannte Laufvariable) kann frei definiert werden und darf Buchstaben, Zahlen sowie Unterstriche enthalten. Die `foreach`-Schleife durchläuft jedes Element des Arrays einmal und führt den eingeschlossenen Codeabschnitt für jedes Element aus. Mit jedem Durchlauf wird das aktuelle Element der Laufvariable zugewiesen. **Beispiel: Produktliste einer Kategorie** ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}{{= $myProduct.description }}
Preis: {{= $myProduct.price }} €
Keine Produkte in dieser Kategorie verfügbar.
{{ /foreach }}
```
***
## Basis-Template (Layout-Template)
Das Basis-Template, auch als **Layout-Template** bezeichnet, legt das allgemeine Grundgerüst für alle Seiten der Storefront fest. Es definiert zentrale Inhalte und Bereiche, die auf den meisten Shopseiten wiederverwendet werden, und sorgt so für eine einheitliche Struktur und Benutzerführung.
Das Layout-Template ist keine eigenständige Shopseite und kann nicht direkt von außen per Link aufgerufen werden. Es wird stattdessen von den spezifischen [Seiten-Templates (Views) ](#view-templates-seiten-templates)erweitert oder eingebunden.
Das Basis-Template befindet sich im Verzeichnis
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
templates
├── layouts
```
Hier können ein oder mehrere Layout-Templates abgelegt werden, je nach Anwendungsfall (z. B. allgemeines Layout, Kundekonto, Checkout-spezifisches Layout, Mails etc.)
Das Layout-Template enthält üblicherweise die folgenden zentralen Elemente:
* **Technischer** ``**-Bereich:**
* Meta-Angaben für Suchmaschinenoptimierung (z. B. Title, Description, Keywords).
* Verweise auf die CSS- und JavaScript-Dateien der Storefront.
* Integration von externen Ressourcen wie Schriftarten oder Tracking-Codes.
* **Sichtbarer Headerbereich:**
* Logo: Darstellung des Shop-Logos.
* Suche: Eingabefeld für die Produktsuche.
* Login-Bereich: Zugriff auf das Kundenkonto.
* Warenkorb und Merkliste: Übersicht über gespeicherte Produkte.
* Navigation: Primäre Navigation des Shops (z. B. Kategorien).
* **Breadcrumb:**
* Anzeige des aktuellen Navigationspfads zur besseren Orientierung der Benutzer.
* **Footer:**
* Weiterführende Verlinkungen wie Impressum, Datenschutz, AGB.
* Kontaktinformationen oder andere zusätzliche Inhalte.
Ein Layout-Template wird in den [Seiten-Templates (Views)](#view-templates-seiten-templates) über den `extends`**-Befehl** eingebunden:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ extends "layouts/default.htm" }}
```
***
## Template-Blöcke
Template-Blöcke bilden die grundlegende Struktur eines Basis-Templates und ermöglichen eine einfache und flexible Anpassung der Storefront. Sie gruppieren die Storefront-Komponenten in kleine, isolierte Blöcke, die unabhängig voneinander bearbeitet oder überschrieben werden können. Dieses Block-System sorgt für eine saubere Struktur und Wiederverwendbarkeit von Inhalten.
Template-Blöcke sind klar definierte Bereiche innerhalb eines Templates, die durch das `block`-Element gekennzeichnet sind. Sie dienen dazu, einzelne Komponenten der Storefront (z. B. Header, Footer, Navigation) voneinander zu trennen, sodass jede Komponente unabhängig angepasst werden kann.
**Beispiel eines Blocks:**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ block header }}
Das ist unser spezieller Header für die Startseite.
Versandkostenfreiheit ab 50.00 € Einkaufswert
{{ /block }} ``` Mehr Informationen zu den Template-Blöcken sowie deren Verwendung und Anpassung finden sich in der [Referenzdokumentation zu Template-Blöcken](/frontend/referenz/blocke). *** ## View-Templates (Seiten-Templates) View-Templates definieren die individuellen Inhalte für spezifische Shopseiten und sind die einzigen Templates, die von außen per Link adressierbar sind. Sie basieren in der Regel auf einem Basis-Template und verwenden dessen Blöcke, um eine konsistente Struktur und Gestaltung beizubehalten. View-Templates befinden sich im Verzeichnis ```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} templates ├── views ``` View-Templates können direkt verlinkt werden, indem ihre URL über den folgenden Befehl generiert wird: ```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}} Impressum ``` In diesem Beispiel wird auf das View-Template `impressum.htm` verlinkt. #### Direkter URL-Aufruf eines View-Templates Intern erzeugt `$wsViews.viewUrl()` eine URL mit den Query-Parametern `wsvc=View` und `view=| Produkt | Menge | Preis | |
|---|---|---|---|
|
|
{{ if $cItem.product.custom.brand }}
{{= $cItem.product.custom.brand }} {{ /if }} {{= $cItem.product.name }} {{ foreach $cVarAttr in $cItem.product.variantSelection | keys }} {{= $cVarAttr }}: {{= $cItem.product.variantSelection[$cVarAttr] }} {{ /foreach }} |
{{= $cItem.quantity | preparedFormat('amount') }} | {{= $cItem.total | currency }} |
| Zwischensumme | {{= $wsBasket.subTotal | currency }} |
| Versandkosten | {{= $wsBasket.shippingCosts | currency }} |
| Gesamtsumme |
Vielen Dank für Ihre Bestellung.
Nur „{{= $compareType }}" vergleichbar
{{ elseif $maxReached }}Max. Produkte im Vergleich erreicht
{{ else }} {{ var $addIds = [] }} {{ foreach $id in $compareIds }} {{ push($addIds, $id) }} {{ /foreach }} {{ push($addIds, $cProduct.id) }} {{ var $addIdsStr = join($addIds, ",") }} {{ var $addTypeStr = $compareType }} {{ if $addTypeStr == "" }} {{ $addTypeStr = $productCategory }} {{ /if }} {{ /if }}`
* an einer SEO-URL des Produkts: `/buntes-t-shirt?insert=`
* **Direktbestellung**: Auf der Direktbestellseite kann pro Eingabezeile ein Feld für das Werbemittelkennzeichen hinzugefügt werden. Dies ist eine Template-Erweiterung. Die Umsetzung ist unter [Beispiele](#werbemittelkennzeichen-in-der-direktbestellung-erfassen) beschrieben.
* **Warenkorb (Schnittstelle)**: Beim Hinzufügen oder Ändern eines Postens kann der Code direkt mitgegeben werden - siehe [Storefront-API Warenkorb](/schnittstellen/storefront-api/storefront-api-warenkorb).
Eine View-URL ist dabei eine über die Template-Funktion `$wsViews.url(...)` bzw. `$wsViews.viewUrl(...)` erzeugte, technische Shop-URL (im Gegensatz zur sprechenden SEO-URL) - Details siehe [Modul \$wsViews](/frontend/referenz/module/wsviews). Beide URL-Arten nehmen den `insert`-Parameter gleichermaßen an.
Wird ein Produkt **ohne** `insert`-Parameter aufgerufen, bleibt ein bereits gesetztes sitzungsweites Werbemittelkennzeichen erhalten - „kein Parameter" wird also nicht wie „kein Code" behandelt. Der Sitzungscode wird erst beim Hinzufügen des Produkts in den Warenkorb herangezogen und dort gegen die gültigen Codes geprüft.
## Praxisbeispiel: von der Anzeige bis zur Bestellung
Folgendes Szenario veranschaulicht, wie die Regeln zusammenspielen:
Ein Kunde erhält ein Mailing mit einem Produktlink, an den das Werbemittelkennzeichen `09` angehängt ist (beispielswiese`/buntes-t-shirt?insert=09`). Mit einem Klick gelangt er auf die Produktseite. Der Code `09` wird als sitzungsweites Werbemittelkennzeichen gespeichert.
Anschließend legt er das T-Shirt in den Warenkorb. Da `09` für dieses Produkt ein gültiger Code ist, trägt die Position das Kennzeichen und die Artikelnummer erscheint als `123456-09`.
Anschließend stöbert er weiter und legt eine Hose in den Warenkorb, ohne dabei einen Code aufzurufen. Der Shop zieht den gemerkten Sitzungscode `09` heran. Wenn `09` auch für die Hose gültig ist, wird auch diese Position mit `09` gekennzeichnet. Andernfalls greift der Standardcode oder die Position bleibt ohne Kennzeichnung.
Beim Wechsel zur Kasse und dem Abschluss der Bestellung wird das ermittelte Kennzeichen jeder Position zusammen mit der Bestellung gespeichert. Anschließend wird die Sitzung beendet und der gemerkte Code `09` wird verworfen.
In der Bestellhistorie steht das gespeicherte Kennzeichen zwar in den Bestelldaten (als `insertCode`), die fertig zusammengesetzte Anzeige `itemNumberWithInsert` ist dort jedoch nicht verfügbar. Wie sich das Kennzeichen in der Bestellhistorie darstellen lässt, ist unter [Beispiele → Bestellhistorie](#bestellhistorie) beschrieben.
## Sonderfälle
**Set-Artikel:** Der Code wird sowohl für die Hauptposition als auch für die enthaltenen Unterartikel aufgelöst. Jeder Unterartikel prüft den Code gegen seine eigenen gültigen Codes (sonst greift der Standardcode). Das funktioniert genauso wie bei einem einzeln hinzugefügten Artikel.
**Varianten:** Die zulässigen Codes werden auf Ebene des Hauptprodukts gepflegt und gelten gleichermaßen für dessen Varianten. Beim Hinzufügen einer Variante wird das sitzungsweite Kennzeichen gegen die gültigen Codes des Hauptprodukts geprüft.
## Einrichtung
Dieser Abschnitt beschreibt die konkreten Schritte zu den unter [Voraussetzungen](#voraussetzungen) genannten Bedingungen.
### Konfiguration
Die Einstellungen liegen im Konfigurationsbereich unter (`content.inserts`):
| **Einstellung** | **Bedeutung** | **Standard** |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `enabled` | Schaltet die gesamte Funktion ein bzw. aus. | aus |
| `defaultInsertCode` | Wird verwendet, wenn kein oder ein ungültiger Code erfasst wurde. Leer lassen, wenn in diesem Fall gar kein Kennzeichen gesetzt werden soll. | leer |
| `separator` | Zeichen zwischen Produktnummer und Code, beispielsweise `-`. | `-` |
| `position` | Steht der Code hinter der Produktnummer (`123456-09`) oder davor (`09-123456`). | dahinter |
Solange `enabled` deaktiviert ist, bleibt die Funktion im gesamten Shop wirkungslos - unabhängig davon, wie die einzelnen Produkte gepflegt sind.
Hinweis zu `defaultInsertCode`: Der Standardcode greift produktübergreifend für jede Eingabe, die nicht zu einem gültigen Code aufgelöst werden kann. Wer den Code auf einen festen Wert setzt, sollte bedenken, dass dieser Wert dann auch für Posten verwendet werden kann, für die eigentlich kein Werbemittelkennzeichen vorgesehen ist. Im Zweifel sollten Sie den Wert leer lassen.
### Produktfeld anlegen
Ist das Feld `validInsertCodes` im Shop noch nicht vorhanden, wird es einmalig als benutzerdefiniertes Produktfeld angelegt. Im Admin Interface geschieht das im Bereich Katalog → Produkte über die Produktfelder-Einstellungen (Einstellungen / Zahnrad rechts oben anwählen). Die dortige Tabelle zeigt alle vorhandenen Produktfelder mit Name, Typ und maximaler Länge. Über die Schaltfläche **Neu** wird das Feld mit folgenden Einstellungen angelegt:
| **Einstellung** | **Wert** |
| --------------- | ------------------------------ |
| Name | `validInsertCodes` |
| Label | Gültige Werbemittelkennzeichen |
| Typ | Liste (Texteinträge) |
| Maximale Länge | 16 Zeichen je Eintrag |
Alternativ kann das Feld über die [REST API Konfiguration](/schnittstellen/admin-interface-api/api-referenz-konfiguration) im Knoten `content.customProductField` erstellt werden.
### Feldzuordnung einrichten
Nach dem Anlegen des Produktfelds muss es einmalig der Funktion zugeordnet werden. Erst durch diese Zuordnung weiß der Shop, in welchem Produktfeld die gültigen Werbemittelkennzeichen stehen.
Die Zuordnung wird im Konfigurationsknoten [content.usedFields](/konfiguration/content-katalog-kategorien-produkte#content-usedfields-zuordnung-benutzerdefinierter-felder) gepflegt. Im Bereich `products` verweist der Eintrag `validInsertCodes` auf das angelegte Produktfeld:
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"products": {
"validInsertCodes": "content.customProductField.validInsertCodes"
}
}
```
Das Beispiel zeigt nur den relevanten Eintrag. Der Knoten enthält daneben die Zuordnungen aller anderen Funktionsbereiche (beispielsweise `weight`, `crossSelling`, `metaTitle`). Diese bestehenden Einträge bleiben unverändert erhalten, es wird ausschließlich der Wert von `validInsertCodes` gesetzt.
Ohne diese Zuordnung wirken die am Produkt gepflegten Codes nicht. Der Shop kann die gültigen Codes eines Produkts dann nicht ermitteln, und jeder Posten erhält stillschweigend den Standardcode oder bleibt ohne Kennzeichen, auch wenn an den Produkten Codes gepflegt sind. Es reicht also nicht, das Produktfeld nur anzulegen, es muss auch zugeordnet werden.
### Zulässige Codes am Produkt
Das Feld „**Gültige Werbemittelkennzeichen**" (`validInsertCodes`) ist ein benutzerdefiniertes Produktfeld und wird im Admin Interface auf der Detailseite des jeweiligen Produkts gepflegt. Wie jedes benutzerdefinierte Feld erscheint es in der Feldgruppe, der es zugeordnet wurde - andernfalls in der Sammelgruppe „Sonstige". Über dieses Feld wird pro Produkt festgelegt, welche Codes für dieses Produkt erlaubt sind.
Es handelt sich um ein Listenfeld. Jeder gültige Code wird als eigener Eintrag erfasst. Ein Trennzeichen wird nicht benötigt und die Codes werden nicht als zusammenhängende Zeichenkette gepflegt. Folgende Voraussetzungen gelten für das Anlegen eines Codes:
* Jeder Eintrag darf maximal 16 Zeichen lang sein.
* Jeder Code ist ein eigener Listeneintrag. Die Codes werden nicht durch Kommas oder andere Trennzeichen in einem Feld aneinandergereiht.
* Die Codes sind case-sensitiv (beispielsweise ist `DA` nicht gleich `da`).
* Das Feld wird auf Ebene des Hauptprodukts gepflegt und gilt für dessen Varianten mit.
* Ist die Liste leer, kann für dieses Produkt kein Code übernommen werden (es greift höchstens der [Standardcode](#konfiguration), sofern gesetzt).
Im Template steht das Feld als Liste zur Verfügung, beispielsweise über `$cProduct.custom.validInsertCodes` auf der Produktseite oder `$item.product.custom.validInsertCodes` an der Warenkorbposition. Die Ausgabe erfolgt per Schleife oder mit `join` und frei wählbarem Trennzeichen:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $cProduct.custom.validInsertCodes | join(", ") }}
```
**Ergebnis**
Die gültigen Codes des Produkts werden kommagetrennt angezeigt, beispielsweise `DA, 09`.
## Anzeige im Shop
Das Werbemittelkennzeichen kann als Teil der Artikelnummer im Warenkorb, in der Bestellübersicht, in der Bestätigungs-E-Mail, im Bestell-PDF und in der Bestellhistorie angezeigt werden (beispielsweise `123456-09`) - in der konfigurierten Reihenfolge und mit dem konfigurierten Trennzeichen. Voraussetzung ist, dass die Ausgabe im jeweiligen Template eingebunden ist (siehe [Beispiele](#beispiele)).
Die Anzeige setzt sich aus der am Produkt gepflegten Artikelnummer (`itemNumber`) und dem Code zusammen. Ist am Produkt keine Artikelnummer gepflegt, erscheint nur der Code.
Wird ein unbekannter Code eingegeben, verwirft der Shop diesen und greift, sofern eingerichtet, auf den Standardwert zurück. Dadurch wird die Bestellung nie blockiert.
## Module
Für die Ausgabe des Werbemittelkennzeichens im Template werden diese Module verwendet:
* [\$wsConfig](/frontend/referenz/module/wsconfig) - liefert über `$wsConfig.inserts` die aktuellen Einstellungen (aktiv, Trennzeichen, Position, Standardcode) und wird benötigt, um Ausgaben nur bei aktiver Funktion anzuzeigen.
* [\$wsBasket](/frontend/referenz/module/wsbasket) - liefert je Warenkorbposition das Kennzeichen über `$item.insert` und die fertige Anzeige über `$item.itemNumberWithInsert`.
Die Erfassung eines Codes (URL, Direktbestellung, Warenkorb-Schnittstelle) benötigt kein eigenes Modul, dies geschieht über URL-Parameter, das Direktbestellformular oder die [Storefront-API](/schnittstellen/storefront-api/storefront-api-warenkorb).
## Beispiele
### Artikelnummer mit Werbemittelkennzeichen ausgeben
Im Warenkorb (und analog dazu in der Bestellübersicht, der E-Mail und dem PDF) genügt es, `itemNumberWithInsert` als Artikelnummer auszugeben. Die Reihenfolge und das Trennzeichen sind darin bereits berücksichtigt. Wenn kein Code gesetzt ist, enthält das Feld die reine Produktnummer.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $item in $wsBasket.items }}
Art.-Nr.: {{= $item.itemNumberWithInsert }}
Produktname: {{= $item.product.name }}
{{ /foreach }}
```
**Ergebnis**
Jede Position zeigt ihre Artikelnummer inklusive Werbemittelkennzeichen, sofern eines erfasst wurde. Andernfalls wird die reine Produktnummer angezeigt.
### Werbemittelkennzeichen als eigenes Feld ausgeben
Wenn der reine Code zusätzlich als eigenes Feld erscheinen soll, prüfen Sie zuerst, ob die Funktion aktiv ist. Andernfalls erscheint bei ausgeschalteter Funktion nichts.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConfig.inserts.enabled }}
{{ foreach $item in $wsBasket.items }}
{{ if $item.insert }}
Werbemittelcode: {{= $item.insert }}
{{ /if }}
{{ /foreach }}
{{ /if }}
```
**Ergebnis**
Der Werbemittelcode erscheint nur bei aktiver Funktion und nur für Positionen, die einen Code tragen.
### Werbemittelkennzeichen in der Direktbestellung erfassen
Auf der Direktbestellseite (Template `modules/directOrder.htm`, Modul [\$wsDirectOrder](/frontend/referenz/module/wsdirectorder)) geben Kunden Produktnummern zeilenweise ein. Standardmäßig ist dort kein Eingabefeld für das Werbemittelkennzeichen vorhanden, es muss pro Eingabezeile ergänzt werden.
Fügen Sie das folgende Feld in jede Eingabezeile des Formulars ein, und zwar neben dem bestehenden Feld `name="id"`. Entscheidend ist der Feldname `insert`: Darüber liest der Shop den Code ein und löst ihn beim Übernehmen in den Warenkorb gegen die für das jeweilige Produkt gültigen Codes auf (siehe [Wie der Shop ein Werbemittelkennzeichen ermittelt](#wie-der-shop-ein-werbemittelkennzeichen-ermittelt)). Über `{{ if $wsConfig.inserts.enabled }}` erscheint das Feld nur, wenn die Funktion aktiv ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConfig.inserts.enabled }}
{{ /if }}
```
**Ergebnis**
Pro Zeile erscheint neben der Produktnummer ein Eingabefeld für das Werbemittelkennzeichen. Der eingegebene Code wird zusammen mit der Zeile erfasst und beim Übernehmen in den Warenkorb wieder aufgelöst. Mit der Funktion `$wsDirectOrder.items[…].insert` wird der bereits erfasste Code nach einem Neuladen der Zeile wieder in das Feld geschrieben.
### Bestellhistorie
Die Bestellhistorie arbeitet nicht mit dem Warenkorb, sondern mit den gespeicherten Bestelldaten (`$order.orderList.item`). Das fertig zusammengesetzte Feld `itemNumberWithInsert` steht dort nicht zur Verfügung, sodass die Anzeige im Template aus der Produktnummer, dem Code und den Werten aus `$wsConfig.inserts` (Position und Trennzeichen) selbst zusammengesetzt werden muss.
## Weiterführende Links
* [\$wsConfig](/frontend/referenz/module/wsconfig) - Einstellungen über `$wsConfig.inserts` (aktiv, Trennzeichen, Position, Standardcode).
* [\$wsBasket](/frontend/referenz/module/wsbasket) - Ausgabe je Position über `$item.insert` und `$item.itemNumberWithInsert`.
* [\$wsViews](/frontend/referenz/module/wsviews) - Erzeugung von View-URLs (`url()`, `viewUrl()`), an die sich der `insert`-Parameter anhängen lässt.
* [content - Katalog](/konfiguration/content-katalog-kategorien-produkte) - Konfigurationsblock `content.inserts` und die zwingende Feldzuordnung `usedFields.products`.
* [API-Referenz Produkte](/schnittstellen/admin-interface-api/api-referenz-produkte) - Pflege der zulässigen Codes je Produkt (`custom.validInsertCodes`); setzt die Feldzuordnung `usedFields.products` voraus (siehe [Voraussetzungen](#voraussetzungen)).
* [API-Referenz Konfiguration](/schnittstellen/admin-interface-api/api-referenz-konfiguration) - Pflege des Konfigurationsblocks `content.inserts` über die Konfigurationsknoten-Endpunkte.
* [Storefront-API Warenkorb](/schnittstellen/storefront-api/storefront-api-warenkorb) - Setzen und Auslesen des Kennzeichens über das `insert`-Feld sowie `GET /api/v1/config/inserts`.
# Übersicht - Zahlungsarten
Source: https://dokumentation.websale.de/frontend/funktionsubersicht/zahlungsarten
Grundprinzip der Zahlungsarten-Konfiguration: Knoten unter payment.payment anlegen, Aktivierung, Bezeichnungen, Icons und Validierungen festlegen.
## Grundprinzip
Jede Zahlungsart wird zunächst als eigener Konfigurationsknoten unter `payment.payment.` angelegt.
Die ID ist frei wählbar; es gibt keine fest vorgegebenen Bezeichnungen pro Zahlungsart. Dadurch können Zahlungsarten beispielsweise unter Knoten wie `payment.payment.bill`, `payment.payment.applepay`, `payment.payment.googlepay` oder `payment.payment.paypal` definiert werden.
In `payment.payment` werden unter anderem festgelegt, ob die Zahlungsart aktiv ist, welche Bezeichnung sie im Checkout trägt, welches Bild oder Icon verwendet wird und welche Regeln und Einschränkungen für ihre Verfügbarkeit gelten. Die offizielle Doku beschreibt `payment.payment` genau als den Bereich, in dem Zahlarten zusammengefasst und Eigenschaften wie `active`, `id`, `name`, `image`, `validations` sowie die Anbindung an Online-Clearing konfiguriert werden.
Typische Angaben einer Zahlungsart sind zum Beispiel:
* Aktiv-/Inaktiv-Schaltung
* Name und Beschreibung
* Bild oder Icon
* Zulässigkeit oder Ausschluss für bestimmte Länder
* Zulässigkeit oder Ausschluss für bestimmte Produkte oder Warenkörbe
* Zusätzliche Eingabefelder oder Prüfungen
* Art der Zahlungsabwicklung
Weitere Informationen zu den allgemeinen Konfigurationsmöglichkeiten einer Zahlungsart finden sich auf der Seite [payment - Zahlungsmethoden](/konfiguration/payment-zahlungsmethoden).
***
## Offline- und Online-Zahlungsarten
Für die Konfiguration ist zunächst wichtig, zwischen **offline** und **online** abgewickelten Zahlungsarten zu unterscheiden. Die Doku nennt für `type` ausdrücklich typische Werte wie `offline` für manuell abgewickelte Zahlungen und `online` für Zahlungen über einen Provider.
### Offline-Zahlungsarten
Bei einer reinen Offline-Zahlungsart ist die Konfiguration mit `payment.payment.` im Regelfall abgeschlossen. Die Zahlungsart wird angelegt, benannt und im Checkout angeboten, ohne dass eine zusätzliche Provider-Anbindung erforderlich ist.
Ein typisches Beispiel dafür ist **Vorauskasse**. Hier reicht die Definition der Zahlart in `payment.payment.prepayment`, da keine Echtzeit-Kommunikation mit einem Zahlungsdienstleister notwendig ist.
**Beispielkonfiguration** `payment.payment.prepayment`
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"active": true,
"basicCost": null,
"description": "Text",
"discount": 0,
"displayedPaymentTypes": [],
"freeFields": null,
"id": "prepayment",
"image": "",
"labels": null,
"name": "Vorauskasse",
"onlineClearing": null,
"orderText": "Text",
"provider": "",
"type": "",
"validations": [ ]
}
```
### Online-Zahlungsarten
Bei Online-Zahlungsarten wird die Zahlungsart ebenfalls zunächst unter `payment.payment.` angelegt. Die Zahlungsart selbst bleibt immer zunächst eine eigenständige Konfiguration unter `payment.payment.ID`.
Erst wenn sie online abgewickelt werden soll, kommt zusätzlich eine passende Online-Anbindung hinzu, in dem bei dem die Zahlungsart beim Parameter `onlineClearing` mit einem konkreten Provider verknüpft wird, z.B. `payment.paypal-checkout`
**Beispielkonfiguration** `payment.payment.GooglePay`
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"active": false,
"basicCost": null,
"description": "Text",
"discount": 0,
"displayedPaymentTypes": [],
"freeFields": null,
"id": "paypalCheckoutGooglePay",
"image": "",
"labels": null,
"name": "GooglePay",
"onlineClearing": {
"options": {
"type": "googlePay",
"view": "paypal_checkout_pending.htm"
},
"service": "payment.paypal-checkout"
},
"orderText": "Text",
"provider": "",
"type": "",
"validations": [ ]
}
```
# stripe
Source: https://dokumentation.websale.de/frontend/funktionsubersicht/zahlungsarten/stripe
Zahlungsart Stripe im Checkout einrichten: relevante Konfigurationen, Module wie $wsStripe und $wsCheckout sowie Aktionen für den Bestellprozess.
## Konfigurationen
Folgende Einstellungen sind relevant für die Konfiguration der Zahlungsart stripe:
***
## Module
Folgende Module sind relevant für die Integration der Zahlungsart stripe im Bestellprozess:
* [\$wsStripe](/frontend/referenz/module/wsstripe) - stripe-Zahlungsarten Modul
* [\$wsCheckout](/frontend/referenz/module/wscheckout) - Checkout-Zustand, Adressen, Versand, Zahlung, Probleme, Summen
* [\$wsActions](/frontend/referenz/module/wsactions) - Aktionen erzeugen und auswerten
* [\$wsAccount](/frontend/referenz/module/wsAccount) - Login-Status, E-Mail, Adressen, loadAddress()
* [\$wsViews](/frontend/referenz/module/wsviews) - Aktuelle URL, Zielseiten, View-URLs
* [\$wsBasket](/frontend/referenz/module/wsbasket) - Warenkorb und Bestellübersicht
* [\$wsConfig](/frontend/referenz/module/wsconfig) - Konfigurationswerte, zum Beispiel Anreden und Währung
***
## Aktionen
Folgende Aktionen sind relevant für die Integration der Zahlungsart stripe:
***
## Zusätzliche relevante Informationen
Folgende zusätzlichen Inhalte müssen für die Zahlungsart integriert werden.
### Frontend-Integration
Stripe stellt ein eigenes JavaScript-SDK bereit, das in das Template eingebunden werden muss. Es übernimmt die Darstellung der Zahlungsfelder und die Kommunikation mit Stripe.
**HTML-Struktur**
Folgender HTML-Block muss im Template plaziert werden:
* `#wsStripePaymentElement` ist der Container, in den Stripe die Zahlungsfelder (z.B. Kreditkartennummer, PayPal-Button etc.) automatisch einbettet
* Das Formular sendet beim Klick auf “Mit Stripe bezahlen” den Bezahlvorgang ab
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
**JavaScript**
Der folgenden Script-Block muss direkt nach dem HTML-Block eingefügt werden. Er muss in `{{ autoescape “js” }}` eingeschlossen sein, damit Template-Variablen im JavaScript-Kontext korrekt verarbeitet werden.
Der Ablauf im Script ist folgender:
1. **Stripe initialisieren** - Das SDK wird mit den Zugangsdaten aus [\$wsStripe.configuration](/frontend/referenz/module/wsstripe) gestartet
2. **Zahlungsfelder anzeigen** - Stripe rendert die Zahlungsauswahl (Kreditkarte, PayPal etc.) in den `#wsStripePaymentElement`-Container. Die Adresseingabefelder von Stripe werden dabei deaktiviert, weil die Adresse des Kunden bereits im Shop bekannt ist und automatisch übergeben wird.
3. **Bezahlung auslösen** - Beim Absenden des Formulars werden die eingegebenen Zahlungsdaten zusammen mit der Rechnungsadresse aus [\$wsAccount](/frontend/referenz/module/wsAccount) an Stripe geschickt. Stripe gibt dafür ein Confirmation-Token zurück.
4. **Token an den Shop senden** - Das Token wird an den Shop übermittelt, der damit den eigentlichen Zahlungsvorgang bei Stripe startet.
5. **Ergebnis verarbeiten** - Schlägt die Zahlung fehl, wird eine Fehlermeldung angezeigt. Ist eine zusätzliche Bestätigung nötig (z.B. 3D Secure), übernimmt Stripe das automatisch.
6. **Weiterleitung** - Nach erfolgreicher Zahlung wird der Kunde zur Bestellbestätigungsseite weitergeleitet.
```javascript theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ autoescape "js" }}
{{ /autoescape }}
```
***
## Weiterführende Links
* Generelle Doku für das Stripe Frontend: [https://docs.stripe.com/js](https://docs.stripe.com/js)
# Getting Started
Source: https://dokumentation.websale.de/frontend/getting-started
Schritt-für-Schritt-Einstieg in einen WEBSALE-Onlineshop: Design anpassen, Produkte und Kategorien anlegen, Zahlungsarten konfigurieren und Shop SEO optimieren.
Ein WEBSALE-Onlineshop bietet zahlreiche Möglichkeiten zur individuellen Anpassung und Konfiguration. Damit Sie schnell und effizient starten können, führt diese Anleitung Sie Schritt für Schritt durch die wichtigsten ersten Aufgaben.
Von der grundlegenden Shop-Konfiguration über die visuelle Anpassung der Storefront bis hin zur Einrichtung von Produkten, Kategorien und Zahlungsarten – diese Anleitung zeigt Ihnen, wie Sie Ihren Shop optimal einrichten.
Jeder Schritt enthält praktische Anleitungen und Erklärungen, damit Sie direkt loslegen können:
### Arbeiten mit GitLab
* [Kennenlernen der WEBSALE GitLab Pipeline](/frontend/getting-started/arbeiten-mit-gitlab)
### Design & Branding anpassen
* Logo austauschen
* Farben und Schriftarten definieren
* Startseite und Layout anpassen
### Produkte & Kategorien verwalten
* Kategorien strukturieren und organisieren
* Produkte anlegen und bearbeiten
* Produktbilder und Beschreibungen hinzufügen
### Grundlegende Shop-Konfiguration
* Währungen, Steuersätze etc. einrichten
* Zahlungsarten konfigurieren
* Versandoptionen festlegen
### SEO & Performance optimieren
* Meta-Titel, Beschreibungen und URLs anpassen
* Bildoptimierung
### Rechtliche Anforderungen berücksichtigen
* DSGVO-Konformität sicherstellen
* Impressum und Datenschutzrichtlinien ergänzen
* Cookie-Banner einrichten
### Tests & Veröffentlichung
* Testbestellungen durchführen
* Checkout-Prozess überprüfen
* Letzte Anpassungen vor dem Livegang vornehmen
### 🚧 **Hinweis: Inhalte in Bearbeitung** 🚧
Diese Seite wird derzeit aktualisiert und um detaillierte Anleitungen zu den einzelnen Schritten erweitert. Die Übersicht bietet bereits einen strukturierten Leitfaden für den Start mit Ihrem WEBSALE-Onlineshop, jedoch sind einige Abschnitte noch in der Bearbeitung. Die fehlenden Inhalte werden **nach und nach ergänzt**, um Ihnen eine umfassende Schritt-für-Schritt-Anleitung zur Verfügung zu stellen. Schauen Sie regelmäßig vorbei, um die neuesten Updates zu erhalten.
Vielen Dank für Ihr Verständnis! 😊
# Arbeiten mit GitLab
Source: https://dokumentation.websale.de/frontend/getting-started/arbeiten-mit-gitlab
Mit dem GitLab-Repository des Shops arbeiten: Zugriff auf gitlab.websale.cloud sowie Versionierung der Layout- und Template-Dateien einrichten.
Zu jedem Shop wird im Standard ein eigenes GitLab-Repository mitgeliefert. Dieses Repository dient zur Verwaltung und Versionierung der Layout- und Template-Dateien, die für das Erscheinungsbild des Shops verantwortlich sind.
***
## Zugriff
Das WEBSALE GitLab ist unter folgender URL erreichbar: [https://gitlab.websale.cloud](https://gitlab.websale.cloud)
Die Zugangsdaten werden beim Bereitstellen des Shops durch die WEBSALE AG übermittelt.\
Für zusätzliche Benutzer kann über das Beauftragungsportal der WEBSALE AG ein weiterer Zugriff beantragt werden.
***
## Einstellungen (Settings → CI/CD → Variables)
Im Menü des Projekts unter Settings → CI/CD → Variables sind Umgebungsvariablen für die Shop-Pipeline definiert.
### Editierbare Variablen
| **Variable** | **Beschreibung** |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AUTO_COMPILE_TEMPLATES` | Steuert, ob Templates nach Veröffentlichung im Main-Branch automatisch kompiliert werden.
- `true`: automatische Kompilierung beim Merge in *main*
- `false`: manuelle Kompilierung über das Admin Interface (Templates & Inhalte → Templates kompilieren). |
| `TEMPLATE_COMPILE_URL` | URL des Shops, über die die Kompilierung ausgeführt wird.
Diese URL muss bei Domainänderungen (z. B. Livegang von `shop-test.websale.net` auf `ihr-shop.de`) angepasst werden, da der Kompilierungsdienst nur über die aktive Shopdomain erreichbar ist. |
Angaben zu *Type*, *Environment*, *Visibility Flags* und *Key* dürfen für diese Variablen nicht verändert werden. Änderungen an diesen Einstellungen können zu Störungen oder Fehlern der Pipeline führen.
### Readonly Variablen
Diese Variablen können aktuell nur durch Mitarbeiter der WEBSALE AG bearbeitet werden.
| **Variable** | **Beschreibung** |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TEMPLATE_COMPILE_PASSWORD` | Passwort des Admin Interface Benutzers, der in `TEMPLATE_COMPILE_USER` hinterlegt ist. |
| `TEMPLATE_COMPILE_USER` | Benutzername des Admin Interface Benutzers.
Der `Template_Compile_User` ist ein separater technischer Benutzer im Admin Interface, der ausschließlich für die GitLab Pipeline vorgesehen ist.
Persönliche Admin-Logins werden dadurch nicht in GitLab hinterlegt und bleiben geschützt. |
| `S3_TEMPLATES_BUCKET` | `template`-Bucket im S3. |
| `S3_MEDIA_BUCKET` | `media`-Bucket im S3. |
| `S3_ENDPOINT` | URL des S3-Storages. |
| `AWS_DEFAULT_REGION` | Vorgegebene S3-Region von WEBSALE. |
| `AWS_SECRET_ACCESS_KEY` | Zugangsdaten für den Zugriff auf den S3-Speicher. |
| `AWS_ACCESS_KEY_ID` | Zugangsdaten für den Zugriff auf den S3-Speicher. |
***
## Verzeichnis- & Dateistruktur (Root-Ebene)
Das Repository enthält auf Root-Ebene folgende Einträge im Standard:
* `media/` (Verzeichnis)
* `templates/` (Verzeichnis)
* `.gitlab-ci.yml` (Datei)
* `README.md` (Datei)
### media
Das Verzeichnis `media` enthält alle statischen Ressourcen, die für das Design und Layout des Shops verwendet werden. Es ist im Standard wie folgt aufgebaut:
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
media
└── themes
└── default
├── favicon
├── fonts
│ └── bootstrap
├── images
├── pdf
├── scripts
└── scss
```
| **Verzeichnis** | **Beschreibung** |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `favicon` | Icons und Favicons für den Browser |
| `fonts` | Schriftdateien (z. B. Bootstrap-Fonts) |
| `images` | Layoutgrafiken (z. B. Logos, Icons, Banner) |
| `pdf` | Statische PDF-Dateien (z. B. AGBs oder Datenschutzerklärung) |
| `scripts` | JavaScript-Dateien |
| `scss` | SCSS-Quelldateien für CSS Die kompilierten CSS-Dateien, die aus SCSS generiert werden, sind nicht Bestandteil des Repositories. Diese Dateien können bei Bedarf zu Debug-Zwecken über den Browser bzw. die Browserkonsole eingesehen werden. |
Unterhalb des Verzeichnisses `media/` können Ordner und Dateien nach Bedarf umbenannt, gelöscht oder neu angelegt werden. Diese Änderungen werden von der Pipeline beim Deployment berücksichtigt.
Beim Umbenennen oder Verschieben bestehender Ordner müssen ggf. auch die entsprechenden Pfadangaben in Templates, Stylesheets oder Skripten angepasst werden, damit Ressourcen weiterhin korrekt geladen werden.
### templates
Das Verzeichnis `templates` enthält die für das Shop-Frontend relevanten Template-Dateien. Es ist im Standard wie folgt aufgebaut:
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
templates
├── components
├── layouts
├── mails
└── views
```
| **Verzeichnis** | **Beschreibung** |
| --------------- | --------------------------------------------------------------- |
| `components` | Wiederverwendbare Template-Bausteine, HTML-Snippets und Widgets |
| `layouts` | Grundlayouts und Seitenstrukturen |
| `mails` | E-Mail-Vorlagen |
| `views` | Ansichten einzelner Shopseiten |
Unterhalb des Verzeichnisses `templates/` können Ordner und Dateien nach Bedarf umbenannt, gelöscht oder neu angelegt werden. Diese Änderungen werden von der Pipeline beim Deployment berücksichtigt.
Beim Umbenennen oder Verschieben bestehender Ordner müssen ggf. auch die verwendeten Pfade in den Templates angepasst werden, damit die entsprechenden Includes, Layouts und Views weiterhin gefunden werden.
### gitlab-ci.yml
Diese Datei definiert die CI/CD-Pipeline (Continuous Integration / Deployment) in Gitlab.
**Standardinhalt**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
### DO NOT EDIT THIS FILE! ###
### CHANGES CAN DESTROY THE SHOP! ###
include:
- remote: 'https://websale.de/git-design/ws_design/templates.yml'
```
Die hinter `remote:` angegebene Datei bindet die zentrale Pipeline-Vorlage der WEBSALE AG ein. Diese Remote-Datei kann ausschließlich durch die WEBSALE AG bearbeitet werden.
### Funktionsweise der WEBSALE Pipeline
Die Pipeline wird ausschließlich durch Commits im `main`-Branch gestartet und führt dabei folgende Jobs aus:
1. **Build (compile-sass)**
* Überwacht Änderungen in `media/themes/default/scss/**`
* Kompiliert SCSS-Dateien zu CSS (`media/themes/default/styles/`)
2. **Deploy (deploy-css)**
* Synchronisiert das CSS-Verzeichnis mit dem entsprechenden S3-Bucket
* Ausgenommen sind bestimmte Unterverzeichnisse (z. B. Fonts, Scripts, Favicons)
3. **Deploy (deploy-media-without-css)**
* Synchronisiert den übrigen `media`-Ordner (ohne Styles-Verzeichnis) mit dem S3-Bucket
4. **Deploy (deploy-templates)**
* Überträgt das Verzeichnis `templates` in den S3-Bucket
* Führt optional (abhängig von `AUTO_COMPILE_TEMPLATES`) die Template-Kompilierung über die API des Shops durch
Der Status der Pipeline sowie Log-Ausgaben der einzelnen Jobs können im GitLab unter **Build → Pipelines** eingesehen werden.
### README.md
Datei mit weiterführenden Informationen zum WEBSALE GitLab und dem WEBSALE Shopsystem.
***
## Eigene Versionsverwaltung verwenden
Verfügen Sie bereits über eine eigene Versionsverwaltung, die Sie für die Entwicklung des WEBSALE-Shops nutzen möchten (z. B. GitHub, eigenes GitLab, o. Ä.), ist dies grundsätzlich möglich.
**Funktionsprinzip**
* Die Entwicklung findet wie gewohnt in Ihrer bestehenden Versionsverwaltung statt.
* Über eine eigene Pipeline (oder manuell per Git-Remote) werden die relevanten Dateien in das zugehörige WEBSALE GitLab-Projekt übertragen und dort in den Branch `main` gepusht bzw. gemerged.
* Ab diesem Zeitpunkt greift die im WEBSALE GitLab-Projekt hinterlegte Pipeline und übernimmt wie gewohnt Build und Deployment (z. B. SCSS-Kompilierung, Medien- und Template-Deployment auf S3).
Für das Pushen in das WEBSALE GitLab-Projekt werden folgende Voraussetzungen benötigt:
* Ein GitLab-Benutzer für das betreffende WEBSALE Shop-Projekt mit Schreibrechten auf das Projekt bzw. den Branch `main`. Der notwendige Zugang wird durch die WEBSALE AG bereitgestellt.
Die Verwendung eines eigenen Repositories ersetzt nicht die Einrichtung des WEBSALE GitLab-Projekts. Die initiale Einrichtung des Projekts und der Benutzer kann derzeit nicht vollständig selbstständig vorgenommen werden und erfolgt vorerst über die WEBSALE AG.
***
## Hinweise & Einschränkungen
* Über das GitLab-Repository besteht kein Zugriff auf Produktdaten (z. B. Produkte, Preise, Bilder) oder Kundendaten. Produkt- und Kundendaten können über das Admin Interface, [REST APIs](/schnittstellen/admin-interface-api), Connectoren etc. verwaltet werden.
* Das Repository dient zur Verwaltung und zum Deployment von Shop-Templates und den dazugehörigen Mediendateien.
* Eigene Prozesse wie z. B. Docker-Container, zusätzliche Build-Jobs oder externe Programme sind mit der Standard-Pipeline nicht vorgesehen.
* Die Standard-Pipeline arbeitet aktuell ausschließlich im Branch `main`.
* Die Deployment-Jobs synchronisieren nur die Verzeichnisse `media` und `templates`. Oberhalb dieser Verzeichnisse angelegte Ordner werden nicht übertragen.
***
## Zugriff auf den Objektspeicher (S3)
Über GitLab besteht nur Zugriff auf die Shop-Templates bzw. das Theme/Template-Repository. GitLab ist damit der zentrale Ort für die Versionsverwaltung und die Bearbeitung des Template-Codes (z. B. Anpassungen am Frontend, Layouts, Komponenten, Styles).
Neben dem Zugriff über GitLab existiert zusätzlich ein Zugriff auf den Objektspeicher des Shops (S3). Über diesen Zugang erhält man Zugriff auf alle Dateien des Shops, z.B. Produktbilder, [JSON-Dateien](/schnittstellen/externe-datenschnittstelle-datei-bucket-basiert) etc.
# Referenz - Übersicht
Source: https://dokumentation.websale.de/frontend/referenz
Komplette Referenz der WEBSALE Template-Sprache: Tags, Anweisungen, Module, Funktionen, Modifier und Aktionen für den Aufbau des Shop-Frontends.
Referenz ist das zentrale Nachschlagewerk für die Template Engine und die Template-Sprache. Hier sind alle relevanten Sprachelemente und Bausteine dokumentiert, die für den Aufbau und die Anpassung des Shop-Frontends auf Basis von Templates benötigt werden – zum Beispiel Tags/Anweisungen, Variablen, Funktionen, Modifier und typische Verwendungsformen.
Diese Referenz richtet sich an Projekte, die das Shop-Frontend mit Templates umsetzen. Soll das Frontend stattdessen über die Storefront API aufgebaut werden (z. B. Headless-Ansatz), ist diese Seite nicht der richtige Einstieg – in diesem Fall sind die Seiten zur [Storefront API](/schnittstellen/storefront-api/storefront-api-basics) relevant.
## Inhaltsverzeichnis
* [Aktionen](/frontend/referenz/aktionen)
* [Anweisungen](/frontend/referenz/anweisungen)
* [Blöcke](/frontend/referenz/blocke)
* [Components](/frontend/referenz/components)
* [Conditions](/frontend/referenz/conditions)
* [Datentypen](/frontend/referenz/datentypen)
* [Funktionen](/frontend/referenz/funktionen) — Globale Template-Funktionen stehen in allen Templates zur Verfügung. Sie werden verwendet, um Werte zu verarbeiten, zu formatieren oder zu prüfen (z. B. Strings anpassen, Zahlen runden, Listen zusammenführen oder Datumswerte vergleichen).
* [Kontrollstrukturen](/frontend/referenz/kontrollstrukturen)
* [Loops](/frontend/referenz/loops)
* [Modifiers](/frontend/referenz/modifiers) — Diese Seite beschreibt die Grundlagen und Schreibweise von Modifiers. Modifiers (auch Filter genannt) werden verwendet, um Werte im Template direkt bei der Ausgabe oder Weiterverarbeitung zu verändern, zu formatieren oder zu prüfen – zum Beispiel Texte anpassen, Zahlen runden oder Listen umwandeln.
* [Operatoren](/frontend/referenz/operatoren)
* [Module](/frontend/referenz/module) — Module sind von WEBSALE vorgegebene, global verfügbare Module (z. B. \$wsAccount). Sie stellen Variablen (Eigenschaften) und Methoden bereit. In der Entwicklung werden sie teilweise auch als View-Module bezeichnet, da sie primär für die Ausgabe (Leseseite) verwendet werden.
* [Variablen](/frontend/referenz/variablen)
# Aktionen - Übersicht
Source: https://dokumentation.websale.de/frontend/referenz/aktionen
Übersicht aller Aktionen der Template-Sprache: Eingaben des Nutzers für Warenkorb, Login, Registrierung und mehr verarbeiten und Ergebnisse auswerten.
Aktionen sind das Bindeglied zwischen dem, was ein Benutzer im Shop macht, und dem, was der Shop daraufhin ausführt. Ob ein Kunde ein Produkt in den Warenkorb legt, sich registriert oder einloggt - hinter jedem dieser Vorgänge steckt eine Aktion.
Aktionen nehmen die Eingaben des Benutzers entgegen, verarbeiten sie im Hintergrund und geben dem Frontend zurück, ob alles geklappt hat oder ein Fehler aufgetreten ist.
***
## Grundprinzip
Der Shop stellt eine Reihe vordefinierter Aktionen bereit. Diese sind vom System vorgegeben und können nicht frei benannt werden. Jede Aktionen hat einen festen Namen, zum Beispiel `BasketItemAdd` (Produkt in den Warenkorb legen), `Login` (Benutzer einloggen) oder `AccountRegister` (neues Konto anlegen).
Aktionen können auf drei Arten ausgeführt werden:
* Über ein Formular - der häufigste Fall. Der Benutzer füllt ein Formular aus und sendet es ab.
* Über einen Link - für Aktionen ohne Benutzereingaben, zum Beispiel das Ausloggen.
* Per AJAX - wenn die Seite nach der Ausführung nicht neu geladen werden soll.
Unabhängig davon, wie eine Aktion ausgeführt wird, läuft im Hintergrund immer derselbe Prozess ab: Der Shop empfängt die Anfrage, verarbeitet sie und gibt zurück, ob die Aktion erfolgreich war oder ein Fehler aufgetreten ist.
Einige Aktionen Verhalten sich abweichend und geben statt einer neuen Seite direkt Daten zurück, zum Beispiel als JSON im Rahmen des Checkouts. Dieses abweichende Verhalten ist bei den betreffenden Aktionen jeweils dokumentiert.
***
## Aktionen vorbereiten
Bevor eine Aktion in einem Template genutzt werden kann, muss ein sogenanntes Aktionsobjekt erstellt werden. Man kann es sich wie einen Behälter vorstellen, der alles enthält, was für die Ausführung der Aktion benötigt wird und nach dem Absenden auch die Rückmeldung des Shops enthält.
Das Aktionsobjekt wird mit [\$wsActions.create()](/frontend/referenz/module/wsactions#%24wsactions-create) erstellt, wobei der Name der gewünschten Aktion übergeben wird:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myAction = $wsActions.create("BasketItemAdd") }}
```
Optional kann hier bereits die Zielseite, auf die nach erfolgreicher Ausführung der Aktion weitergeleitet wird, mitgegeben werden:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myAction = $wsActions.create("BasketItemAdd", target=$wsViews.viewUrl('basket.htm')) }}
```
Das Objekt löst dabei noch nicht aus, es bereitet lediglich die Aktion vor. Die Aktion selbst wird erst ausgeführt, wenn der Benutzer das Formular absendet, auf einen Link klickt oder eine AJAX-Anfrage abgesendet wird.
Nach der Ausführung befüllt der Shop das Aktionsobjekt automatisch mit Rückmeldungen. Im Template kann dann über die Variable `$myAction` darauf zugegriffen werden, zum Beispiel mit `$myAction.success` oder `$myAction.errors`. Eine vollständige Beschreibung aller verfügbaren Eigenschaften findet sich in der [\$wsActions Modulreferenz](/frontend/referenz/module/wsactions).
| **Eigenschaft** | **Beschreibung** |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `$action.id` | Die ID der Aktion, die im Formular benötigt wird, damit der Shop weiß, was ausgeführt werden soll. |
| `$action.csrf` | Ein Sicherheits-Token, das jede Anfrage absichert (mehr dazu [hier](#3-2-1-csrf-schutz)). |
| `$action.success` | Ist `true`, wenn die Aktion erfolgreich ausgeführt wurde. |
| `$action.error` | Ist `true`, wenn ein Fehler aufgetreten ist. |
| `$action.errors` | Eine Liste aller aufgetretenen Fehler mit Fehlercode, betroffenem Feld und optionalem Detail. |
| `$action.params` | Die zuletzt eingegebenen Werte. Nützlich, um ein Formular bei einem Fehler vorausgefüllt anzuzeigen, damit der Benutzer nicht alles neu eingeben muss. |
***
## Aktionen ausführen
### Ausführung über Formulare
Der häufigste Weg, eine Aktion auszuführen, ist ein HTML-Formular. Das vorbereitete Aktionsobjekt wird in das Formular eingebunden und die Aktion wird ausgeführt, sobald der Benutzer das Formular absendet.
Das Formular wird immer an die URL der aktuellen Seite gesendet, damit der Shop nach der Ausführung dieselbe Seite neu aufbauen und die Rückmeldung anzeigen kann:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
### Tags - mehrere Formulare derselben Aktionsart unterscheiden
Wenn auf einer Seite mehrere Formulare derselben Aktionsart vorkommen, zum Beispiel ein “In den Warenkorb”-Button in jeder Produktbox einer Kategorieseite, teilen sich alle diese Formulare standardmäßig dieselben Rückmeldungen. Das bedeutet: Tritt bei einem Produkt ein Fehler auf, würden alle Formulare auf der Seite diesen Fehler anzeigen.
Mit einem Tag lässt sich jede Aktion eindeutig unterscheiden. Als Tag eignet sich zum Beispiel die Produkt-ID:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $action = $wsActions.create("BasketItemAdd", tag=$product.id) }}
```
Der Shop erzeugt daraus eine eindeutige ID im Format `BasketItemAdd:42` (wobei `42` in diesem Beispiel die Produkt-ID wäre). Dadurch erhält jedes Produkt ein eigenes Aktionsobjekt und Fehler erscheinen nur beim betreffenden Formular.
Bei einigen Aktionen, insbesondere im Checkout, wird der Tag genutzt, um den Adresstyp direkt im Aktionsnamen festzulegen:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $commitBillAction = $wsActions.create("CheckoutCommitDraftAddress:bill") }}
{{ var $commitShippingAction = $wsActions.create("CheckoutCommitDraftAddress:shipping") }}
```
### Aktionen absichern
Aktionen können auf zwei Arten gegen unerlaubte Zugriffe geschützt werden - durch einen CSRF-Token, der bei jeder Aktion Pflicht ist und optional durch ein Captcha.
### CSRF-Schutz
CSRF (`Cross-Site Request Forgery`) bezeichnet einen Angriff, bei dem eine externe Website im Namen eines eingeloggten Benutzers unbemerkt Anfragen an den Shop sendet, zum Beispiel um eine Bestellung auszulösen oder Kontodaten zu ändern. Der CSRF-Schutz verhindert, dass solche Anfragen vom Shop akzeptiert werden.
Dazu wird für jede Benutzersitzung ein einmaliger CSRF-Token erzeugt. Weil der Token an die aktuelle Sitzung gebunden ist, kann eine fremde Website ihn nicht kennen und die Aktion damit nicht unbemerkt auslösen. Der Token steht direkt am Aktionsobjekt zur Verfügung und wird so eingebunden:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
### Captcha-Schutz
Für bestimmte Aktionen, zum Beispiel die Registrierung oder ein Kontaktformular, kann zusätzlich ein Captcha aktiviert werden. Ein Captcha ist eine Sicherheitsabfrage, die sicherstellt, dass das Formular von einem echten Menschen ausgefüllt wird und nicht von einem automatisierten Bot.
Ist der Captcha-Schutz für eine Aktion aktiv, wird die Aktion nur ausgeführt, wenn der Benutzer das Captcha erfolgreich gelöst hat. Schlägt die Prüfung fehl, wird die Aktion nicht ausgeführt.
Damit der Schutz greift, sind zwei Voraussetzungen nötig:
1. Die Aktion muss in der [Shop-Konfiguration](/konfiguration/security-sicherheitsregeln) unter `security.actionGuard` für den Captcha-Schutz eingetragen sein.
2. Das Captcha-Widget muss im Template des zugehörigen Formulars eingebunden sein. Mehr dazu [hier](https://websale.atlassian.net/wiki/x/AwAhdw).
Wird eine Aktion über einen Bestätigungslink per E-Mail ausgeführt (Opt-In-Link), findet keine Captcha-Prüfung statt. In diesem Fall gilt der Link selbst als Nachweis, dass ein Mensch gehandelt hat.
### Ausführung über Links
Aktionen ohne Benutzereingaben, zum Beispiel das Ausloggen oder das Entfernen eines Artikels aus dem Warenkorb, können über einen Link ausgelöst werden, ohne das ein Formular nötig ist.
Dazu wird mit [\$wsActions.url()](/frontend/referenz/module/wsactions#\$wsactions-url) eine URL erzeugt. Die Methode erwartet drei Angaben: den Aktionsnamen, die Zielseite nach der Ausführung und optionale Parameter als Liste. Sind keine optionalen Parameter nötig, wird eine leere Liste `{}` übergeben:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Ausloggen
```
### Ausführung per AJAX
Standardmäßig wird nach dem Absenden eines Formulars die gesamte Seite neu geladen. Manchmal ist das aber nicht gewünscht, zum Beispiel wenn nur ein kleiner Bereich der Seite aktualisiert werden soll, ohne das der Benutzer einen sichtbaren Neuladevorgang erlebt.
In solchen Fällen kann die Aktion per AJAX ausgeführt werden. Dabei werden die Daten im Hintergrund an den Shop geschickt und die Antwort (Erfolg oder Fehler) direkt per JavaScript verarbeitet, ohne die Seite neu zu laden. CSRF-Schutz ist dabei genauso erforderlich wie bei Formularen, der Token ist über [\$wsActions.csrfToken](/frontend/referenz/module/wsactions#\$wsactions-current-csrf) abrufbar.
Ein typisches Anwendungsbeispiel:\
Der Benutzer legt ein Produkt in den Warenkorb und nur der Warenkorb-Zähler im Header aktualisiert sich, der Rest der Seite bleibt unverändert.
```javascript theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
$.post("{{= $wsViews.viewUrl('ajax/actionResponse.json') }}", {
"wscsrf": "{{= $wsActions.csrfToken }}",
"wsact": "BasketItemAdd",
"productId": "12345",
"quantity": 2
}, function(data) {
if (data.success) {
// Aktion erfolgreich – z.B. Warenkorb-Zähler im Header aktualisieren
} else {
// Fehler anzeigen
console.log(data.errors);
}
});
```
### Mehrere Aktionen gleichzeitig ausführen
Manchmal sollen mit einem einzigen Klick auf “Absenden” mehrere Aktionen nacheinander ausgeführt werden. Ein typisches Beispiel ist der letzte Schritt im Checkout, bei dem die Rechnungsadresse und die Lieferadresse bestätigt und die Bestellung abgeschlossen werden.
Dafür wird statt des normalen `wsact`-Feldes das Feld `wsmultiact` verwendet, und zwar einmal pro Aktion. `wsact` und `wsmultiact` können nicht im selben Formular kombiniert werden.
Die Aktionen werden in der Reihenfolge ausgeführt in der die `wsmultiact`-Felder im Formular aufgelistet sind.\\
#### Felder einer Aktion zuordnen
Weil mehrere Aktionen im selben Formular Felder entgegennehmen, muss jedes Feld klar einer bestimmten Aktion zugeordnet werden. Das geschieht durch ein Präfix vor dem Feldnamen, getrennt durch `|`. Im Template sieht es so aus:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
Das bedeutet: Das Feld `addressType` mit dem Wert `bill` gehört zur Aktion `$commitBillAction`.\\
#### Fehler einer Aktion soll die nächste stoppen
Standardmäßig werden alle Aktionen ausgeführt, auch wenn eine davon fehlschlägt. Soll eine fehlgeschlagene Aktion die nachfolgende abbrechen, kann der Parameter `wsmultiactabortonerror` auf `on` gesetzt werden:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
#### Fehler einer Aktion ignorieren
`wsmultiactignoreerror` können einzelne Aktionen als unkritisch markiert werden. Schlägt eine so markierte Aktion fehl, wird das nicht als fataler Fehler behandelt. Der Parameter kann mehrfach angegeben werden, einmal pro Aktion:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
Einen Fehler zu ignorieren wirkt sich auf zwei Situationen aus:
* **Weiterleitung trotz Fehler** \
Standardmäßig bleibt der Nutzer bei einem Fehler auf der aktuellen Seite und wird nicht auf die in `wstarget` angegebene Zielseite weitergeleitet. Ist die fehlgeschlagene Aktion über `wsmultiactignoreerror` markiert, findet die Weiterleitung dennoch statt.
* **Folgeaktionen laufen weiter** \
Ist zusätzlich `wsmultiactabortonerror=on` gesetzt, würde ein Fehler normalerweise alle nachfolgenden Aktionen abbrechen. Aktionen, die über `wsmultiactignoreerror` markiert sind, lösen diesen Abbruch nicht aus - die Ausführung wird fortgesetzt.
**Beispiel: Checkout-Abschluss**\
Das folgende Beispiel zeigt den letzten Schritt eines Checkouts. Mit einem Klick auf “Jetzt bestellen” werden drei Aktionen nacheinander ausgeführt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $commitBillAction = $wsActions.create("CheckoutCommitDraftAddress:bill") }}
{{ var $commitShippingAction = $wsActions.create("CheckoutCommitDraftAddress:shipping") }}
{{ var $checkoutConfirm = $wsActions.create("CheckoutConfirm") }}
```
Ausführungsreihenfolge des Beispiels:
1. `CheckoutCommitDraftAddress:bill` - Rechnungsadresse übernehmen
2. `CheckoutCommitDraftAddress:shipping`- Lieferadresse übernehmen
3. `CheckoutConfirm` - Bestellung abschließen
### Ergebnis der Ausführung
#### Erfolg
War die Aktion erfolgreich, ist `$myAction.success` gleich `true`. In diesem Fall kann eine Erfolgsmeldung angezeigt oder der Benutzer über `wstarget` auf eine andere Seite weitergeleitet werden.
#### Fehler
Schlägt die Aktion fehl, zum Beispiel weil ein Pflichtfeld fehlt oder eine E-Mail-Adresse ungültig ist, ist `$myAction.error` gleich `true`. Die Fehlermeldungen sollten im Template ausgegeben werden, damit der Benutzer weiß, was korrigiert werden muss:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $myAction.error }}
Bitte korrigiere folgende Angaben:
{{ foreach $error in $myAction.errors }}
{{ if $error.text }}
- {{= $error.text }} ({{= $error.field }}){{ if $error.subCode }} – {{= $error.subCode }}{{ /if }}
{{ else }}
- {{= $error.code }} ({{= $error.field }}){{ if $error.subCode }} – {{= $error.subCode }}{{ /if }}
{{ /if }}
{{ /foreach }}
{{ /if }}
```
Welche Fehlercodes eine bestimmte Aktion zurückgeben kann, ist in der jeweiligen Aktionsdokumentation ausgeführt. Eine Erklärung aller Fehlereigenschaften findet sich in der [\$wsActions Modulreferenz](/frontend/referenz/module/wsactions).
### Weiterleitung
Nach einer erfolgreich ausgeführten Aktion kann der Benutzer auf eine Zielseite weitergeleitet werden. Das verhindert außerdem, dass ein Seiten-Reload das Formular erneut absendet. Mehr dazu [hier](#2-aktionen-vorbereiten).
***
## Aktionsübersicht
Eine vollständige Übersicht aller verfügbaren Aktionen findet sich in den jeweiligen Themenbereichen:
* [Account](/frontend/referenz/aktionen/account)
* [Basket](/frontend/referenz/aktionen/basket)
* [Checkout](/frontend/referenz/aktionen/checkout)
* [Consent](/frontend/referenz/aktionen/consent)
* [DirectOrder](/frontend/referenz/aktionen/directorder)
* [Inquiry](/frontend/referenz/aktionen/inquiry)
* [Inventory](/frontend/referenz/aktionen/inventory)
* [Newsletter](/frontend/referenz/aktionen/newsletter)
* [ProductRating](/frontend/referenz/aktionen/productrating)
* [Session](/frontend/referenz/aktionen/session)
* [Stores](/frontend/referenz/aktionen/stores)
* [TestMode](/frontend/referenz/aktionen/testmode)
* [Voucher](/frontend/referenz/aktionen/voucher)
* [WatchList](/frontend/referenz/aktionen/watchlist)
# Account
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/account
Aktionen für Kundenkonten: Konten und Adressen anlegen, Anmeldedaten und Passwörter ändern sowie B2B-Mitarbeiterkonten und Berechtigungen verwalten.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Kundenkonto beschrieben. Mithilfe dieser Aktionen können Sie Kundenkonten anlegen und verwalten, Anmeldedaten und Passwörter ändern sowie Adressen pflegen. Im B2B-Bereich ist zudem die Verwaltung von Mitarbeiterkonten und Berechtigungsgruppen möglich.
## Grundkonzept
**Abgrenzung der Möglichkeiten im Kundenkonto:**
* Daten lesen (Adressen, Profil, Login-Status) - erfolgt nicht über Aktionen, sondern über das Modul [\$wsAccount](/frontend/referenz/module/wsAccount).
* **Strukturelle Einstellungen** - (Adressfelder, Kundendatenfelder, B2B-Konfiguration) werden in der [Konfiguration](/konfiguration) festgelegt.
* Diese Seite beschreibt ausschließlich die Aktionen, die Konto-, Adress- und Berechtigungsdaten
### Grundlagen: Aufbau einer Aktion
Jede Aktion wird mit `$wsActions.create("")` erzeugt und in ein Formular eingebunden. Pflichtfelder jedes Formulars sind `wsact` (ID der Aktion) und `wscsrf` (CSRF-Token). Details siehe [Aktionen - Übersicht](/frontend/referenz/aktionen).
### Adressen: Typen, Standard und Sichtbarkeit
Adressen haben einen Typ (`bill` = Rechnungsadresse, `delivery` = Lieferadresse). Die erste Adresse eines Typs wird automatisch zur Hauptadresse dieses Typs. Über `SetMainAddress`, `SetDefaultBillAddress` und `SetDefaultDeliveryAddress` lassen sich Standardadressen festlegen, die im Checkout vorausgewählt werden.
Im B2B-Kontext besitzt jede Adresse zusätzlich eine Sichtbarkeit: privat (nur für ein Mitarbeiterkonto) oder firmenweit freigegeben. Welcher Wert beim Anlegen vorausgewählt ist, steuert `defaultAddressVisibility` (siehe `UpdateSubAccount`). Wem eine Adresse gehört, steuert das Feld `addressOwnerMemberId` (siehe `AddressCreate`).
### B2B: Mitarbeiterkonten & Berechtigungsgruppen
Diese Funktionen stehen ausschließlich für Firmenkonten im B2B-Bereich zur Verfügung; alle zugehörigen Aktionen erfordern Admin-Rechte. Eine Berechtigungsgruppe bündelt Rechte und Einschränkungen (z. B. erlaubte Zahlungsarten, Budgetgrenzen, gesperrte Seiten). Der typische Ablauf:
1. Gruppe anlegen → `CreatePrivilegeGroup`
2. Rechte/Einschränkungen der Gruppe setzen → `UpdatePrivileges`
3. Gruppe einem Mitarbeiterkonto zuweisen → `UpdateSubAccount` (`privilegeGroupId`)
Mitarbeiterkonten selbst werden über `SubAccountCreate`, `UpdateSubAccount` und `SubAccountDelete` verwaltet. Die in der Gruppe gesetzten Budgetgrenzen werden im Frontend am Mitarbeiterkonto schreibgeschützt über [\$wsAccount.paymentLimit](/frontend/referenz/module/wsAccount) und `$wsAccount.paymentLimitPerOrder` gelesen.
***
## Aktionen im Überblick
**Konto**
| **Aktion** | **Beschreibung** |
| ---------------------- | --------------------------------------------------------------- |
| `AccountRegister` | Erstellt ein neues Kundenkonto. |
| `AccountActivate` | Aktiviert ein bestehendes Kundenkonto über eine E-Mail-Adresse. |
| `AccountActivateOptIn` | Aktiviert ein bestehendes Kundenkonto per Opt-In-Token. |
| `EmailVerify` | Verifiziert eine E-Mail-Adresse per Double-Opt-In. |
| `AccountDelete` | Löscht den Account des eingeloggten Benutzers. |
| `AccountDeleteOptIn` | Bestätigt die Löschung eines Kundenkontos per Opt-In-Token. |
**Anmeldung & Passwort**
| **Aktion** | **Beschreibung** |
| ----------------------- | ------------------------------------------------------------------- |
| `Login` | Meldet einen Benutzer an. |
| `Logout` | Meldet einen eingeloggten Benutzer ab. |
| `UnlockLogin` | Entsperrt einen gesperrten Login-Zugang. |
| `PasswordForgotten` | Sendet eine Passwort-vergessen-E-Mail. |
| `ResetPassword` | Setzt das Passwort eines Benutzerkontos neu. |
| `CheckPasswordStrength` | Prüft die Stärke eines eingegebenen Passworts in Echtzeit per AJAX. |
**Konto- & Kontaktdaten**
| **Aktion** | **Beschreibung** |
| -------------------------- | ----------------------------------------------------------- |
| `EmailUpdate` | Ändert die hinterlegte E-Mail-Adresse eines Benutzerkontos. |
| `EmailUpdateOptIn` | Bestätigt die Änderung der E-Mail-Adresse per Opt-In-Token. |
| `accountDisplayNameUpdate` | Ändert den Anzeigenamen eines Kundenkontos. |
| `AccountSetCustomerData` | Setzt oder aktualisiert benutzerdefinierte Kundendaten. |
**Adressen**
| **Aktion** | **Beschreibung** |
| ------------------------------ | -------------------------------------------------------------- |
| `AddressCreate` | Erstellt eine neue Adresse für den eingeloggten Benutzer. |
| `AddressUpdate` | Bearbeitet eine bestehende Adresse des eingeloggten Benutzers. |
| `AddressDelete` | Löscht eine Adresse des eingeloggten Benutzers. |
| `SetMainAddress` | Legt eine Adresse als Hauptadresse fest. |
| `SetDefaultBillAddress` | Legt eine Adresse als Standard-Rechnungsadresse fest. |
| `SetDefaultDeliveryAddress` | Legt eine Adresse als Standard-Lieferadresse fest. |
| `RemoveDefaultBillAddress` | Entfernt die gesetzte Standard-Rechnungsadresse. |
| `RemoveDefaultDeliveryAddress` | Entfernt die gesetzte Standard-Lieferadresse. |
**Kreditkarten**
| **Aktion** | **Beschreibung** |
| ------------------ | --------------------------------------------------------- |
| `CreditCardDelete` | Löscht eine gespeicherte Kreditkarte aus dem Kundenkonto. |
**Gastkonto**
| **Aktion** | **Beschreibung** |
| --------------------- | ------------------------------------------------------------------------------------------ |
| `GuestRegister` | Erstellt aus einem Gast-Checkout ein vollwertiges Kundenkonto (E-Mail aus Checkout-Daten). |
| `SaveGuestDataToUser` | Erstellt aus einem Gast-Checkout ein vollwertiges Kundenkonto. |
**B2B – Mitarbeiterkonten** (Admin-Rechte erforderlich)
| **Aktion** | **Beschreibung** |
| ------------------ | ------------------------------------------------------------------------------------------------ |
| `SubAccountCreate` | Legt ein neues Mitarbeiterkonto an und sendet eine E-Mail mit dem Link zum Setzen des Passworts. |
| `UpdateSubAccount` | Aktualisiert die Einstellungen eines Mitarbeiterkontos. |
| `SubAccountDelete` | Löscht ein bestehendes Mitarbeiterkonto. |
| `AcceptInvitation` | Nimmt eine Einladung zu einem Firmenkonto per Double-Opt-In an. |
**B2B – Berechtigungsgruppen** (Admin-Rechte erforderlich)
| **Aktion** | **Beschreibung** |
| ---------------------- | ---------------------------------------------------------------------------- |
| `CreatePrivilegeGroup` | Legt eine neue Berechtigungsgruppe an. |
| `UpdatePrivileges` | Erstellt oder aktualisiert eine Berechtigungsgruppe mit definierten Rechten. |
| `DeletePrivilegeGroup` | Löscht eine bestehende Berechtigungsgruppe. |
***
## Konto-Lebenszyklus
### AccountRegister
Mit dieser Aktion wird ein neues Kundenkonto angelegt. Der Benutzer gibt dabei seine E-Mail-Adresse sowie ein Passwort an.
**Anwendungsbeispiel**\
Nutzbar auf einer Registrierungsseite, auf der neue Kunden ein Konto erstellen können, um z.B. ihre Bestellhistorie einzusehen oder Adressen zu verwalten.
**Parameter**
| **Name** | **Beschreibung** |
| ---------------- | -------------------------------------------------------------------- |
| `email` | Identifier des Benutzer-Accounts (standardmäßig die E-Mail-Adresse). |
| `password` | Passwort des Benutzer-Accounts. |
| `passwordRepeat` | Erneute Eingabe des Passworts - muss mit `password` übereinstimmen. |
**Fehlercodes**
| **Code** | **Beschreibung** |
| ---------------------- | --------------------------------------------------------------- |
| `missingId` | Parameter `id` ist leer. |
| `missingPassword` | Parameter `password` ist leer. |
| `passwordMismatch` | Parameter `password` und `passwordRepeat` sind nicht identisch. |
| `emailCheckFailed` | Parameter `id` enthält eine ungültige E-Mail-Adresse. |
| `passwordCheckFailed` | Passwort erfüllt nicht die erforderlichen Richtlinien. |
| `accountAlreadyExists` | Es existiert bereits ein Account mit der angegebenen `id`. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie die Aktion erstellt und in ein Formular eingebunden wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionAccountRegister = $wsActions.create("AccountRegister") }}
```
***
### AccountActivate
Mit dieser Aktion wird ein bestehendes Kundenkonto aktiviert. Die Aktion wird typischerweise über ein Formular ausgelöst.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf der der Kunde seine E-Mail-Adresse eingibt, um sein Konto zu aktivieren.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | -------------------------------------------------------------------- |
| `id` | Identifier des Benutzer-Accounts (standardmäßig die E-Mail-Adresse). |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------------- | ------------------------------------------------------------------ |
| `missingId` | Parameter `id` ist leer. |
| `emailCheckFailed` | Parameter `id`enthält eine ungültige E-Mail-Adresse. |
| `accountAlreadyExists` | Es existiert bereits ein aktiver Account mit der angegebenen `id`. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isAccountVerified](/frontend/referenz/module/wsAccount#%24wsaccount-isaccountverified)
**Beispiel** das zeigt, wie die Aktion erstellt und in ein Formular eingebunden wird, über das der Kunde seinen Account mit seiner E-Mail-Adresse aktiviert.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionAccountActivate = $wsActions.create("AccountActivate") }}
```
***
### AccountActivateOptIn
Mit dieser Aktion wird ein bestehendes Kundenkonto per Opt-In-Token aktiviert. Der Token wird dabei über einen Link in einer Bestätigungs-E-Mail an den Benutzer übermittelt.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf die der Kunde nach Klick auf den Opt-In-Link in der Registrierungs-E-Mail weitergeleitet wird.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------- | ---------------------------------------------- |
| `unauthorized` | Es wurde kein gültiger Opt-In-Token übergeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isAccountVerified](/frontend/referenz/module/wsAccount#%24wsaccount-isaccountverified)
**Beispiel** das zeigt, wie nach erfolgreicher Ausführung der Aktion eine Bestätigungsmeldung angezeigt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.name == "AccountActivateOptIn" and $wsActions.current.success }}
Account wurde aktiviert.
{{ /if }}
```
***
### EmailVerify
Mit dieser Aktion wird eine E-Mail-Adresse per Double-Opt-In verifiziert. Nach der Registrierung erhält der Kunde eine Bestätigungs-E-Mail; durch Klick auf den enthaltenen Link wird diese Aktion auf der Shop-Seite ausgeführt.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf die der Kunde nach Klick auf den Verifizierungslink in der Registrierungs-E-Mail weitergeleitet wird.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | -------------------------------------------- |
| `actionNotAllowed` | Kein gültiger Double-Opt-In-Token vorhanden. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie nach erfolgreichem Klick auf den Bestätigungslink eine Erfolgsmeldung ausgegeben wird und bei einem ungültigen Token ein entsprechender Hinweis erscheint.
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.name == "EmailVerify" }}
{{ if $wsActions.current.success }}
E-Mail-Adresse wurde verifiziert.
{{ else }}
E-Mail-Adresse konnte nicht verifiziert werden.
{{ /if }}
{{ /if }}
```
***
### AccountDelete
Mit dieser Aktion wird der Account des aktuell eingeloggten Benutzers unwiderruflich gelöscht.
**Anwendungsbeispiel**\
Nutzbar auf einer Account-Verwaltungsseite, auf der eingeloggte Kunden ihr Konto auf Wunsch selbst löschen können.
**Fehlercodes**
| **Code** | **Beschreibung** |
| --------------- | ---------------------------------- |
| **notLoggedIn** | Der Benutzer ist nicht eingeloggt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie die Aktion erstellt wird und über einen Bestätigungs-Button ausgelöst wird.
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionAccountDelete = $wsActions.create("AccountDelete") }}
```
***
### AccountDeleteOptIn
Mit dieser Aktion wird die Löschung eines Kundenkontos per Opt-In-Token bestätigt. Der Token wird über einen Link in einer Bestätigungs-E-Mail an den Benutzer übermittelt.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf die der Kunde nach Klick auf den Opt-In-Link in der Löschungs-E-Mail weitergeleitet wird.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------- | ---------------------------------------------- |
| `unauthorized` | Es wurde kein gültiger Opt-In-Token übergeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie nach erfolgreicher Ausführung der Aktion eine Bestätigungsmeldung angezeigt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.name == "AccountDeleteOptIn" and $wsActions.current.success }}
Account wurde gelöscht.
{{ /if }}
```
***
## Anmeldung & Passwort
### Login
Mit dieser Aktion wird ein Benutzer mit seinen Zugangsdaten angemeldet.
**Anwendungsbeispiel**\
Nutzbar auf der Login-Seite, auf der Kunden sich mit E-Mail-Adresse und Passwort in ihr Konto einloggen können.
**Parameter**
| **Name** | **Beschreibung** |
| ---------- | -------------------------------------------------------------------- |
| `id` | Identifier des Benutzer-Accounts (standardmäßig die E-Mail-Adresse). |
| `password` | Passwort des Benutzer-Accounts. |
**Fehlercodes**
| **Code** | **Beschreibung** |
| -------------------- | ------------------------------------------------------------------ |
| `missingId` | Parameter `id` ist leer. |
| `missingPassword` | Parameter `password` ist leer. |
| `emailCheckFailed` | Parameter `id` enthält eine ungültige E-Mail-Adresse. |
| `loginBlocked` | Zu viele ungültige Loginversuche. |
| `invalidCredentials` | Ungültiger Loginversuch - `id` oder `password` sind nicht korrekt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das ein Login-Formular mit E-Mail und Passwort sowie einer allgemeinen Fehlerausgabe bei ungültigen Angaben erstellt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionLogin = $wsActions.create("Login") }}
```
***
### Logout
Mit dieser Aktion wird ein eingeloggter Benutzer abgemeldet.
**Anwendungsbeispiel**\
Nutzbar als Logout-Button im Header oder auf der Account-Übersichtsseite.
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie die Aktion über einen einfachen Link ausgelöst wird, der den Benutzer nach dem Logout auf eine definierte Seite weiterleitet.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Ausloggen
```
***
### UnlockLogin
Mit dieser Aktion wird ein Login-Zugang entsperrt, der aufgrund zu vieler fehlgeschlagener Anmeldeversuche gesperrt wurde. Die Aktion kann sowohl von einem eingeloggten Benutzer als auch über einen Opt-In-Token ausgeführt werden.
**Anwendungsbeispiel**\
Nutzbar, wenn ein Kunde nach mehreren Fehleingaben aus seinem Konto ausgesperrt wurde und einen Entsperrlink per E-Mail erhalten hat.
**Fehlercodes**
| **Code** | **Beschreibung** |
| -------------- | ------------------------------------------------------------------------------------- |
| `unauthorized` | Der Benutzer ist nicht eingeloggt oder es wurde kein gültiger Opt-In-Token übergeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
* [\$wsAccount.isAccountVerified](/frontend/referenz/module/wsAccount#%24wsaccount-isaccountverified)
**Beispiel** das zeigt, wie nach erfolgreicher Ausführung der Aktion eine Bestätigungsmeldung angezeigt wird. Die Aktion selbst wird typischerweise über einen Opt-In-Link in einer E-Mail ausgelöst und benötigt kein Formular.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.name == "UnlockLogin" and $wsActions.current.success }}
Account wurde entsperrt
{{ /if }}
```
***
### PasswordForgotten
Mit dieser Aktion wird eine Passwort-vergessen-E-Mail an die angegebene E-Mail-Adresse gesendet. Die E-Mail enthält einen Opt-In-Link, der die Ausführung der Aktion `ResetPassword` erlaubt.
**Anwendungsbeispiel**\
Nutzbar auf einer “Passwort vergessen”-Seite, auf der Kunden ihre E-Mail-Adresse eingeben, um einen Wiederherstellungslink zu erhalten.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | ------------------------------------------------------------------------ |
| `email` | E-Mail-Adresse des Benutzerkontos, an die der Opt-In-Link gesendet wird. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------------ | ------------------------------------------------------------------ |
| `missingEmail` | Parameter `email` ist leer. |
| `emailCheckFailed` | Parameter `email` enthält keine gültige E-Mail-Adresse. |
| `passwordRecoveryFailed` | Es existiert kein Benutzerkonto zu der angegebenen E-Mail-Adresse. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
**Beispiel,** das ein Formular erstellt, über das der Kunde seine E-Mail-Adresse eingibt und nach erfolgreicher Ausführung eine Bestätigung erhält.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionPasswordForgotten = $wsActions.create("PasswordForgotten") }}
```
***
### ResetPassword
Mit dieser Aktion wird das Passwort eines Benutzerkontos neu gesetzt. Nach erfolgreicher Ausführung wird der Benutzer automatisch ausgeloggt. Standardmäßig gilt die Aktion für den eingeloggten Benutzer - wird ein Opt-In-Token mitgesendet, gilt sie für den mit dem Token verknüpften Benutzer.
**Anwendungsbeispiel**\
Nutzbar auf der Seite, auf die der Kunde über den Passwort-vergessen-Link weitergeleitet wird, um dort ein neues Passwort zu vergeben.
**Parameter**
| **Name** | **Beschreibung** |
| ------------------- | ------------------------------------------------------------------------------------------------- |
| `newPassword` | Das neue Passwort, das für das Benutzerkonto gesetzt werden soll. |
| `newPasswordRepeat` | Wiederholung des neuen Passworts zur Vermeidung von Tippfehlern. |
| `passwordAuth` | Bisheriges Passwort des Benutzerkontos. Nicht erforderlich, wenn ein Opt-In-Token verwendet wird. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| --------------------- | -------------------------------------------------------------------------- |
| `notLoggedIn` | Weder ein Opt-In-Token noch eine eingeloggte Session ist vorhanden. |
| `missingPassword` | Parameter `newPassword` ist leer. |
| `passwordMismatch` | Parameter `newPassword`und `newPasswordRepeat`sind nicht identisch. |
| `missingPasswordAuth` | Parameter `passwordAuth` ist leer. Tritt nur ohne Opt-In-Token auf. |
| `failedPasswordAuth` | Parameter `passwordAuth` stimmt nicht mit dem bisherigen Passwort überein. |
| `passwordCheckFailed` | `newPassword` entspricht nicht den Passwortregeln. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
* [\$wsAccount.isPasswordResetRequired](/frontend/referenz/module/wsAccount#%24wsaccount-ispasswordresetrequired)
**Beispiel** das zeigt, wie nach erfolgreichem Reset eine Bestätigung ausgegeben wird, bei einem gültigen Opt-In-Token das Formular zur Passwortvergabe erscheint und bei einem ungültigen Token ein Hinweis auf den abgelaufenen Link angezeigt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsOptIn.current.valid }}
{{ var $cActionResetPassword = $wsActions.create("ResetPassword") }}
{{ else }}
Der Link ist abgelaufen.
{{ /if }}
```
***
### CheckPasswordStrength
Mit dieser Aktion wird die Stärke eines eingegebenen Passworts in Echtzeit geprüft. Die Aktion wird per AJAX im Hintergrund ausgeführt und gibt ein JSON-Objekt mit dem Bewertungsergebnis zurück.
**Anwendungsbeispiel**\
Nutzbar auf Seiten mit Passwort-Eingabefeldern, z.B. auf der Registrierungsseite, um dem Kunden direktes Feedback zur Passwortstärke zu geben.
**Parameter**
| **Name** | **Beschreibung** |
| ---------- | ------------------------- |
| `password` | Das zu prüfende Passwort. |
**Rückgabewerte**
| **Wert** | **Beschreibung** |
| -------- | --------------------------------------- |
| `value` | Erreichte Punktzahl der Passwortstärke. |
| `max` | Maximale Punktzahl der Passwortstärke. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
**Beispiel** das zeigt, wie die Passwortstärke bei Eingabe in Echtzeit geprüft und dem Benutzer visuell als schwach, mittel oder stark angezeigt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionCheckPasswordStrength = $wsActions.create("CheckPasswordStrength") }}
```
***
## Konto- & Kontaktdaten
### EmailUpdate
Mit dieser Aktion wird die hinterlegte E-Mail-Adresse eines Benutzerkontos geändert.
**Anwendungsbeispiel**\
Nutzbar auf der Account-Verwaltungsseite, auf der eingeloggte Kunden ihre E-Mail-Adresse aktualisieren können.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | ---------------------------------------------------------------------- |
| `email` | Neue E-Mail-Adresse, die für das Benutzerkonto hinterlegt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------------- | ------------------------------------------------------------------- |
| `missingEmail` | Parameter `email` fehlt. |
| `emailCheckFailed` | Parameter `email` enthält keine gültige E-Mail-Adresse. |
| `accountAlreadyExists` | Es existiert bereits ein anderer Account mit dieser E-Mail-Adresse. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.email](/frontend/referenz/module/wsAccount#%24wsaccount-email)
**Beispiel** das ein Formular zur Eingabe einer neuen E-Mail-Adresse bereitstellt und nach erfolgreicher Ausführung eine Bestätigung ausgibt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionEmailUpdate = $wsActions.create("EmailUpdate") }}
{{ if $cActionEmailUpdate.success }}
E-Mail-Adresse erfolgreich aktualisiert.
{{ else }}
{{ /if }}
```
***
### EmailUpdateOptIn
Mit dieser Aktion wird die Änderung der E-Mail-Adresse per Opt-In-Token bestätigt. Der Token wird über einen Link in einer Bestätigungs-E-Mail an die neue E-Mail-Adresse übermittelt.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf die der Kunde nach Klick auf den Opt-In-Link in der Bestätigungs-E-Mail weitergeleitet wird.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------- | ---------------------------------------------- |
| `unauthorized` | Es wurde kein gültiger Opt-In-Token übergeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
**Beispiel** das zeigt, wie bei einem gültigen Opt-In-Token ein Bestätigungsformular angezeigt wird, nach erfolgreicher Ausführung eine Erfolgsmeldung erscheint und bei einem abgelaufenen Token ein entsprechender Hinweis ausgegeben wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionEmailUpdateOptIn = $wsActions.create("EmailUpdateOptIn") }}
{{ if $wsActions.current.success and $wsActions.current.name == "EmailUpdateOptIn" }}
E-Mail-Adresse wurde erfolgreich geändert.
{{ elseif $wsOptIn.current.valid }}
{{ else }}
Der Token ist abgelaufen.
{{ /if }}
```
***
### accountDisplayNameUpdate
Mit dieser Aktion wird der Anzeigename eines Kundenkontos geändert.
**Anwendungsbeispiel**\
Nutzbar auf der Account-Verwaltungsseite, auf der eingeloggte Kunden ihren Anzeigenamen aktualisieren können.
**Parameter**
| **Name** | **Beschreibung** |
| ------------- | ----------------------------------------------------------------------- |
| `displayName` | Der neue Anzeigename, der für das Benutzerkonto hinterlegt werden soll. |
**Fehlercodes**
| **Code** | **Beschreibung** |
| -------------------- | ---------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingDisplayName` | Parameter `displayName` fehlt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie die Aktion erstellt und in ein Formular eingebunden wird, über das der Kunde seinen Anzeigenamen aktualisieren kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionAccountDisplayNameUpdate = $wsActions.create("accountDisplayNameUpdate") }}
```
***
### AccountSetCustomerData
Mit dieser Aktion werden benutzerdefinierte Kundendaten für das eingeloggte Benutzerkonto gesetzt oder aktualisiert.
**Anwendungsbeispiel**\
Nutzbar auf der Account-Verwaltungsseite, auf der eingeloggte Kunden ihre persönlichen Daten wie z.B. Geburtsdatum oder Telefonnummer hinterlegen können.
**Parameter**
| **Name** | **Beschreibung** |
| -------------------------- | ------------------------------------- |
| `customerData.(fieldname)` | Die einzelnen Felder der Kundendaten. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------- | -------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `emptyCustomerData` | Es wurden keine Kundendatenfelder übergeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie die Aktion erstellt und in ein Formular eingebunden wird, über das der Kunde seine persönlichen Daten aktualisieren kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionAccountSetCustomerData = $wsActions.create("AccountSetCustomerData") }}
```
***
## Adressen
### AddressCreate
Mit dieser Aktion wird eine neue Adresse für den eingeloggten Benutzer erstellt.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, auf der Kunden neue Liefer- oder Rechnungsadressen anlegen können.
**Parameter**
| **Name** | **Beschreibung** |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `address.(fieldname)` | Die einzelnen Felder der Adresse, z.B. `address.firstName`, `address.street`etc. |
| `type` | Art der Adresse: - `“bill”` - Rechnungsadresse - `“delivery”` - Lieferadresse Handelt es sich für das betreffende Kundenkonto um die erste Adresse seiner Art, wird sie automatisch als Hauptadresse für den jeweiligen Typ gesetzt. |
| `address.addressOwnerMemberId` | *(B2B)* ID des Mitarbeiters, dem die Adresse gehört. Wird das Feld nicht übergeben oder auf `0` gesetzt, ist die Adresse eine firmenweite Adresse, die jeder Mitarbeiter sehen und nutzen kann. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt und kein Opt-In-Token vorhanden. |
| `emptyAddress` | Es wurden keine Adressfelder übergeben. |
| `addressCheckFailed` | Fehler in den Adressdaten. Wird über Sub-Codes konkretisiert: - `minlen` = zu wenig Zeichen - `maxlen` = zu viele Zeichen - `numeric` = ungültige Zeichen - `country` = Land nicht konfiguriert - `zip` = Postleitzahl fehlerhaft |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
**Beispiel** das zeigt, wie eine neue Adresse über ein Formular mit einzelnen Adressfeldern angelegt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionAddressCreate = $wsActions.create("AddressCreate") }}
```
**Beispiel (B2B)** das zeigt, wie eine Lieferadresse angelegt wird, die nur einem bestimmten Mitarbeiter gehört.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionAddressCreate = $wsActions.create("AddressCreate") }}
```
***
### AddressUpdate
Mit dieser Aktion wird eine bestehende Adresse des eingeloggten Benutzers bearbeitet.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, wenn ein Kunde eine seiner gespeicherten Adressen aktualisieren möchte.
**Parameter**
| **Name** | **Beschreibung** |
| --------------------- | ------------------------------------------------------------------------------ |
| `addressId` | Die ID der Adresse, die bearbeitet werden soll. |
| `address.(fieldname)` | Die einzelnen Felder der Adresse, die aktualisiert werden sollen. |
| `type` | Art der Adresse: - `“bill”` - Rechnungsadresse - `“delivery”` - Lieferadresse |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ---------------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt und es ist kein Opt-In-Token vorhanden. |
| `emptyAddress` | Es wurden keine Adressfelder übergeben. |
| `invalidAddressId` | Ungültige `addressId` - die Adresse existiert nicht oder gehört nicht zu diesem Benutzerkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
* [\$wsAccount.loadAddress](/frontend/referenz/module/wsAccount#%24wsaccount-loadaddress)
**Beispiel** das zeigt, wie eine bestehende Adresse anhand ihrer ID bearbeitet wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionAddressUpdate = $wsActions.create("AddressUpdate") }}
```
***
### AddressDelete
Mit dieser Aktion wird eine Adresse des eingeloggten Benutzers gelöscht.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, wenn ein Kunde eine nicht mehr benötigte Adresse entfernen möchte.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | --------------------------------------------- |
| `addressId` | Die ID der Adresse, die gelöscht werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ---------------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt und es ist kein Opt-In-Token vorhanden. |
| `invalidAddressId` | Ungültige `addressId` - die Adresse existiert nicht oder gehört nicht zu diesem Benutzerkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
**Beispiel** das zeigt, wie eine Adresse über ihre ID gelöscht wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionAddressDelete = $wsActions.create("AddressDelete") }}
```
***
### SetMainAddress
Mit dieser Aktion wird eine gespeicherte Adresse als Hauptadresse festgelegt. Die Hauptadresse wird im Checkout automatisch vorausgewählt.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, damit Kunden ihre bevorzugte Adresse als Standard für zukünftige Bestellungen hinterlegen können.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | ------------------------------------------------------------- |
| `addressId` | Die ID der Adresse, die als Hauptadresse gesetzt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | --------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingAddressId` | Parameter `addressId` fehlt. |
| `invalidAddressId` | Ungültige `addressId` - die Adresse existiert nicht oder gehört zu einem anderen Konto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
**Beispiel** das zeigt, wie eine Adresse per Button als Hauptadresse gesetzt wird, sofern sie es nicht bereits ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionSetMainAddress = $wsActions.create("SetMainAddress") }}
{{ foreach $cAddress in $wsAccount.addresses }}
{{ if $cAddress.id != $wsAccount.mainAddress.id }}
{{ /if }}
{{ /foreach }}
```
***
### SetDefaultBillAddress
Mit dieser Aktion wird eine gespeicherte Adresse als Standard-Rechnungsadresse festgelegt. Die Standard-Rechnungsadresse wird im Checkout automatisch als Rechnungsadresse vorausgewählt.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, damit Kunden eine bevorzugte Rechnungsadresse als Standard für zukünftige Bestellungen hinterlegen können.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | -------------------------------------------------------------------------- |
| `addressId` | Die ID der Adresse, die als Standard-Rechnungsadresse gesetzt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | --------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingAddressId` | Parameter `addressId` fehlt. |
| `invalidAddressId` | Ungültige `addressId` - die Adresse existiert nicht oder gehört zu einem anderen Konto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
* [\$wsAccount.defaultBillAddress](/frontend/referenz/module/wsAccount#%24wsaccount-defaultbilladdress)
**Beispiel** das zeigt, wie eine Adresse per Button als Standard-Rechnungsadresse gesetzt wird, sofern sie es nicht bereits ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSetDefaultBillAddress = $wsActions.create("SetDefaultBillAddress") }}
```
***
### SetDefaultDeliveryAddress
Mit dieser Aktion wird eine gespeicherte Adresse als Standard-Lieferadresse festgelegt. Die Standard-Lieferadresse wird im Checkout automatisch als Lieferadresse vorausgewählt.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, damit Kunden eine bevorzugte Lieferadresse als Standard für zukünftige Bestellungen hinterlegen können.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | ----------------------------------------------------------------------- |
| `addressId` | Die ID der Adresse, die als Standard-Lieferadresse gesetzt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | --------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingAddressId` | Parameter `addressId` fehlt. |
| `invalidAddressId` | Ungültige `addressId` - die Adresse existiert nicht oder gehört zu einem anderen Konto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
* [\$wsAccount.defaultDeliveryAddress](/frontend/referenz/module/wsAccount#\$wsaccount-defaultdeliveryaddress)
**Beispiel** das zeigt, wie eine Adresse per Button als Standard-Lieferadresse gesetzt wird, sofern sie es nicht bereits ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSetDefaultDeliveryAddress = $wsActions.create("SetDefaultDeliveryAddress") }}
```
***
### RemoveDefaultBillAddress
Mit dieser Aktion wird die gesetzte Standard-Rechnungsadresse des eingeloggten Benutzers entfernt.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, wenn ein Kunde die Standard-Rechnungsadresse zurücksetzen möchte, sodass im Checkout keine Adresse mehr vorausgewählt ist.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------- | ---------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
* [\$wsAccount.defaultBillAddress](/frontend/referenz/module/wsAccount#%24wsaccount-defaultbilladdress)
**Beispiel** das zeigt, wie die Standard-Rechnungsadresse über einen Button entfernt wird, sofern eine gesetzt ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionRemoveDefaultBillAddress = $wsActions.create("RemoveDefaultBillAddress") }}
```
***
### RemoveDefaultDeliveryAddress
Mit dieser Aktion wird die gesetzte Standard-Lieferadresse des eingeloggten Benutzers entfernt.
**Anwendungsbeispiel**\
Nutzbar auf der Adressverwaltungsseite, wenn ein Kunde die Standard-Lieferadresse zurücksetzen möchte, sodass im Checkout keine Adresse mehr vorausgewählt ist.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------- | ---------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
* [\$wsAccount.defaultDeliveryAddress](/frontend/referenz/module/wsAccount#\$wsaccount-defaultdeliveryaddress)
**Beispiel** das zeigt, wie die Standard-Lieferadresse über einen Button entfernt wird, sofern eine gesetzt ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionRemoveDefaultDeliveryAddress = $wsActions.create("RemoveDefaultDeliveryAddress") }}
```
***
## Kreditkarten
### CreditCardDelete
Mit dieser Aktion wird eine gespeicherte Kreditkarte aus dem Kundenkonto gelöscht.
**Anwendungsbeispiel**\
Nutzbar auf der Kreditkartenverwaltungsseite, auf der eingeloggte Kunden ihre gespeicherten Kreditkarten einsehen und entfernen können.
**Parameter**
| **Name** | **Beschreibung** |
| ------------ | ------------------------------------------------- |
| `pseudoCCId` | Die ID der Kreditkarte, die gelöscht werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------- | --------------------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `invalidPseudoCCId` | Ungültige `pseudoCCId` - die Kreditkarte existiert nicht oder gehört nicht zu diesem Benutzerkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.pseudoCreditCards](/frontend/referenz/module/wsAccount#%24wsaccount-pseudocreditcards)
**Beispiel** das zeigt, wie alle gespeicherten Kreditkarten aufgelistet werden und jede einzelne über einen Button gelöscht werden kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cCreditCards = $wsAccount.pseudoCreditCards }}
{{ foreach $cCreditCard in $wsAccount.pseudoCreditCards }}
{{ var $cActionCreditCardDelete = $wsActions.create("CreditCardDelete") }}
{{ /foreach }}
```
***
## Gast → Konto
### GuestRegister
Mit dieser Aktion wird aus einem Gast-Checkout ein vollwertiges Kundenkonto erstellt. Der Gast gibt dabei ein Passwort an, die E-Mail-Adresse wird automatisch aus den Checkout-Daten übernommen.
**Anwendungsbeispiel**\
Nutzbar auf der Bestellbestätigungsseite nach einem Gast-Checkout, auf der nicht eingeloggte Kunden die Möglichkeit erhalten, sich direkt ein Konto anzulegen.
**Parameter**
| **Name** | **Beschreibung** |
| ---------------- | ----------------------------------------------------------------------------------- |
| `guestMail` | E-Mail-Adresse des Gast-Kontos, wird automatisch aus den Checkout-Daten übernommen. |
| `password` | Neues Passwort für das Kundenkonto. |
| `passwordRepeat` | Wiederholung des Passworts. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `passwordCheckFailed` | Passwort erfüllt nicht die erforderlichen Richtlinien. Wird über Sub-Codes konkretisiert: - `minlen` = zu wenig Zeichen - `maxlen` = zu viele Zeichen |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
* [\$wsAccount.email](/frontend/referenz/module/wsAccount#%24wsaccount-email)
**Beispiel** das zeigt, wie nicht eingeloggten Kunden nach einem Gast-Checkout die Möglichkeit geboten wird, ein Kundenkonto anzulegen, inklusive Erfolgsausgabe.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if not $wsAccount.isLoggedIn }}
{{ var $cGuestRegister = $wsActions.create("GuestRegister") }}
{{ if $cGuestRegister.success }}
Es wurde ein Konto angelegt.
{{ /if }}
{{ if not $cGuestRegister.success }}
{{ /if }}
{{ /if }}
```
***
### SaveGuestDataToUser
Mit dieser Aktion wird aus den Daten eines Gast-Checkouts ein vollwertiges Kundenkonto erstellt. Der Gast gibt dabei ein Passwort an und erhält damit Zugang zu einem dauerhaften Konto.
**Anwendungsbeispiel**\
Nutzbar auf der Bestellbestätigungsseite nach einem Gast-Checkout, um dem Kunden die Möglichkeit zu geben, sich direkt ein Konto anzulegen, ohne erneut alle Daten eingeben zu müssen.
**Parameter**
| **Name** | **Beschreibung** |
| ---------------- | ----------------------------------- |
| `id` | E-Mail-Adress des Gast-Kontos. |
| `password` | Neues Passwort für das Kundenkonto. |
| `passwordRepeat` | Wiederholung des Passworts. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| --------------------- | --------------------------------------------------------------- |
| `nonGuestAccount` | Der Benutzer ist bereits in einem Kundenkonto eingeloggt. |
| `missingId` | Parameter `id` fehlt. |
| `missingPassword` | Parameter `password` fehlt. |
| `passwordMismatch` | Parameter `password` und `passwordRepeat` sind nicht identisch. |
| `passwordCheckFailed` | Passwortregel-Prüfung ist fehlgeschlagen. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#%24wsaccount-addresses)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie ein Gast-Kunde nach dem Checkout ein dauerhaftes Konto anlegen kann, indem er nur ein Passwort vergeben muss.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionSaveGuestDataToUser = $wsActions.create("SaveGuestDataToUser") }}
```
***
## B2B – Mitarbeiterkonten
Alle Aktionen in diesem Abschnitt erfordern Admin-Rechte und stehen nur für Firmenkonten im B2B-Bereich zur Verfügung. Eine Einführung in das Zusammenspiel von Mitarbeiterkonten und Berechtigungsgruppen findet sich im Abschnitt [Konzepte](#konzepte).
### SubAccountCreate
Mit dieser Aktion wird ein neues Mitarbeiterkonto angelegt. An die angegebene E-Mail-Adresse wird automatisch eine [E-Mail](https://dokumentation.websale.de/konfiguration/b2b-business-to-business-b2b#b2b-userinvitation-benutzereinladung) mit einem Link zum Setzen des Passworts gesendet. Für diese Aktion sind Admin-Rechte erforderlich.
**Anwendungsbeispiel**\
Nutzbar auf der Account-Verwaltungsseite, auf der Administratoren neue Mitarbeiterkonten anlegen können.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | ------------------------------------------------------------------------------------------------------------------- |
| `email` | E-Mail-Adresse des neuen Mitarbeiterkontos.
An diese Adresse wird der Link zum Setzen des Passworts gesendet. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------------- | -------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `unauthorized` | Der Benutzer verfügt nicht über Admin-Rechte. |
| `missingId` | Parameter `email` ist leer. |
| `emailCheckFailed` | Parameter `email`enthält eine ungültige E-Mail-Adresse. |
| `accountAlreadyExists` | Es existiert bereits ein Account mit der angegebenen E-Mail-Adresse. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie die Aktion erstellt und in ein Formular eingebunden wird, über das ein neues Mitarbeiterkonto angelegt werden kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSubAccountCreate = $wsActions.create("SubAccountCreate") }}
```
***
### UpdateSubAccount
Mit dieser Aktion werden die Einstellungen des bestehenden Mitarbeiterkontos aktualisiert. Eine Deaktivierung des eigenen Kontos oder das Entziehen der Admin-Rechte ist nicht möglich. Für diese Aktion sind Admin-Rechte erforderlich.
**Anwendungsbeispiel**\
Nutzbar auf der Mitarbeiterverwaltungsseite, auf der Administratoren Rollen und weitere Einstellungen von Mitarbeiterkonten anpassen können.
**Parameter**
| Name | Beschreibung |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `memberId` | Die ID des Mitarbeiterkontos, das aktualisiert werden soll. |
| `displayName` | Anzeigename des Mitarbeiterkontos. |
| `active` | Gibt an, ob sich das Mitarbeiterkonto anmelden darf (`true` / `false`).
Das eigene Konto kann nicht deaktiviert werden. |
| `admin` | Gibt an, ob das Konto Admin-Rechte besitzt (`true` / `false`).
Dem eigenen Konto können keine Admin-Rechte entzogen werden. |
| `privilegeGroupId` | ID der Berechtigungsgruppe, die dem Mitarbeiterkonto zugewiesen wird. |
| `defaultAddressVisibility` | Legt fest, welche Sichtbarkeit beim Anlegen neuer Adressen standardmäßig vorausgewählt ist.
Mögliche Werte:
- `private` (nur für dieses Konto sichtbar)
- `shared` (firmenweit freigegeben) |
| `allowedSubshops` | Legt fest, auf welche Subshops das Mitarbeiterkonto Zugriff hat.
Die [Subshop-IDs](https://dokumentation.websale.de/frontend/referenz/module/wssubshop#\$wssubshop-subshops) werden als Schlüssel eines JSON-Objekts übergeben, z.B. `{"shop1": true, "shop2": true}.` |
**Fehlercodes**
| Fehlercode | Beschreibung |
| -------------------------- | ------------------------------------------------------------------------------------------------ |
| notLoggedIn | Der Benutzer ist nicht eingeloggt. |
| unauthorized | Der Benutzer verfügt nicht über Admin-Rechte. |
| missingMemberId | Parameter `memberId` fehlt. |
| invalidMemberId | Ungültige `memberId` - das Mitarbeiterkonto existiert nicht oder gehört nicht zu diesem Account. |
| selfDeactivationNotAllowed | Das eigene Konto kann nicht deaktiviert werden. |
| selfAdminRemovalNotallowed | Dem eigenen Konto können keine Admin-Rechte entzogen werden. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](https://dokumentation.websale.de/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](https://dokumentation.websale.de/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
* [\$wsSubshop.subshops](https://dokumentation.websale.de/frontend/referenz/module/wssubshop#\$wssubshop-subshops)
**Beispiel** das zeigt, wie die Einstellungen eines Mitarbeiterkontos über ein Formular aktualisiert werden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionUpdateSubAccount = $wsActions.create("UpdateSubAccount") }}
```
***
### SubAccountDelete
Mit dieser Aktion wird ein bestehendes Mitarbeiterkonto gelöscht. Das eigene Konto sowie Konten mit Admin-Rechten können nicht gelöscht werden. Für diese Aktion sind Admin-Rechte erforderlich.
**Anwendungsbeispiel**\
Nutzbar auf der Mitarbeiterverwaltungsseite, auf der Administratoren nicht mehr benötigte Mitarbeiterkonten entfernen können.
**Parameter**
| Name | Beschreibung |
| ---------- | ------------------------------------------------------- |
| `memberId` | Die ID des Mitarbeiterkontos, das gelöscht werden soll. |
**Fehlercodes**
| Fehlercode | Beschreibung |
| -------------------- | ---------------------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `unauthorized` | Der Benutzer verfügt nicht über Admin-Rechte. |
| `missingMemberId` | Parameter `memberId `fehlt. |
| `invalidMemberId` | Ungültige `memberId `- das Mitarbeiterkonto existiert nicht oder gehört nicht zu diesem Account. |
| `deletionNotAllowed` | Das Konto darf nicht gelöscht werden, weil es sich um das eigene Konto oder ein Admin-Konto handelt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](https://dokumentation.websale.de/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](https://dokumentation.websale.de/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie ein Mitarbeiterkonto über seine ID gelöscht wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSubAccountDelete = $wsActions.create("SubAccountDelete") }}
```
***
### AcceptInvitation
Mit dieser Aktion nimmt ein B2B-Firmenkunde eine Einladung per Double-Opt-In-Verfahren an. Der Token ist in einem Link enthalten, den der Kunde per E-Mail erhält. Nach erfolgreicher Verifizierung hat das Konto vollen Zugriff auf den Shop.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf die der eingeladene Kunde nach Klick auf den Einladungslink in der E-Mail weitergeleitet wird.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | -------------------------------------------------------------------- |
| `unauthorized` | Es wurde kein gültiger Opt-In-Token übergeben. |
| `invalidAccountId` | Der Double-Opt-In-Token konnte keinem Kundenkonto zugeordnet werden. |
| `actionNotAllowed` | Der Double-Opt-In-Token ist ungültig oder passt nicht zum Konto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.isAccountVerified](/frontend/referenz/module/wsAccount#%24wsaccount-isaccountverified)
**Beispiel** das zeigt, wie nach erfolgreicher Annahme der Einladung eine Bestätigungsmeldung angezeigt wird.
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.name == "AcceptInvitation" and $wsActions.current.success }}
Einladung wurde angenommen.
{{ /if }}
```
***
## B2B – Berechtigungsgruppen
Alle Aktionen in diesem Abschnitt erfordern Admin-Rechte und stehen nur für Firmenkonten im B2B-Bereich zur Verfügung. Zum Zusammenspiel mit Mitarbeiterkonten siehe Abschnitt [Konzepte](#konzepte).
### CreatePrivilegeGroup
Mit dieser Aktion wird eine neue Berechtigungsgruppe erstellt. Für diese Aktion sind Admin-Rechte erforderlich.
**Anwendungsbeispiel**\
Nutzbar auf der Berechtigungsverwaltungsseite, auf der Administratoren neue Gruppen mit definierten Rechten für Mitarbeiterkonten erstellen können.
**Parameter**
| Name | Beschreibung |
| ------ | ----------------------------------- |
| `name` | Name der neuen Berechtigungsgruppe. |
**Fehlercodes**
| Fehlercode | Beschreibung |
| -------------- | --------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `unauthorized` | Der Benutzer verfügt nicht über Admin-Rechte. |
| `missingName` | Parameter `name` fehlt oder ist leer. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](https://dokumentation.websale.de/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](https://dokumentation.websale.de/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie eine neue Berechtigungsgruppe über ein Formular angelegt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCreatePrivilegeGroup = $wsActions.create("CreatePrivilegeGroup") }}
```
***
### UpdatePrivileges
Mit dieser Aktion wird eine Berechtigungsgruppe aktualisiert. Für diese Aktion sind Admin-Rechte erforderlich.
**Anwendungsbeispiel**\
Nutzbar auf der Berechtigungsverwaltungsseite, auf der Administratoren Rechte und Einschränkungen für Berechtigungsgruppen definieren können.
**Parameter**
| Name | Beschreibung |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `privilegeId` | Die ID der Berechtigungsgruppe, die aktualisiert werden soll. |
| `createMissing` | Gibt an, ob die Gruppe automatisch erstellt werden soll, falls sie nicht existiert.
Mögliche Werte:
- `yes` |
| `type` | Art der Berechtigungsgruppe:
- `global` (shopweit)
- `account` (kontobezogen) |
| `privileges` | JSON-Objekt mit den Berechtigungsfeldern.
Mögliche Felder:
- `allowedPaymentMethods` (JSON-Objekt mit erlaubten Zahlungsarten: Zahlarten-ID als Schlüssel, `"1"` als Wert schaltet die Zahlart frei, alle anderen Werte werden ignoriert)
- `paymentLimitPerOrder` (maximaler Bestellwert pro Bestellung)
- `paymentLimit` (globale Budgetgrenze über alle Bestellungen seit Limitsetzung)
- `blockedTemplates` (gesperrte Templates / Seiten der Gruppe)
- `blockedUrls` (gesperrte URLs der Gruppe)
- `editableFields` (bearbeitbare Felder der Gruppe)
- `groupName` (nur relevant bei `type = global`) |
Die beiden Budgetgrenzen wirken zusammen: `paymentLimitPerOrder` begrenzt jede einzelne Bestellung, `paymentLimit` die kumulierte Ausgabensumme. Beide Werte werden im Frontend schreibgeschützt direkt am Account gelesen, über [\$wsAccount.paymentLimit](/frontend/referenz/module/wsAccount) bzw. `$wsAccount.paymentLimitPerOrder`.
Über `allowedPaymentMethods` können nur Zahlarten freigeschaltet werden, die auch für das Firmenkonto selbst verfügbar sind: Zahlarten, die für das Konto gesperrt sind (`blockedPaymentMethods`) oder in der Shop-Konfiguration mit `availableByDefault: false` angelegt und nicht gezielt für das Konto freigeschaltet wurden (`enabledPaymentMethods`), können keiner Berechtigungsgruppe zugewiesen werden (siehe [Konfiguration Zahlungsmethoden](/konfiguration/payment-zahlungsmethoden)).
**Fehlercodes**
| Fehlercode | Beschreibung |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `unauthorized` | Der Benutzer verfügt nicht über Admin-Rechte. |
| `missingPrivilegeId` | Parameter `privilegeId` fehlt. |
| `invalidPrivilegeId` | Ungültige `privilegeId` - die Gruppe existiert nicht und `createMissing` ist nicht gesetzt. |
| `invalidType` | Parameter `type` enthält einen ungültigen Wert. |
| `paymentMethodNotAllowedByAccount` | Eine Zahlart in `allowedPaymentMethods` ist für das Firmenkonto selbst nicht verfügbar (gesperrt oder nicht freigeschaltet). |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](https://dokumentation.websale.de/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](https://dokumentation.websale.de/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
* [\$wsAccount.paymentLimit](/frontend/referenz/module/wsAccount)
**Beispiel** das zeigt, wie die Berechtigungen einer Gruppe inklusive globaler und bestellbezogener Budgetgrenze aktualisiert werden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionUpdatePrivileges = $wsActions.create("UpdatePrivileges") }}
```
***
### DeletePrivilegeGroup
Mit dieser Aktion wird eine bestehende Berechtigungsgruppe gelöscht. Eine Gruppe kann jedoch nicht gelöscht werden, solange ihr noch Mitarbeiterkonten zugewiesen sind. Für diese Aktion sind Admin-Rechte erforderlich.
**Anwendungsbeispiel**\
Nutzbar auf der Berechtigungsverwaltungsseite, wenn eine nicht mehr benötigte Berechtigungsgruppe entfernt werden soll.
**Parameter**
| Name | Beschreibung |
| ---- | --------------------------------------------------------- |
| `id` | Die ID der Berechtigungsgruppe, die gelöscht werden soll. |
**Fehlercodes**
| Fehlercode | Beschreibung |
| ----------------- | -------------------------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `unauthorized` | Der Benutzer verfügt nicht über Admin-Rechte. |
| `missingId` | Parameter `id` fehlt. |
| `invalidId` | Ungültige `id` - die Berechtigungsgruppe existiert nicht. |
| `groupHasMembers` | Die Berechtigungsgruppe kann nicht gelöscht werden, da ihr noch Mitarbeiterkonten zugewiesen sind. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](https://dokumentation.websale.de/frontend/referenz/module/wsAccount)
* [\$wsAccount.isLoggedIn](https://dokumentation.websale.de/frontend/referenz/module/wsAccount#%24wsaccount-isloggedin)
**Beispiel** das zeigt, wie eine Berechtigungsgruppe über ihre ID gelöscht wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionDeletePrivilegeGroup = $wsActions.create("DeletePrivilegeGroup") }}
```
# Basket
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/basket
Warenkorb-Aktionen im Überblick: BasketItemAdd, BasketItemUpdate, BasketItemDelete sowie VoucherAdd und VoucherDelete zum Verwalten des Warenkorbs.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Warenkorb beschrieben. Mit diesen Aktionen können Produkte hinzugefügt, aktualisiert und entfernt sowie Gutscheine verwaltet werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| ------------------ | ------------------------------------------------------- |
| `BasketItemAdd` | Legt ein Produkt in den Warenkorb. |
| `BasketItemUpdate` | Aktualisiert die Menge eines Produkts im Warenkorb. |
| `BasketItemDelete` | Entfernt ein Produkt aus dem Warenkorb. |
| `VoucherAdd` | Löst einen Gutscheincode im Warenkorb ein. |
| `VoucherDelete` | Entfernt einen eingelösten Gutschein aus dem Warenkorb. |
***
## Aktionen
### BasketItemAdd
Mit dieser Aktion wird ein Produkt in den Warenkorb gelegt.
**Anwendungsbeispiel**\
Nutzbar auf Produktedetail-, Kategorie- oder Merklisten-Seiten, auf denen Produkte direkt in den Warenkorb legen können.
**Parameter**
| **Name** | **Beschreibung** |
| ------------------------ | ------------------------------------------------------------------------------ |
| `productId` | Die ID des Produkts, das in den Warenkorb gelegt werden soll. |
| `quantity` | Die gewünschte Menge des Produkts. |
| `freeFieldscategoryPath` | Optionales Freifeld zur Übergabe des Kategoriepfads, z.B. für Tracking-Zwecke. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ----------------------------------------------------- |
| `missingProductId` | Parameter `productId` fehlt. |
| `invalidProductId` | Das Produkt existiert nicht oder ist nicht verfügbar. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsBasket](/frontend/referenz/module/wsbasket)
* [\$wsBasket.items](/frontend/referenz/module/wsbasket#\$wsbasket-items)
* [\$wsBasket.lastBasketAction](/frontend/referenz/module/wsbasket#\$wsbasket-lastbasketaction)
* [\$wsBasket.lastUpdatedItem](/frontend/referenz/module/wsbasket#\$wsbasket-lastupdateditem)
**Beispiel** das zeigt, wie ein Produkt mit Mengenauswahl in den Warenkorb gelegt wird und nach erfolgreicher Ausführung eine Bestätigungsmeldung erscheint.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.success and $wsActions.current.name == "BasketItemAdd" }}
Produkt zum Warenkorb hinzugefügt.
{{ /if }}
{{ var $myActionBasketItemAdd = $wsActions.create("BasketItemAdd") }}
```
***
### BasketItemUpdate
Mit dieser Aktion wird die Menge eines im Warenkorb enthaltenen Produkts aktualisiert.
**Anwendungsbeispiel**\
Nutzbar auf der Warenkorbseite oder im Warenkorb-Offcanvas, wenn Kunden die Menge eines bereits hinzugefügten Produkts anpassen möchten.
**Parameter**
| **Name** | **Beschreibung** |
| -------------- | --------------------------------------------------------------------- |
| `basketItemId` | Die ID des Warenkorb-Eintrags, dessen Menge aktualisiert werden soll. |
| `quantity` | Die neue Menge des Produkts. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| --------------------- | ---------------------------------------------------------------------------- |
| `missingBasketItemId` | Parameter `basketItemId` fehlt. |
| `invalidBasketItemId` | Der Warenkorb-Eintrag existiert nicht oder gehört nicht zu diesem Warenkorb. |
| `missingQuantity` | Parameter `quantity` fehlt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsBasket](/frontend/referenz/module/wsbasket)
* [\$wsBasket.items](/frontend/referenz/module/wsbasket#\$wsbasket-items)
* [\$wsBasket.lastBasketAction](/frontend/referenz/module/wsbasket#\$wsbasket-lastbasketaction)
* [\$wsBasket.lastUpdatedItem](/frontend/referenz/module/wsbasket#\$wsbasket-lastupdateditem)
**Beispiel** das zeigt, wie die Menge eines Warenkorb-Eintrags über ein Formular aktualisiert wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionBasketItemUpdate = $wsActions.create("BasketItemUpdate", tag = $myProduct.id) }}
```
***
### BasketItemDelete
Mit dieser Aktion wird ein Produkt aus dem Warenkorb entfernt.
**Anwendungsbeispiel**\
Nutzbar auf der Warenkorbseite oder im Warenkorb-Offcanvas, wenn Kunden ein Produkt vollständig aus dem Warenkorb entfernen möchten.
**Parameter**
| **Name** | **Beschreibung** |
| -------------- | -------------------------------------------------------- |
| `basketItemId` | Die ID des Warenkorb-Eintrags, der entfernt werden soll. |
| `productId` | Die ID des Produkts, das entfernt werden soll. |
| `quantity` | Die aktuelle Menge des Produkts. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| --------------------- | ---------------------------------------------------------------------------- |
| `missingBasketItemId` | Parameter `basketItemId` fehlt. |
| `invalidBasketItemId` | Der Warenkorb-Eintrag existiert nicht oder gehört nicht zu diesem Warenkorb. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsBasket](/frontend/referenz/module/wsbasket)
* [\$wsBasket.items](/frontend/referenz/module/wsbasket#\$wsbasket-items)
* [\$wsBasket.lastBasketAction](/frontend/referenz/module/wsbasket#\$wsbasket-lastbasketaction)
* [\$wsBasket.lastUpdatedItem](/frontend/referenz/module/wsbasket#\$wsbasket-lastupdateditem)
**Beispiel** das zeigt, wie ein Produkt über einen Button aus dem Warenkorb entfernt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionBasketItemDelete = $wsActions.create("BasketItemDelete", tag = $myProduct.id) }}
```
# Checkout
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/checkout
Checkout-Aktionen für den Bestellablauf: Rechnungs- und Lieferadressen auswählen, zwischenspeichern und in den Bestellprozess übernehmen.
In diesem Abschnitt werden die verfügbaren Aktionen im Checkout beschrieben. Mit diesen Aktionen können beispielsweise Rechnungs- und Lieferadressen ausgewählt, zwischengespeichert und übernommen werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| ------------------------------------- | ---------------------------------------------------------------------------------- |
| `CheckoutAccountTypeSelect` | Legt den Kontotyp für den aktuellen Bestellvorgang fest. |
| `CheckoutBillAddressSelect` | Setzt eine gespeicherte Adresse als aktive Rechnungsadresse. |
| `CheckoutShippingAddressSelect` | Setzt eine gespeicherte Adresse als aktive Lieferadresse. |
| `CheckoutSetDraftAddress` | Speichert eine Adresse temporär als Entwurf (ohne Validierung). |
| `CheckoutCommitDraftAddress` | Übernimmt einen Adressentwurf als verbindliche Checkout-Adresse (mit Validierung). |
| `CheckoutUseSameShippingAddress` | Setzt die Lieferadresse gleich der Rechnungsadresse. |
| `CheckoutUseDifferentShippingAddress` | Aktiviert eine abweichende Lieferadresse. |
| `CheckoutSetGuestEmail` | Setzt die E-Mail-Adresse für eine Gastbestellung. |
| `CheckoutPaymentUpdate` | Setzt die Zahlungsart für den aktuellen Bestellvorgang. |
| `CheckoutShippingMethodUpdate` | Setzt die Versandart für den aktuellen Bestellvorgang. |
| `CheckoutConfirm` | Schickt die Bestellung verbindlich ab. |
| `RefreshPaymentStatus` | Aktualisiert den Status einer laufenden Zahlung und gibt ihn zurück. |
| `CheckoutSetFreeFields` | Setzt die freien Checkout-Felder, beispielsweise die AGB-Zustimmung. |
| `CheckoutSetCustomerData` | Setzt Kundendaten im Checkout. |
| `CheckoutPseudoCCSelect` | Wählt eine gespeicherte Pseudo-Kreditkarte aus. |
| `CheckoutNewsletterSubscribe` | Meldet den Kunden während des Checkouts zum Newsletter an. |
| `CheckoutSetVerificationStatus` | Setzt den Verifizierungsstatus der Bestellung. (**Doku folgt**) |
| `CheckoutStoreIdSelect` | Setzt einen Markt als Abholort für den aktuellen Bestellvorgang. |
***
## Aktionen
### CheckoutBillAddressSelect
Mit dieser Aktion wählt der Kunde eine seiner bereits gespeicherten Adressen als Rechnungsadresse für den aktuellen Bestellvorgang aus. Die Auswahl wird sofort übernommen, es ist keine weitere Bestätigung nötig.
**Anwendungsbeispiel**
Nutzbar, um beispielsweise eingeloggten Kunden im Checkout ein Dropdown mit ihren gespeicherten Adressen anzuzeigen, sodass sie eine Rechnungsadresse mit einem Klick auswählen können, ohne erneute Eingabe.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | ----------------------------------------------------------------- |
| `addressId` | Die ID der Adresse, die als Rechnungsadresse gesetzt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ------------------------------------------------------------------------------- |
| `missingAddressId` | Parameter `addressId` fehlt. |
| `invalidAddressId` | Die angegebene Adresse existiert nicht oder gehört nicht zu diesem Kundenkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.selectedBillAddress](/frontend/referenz/module/wscheckout#\$wscheckout-selectedbilladdress)
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#\$wsaccount-addresses)
**Beispiel** das zeigt, wie eingeloggten Kunden ein Dropdown mit ihren gespeicherten Adressen angezeigt wird, über das sie eine Rechnungsadresse auswählen können.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myCheckoutBillAddressSelect = $wsActions.create("CheckoutBillAddressSelect") }}
```
***
### CheckoutShippingAddressSelect
Mit dieser Aktion wählt der Kunde eine seiner bereits gespeicherten Adressen als Lieferadresse für den aktuellen Bestellvorgang aus. Die Aktion ist nur relevant, wenn der Kunde eine abweichende Lieferadresse angeben möchte.
**Anwendungsbeispiel**
Nutzbar, wenn ein Kunde eine Bestellung an eine andere Adresse schicken möchte.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | -------------------------------------------------------------- |
| `addressId` | Die ID der Adresse, die als Lieferadresse gesetzt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ------------------------------------------------------------------------------- |
| `missingAddressId` | Parameter `addressId` fehlt. |
| `invalidAddressId` | Die angegebene Adresse existiert nicht oder gehört nicht zu diesem Kundenkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsAccount.addresses](/frontend/referenz/module/wsAccount#\$wsaccount-addresses)
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.selectedShippingAddress](/frontend/referenz/module/wscheckout#\$wscheckout-selectedshippingaddress)
**Beispiel** das zeigt, wie eingeloggten Kunden ein Dropdown mit ihren gespeicherten Adressen angezeigt wird, über das sie eine Lieferadresse auswählen können.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myCheckoutShippingAddressSelect = $wsActions.create("CheckoutShippingAddressSelect") }}
```
***
### CheckoutSetDraftAddress
Mit dieser Aktion wird eine vom Kunden eingegebene Adresse vorläufig gespeichert, ohne dass die Eingaben sofort auf Vollständigkeit oder Korrektheit geprüft werden. Die Draft-Adresse wirkt sich dabei bereits auf die verfügbaren Versand- und Zahlungsarten aus, die auf Basis der Eingaben angepasst werden (relevant für den OnePage-Checkout).
Die Adresse gilt zunächst als Entwurf und wird erst durch [CheckoutCommitDraftAddress](#checkoutcommitdraftaddress) als verbindliche Checkout-Adresse übernommen. Der Adresstyp wird direkt im Aktionsnamen angegeben (`bill` oder `shipping`).
**Anwendungsbeispiel**
Nutzbar im OnePage-Checkout, um die eingegebene Adresse laufend zwischenzuspeichern, ohne den Kunden sofort mit Validierungsfehlern zu konfrontieren. Die eigentliche Prüfung der Adresse erfolgt erst beim Klick auf “Jetzt kaufen” über [CheckoutCommitDraftAddress](#checkoutcommitdraftaddress).
**Parameter**
| **Name** | **Beschreibung** |
| --------------------- | ------------------------------------------------------------------------------------------- |
| `address.(fieldname)` | Die einzelnen Felder der Adresse, beispielsweise `address.firstName` oder `address.street`. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.draftBillAddressId](/frontend/referenz/module/wscheckout#\$wscheckout-draftbilladdressid)
* [\$wsCheckout.draftShippingAddressId](/frontend/referenz/module/wscheckout#\$wscheckout-draftshippingaddressid)
**Beispiel** das zeigt, wie eine Rechnungsadresse als Entwurf zwischengespeichert wird, ohne sie sofort zu validieren.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSetDraftBillAddress = $wsActions.create("CheckoutSetDraftAddress:bill") }}
```
***
### CheckoutCommitDraftAddress
Mit dieser Aktion wird ein zuvor per [CheckoutSetDraftAddress](#checkoutsetdraftaddress) gespeicherter Adressentwurf validiert und als Checkout-Adresse übernommen. Das Verhalten unterscheidet sich je nach Bestelltyp:
* Gastbestellung - die eingegebene Adresse wird geprüft und, sofern gültig, direkt für den Checkout übernommen.
* Bestellung mit Kundenkonto - die eingegebene Adresse wird geprüft und, sofern gültig, als neue Adresse im Kundenkonto angelegt und gleichzeitig für den aktuellen Checkout ausgewählt.
Sind die Daten fehlerhaft oder unvollständig, schlägt die Validierung fehl und der Entwurf bleibt erhalten, sodass der Kunde seine Eingaben korrigieren kann. Der Adresstyp wird direkt im Aktionsnamen angegeben (`bill` oder `shipping`).
Diese Aktion bildet zusammen mit [CheckoutSetDraftAddress](#checkoutsetdraftaddress) den typischen Adress-Workflow im OnePage-Checkout:
[CheckoutSetDraftAddress](#checkoutsetdraftaddress) speichert die Eingaben laufend zwischen (ohne Validierung), `CheckoutCommitDraftAddress` schließt den Prozess ab.
**Anwendungsbeispiel**
Nutzbar als abschließender Schritt im OnePage-Checkout. Der Kunde hat seine Adresse bereits eingegeben und erst beim Klick auf “Jetzt kaufen” wird geprüft, ob alle Angaben korrekt und vollständig sind.
**Parameter**
| **Name** | **Beschreibung** |
| --------------------- | ------------------------------------------------------------------------------------------- |
| `address.(fieldname)` | Die einzelnen Felder der Adresse, beispielsweise `address.firstName` oder `address.street`. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `addressCheckFailed` | Fehler in den Adressdaten. Wird über Sub-Codes konkretisiert:
`minlen` = zu wenig Zeichen
`maxlen` = zu viele Zeichen
`numeric` = ungültige Zeichen
`country` = Land nicht konfiguriert
`zip` = Postleitzahl fehlerhaft |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.isValidShippingAddress()](/frontend/referenz/module/wscheckout#\$wscheckout-isvalidshippingaddress)
* [\$wsCheckout.isValidBillAddress()](/frontend/referenz/module/wscheckout#\$wscheckout-isvalidbilladdress)
**Beispiel** das zeigt, wie ein Rechnungsadress-Entwurf validiert und als verbindliche Checkout-Adresse übernommen wird. Bei fehlerhaften Eingaben bleibt der Entwurf erhalten und Fehler werden ausgegeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCommitDraftBillAddress = $wsActions.create("CheckoutCommitDraftAddress:bill") }}
{{ include "components/errorAlert.htm" with $myAction = $myActionCommitDraftBillAddress }}
```
***
### CheckoutUseSameShippingAddress
Mit dieser Aktion wird festgelegt, dass die Lieferung an dieselbe Adresse wie die Rechnungsadresse erfolgen soll. Eine zuvor eingegebene oder ausgewählte abweichende Lieferadresse wird dadurch nicht gelöscht, aber für den Checkout nicht mehr berücksichtigt.
**Anwendungsbeispiel**
Nutzbar, um dem Kunden beispielsweise per Checkbox die Möglichkeit zu geben, Rechnungs- und Lieferadresse mit einem Klick gleichzusetzen, ohne erneute Eingabe.
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.useAlternativeShippingAddress](/frontend/referenz/module/wscheckout#\$wscheckout-usealternativeshippingaddress)
**Beispiel** das zeigt, wie die Aktion über ein verstecktes Formular ausgelöst wird, das per JavaScript an eine Checkbox gekoppelt werden kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutUseSameShippingAddress = $wsActions.create("CheckoutUseSameShippingAddress") }}
```
***
### CheckoutUseDifferentShippingAddress
Mit dieser Aktion wird eine abweichende Lieferadresse für den Checkout aktiviert. Sobald sie ausgelöst wurde, wird der Bereich zur Auswahl oder Eingabe einer separaten Lieferadresse relevant. Die Aktion kehrt den Effekt von [CheckoutUseSameShippingAddress](#checkoutusesameshippingaddress) um.
**Anwendungsbeispiel**
Nutzbar, wenn der Kunde eine Bestellung an eine andere Adresse liefern lassen möchte, beispielsweise direkt an eine Filiale.
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.useAlternativeShippingAddress](/frontend/referenz/module/wscheckout#\$wscheckout-usealternativeshippingaddress)
**Beispiel** das zeigt, wie die Aktion über ein verstecktes Formular ausgelöst wird, das per JavaScript an eine Checkbox gekoppelt werden kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutUseDifferentShippingAddress = $wsActions.create("CheckoutUseDifferentShippingAddress") }}
```
***
### CheckoutAccountTypeSelect
Mit dieser Aktion wird der Kontotyp für den aktuellen Bestellvorgang festgelegt. Der gewählte Typ bestimmt, welche Schritte im Checkout-Prozess angezeigt werden.
**Anwendungsbeispiel**
Nutzbar auf der Login-Seite im Checkout-Kontext, um dem Kunden die Möglichkeit zu geben, als Gast zu bestellen, ohne ein Konto anlegen zu müssen.
**Parameter**
| **Name** | **Beschreibung** |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `accountType` | Der gewünschte Kontotyp. Mögliche Werte: - `guest` - Gastkonto - `new` - Neues Kundenkonto - `registered` - Registrierter Kunde |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------------- | ------------------------------------- |
| `invalidAccountType` | Der angegebene Kontotyp ist ungültig. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.accountType](/frontend/referenz/module/wscheckout#\$wscheckout-accounttype)
**Beispiel** das zeigt, wie der Kontotyp auf “`guest`” gesetzt wird, um eine Gastbestellung zu ermöglichen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutAccountTypeSelect = $wsActions.create("CheckoutAccountTypeSelect") }}
```
***
### CheckoutSetGuestEmail
Mit dieser Aktion wird die E-Mail-Adresse für eine Gastbestellung gesetzt. Sie ist nur relevant, wenn der Kontotyp auf “`guest`” gesetzt wurde.
**Anwendungsbeispiel**
Nutzbar im Checkout, wenn ein Kunde als Gast bestellen möchte und dafür seine E-Mail-Adresse angeben muss.
**Parameter**
| **Name** | **Beschreibung** |
| ------------ | ---------------------------------- |
| `guestEmail` | Die E-Mail-Adresse des Gastkunden. |
**Fehlercodes**
| **Code** | **Beschreibung** |
| ------------------ | ------------------------------------------------------------ |
| `missingEmail` | Parameter `guestEmail` fehlt. |
| `emailCheckFailed` | Parameter `guestEmail` enthält keine gültige E-Mail-Adresse. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.guestMail](/frontend/referenz/module/wscheckout#\$wscheckout-guestmail)
* [\$wsCheckout.accountType](/frontend/referenz/module/wscheckout#\$wscheckout-accounttype)
**Beispiel** das zeigt, wie ein Gastkunde seine E-Mail-Adresse im Checkout eingibt, inklusive Fehlerausgabe bei ungültiger Eingabe.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutSetGuestEmail = $wsActions.create("CheckoutSetGuestEmail") }}
```
***
### CheckoutShippingMethodUpdate
Mit dieser Aktion wird die Versandart für den aktuellen Bestellvorgang gesetzt.
**Anwendungsbeispiel**
Nutzbar im Checkout, um dem Kunden eine Liste der verfügbaren Versandarten anzuzeigen, aus der er eine auswählen kann.
**Parameter**
| **Name** | **Beschreibung** |
| ------------------ | -------------------------------------------------- |
| `shippingMethodId` | Die ID der Versandart, die ausgewählt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------------- | ---------------------------------------------- |
| `missingShippingMethodId` | Parameter `shippingMethodId` fehlt. |
| `invalidShippingMethodId` | Die angegebene Versandart ist nicht verfügbar. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.selectedShippingMethod](/frontend/referenz/module/wscheckout#\$wscheckout-selectedshippingmethod)
* [\$wsCheckout.isValidShippingMethod()](/frontend/referenz/module/wscheckout#\$wscheckout-isvalidshippingmethod)
* [\$wsCheckout.problems.shippingMethod](/frontend/referenz/module/wscheckout#\$wscheckout-problems-shippingmethod)
**Beispiel** das zeigt, wie alle verfügbaren Versandarten als Auswahlliste dargestellt werden, wobei nicht verfügbare Optionen deaktiviert sind.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutShippingMethodUpdate = $wsActions.create("CheckoutShippingMethodUpdate") }}
```
***
### CheckoutConfirm
Mit dieser Aktion wird die Bestellung verbindlich abgeschickt. Sie ist der abschließende Schritt im Checkout-Prozess und setzt voraus, dass alle erforderlichen Angaben (Adresse, Zahlungsart und Versandart) vollständig und gültig sind.
**Anwendungsbeispiel**
Nutzbar als “Jetzt kaufen”-Button auf der Bestellübersichtsseite, über den der Kunde die Bestellung verbindlich aufgibt.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ----------------- | ------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt und es ist keine Gast-E-Mail vorhanden. |
| `invalidCheckout` | Der Checkout ist nicht vollständig oder enthält ungültige Angaben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.isValid](/frontend/referenz/module/wscheckout#\$wscheckout-isvalid)
* [\$wsCheckout.problems](/frontend/referenz/module/wscheckout#\$wscheckout-problems)
* [\$wsCheckout.isExpressCheckoutLocked](/frontend/referenz/module/wscheckout#\$wscheckout-isexpresscheckoutlocked)
**Beispiel** das zeigt, wie die Bestellung über einen Button verbindlich abgeschickt wird, sofern der Kunde eingeloggt oder als Gast identifiziert ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutConfirm = $wsActions.create("CheckoutConfirm") }}
```
***
### RefreshPaymentStatus
Mit dieser Aktion wird der Status einer Zahlung manuell aktualisiert. Die Aktion fragt den aktuellen Stand ab und gibt ihn im JSON-Format zurück.
Eine Erfolgsmeldung des Zahlungsdienstleisters bedeutet dabei noch nicht, dass die Zahlung im Shop gültig ist. Meldet PayPal beispielsweise eine erfolgreiche Zahlung, muss der Shop diese nicht zwingend akzeptieren. Ist die 3DS-Prüfung nicht durchgelaufen, lehnt der Shop die Zahlung aus Sicherheitsgründen ab. Außerdem kann die Zahlung beim Einzug des Betrags noch in einen Fehler laufen. Der zurückgegebene Status ist deshalb die Bewertung des Shops und nicht die Rückmeldung des Zahlungsdienstleisters.
**Anwendungsbeispiel**
Nutzbar auf der Wartseite einer Online-Zahlung. Der Kunde darf erst dann auf die Bestellbestätigung geführt werden, wenn diese Aktion die Zahlung als fehlerfrei abgeschlossen meldet. Meldet sie einen Fehler oder einen Abbruch, gehört der Kunde in die Fehlerbehandlung.
**Antwort**
Die Antwort enthält immer das Feld `paymentStatus`.
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"paymentStatus": "pending"
}
```
| **Wert** | **Bedeutung** |
| ----------------- | -------------------------------------------------------------------------------------------- |
| `unknown` | Es gibt keine Zahlung, deren Status abgefragt werden kann. |
| `redirected` | Der Kunde wurde zum Zahlungsdienstleister weitergeleitet, ein Ergebnis liegt noch nicht vor. |
| `pending` | Die Zahlung wurde angenommen, ist aber noch in Bearbeitung. |
| `finished` | Die Zahlung ist abgeschlossen und vom Shop akzeptiert. |
| `canceledByUser` | Die Zahlung wurde vom Kunden abgebrochen. |
| `canceledByAdmin` | Die Zahlung wurde im Backend abgebrochen. |
| `error` | Bei der Zahlung ist ein Fehler aufgetreten oder der Shop hat sie abgelehnt. |
Die Zustände entsprechen den Zahlungsstatus, die auch die REST-API für [Bestellungen](/schnittstellen/admin-interface-api/api-referenz-bestellungen) und Transaktionen verwendet. Dort werden sie numerisch geführt, in dieser Antwort als Text. Neben den hier aufgeführten Werten kann die Transaktion weitere Status annehmen, beispielsweise nach einer Rückerstattung im Backend. Behandeln Sie unbekannte Werte im Template daher als offenen Status.
**Fehler in der Antwort**
Hat `paymentStatus` den Wert `error`, enthält die Antwort zusätzlich das Feld `errors` mit einer Liste der aufgetretenen Fehler.
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"paymentStatus": "error",
"errors": [
{
"code": "",
"subCode": "",
"field": "",
"text": "",
"details": {}
}
]
}
```
| **Feld** | **Typ** | **Beschreibung** |
| --------- | ------- | --------------------------------------------------------------------------------- |
| `code` | string | Fehlercode. |
| `subCode` | string | Optionaler Code zur genaueren Bestimmung von `code`. |
| `field` | string | Feld, in dem der Fehler aufgetreten ist. Bei Zahlungsfehlern ohne Feldbezug leer. |
| `text` | string | Anzeigetext des Fehlers. |
| `details` | object | Zusätzliche Angaben zum Fehler. |
Die Liste ist bisher immer leer. Die Befüllung wird erst später umgesetzt, das Format steht aber bereits fest und kann im Frontend berücksichtigt werden. Werten Sie den Fehlerfall deshalb über den Statuswert `error` aus und nicht über die Länge der Liste.
**Zugehörige Module, Variablen & Methoden**
* [\$wsActions](/frontend/referenz/module/wsactions)
* [API-Referenz Bestellungen](/schnittstellen/admin-interface-api/api-referenz-bestellungen)
***
### CheckoutSetFreeFields
Mit dieser Aktion werden die freien Checkout-Felder gesetzt, beispielsweise die Zustimmung zu den AGB oder ein Kommentarfeld. Die Aktion wird typischerweise zusammen mit `CheckoutConfirm` auf der Bestellübersichtsseite eingesetzt.
**Anwendungsbeispiel**
Nutzbar auf der Bestellübersichtsseite, um dem Kunden beispielsweise eine Checkbox zur Zustimmung der AGB anzuzeigen, die vor dem Abschicken der Bestellung akzeptiert werden muss.
**Parameter**
| **Name** | **Beschreibung** |
| ----------------------- | -------------------------------------------------------------------------------------- |
| `freeFields.(id).value` | Der Wert des freien Felds, beispielsweise `freeFields.agb.value` für die AGB-Checkbox. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------------- | --------------------------------------- |
| `missingRequiredField` | Ein Pflichtfeld wurde nicht ausgefüllt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.freeFields](/frontend/referenz/module/wscheckout#\$wscheckout-freefields)
**Beispiel** das zeigt, wie eine AGB-Checkbox als freies Checkout-Feld eingebunden wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSetFreeFields = $wsActions.create("CheckoutSetFreeFields") }}
```
***
### CheckoutSetCustomerData
Mit dieser Aktion werden zusätzliche Kundendaten im Checkout gesetzt. Die Felder werden dynamisch aus der Konfiguration geladen und können gruppiert oder ungruppiert vorliegen.
**Anwendungsbeispiel**
Nutzbar im Checkout, um konfigurierte Kundendaten-Felder (beispielsweise Firmenname oder Telefon) abzufragen, die über die Standardadresse hinausgehen.
**Parameter**
| **Name** | **Beschreibung** |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `(dynamisch)` | Die Felder werden aus [\$wsCheckout.customerData](/frontend/referenz/module/wscheckout#\$wscheckout-customerdata) geladen und variieren je nach Shop-Konfiguration. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.customerData](/frontend/referenz/module/wscheckout#\$wscheckout-customerdata)
* [\$wsCheckout.customerData.fieldGroups](/frontend/referenz/module/wscheckout#\$wscheckout-customerdata-fieldgroups)
**Beispiel** das zeigt, wie gruppierte Kundendaten-Felder dynamisch gerendert und Fehler feldspezifisch ausgegeben werden:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $setCustomerDataAction = $wsActions.create("CheckoutSetCustomerData") }}
```
***
### CheckoutPseudoCCSelect
Mit dieser Aktion wählt der Kunde eine seiner gespeicherten Pseudo-Kreditkarten für den aktuellen Bestellvorgang aus. Die Aktion ist ausschließlich für die Computop-Kreditkarten-Integration relevant.
**Anwendungsbeispiel**
Nutzbar im Checkout, wenn der Kunde eine zuvor hinterlegte Kreditkarte verwenden möchte, ohne die Kartendaten erneut einzugeben. Der Wert `0` steht für “keine gespeicherte Karte verwenden”.
**Parameter**
| **Name** | **Beschreibung** |
| ------------ | -------------------------------------------------------------------------------- |
| `pseudoCCId` | Die ID der gespeicherten Pseudo-Kreditkarte. Der Wert `0` wählt keine Karte aus. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.selectedPseudoCC](/frontend/referenz/module/wscheckout#\$wscheckout-selectedpseudocc)
**Beispiel** das zeigt, wie gespeicherte Kreditkarten zur Auswahl angezeigt werden, inklusive der Option, keine Karte zu verwenden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myAction = $wsActions.create("CheckoutPseudoCCSelect") }}
```
***
### CheckoutNewsletterSubscribe
Mit dieser Aktion wird ein Kunde während des Bestellvorgangs für den Newsletter angemeldet. Sie funktioniert analog zur Aktion [NewsletterSubscribe](/frontend/referenz/aktionen/newsletter). Parameter, Fehlercodes und das Feldübergabe-Verhalten sind identisch.
**Anwendungsbeispiel**
Nutzbar im Checkout, um Kunden während des Bestellvorgangs die Möglichkeit zu geben, sich für den Newsletter anzumelden, beispielsweise über eine Checkbox auf der Bestellübersichtsseite.
**Parameter**
| Name | Beschreibung |
| -------------------- | ------------------------------------------------------------------- |
| `email` | Die E-Mail-Adresse, die für den Newsletter angemeldet werden soll. |
| `targetGroupId.(id)` | Optionale Zielgruppen-ID, für die der Kunde angemeldet werden soll. |
**Fehlercodes**
| Fehlercode | Beschreibung |
| ---------------------- | ------------------------------------------------------------- |
| `missingEmail` | Parameter `email` fehlt. |
| `emailCheckFailed` | Die angegebene E-Mail-Adresse ist ungültig. |
| `accountAlreadyExists` | Die E-Mail-Adresse ist bereits für den Newsletter angemeldet. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsNewsletter](/frontend/referenz/module/wsnewsletter)
* [\$wsNewsletter.getTargetGroups()](/frontend/referenz/module/wsnewsletter#\$wsnewsletter-gettargetgroups)
**Beispiel** das zeigt, wie ein Kunde im Checkout eine Zielgruppe auswählt und sich für den Newsletter anmeldet.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutNewsletterSubscribe = $wsActions.create("CheckoutNewsletterSubscribe") }}
```
***
### CheckoutStoreIdSelect
Mit dieser Aktion wählt der Kunde einen Markt als Abholort für den aktuellen Bestellvorgang aus. Die Aktion ist nur relevant, wenn eine Versandart vom Typ `pickup` ausgewählt wurde. Bei der Auswahl wird geprüft, ob alle Produkte im gewählten Markt verfügbar sind. Ist das nicht der Fall, wird die Aktion nicht ausgeführt und es wird ein Fehler zurückgegeben.
Wurde kein Markt ausgewählt, wird standardmäßig der Markt aus der allgemeinen [Session-Auswahl](/frontend/referenz/aktionen/stores#selectstore) verwendet.
**Anwendungsbeispiel**
Nutzbar, wenn der Kunde eine Bestellung direkt in einem Markt abholen möchte und im Checkout aus den verfügbaren Click & Collect-Märkten wählen soll.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `reservationFailed` | Die Artikel sind im gewählten Markt nicht verfügbar. Details zum betroffenen Produkt werden über `error.details.productId` zurückgegeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCheckout.selectedStoreID](/frontend/referenz/module/wscheckout#\$wscheckout-selectedstoreid)
* [\$wsCheckout.selectedShippingMethod](/frontend/referenz/module/wscheckout#\$wscheckout-selectedshippingmethod)
* [\$wsStores](/frontend/referenz/module/wsstores)
* [\$wsStores.loadAllStores()](/frontend/referenz/module/wsstores#\$wsstores-loadallstores)
* [\$wsConfig.shippingMethods](/frontend/referenz/module/wsconfig#\$wsconfig-shippingmethods)
**Beispiel,** das für jede Versandart vom Typ `pickup` ein Dropdown mit allen Click & Collect-fähigen Märkten zeigt. Es setzt den gewählten Markt per `CheckoutStoreIdSelect` als Abholort, inklusive Fehlerbehandlung bei nicht verfügbaren Artikeln im gewählten Markt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionCheckoutStoreIdSelect = $wsActions.create("CheckoutStoreIdSelect") }}
{{ foreach $myShipping in $wsConfig.shippingMethods }}
{{ if $wsCheckout.selectedShippingMethod == $myShipping.id and $myShipping.type == "pickup" }}
{{ if $myActionCheckoutStoreIdSelect.error }}
{{ foreach $myError in $myActionCheckoutStoreIdSelect.errors }}
{{ if $myError.code == "reservationFailed" }}
Artikel im Store nicht verfügbar: {{= $myError.details.productId }}
{{ /if }}
{{ /foreach }}
{{ /if }}
{{ /if }}
{{ /foreach }}
```
***
## Weiterführende Links
* [\$wsActions](/frontend/referenz/module/wsactions)
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsStores](/frontend/referenz/module/wsstores)
* [payment - Zahlungsmethoden](/konfiguration/payment-zahlungsmethoden)
# Consent
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/consent
Consent-Aktionen für den Cookie-Banner: Einwilligung des Nutzers zu nicht-essenziellen Cookies und Diensten setzen oder nachträglich ändern.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Consent beschrieben. Mit diesen Aktionen kann die Zustimmung des Nutzers zu nicht-essenziellen Cookies und Diensten gesetzt oder geändert werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| --------------- | ---------------------------------------------------------------------------- |
| `ConsentChange` | Setzt oder ändert die Zustimmung zu nicht-essenziellen Cookies und Diensten. |
***
## Aktionen
### ConsentChange
Mit dieser Aktion wird die Zustimmung des Nutzers zu nicht-essenziellen Cookies gesetzt oder geändert. Die Zustimmung kann auf oberster Ebene (gesamtes Consent-Objekt), auf Gruppenebene oder auf Ebene einzelner Dienste innerhalb einer Gruppe gesteuert werden.
**Anwendungsbeispiel**\
Nutzbar, um z.B. in einem Cookie-Banner dem Nutzer die Möglichkeit zu geben, seine Zustimmung für alle Cookies auf einmal, für bestimmte Gruppen (z.B. “Marketing”, “Statistik”) oder für einzelne Dienste (z.B. “Google Analytics”) gezielt zu erteilen oder zu widerrufen.
**Parameter**
| **Parameter** | **Beschreibung** |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `consent` | Setzt die Zustimmung auf oberster Ebene für alle nicht-essenziellen Cookies. |
| `groups.` | Setzt die Zustimmung für eine bestimmte Consent-Gruppe. `` steht für den Namen der jeweiligen Gruppe. |
| `groups..services.` | Setzt die Zustimmung für einen einzelnen Dienst innerhalb einer Gruppe. `` steht für den Namen des jeweiligen Dienstes. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------- | -------------------------------------------------------- |
| `invalidGroup` | Die angegebene Gruppe existiert nicht oder ist ungültig. |
| `invalidService` | Der angegebene Dienst existiert nicht oder ist ungültig. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsConsent](/frontend/referenz/module/wsconsent)
* [\$wsConsent.groups](/frontend/referenz/module/wsconsent#\$wsconsent-groups)
* [\$wsConsent.services](/frontend/referenz/module/wsconsent#\$wsconsent-services)
**Beispiel** das zeigt, wie in einem Cookie-Banner die Zustimmung pro Gruppe und pro Dienst über Checkboxen gesteuert wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionConsentChange = $wsActions.create("ConsentChange") }}
```
# DirectOrder
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/directorder
DirectOrder-Aktionen für die Direktbestellung: Produkte per Artikelnummer in eine Bestellliste eintragen, ändern und in den Warenkorb übernehmen.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Direktbestellung beschrieben. Mit diesen Aktionen können Produkte pro Artikelnummer direkt in eine Bestellliste eingetragen, aktualisiert und in den Warenkorb übernommen werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| ------------------------ | ---------------------------------------------------------------- |
| `DirectOrderAdd` | Fügt ein Produkt per Artikelnummer zur Direktbestellliste hinzu. |
| `DirectOrderUpdate` | Aktualisiert die Menge eines Produkts in der Direktbestellliste. |
| `DirectOrderDelete` | Entfernt ein Produkt aus der Direktbestellliste. |
| `DirectOrderAddLines` | Fügt eine weitere Eingabezeile zur Direktbestellliste hinzu. |
| `DirectOrderDeleteLines` | Entfernt die letzte Eingabezeile aus der Direktbestellliste. |
***
## Aktionen
### DirectOrderAdd
Mit dieser Aktion wird ein Produkt per Artikelnummer zur Direktbestellliste hinzugefügt. Nach erfolgreicher Ausführung wird das Produkt mit seinen Informationen in der Liste angezeigt.
**Anwendungsbeispiel**\
Nutzbar auf der Direktbestellseite, auf der Kunden Produkte schnell per Artikelnummer suchen und zur Bestellliste hinzufügen können, ohne die Produktdetailseite aufrufen zu müssen.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | ------------------------------------------------------------ |
| `id` | Die Artikelnummer des Produkts, das hinzugefügt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------------ | ----------------------------------------- |
| `errorsByField.id` | Fehler bei der Eingabe der Artikelnummer. |
| `errorsByField.quantity` | Fehler bei der Eingabe der Menge. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsDirectOrder](/frontend/referenz/module/wsdirectorder)
* [\$wsDirectOrder.items](/frontend/referenz/module/wsdirectorder#\$wsdirectorder-items)
* [\$wsDirectOrders.currentLines](/frontend/referenz/module/wsdirectorder#\$wsdirectorder-currentlines)
**Beispiel** das zeigt, wie ein Produkt über ein Artikelnummer-Eingabefeld zur Direktbestellliste hinzugefügt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionDirectOrderAdd = $wsActions.create("DirectOrderAdd", tag=string($myDirectOrderProduct)) }}
```
***
### DirectOrderUpdate
Mit dieser Aktion wird die Menge eines Produkts in der Direktbestellliste aktualisiert.
**Anwendungsbeispiel**\
Nutzbar auf der Direktbestellseite, wenn ein Kunde die Menge eines bereits eingetragenen Produkts anpassen möchte.
**Parameter**
| **Name** | **Beschreibung** |
| ---------- | ---------------------------- |
| `quantity` | Die neue Menge des Produkts. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------------ | --------------------------------- |
| `errorsByField.quantity` | Fehler bei der Eingabe der Menge. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsDirectOrder](/frontend/referenz/module/wsdirectorder)
* [\$wsDirectOrder.items](/frontend/referenz/module/wsdirectorder#\$wsdirectorder-items)
**Beispiel** das zeigt, wie die Menge eines Produkts in der Direktbestellliste über ein Eingabefeld aktualisiert wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionDirectOrderUpdate = $wsActions.create("DirectOrderUpdate", tag=string($myDirectOrderProduct)) }}
```
***
### DirectOrderDelete
Mit dieser Aktion wird ein Produkt aus der Direktbestellliste entfernt.
**Anwendungsbeispiel**\
Nutzbar auf der Direktbestellseite, wenn ein Kunde ein Produkt aus der Bestellliste entfernen möchte.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | --------------------------------------------------------- |
| `id` | Die Artikelnummer des Produkts, das entfernt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ----------------------------------------- |
| `errorsByField.id` | Fehler bei der Eingabe der Artikelnummer. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsDirectOrder](/frontend/referenz/module/wsdirectorder)
* [\$wsDirectOrder.items](/frontend/referenz/module/wsdirectorder#\$wsdirectorder-items)
**Beispiel** das zeigt, wie ein Produkt über einen Button aus der Direktbestellliste entfernt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionDirectOrderDelete = $wsActions.create("DirectOrderDelete", tag=string($myDirectOrderProduct)) }}
```
***
### DirectOrderAddLines
Mit dieser Aktion wird eine weitere Eingabezeile zur Direktbestellliste hinzugefügt, sodass der Kunde mehr Produkte auf einmal eintragen kann.
**Anwendungsbeispiel**\
Nutzbar auf der Direktbestellseite, wenn ein Kunde mehr Produkte eintragen möchte als aktuell Zeilen vorhanden sind.
**Zugehörige Module, Variablen & Methoden**
* [\$wsDirectOrder](/frontend/referenz/aktionen/directorder)
* [\$wsDirectOrders.currentLines](/frontend/referenz/module/wsdirectorder#\$wsdirectorder-currentlines)
**Beispiel** das zeigt, wie über einen Button eine neue Eingabezeile zur Direktbestellliste hinzugefügt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionDirectOrderAddLines = $wsActions.create("DirectOrderAddLines") }}
```
***
### DirectOrderDeleteLines
Mit dieser Aktion wird die letzte Eingabezeile aus der Direktbestellliste entfernt. Die Aktion ist nur verfügbar, wenn mehr als fünf Zeilen vorhanden sind.
**Anwendungsbeispiel**\
Nutzbar auf der Direktbestellseite, wenn ein Kunde zu viele Zeilen hinzugefügt hat und diese wieder entfernen möchte.
**Zugehörige Module, Variablen & Methoden**
* [\$wsDirectOrder](/frontend/referenz/aktionen/directorder)
* [\$wsDirectOrders.currentLines](/frontend/referenz/module/wsdirectorder#\$wsdirectorder-currentlines)
**Beispiel** das zeigt, wie die letzte Eingabezeile über einen Button entfernt wird, sofern mehr als fünf Zeilen vorhanden sind.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsDirectOrder.currentLines > 5 }}
{{ var $myActionDirectOrderDeleteLines = $wsActions.create("DirectOrderDeleteLines") }}
{{ /if }}
```
# Inquiry
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/inquiry
Inquiry-Aktionen für Anfragen: Kontakt- und Anfrageformulare sowie Frage-zum-Produkt-Formulare im Frontend absenden und auswerten.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Inquiry beschrieben. Mit diesen Aktionen können z.B. Kontakt- oder Anfrage-Formulare abgesendet werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| -------------- | -------------------------------------------------------------- |
| `InquirySend` | Sendet ein Anfrage-Formular mit den angegebenen Parametern ab. |
| `InquiryCheck` | Prüft die Eingaben eines Formulars, ohne es abzusenden. |
***
## Aktionen
### InquirySend
Mit dieser Aktion wird ein Anfrage-Formular abgesendet. Dabei werden die übermittelten Eingaben geprüft und die Anfrage verarbeitet. Schlägt die Verarbeitung fehl, wird ein entsprechender Fehler zurückgegeben, sodass der Nutzer seine Eingaben korrigieren kann.
**Anwendungsbeispiel**\
Nutzbar, um z.B. ein Kontaktformular auf einer Seite einzubinden, über das Kunden eine Anfrage stellen können. Nach dem Klick auf “Absenden” wird das Formular validiert und die Anfrage übermittelt.
**Parameter**
| **Parameter** | **Beschreibung** |
| ------------- | ----------------------------------- |
| `email` | Die E-Mail-Adresse des Absenders. |
| `formId` | Die ID des abzusendenden Formulars. |
**Fehler**
| **Fehlercode** | **Beschreibung** |
| --------------------- | ---------------------------------------------------------------------------- |
| `missingEmail` | Es wurde keine E-Mail-Adresse angegeben. |
| `emailCheckFailed` | Die angegebene E-Mail-Adresse ist ungültig oder konnte nicht geprüft werden. |
| `emptyForm` | Das Formular enthält keine Eingaben. |
| `missingFormId` | Es wurde keine Formular-ID übergeben. |
| `invalidFormId` | Die angegebene Formular-ID ist nicht gültig. |
| `formCheckFailed` | Die Formularprüfung ist fehlgeschlagen. |
| `createInquiryFailed` | Die Anfrage konnte nicht erstellt werden. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsForm](/frontend/referenz/module/wsform)
* [\$wsForm.inquiryId](/frontend/referenz/module/wsform#\$wsform-inquiryid)
* [\$wsForm.loadType()](/frontend/referenz/module/wsform#\$wsform-loadtype)
* [\$wsForm.load()](/frontend/referenz/module/wsform#\$wsform-load)
**Beispiel,** das die Aktion erstellt, per Hidden-Input an das Formular bindet und nach dem Absenden auf Erfolg oder Fehler prüft.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cMyInquirySendAction = $wsActions.create('InquirySend') }}
```
***
### InquiryCheck
Mit dieser Aktion werden die Eingaben eines Formulars geprüft, ohne die Anfrage tatsächlich abzusenden. Die geprüften Feldwerte werden dabei in `$myField.value` zurückgeschrieben und können im Frontend wiederverwendet werden.
**Anwendungsbeispiel**\
Nutzbar, um Formulareingaben bereits vor dem endgültigen Absenden zu validieren und dem Nutzer direktes Feedback zu seinen Eingaben zu geben.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | ---------------------------------- |
| `email` | Die E-Mail-Adresse des Absenders. |
| `formId` | Die ID des zu prüfenden Formulars. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | -------------------------------------------- |
| `missingEmail` | Es wurde keine E-Mail-Adresse angegeben. |
| `emailCheckFailed` | Die angegebene E-Mail-Adresse ist ungültig. |
| `missingFormId` | Es wurde keine Formular-ID übergeben. |
| `invalidFormId` | Die angegebene Formular-ID ist nicht gültig. |
| `formCheckFailed` | Die Formularprüfung ist fehlgeschlagen. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsForm](/frontend/referenz/module/wsform)
* [\$wsForm.loadType()](/frontend/referenz/module/wsform#\$wsform-loadtype)
**Beispiel** folgt.
# Inventory
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/inventory
Inventory-Aktionen für Lagerbestände: Produktreservierungen erneuern und Benachrichtigungen bei Wiederverfügbarkeit von Artikeln verwalten.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich `Inventory` beschrieben. Mit diesen Aktionen können Produktreservierungen erneuert und Benachrichtigungen bei Wiederverfügbarkeit verwaltet werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| ----------------------------- | ----------------------------------------------------------------------- |
| `InventoryReserve` | Erneuert die Reservierung eines Produkts im Warenkorb. |
| `BackInStockActivateNotify` | Aktiviert eine Benachrichtigung, wenn ein Produkt wieder verfügbar ist. |
| `BackInStockDeactivateNotify` | Deaktiviert eine bestehende Wiedervorrätig-Benachrichtigung. |
***
## Aktionen
### InventoryReserve
Mit dieser Aktion wird die Reservierung eines Produkts im Warenkorb erneuert. Sie ist nur relevant, wenn die Reservierungsdauer eines Artikels abgelaufen ist und der Kunde die Reservierung verlängern möchte.
**Anwendungsbeispiel**\
Nutzbar auf der Warenkorbseite, wenn die Reservierungszeit eines Artikels abgelaufen ist und dem Kunden die Möglichkeit gegeben werden soll, die Reservierung zu erneuern.
**Parameter**
| **Name** | **Beschreibung** |
| -------------- | ------------------------------------------------------------------------ |
| `basketItemId` | Die ID des Warenkorb-Eintrags, dessen Reservierung erneuert werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| --------------------- | ---------------------------------------------------------------------------------------------- |
| `missingBasketItemId` | Parameter `basketItemId` fehlt. |
| `invalidBasketItemId` | Der Warenkorb-Eintrag existiert nicht oder gehört nicht zu diesem Warenkorb. |
| `reservationFailed` | Die Reservierung konnte nicht erneuert werden, z.B. weil das Produkt nicht mehr verfügbar ist. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsInventory](/frontend/referenz/module/wsinventory)
* [\$wsInventory.load()](/frontend/referenz/module/wsinventory#\$wsinventory-load)
* [\$wsInventory.loadReservation()](/frontend/referenz/module/wsinventory#\$wsinventory-loadreservation)
* [\$wsBasket.items](/frontend/referenz/module/wsbasket#\$wsbasket-items)
**Beispiel** das zeigt, wie einem Kunden bei abgelaufener Reservierung die Möglichkeit gegeben wird, diese über einen Button zu erneuern.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myReservation = $wsInventory.loadReservation($myProduct.id) }}
{{ if $myReservation and $myReservation.duration == 0 }}
{{ var $myActionInventoryReserve = $wsActions.create("InventoryReserve", tag=$myProduct.id) }}
{{ /if }}
```
***
### BackInStockActivateNotify
Mit dieser Aktion wird eine Benachrichtigung aktiviert, die den Kunden per E-Mail informiert, sobald ein ausverkauftes Produkt wieder verfügbar ist.
**Anwendungsbeispiel**\
Nutzbar auf der Produktdetailseite, wenn ein Produkt ausverkauft ist und der Kunde benachrichtigt werden möchte, sobald es wieder bestellbar ist.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | ------------------------------------------------------------------------ |
| `productId` | Die ID des Produkts, für das die Benachrichtigung aktiviert werden soll. |
| `email` | Die E-Mail-Adresse, an die die Benachrichtigung gesendet werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ------------------------------------------- |
| `missingProductId` | Parameter `productId` fehlt. |
| `missingEmail` | Parameter `email` fehlt. |
| `emailCheckFailed` | Die angegebene E-Mail-Adresse ist ungültig. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsInventory](/frontend/referenz/module/wsinventory)
* [\$wsAccount.backInStockList](/frontend/referenz/module/wsAccount#\$wsaccount-backinstocklist)
**Beispiel** das zeigt, wie ein Kunde eine Benachrichtigung für ein ausverkauftes Produkt aktivieren kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionBackInStockActivateNotify = $wsActions.create("BackInStockActivateNotify") }}
```
***
### BackInStockDeactivateNotify
Mit dieser Aktion wird eine bestehende Wiedervorrätig-Benachrichtigung deaktiviert.
**Anwendungsbeispiel**\
Nutzbar auf der Account-Übersichtsseite, auf der eingeloggte Kunden ihre aktiven Benachrichtigungen einsehen und entfernen können.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | -------------------------------------------------------------------------- |
| `productId` | Die ID des Produkts, für das die Benachrichtigung deaktiviert werden soll. |
| `email` | Die E-Mail-Adresse, für die die Benachrichtigung deaktiviert werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ---------------------------- |
| `missingProductId` | Parameter `productId` fehlt. |
| `missingEmail` | Parameter `email` fehlt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsInventory](/frontend/referenz/module/wsinventory)
* [\$wsAccount.backInStockList](/frontend/referenz/module/wsAccount#\$wsaccount-backinstocklist)
**Beispiel** das zeigt, wie eine aktive Benachrichtigung über einen Button deaktiviert wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionBackInStockDeactivateNotify = $wsActions.create("BackInStockDeactivateNotify") }}
```
# Newsletter
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/newsletter
Newsletter-Aktionen für Abonnenten: Anmeldung, Double-Opt-In-Bestätigung und Abmeldung vom Newsletter direkt aus dem Frontend ausführen.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Newsletter beschrieben. Mit diesen Aktionen können Kunden den Newsletter abonnieren, ihre Anmeldung bestätigen und sich wieder abmelden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| ------------------------------ | ----------------------------------------------------- |
| `NewsletterSubscribe` | Meldet einen Kunden für den Newsletter an. |
| `NewsletterSubscribeConfirm` | Bestätigt die Newsletter-Anmeldung per Double-Opt-In. |
| `NewsletterUnsubscribe` | Meldet einen Kunden vom Newsletter ab. |
| `NewsletterUnsubscribeConfirm` | Bestätigt die Newsletter-Abmeldung per Double-Opt-In. |
***
## Aktionen
### NewsletterSubscribe
Mit dieser Aktion wird ein Kunde für den Newsletter angemeldet. Nach erfolgreicher Anmeldung erhält der Kunde eine Bestätigungs-E-Mail mit einem Double-Opt-In Link.
**Anwendungsbeispiel**\
Nutzbar auf einer Newsletter-Anmeldeseite, auf der Kunden ihre E-Mail-Adresse und optional eine oder mehrere Zielgruppen auswählen können.
**Parameter**
| **Name** | **Beschreibung** |
| -------------------- | ------------------------------------------------------------------- |
| `email` | Die E-Mail-Adresse, die für den Newsletter angemeldet werden soll. |
| `targetGroupId.(id)` | Optionale Zielgruppen-ID, für die der Kunde angemeldet werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------------- | ------------------------------------------------------------- |
| `missingEmail` | Parameter `email` fehlt. |
| `emailCheckFailed` | Die angegebene E-Mail-Adresse ist ungültig. |
| `accountAlreadyExists` | Die E-Mail-Adresse ist bereits für den Newsletter angemeldet. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsNewsletter](/frontend/referenz/module/wsnewsletter)
* [\$wsNewsletter.getTargetGroups()](/frontend/referenz/module/wsnewsletter#\$wsnewsletter-gettargetgroups)
**Beispiel** das zeigt, wie ein Kunde seine E-Mail-Adresse und optional Zielgruppen auswählt, um den Newsletter zu abonnieren, inklusive Erfolgsausgabe nach der Anmeldung.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionNewsletterSubscribe = $wsActions.create("NewsletterSubscribe") }}
```
***
### NewsletterSubscribeConfirm
Mit dieser Aktion wird die Newsletter-Anmeldung per Double-Opt-In bestätigt. Der Kunde erhält nach der Anmeldung eine E-Mail mit einem Bestätigungslink, über den diese Aktion ausgelöst wird.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf die der Kunde nach Klick auf den Opt-In-Link in der Anmelde-E-Mail weitergeleitet wird.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------- | ---------------------------------------------- |
| `unauthorized` | Es wurde kein gültiger Opt-In-Token übergeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsNewsletter](/frontend/referenz/module/wsnewsletter)
**Beispiel** das zeigt, wie nach erfolgreicher Bestätigung eine Erfolgsmeldung angezeigt wird und bei einem ungültigen Token ein Fehlerhinweis erscheint.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionNewsletterSubscribeConfirm = $wsActions.create('NewsletterSubscribeConfirm') }}
```
***
### NewsletterUnsubscribe
Mit dieser Aktion wird ein Kunde vom Newsletter abgemeldet. Der Kunde gibt dabei seine E-Mail-Adresse an und kann optional einzelne Zielgruppen abwählen.
**Anwendungsbeispiel**\
Nutzbar auf der Abmeldeseite, auf der Kunden ihre E-Mail-Adresse eingeben und sich von einzelnen oder allen Newsletter-Zielgruppen abmelden können.
**Parameter**
| **Name** | **Beschreibung** |
| -------------------- | ------------------------------------------------------------------- |
| `email` | Die E-Mail-Adresse, die vom Newsletter abgemeldet werden soll. |
| `targetGroupId.(id)` | Optionale Zielgruppen-ID, von der der Kunde abgemeldet werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ------------------------------------------- |
| `missingEmail` | Parameter `email` fehlt. |
| `emailCheckFailed` | Die angegebene E-Mail-Adresse ist ungültig. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsNewsletter](/frontend/referenz/module/wsnewsletter)
* [\$wsNewsletter.getTargetGroups()](/frontend/referenz/module/wsnewsletter#\$wsnewsletter-gettargetgroups)
**Beispiel** das zeigt, wie ein Kunde seine E-Mail-Adresse eingibt und sich von einzelnen Zielgruppen abmeldet, inklusive Erfolgsausgabe.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionNewsletterUnsubscribe = $wsActions.create('NewsletterUnsubscribe') }}
```
***
### NewsletterUnsubscribeConfirm
Mit dieser Aktion wird die Newsletter-Abmeldung per Double-Opt-In bestätigt. Der Kunde erhält nach der Abmeldung eine E-Mail mit einem Bestätigungslink, über den diese Aktion ausgelöst wird.
**Anwendungsbeispiel**\
Nutzbar auf der Bestätigungsseite, auf die der Kunde nach Klick auf den Opt-In-Link in der Abmelde-E-Mail weitergeleitet wird.
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------- | ---------------------------------------------- |
| `unauthorized` | Es wurde kein gültiger Opt-In-Token übergeben. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsNewsletter](/frontend/referenz/module/wsnewsletter)
**Beispiel** das zeigt, wie nach erfolgreicher Bestätigung der Abmeldung eine Erfolgsmeldung angezeigt wird und bei einem ungültigen Token ein Fehlerhinweis erscheint.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionNewsletterUnsubscribeConfirm = $wsActions.create('NewsletterUnsubscribeConfirm') }}
```
# ProductRating
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/productrating
ProductRating-Aktionen für Produktbewertungen: Bewertungen durch eingeloggte Kunden erstellen, bearbeiten und wieder löschen lassen.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Produktbewertungen beschrieben. Mit diesen Aktionen können Bewertungen erstellt, bearbeitet und gelöscht werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| --------------------- | -------------------------------------------- |
| `ProductRatingAdd` | Erstellt eine neue Produktbewertung. |
| `ProductRatingUpdate` | Bearbeitet eine bestehende Produktbewertung. |
| `ProductRatingDelete` | Löscht eine bestehende Produktbewertung. |
***
## Aktionen
### ProductRatingAdd
Mit dieser Aktion wird eine neue Bewertung für ein Produkt erstellt. Der Kunde muss dafür eingeloggt sein.
**Anwendungsbeispiel**\
Nutzbar auf der Produktdetailseite oder in der Bestellhistorie, um eingeloggten Kunden die Möglichkeit zu geben, ein gekauftes Produkt zu bewerten.
**Parameter**
| **Name** | **Beschreibung** |
| ------------- | ------------------------------------------------------- |
| `productId` | Die ID des Produkts, das bewertet werden soll. |
| `orderId` | Die ID der Bestellung, zu der die Bewertung gehört. |
| `points` | Die Bewertung in Punkten (z.B. 1-5 Sterne). |
| `subject` | Der Titel der Bewertung. |
| `description` | Der Bewertungstext. |
| `anonymous` | Gibt an, ob die Bewertung anonym abgegeben werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| --------------------- | ------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingProductId` | Parameter `productId` fehlt. |
| `missingOrderId` | Parameter `orderId` fehlt. |
| `missingPoints` | Parameter `points` fehlt. |
| `ratingAlreadyExists` | Für dieses Produkt und diese Bestellung existiert bereits eine Bewertung. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsProductRating](/frontend/referenz/module/wsproductrating)
* [\$wsProductRating.checkRatingExistence()](/frontend/referenz/module/wsproductrating#\$wsproductrating-checkratingexistence)
* [\$wsProductRating.loadAllProductRatings()](/frontend/referenz/module/wsproductrating#\$wsproductrating-loadallproductratings)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#\$wsaccount-isloggedin)
**Beispiel** das zeigt, wie ein eingeloggter Kunde ein Produkt mit Sternebewertung, Titel und Kommentar bewerten kann, inklusive Erfolgsausgabe.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionProductRatingAdd = $wsActions.create("ProductRatingAdd") }}
```
***
### ProductRatingUpdate
Mit dieser Aktion wird eine bestehende Produktbewertung des eingeloggten Kunden bearbeitet.
**Anwendungsbeispiel**\
Nutzbar auf der Produktdetailseite oder im Kundenkonto, wenn ein Kunde seine abgegebene Bewertung nachträglich anpassen möchte.
**Parameter**
| **Name** | **Beschreibung** |
| ------------- | ------------------------------------------------------------- |
| `productId` | Die ID des Produkts, dessen Bewertung bearbeitet werden soll. |
| `orderId` | Die ID der Bestellung, zu der die Bewertung gehört. |
| `points` | Die neue Bewertung in Punkten. |
| `subject` | Der neue Titel der Bewertung. |
| `description` | Der neue Bewertungstext. |
| `anonymous` | Gibt an, ob die Bewertung anonym abgegeben werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ---------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingProductId` | Parameter `productId` fehlt. |
| `missingOrderId` | Parameter `orderId` fehlt. |
| `invalidRating` | Die Bewertung existiert nicht oder gehört nicht zu diesem Kundenkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsProductRating](/frontend/referenz/aktionen/productrating)
* [\$wsProductRating.loadSingleRating()](/frontend/referenz/module/wsproductrating#\$wsproductrating-loadsinglerating)
* [\$wsProductRating.loadRatingByAccount()](/frontend/referenz/module/wsproductrating#\$wsproductrating-loadratingbyaccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#\$wsaccount-isloggedin)
**Beispiel** das zeigt, wie ein Kunde eine bestehende Bewertung bearbeiten kann, mit vorausgefüllten Feldern.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionProductRatingUpdate = $wsActions.create("ProductRatingUpdate") }}
{{ var $myRating = $wsProductRating.loadSingleRating($myProduct, $myOrderId) }}
```
***
### ProductRatingDelete
Mit dieser Aktion wird eine bestehende Produktbewertung des eingeloggten Kunden gelöscht.
**Anwendungsbeispiel**\
Nutzbar auf der Produktdetailseite oder im Kundenkonto, wenn ein Kunde seine abgegebene Bewertung entfernen möchte.
**Parameter**
| **Name** | **Beschreibung** |
| ----------- | ----------------------------------------------------------- |
| `productId` | Die ID des Produkts, dessen Bewertung gelöscht werden soll. |
| `orderId` | Die ID der Bestellung, zu der die Bewertung gehört. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ---------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingProductId` | Parameter `productId` fehlt. |
| `missingOrderId` | Parameter `orderId` fehlt. |
| `invalidRating` | Die Bewertung existiert nicht oder gehört nicht zu diesem Kundenkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsProductRating](/frontend/referenz/aktionen/productrating)
* [\$wsProductRating.loadRatingByAccount()](/frontend/referenz/module/wsproductrating#\$wsproductrating-loadratingbyaccount)
* [\$wsAccount.isLoggedIn](/frontend/referenz/module/wsAccount#\$wsaccount-isloggedin)
**Beispiel** das zeigt, wie eine Bewertung über einen Button gelöscht wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionProductRatingDelete = $wsActions.create("ProductRatingDelete") }}
```
# Session
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/session
Session-Aktionen im Frontend: eigene Session-Variablen schreiben und nach fehlgeschlagenem Bezahlvorgang eine gesperrte Session entsperren.
In diesem Abschnitt werden die verfügbaren Aktionen der Session beschrieben. Mit diesen Aktionen können z.B. Session-Variablen geschrieben oder eine gesperrte Session nach einem fehlgeschlagenen Bezahlvorgang wieder entsperrt werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| --------------- | ----------------------------------------------------------------------- |
| `SessionUpdate` | Schreibt einen Wert in eine Session-Variable. |
| `SessionUnlock` | Entsperrt die Session nach einem fehlgeschlagenen Online-Bezahlvorgang. |
***
## Aktionen
### SessionUpdate
Mit dieser Aktion wird ein Wert in eine Session-Variable geschrieben. Die Variable wird dabei über den Parameternamen `session.(variableName)` adressiert, wobei `variableName` für den gewünschten Schlüssel innerhalb der Session steht.
**Anwendungsbeispiel**\
Nutzbar, um während des Nutzererlebnisses benutzerdefinierte Zustandsinformationen in der Session zu speichern, z.B. einen ausgewählten Filter, einen Fortschritt im Checkout oder einen temporären Hinweis, der seitenübergreifend verfügbar sein soll.
**Parameter**
| **Name** | **Beschreibung** |
| ------------------------ | --------------------------------------------------------------------- |
| `session.(variableName)` | Der Schlüssel und Wert der Session-Variable, die gesetzt werden soll. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsSession](/frontend/referenz/module/wssession)
* [\$wsSession.set()](/frontend/referenz/module/wssession#\$wssession-set)
* [\$wsSession.get()](/frontend/referenz/module/wssession#\$wssession-get)
**Beispiel** das zeigt, wie ein Wert in eine Session-Variable geschrieben und anschließend ausgelesen wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSessionUpdate = $wsActions.create("SessionUpdate") }}
{{ if $wsSession.get("lastViewedCategory") }}
Kategorie: {{= $wsSession.get("lastViewedCategory") }}
{{ /if }}
```
***
### SessionUnlock
Mit dieser Aktion wird eine gesperrte Session wieder entsperrt. Eine Session kann nach einem fehlgeschlagenen Online-Bezahlvorgang in einen gesperrten Zustand geraten, um unbeabsichtigte Folgeaktionen zu verhindern. `SessionUnlock` setzt diesen Sperrzustand zurück, sodass der Kunde den Vorgang erneut starten oder fortsetzen kann.
Diese Aktion erwartet keine Parameter und liefert keine Fehlerrückmeldungen.
**Anwendungsbeispiel**\
Nutzbar auf einer Fehler- oder Rücksprungs-Seite nach einem fehlgeschlagenen Zahlungsvorgang, um dem Kunden zu ermöglichen, die Zahlung erneut zu versuchen oder eine andere Zahlungsmethode auszuwählen.
**Zugehörige Module, Variablen & Methoden**
* [\$wsSession](/frontend/referenz/module/wssession)
* [\$wsSession.isLocked](/frontend/referenz/module/wssession#\$wssession-islocked)
**Beispiel** das zeigt, wie einem Kunden bei gesperrter Session die Möglichkeit gegeben wird, diese über einen Button zu entsperren.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsSession.isLocked }}
{{ var $myActionSessionUnlock = $wsActions.create("SessionUnlock") }}
{{ /if }}
```
# Stores
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/stores
Stores-Aktionen für Märkte und Filialen: Markt für aktuelle Session oder den Checkout-Prozess setzen, ändern und für Click & Collect nutzen.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Märkte (Stores) beschrieben. Mit diesen Aktionen kann z.B. ein Markt für die aktuelle Session oder den Checkout-Prozess ausgewählt werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| ------------- | ------------------------------------------------------------- |
| `SelectStore` | Setzt einen Markt als aktiven Markt für die aktuelle Session. |
***
## Aktionen
### SelectStore
Mit dieser Aktion wählt der Kunde einen Markt als seinen aktiven Markt für die aktuelle Session aus. Die Auswahl wird sofort übernommen und steht anschließend z.B. für die Anzeige von standortbezogenen Inhalten oder als Vorauswahl im Checkout zur Verfügung.
**Anwendungsbeispiel**\
Nutzbar, um z.B. auf einer Markt-Übersichtsseite, auf der dem Kunden alle verfügbaren Märkte angezeigt werden und er per Klick seinen gewünschten Markt auswählen kann, z.B. um Öffnungszeiten, Verfügbarkeiten oder Click & Collect-Optionen für seinen Markt zu sehen.
**Parameter**
| **Name** | **Beschreibung** |
| --------- | -------------------------------------------------------------- |
| `storeId` | Die ID des Marktes, der als aktiver Markt gesetzt werden soll. |
**Fehlercodes**
| **Code** | **Beschreibung** |
| ---------------- | ---------------------------------------------------------- |
| `missingStoreId` | Parameter `storeId` fehlt. |
| `invalidStoreId` | Die angegebene Markt-ID existiert nicht oder ist ungültig. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsStores](/frontend/referenz/module/wsstores)
* [\$wsStores.loadAllStores()](/frontend/referenz/module/wsstores#\$wsstores-loadallstores)
* [\$wsStores.selectedStore](/frontend/referenz/module/wsstores#\$wsstores-selectedstore)
**Beispiel** das zeigt, wie alle verfügbaren Märkte als Auswahlliste dargestellt werden und der aktuell ausgewählte Markt vorausgewählt ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionSelectStore = $wsActions.create("SelectStore") }}
```
# TestMode
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/testmode
TestMode-Aktionen: Testmodus im Frontend aktivieren, deaktivieren und zwischen Test- und Live-Modus wechseln, ohne Live-Betrieb zu beeinflussen.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Testmodus beschrieben. Mit diesen Aktionen kann der Testmodus aktiviert, deaktiviert und gewechselt werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| ---------------- | ------------------------------- |
| `TestModeOn` | Aktiviert den Testmodus. |
| `TestModeOff` | Deaktiviert den Testmodus. |
| `TestModeChange` | Wechselt den aktiven Testmodus. |
***
## Aktionen
### TestModeOn
Mit dieser Aktion wird der Testmodus aktiviert. Der Benutzer muss dafür das konfigurierte Testmodus-Passwort angeben.
**Anwendungsbeispiel**\
Nutzbar auf der Testmodus Seite (`testMode.htm`), über die Shopbetreiber oder Tester den Testmodus mit einem Passwort aktivieren können, um testspezifische Inhalte zu sehen.
**Parameter**
| **Name** | **Beschreibung** |
| ---------- | -------------------------------------------------- |
| `password` | Das Passwort zur Aktivierung des Testmodus. |
| `debug` | Aktiviert das erweiterte Debugging (Wert: “`on`”). |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ----------------- | ----------------------------------- |
| `missingPassword` | Parameter `password` fehlt. |
| `invalidPassword` | Das angegebene Passwort ist falsch. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsTestMode](/frontend/referenz/module/wstestmode)
* [\$wsTestMode.active](/frontend/referenz/module/wstestmode#\$wstestmode-active)
* [\$wsTestMode.debug](/frontend/referenz/module/wstestmode#\$wstestmode-debug)
**Beispiel** das zeigt, wie der Testmodus über ein Passwortformular aktiviert wird, optional mit Debugging.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cActionTestModeOn = $wsActions.create("TestModeOn") }}
```
***
### TestModeOff
Mit dieser Aktion wird der Testmodus deaktiviert und der Shop kehrt in den normalen Live-Betrieb zurück.
**Anwendungsbeispiel**\
Nutzbar auf der Testmodus-Seite oder im Shop-Header, um den Testmodus direkt im Shop zu deaktivieren.
**Zugehörige Module, Variablen & Methoden**
* [\$wsTestMode](/frontend/referenz/module/wstestmode)
* [\$wsTestMode.active](/frontend/referenz/module/wstestmode#\$wstestmode-active)
**Beispiel** das zeigt, wie der Testmodus über einen Button deaktiviert wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionTestModeOff = $wsActions.create("TestModeOff") }}
```
***
### TestModeChange
Mit dieser Aktion wird der aktive Testmodus gewechselt, ohne ihn komplett zu deaktivieren. Dies ist nützlich, wenn mehrere Testmodi konfiguriert sind.
**Anwendungsbeispiel**\
Nutzbar auf der Testmodus-Seite, wenn verschiedene Testszenarien oder Konfigurationen parallel verfügbar sind und zwischen diesen gewechselt werden soll.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | ------------------------------------------------------------------- |
| `debug` | Aktiviert oder deaktiviert das erweiterte Debugging (Wert: “`on`”). |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ----------------- | ----------------------------------- |
| `invalidPassword` | Das angegebene Passwort ist falsch. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsTestMode](/frontend/referenz/module/wstestmode)
* [\$wsTestMode.active](/frontend/referenz/module/wstestmode#\$wstestmode-active)
* [\$wsTestMode.debug](/frontend/referenz/module/wstestmode#\$wstestmode-debug)
**Beispiel** das zeigt, wie die Debug-Einstellung des aktiven Testmodus geändert wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionTestModeChange = $wsActions.create("TestModeChange") }}
```
# Voucher
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/voucher
Voucher-Aktionen im Warenkorb: Gutscheincodes mit VoucherAdd einlösen und über VoucherDelete wieder aus dem aktuellen Warenkorb entfernen.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Gutscheine beschrieben. Mit diesen Aktionen können Gutscheincodes im Warenkorb eingelöst und wieder entfernt werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| --------------- | ------------------------------------------------------- |
| `VoucherAdd` | Löst einen Gutscheincode im Warenkorb ein. |
| `VoucherDelete` | Entfernt einen eingelösten Gutschein aus dem Warenkorb. |
***
## Aktionen
### VoucherAdd
Mit dieser Aktion wird ein Gutscheincode im Warenkorb eingelöst.
**Anwendungsbeispiel**\
Nutzbar auf der Warenkorbseite oder im Warenkorb-Offcanvas, wo Kunden einen Gutscheincode eingeben und direkt auf ihre Bestellung anwenden können.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | --------------------------------------------- |
| `id` | Der Gutscheincode, der eingelöst werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------- | ----------------------------------------------------------------- |
| `missingId` | Parameter `id` fehlt. |
| `invalidVoucher` | Der angegebene Gutscheincode ist ungültig oder bereits eingelöst. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsVoucher](/frontend/referenz/module/wsvoucher)
* [\$wsVoucher.vouchers](/frontend/referenz/module/wsvoucher#\$wsvoucher-vouchers)
* [\$wsVoucher.totalValue](/frontend/referenz/module/wsvoucher#\$wsvoucher-totalvalue)
**Beispiel** das zeigt, wie ein Gutscheincode über ein Eingabefeld eingelöst wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionVoucherAdd = $wsActions.create("VoucherAdd") }}
```
***
### VoucherDelete
Mit dieser Aktion wird ein bereits eingelöster Gutschein aus dem Warenkorb entfernt.
**Anwendungsbeispiel**\
Nutzbar auf der Warenkorbseite oder im Warenkorb-Offcanvas, wenn Kunden einen eingelösten Gutschein wieder entfernen möchten.
**Parameter**
| **Name** | **Beschreibung** |
| -------- | ------------------------------------------------ |
| `id` | Die ID des Gutscheins, der entfernt werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ------------------------------------------------------------------------------- |
| `missingId` | Parameter `id` fehlt. |
| `invalidVoucherId` | Der angegebene Gutschein existiert nicht oder gehört nicht zu diesem Warenkorb. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsVoucher](/frontend/referenz/module/wsvoucher)
* [\$wsVoucher.vouchers](/frontend/referenz/module/wsvoucher#\$wsvoucher-vouchers)
* [\$wsVoucher.totalValue](/frontend/referenz/module/wsvoucher#\$wsvoucher-totalvalue)
**Beispiel** das zeigt, wie alle eingelösten Gutscheine aufgelistet werden und jeder einzelne über einen Button entfernt werden kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $myVoucher in $wsVoucher.vouchers }}
{{ var $myActionVoucherDelete = $wsActions.create("VoucherDelete") }}
{{ /foreach }}
```
# WatchList
Source: https://dokumentation.websale.de/frontend/referenz/aktionen/watchlist
WatchList-Aktionen für die Merkliste: Produkte über WatchListItemAdd hinzufügen und über WatchListItemDelete aus der Wunschliste entfernen.
In diesem Abschnitt werden die verfügbaren Aktionen im Bereich Merkliste beschrieben. Mit diesen Aktionen können Produkte zur Merkliste hinzugefügt oder daraus entfernt werden.
***
## Aktionen im Überblick
| **Aktion** | **Beschreibung** |
| --------------------- | --------------------------------------------------- |
| `WatchListItemAdd` | Fügt ein oder mehrere Produkte zur Merkliste hinzu. |
| `WatchListItemDelete` | Entfernt ein Produkt aus der Merkliste. |
| `AddWatchList` | Erstellt eine neue Merkliste. |
| `DeleteWatchList` | Löscht eine bestehende Merkliste. |
| `RenameWatchList` | Benennt eine bestehende Merkliste um. |
***
## Aktionen
### WatchListItemAdd
Mit dieser Aktion wird ein Produkt zur Merkliste des Benutzers hinzugefügt. Es können sowohl einzelne Produkte als auch mehrere Produkte gleichzeitig übergeben werden.
**Anwendungsbeispiel**\
Nutzbar auf Produkt- oder Kategorieseiten, auf denen Kunden Artikel auf ihre Merkliste setzen können, um sie später wiederzufinden oder zu kaufen.
**Parameter**
| **Name** | **Beschreibung** |
| -------------------------------------- | ------------------------------------------------------------------------------- |
| `productId` | Die ID des Produkts, das zur Merkliste hinzugefügt werden soll. |
| `freeFields.` | Optionale Freifelder, die dem Merklisten-Eintrag zugeordnet werden können. |
| `multiProducts..` | Ermöglicht das gleichzeitige Hinzufügen mehrerer Produkte mit jeweiliger Menge. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------ | ----------------------------------------------------------------------- |
| `missingProductId` | Parameter `productId` fehlt oder ist leer. |
| `invalidProductId` | Das Produkt mit der angegebenen `productId` existiert nicht. |
| `invalidVariantId` | Die angegebene Variante des Produkts ist ungültig oder nicht vorhanden. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsWatchList](/frontend/referenz/module/wswatchlist)
* [\$wsWatchList.watchLists](/frontend/referenz/module/wswatchlist#\$wswatchlist-watchlists)
* [\$wsWatchList.loadWatchList()](/frontend/referenz/module/wswatchlist#\$wswatchlist-loadwatchlist)
* [\$wsWatchList.isProductOnWatchList()](/frontend/referenz/module/wswatchlist#\$wswatchlist-isproductonwatchlist)
* [\$wsWatchList.countWatchListsWithProduct()](/frontend/referenz/module/wswatchlist#\$wswatchlist-countwatchlistswithproduct)
**Beispiel** das zeigt, wie ein Produkt zur Standard-Merkliste hinzugefügt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionWatchListItemAdd = $wsActions.create("WatchListItemAdd") }}
```
***
### WatchListItemDelete
Mit dieser Aktion wird ein Eintrag aus der Merkliste des Benutzers entfernt.
**Anwendungsbeispiel**\
Nutzbar auf der Merklisten-Seite, auf der Kunden einzelne Produkte wieder von ihrer Merkliste löschen können.
**Parameter**
| **Name** | **Beschreibung** |
| ----------------- | --------------------------------------------------------- |
| `watchListItemId` | Die ID des Merklisten-Eintrags, der gelöscht werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ------------------------ | ------------------------------------------------ |
| `missingWatchListItemId` | Parameter `watchListItemId` fehlt oder ist leer. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsWatchList](/frontend/referenz/module/wswatchlist)
* [\$wsWatchList.watchLists](/frontend/referenz/module/wswatchlist#\$wswatchlist-watchlists)
* [\$wsWatchList.loadWatchList()](/frontend/referenz/module/wswatchlist#\$wswatchlist-loadwatchlist)
* [\$wsWatchList.loadWatchListItemId()](/frontend/referenz/module/wswatchlist#\$wswatchlist-loadwatchlistitemid)
**Beispiel** das zeigt, wie ein Produkt anhand seiner Merklisten-Eintrags-ID aus der Standard-Merkliste entfernt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionWatchListItemDelete = $wsActions.create("WatchListItemDelete") }}
{{ var $myWatchListItemId = $wsWatchList.loadWatchListItemId("default", $myProduct.id) }}
```
***
### AddWatchList
Mit dieser Aktion wird eine neue Merkliste für den eingeloggten Benutzer erstellt.
**Anwendungsbeispiel**\
Nutzbar auf der Merklisten-Verwaltungsseite, auf der Kunden zusätzlich Merklisten anlegen können, z.B. für verschiedene Anlässe oder Kategorien.
**Parameter**
| **Name** | **Beschreibung** |
| --------------- | ----------------------------- |
| `watchListName` | Der Name der neuen Merkliste. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------------- | ---------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingWatchListName` | Parameter `watchListName` fehlt. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsWatchList](/frontend/referenz/module/wswatchlist)
* [\$wsWatchList.watchLists](/frontend/referenz/module/wswatchlist#\$wswatchlist-watchlists)
**Beispiel** das zeigt, wie eine neue Merkliste über ein Eingabefeld erstellt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionAddWatchList = $wsActions.create("AddWatchList") }}
```
***
### DeleteWatchList
Mit dieser Aktion wird eine bestehende Merkliste des eingeloggten Benutzers gelöscht.
**Anwendungsbeispiel**\
Nutzbar auf der Merklisten-Verwaltungsseite, auf der Kunden nicht mehr benötigte Merklisten entfernen können.
**Parameter**
| **Name** | **Beschreibung** |
| ------------- | ----------------------------------------------- |
| `watchListId` | Die ID der Merkliste, die gelöscht werden soll. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| -------------------- | ----------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingWatchListId` | Parameter `watchListId` fehlt. |
| `invalidWatchListId` | Die angegebene Merkliste existiert nicht oder gehört nicht zu diesem Benutzerkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsWatchList](/frontend/referenz/module/wswatchlist)
* [\$wsWatchList.watchLists](/frontend/referenz/module/wswatchlist#\$wswatchlist-watchlists)
**Beispiel** das zeigt, wie eine Merkliste über einen Button gelöscht wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionDeleteWatchList = $wsActions.create("DeleteWatchList") }}
```
***
### RenameWatchList
Mit dieser Aktion wird eine bestehende Merkliste des eingeloggten Benutzers umbenannt.
**Anwendungsbeispiel**\
Nutzbar auf der Merklisten-Verwaltungsseite, auf der Kunden den Namen einer bestehenden Merkliste anpassen können.
**Parameter**
| **Name** | **Beschreibung** |
| --------------- | ------------------------------------------------ |
| `watchListId` | Die ID der Merkliste, die umbenannt werden soll. |
| `watchListName` | Der neue Name der Merkliste. |
**Fehlercodes**
| **Fehlercode** | **Beschreibung** |
| ---------------------- | ----------------------------------------------------------------------------------- |
| `notLoggedIn` | Der Benutzer ist nicht eingeloggt. |
| `missingWatchListId` | Parameter `watchListId` fehlt. |
| `missingWatchListName` | Parameter `watchListName` fehlt. |
| `invalidWatchListId` | Die angegebene Merkliste existiert nicht oder gehört nicht zu diesem Benutzerkonto. |
**Zugehörige Module, Variablen & Methoden**
* [\$wsWatchList](/frontend/referenz/module/wswatchlist)
* [\$wsWatchList.watchLists](/frontend/referenz/module/wswatchlist#\$wswatchlist-watchlists)
**Beispiel** das zeigt, wie eine Merkliste über ein Eingabefeld umbenannt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myActionRenameWatchList = $wsActions.create("RenameWatchList") }}
```
# Anweisungen und Ausgabe
Source: https://dokumentation.websale.de/frontend/referenz/anweisungen
Anweisungen und Ausgabe in Templates: Syntax für Verarbeitung, Ausgabe und automatisches Escaping verstehen und kontextsicher einsetzen.
Beim Erstellen von Templates reicht es nicht aus, nur [Variablen](/frontend/referenz/variablen), [Funktionen ](/frontend/referenz/funktionen)oder [Operatoren ](/frontend/referenz/operatoren)zu kennen. Ebenso wichtig ist es, wie ein Ausdruck im Template verarbeitet wird. Die verwendete Syntax entscheidet darüber, ob eine Anweisung nur ausgeführt, ein Wert ausgegeben oder eine Ausgabe automatisch escaped wird.
Diese Unterscheidung ist für die Template-Entwicklung relevant, weil sie direkten Einfluss auf das erzeugte Ergebnis hat. Je nach Schreibweise erscheint ein Wert im HTML, wird nur intern verarbeitet oder unverändert ausgegeben. Dadurch bestimmt die Syntax nicht nur die Ausgabe selbst, sondern auch, ob Inhalte für den jeweiligen Kontext korrekt und sicher ausgegeben werden.
Die verschiedenen Formen von Anweisungen helfen daher dabei, Template-Logik und Ausgabe sauber zu steuern. Sie legen fest, wann ein Ausdruck lediglich verarbeitet wird und wann sein Ergebnis im generierten Dokument erscheint. Gleichzeitig steuern sie das Escaping und damit den Umgang mit Sonderzeichen, HTML-Inhalten oder anderen Ausgabekontexten.
Diese Seite beschreibt die verfügbaren Schreibweisen für Anweisungen und zeigt, wie sie sich auf Verarbeitung, Ausgabe und Escaping auswirken.
***
## Anweisungen im Überblick
| **Syntax** | **Beschreibung** | Typische Verwendung |
| --------------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------------- |
| `{{ ... }}` | Führt eine Anweisung aus, ohne eine Ausgabe zu erzeugen. | Variablen setzen, Hilfslogik ausführen. |
| `{{= … }}` | Gibt einen Wert aus und ersetzt dabei HTML-Sonderzeichen. | Normale Ausgabe im HTML. |
| `{{! … !}}` | Gibt einen Wert aus, ohne HTML-Sonderzeichen zu ersetzen. | Bereits aufbereitete Inhalte gezielt unverändert
ausgeben. |
| `{{ autoescape “js” }} … `
`{{ /autoescape }}` | Wechselt den Escaping-Modus innerhalb eines Blocks. | Ausgabe in speziellen Kontexten, z.B. JavaScript |
## Anweisungen ohne Ausgabe
Mit `{{ ... }}` wird eine Anweisung ausgeführt, ohne dass ihr Ergebnis direkt ausgegeben wird. Diese Schreibweise wird verwendet, wenn im Template etwas vorbereitet oder verarbeitet werden soll, ohne dass an dieser Stelle bereits Inhalt im generierten Dokument bzw. Seite erscheint.
Typische Anwendungsfälle sind das Setzen von Variablen, das Vorbereiten von Hilfswerten oder das Aufrufen von Logik, deren Ergebnis erst später benötigt wird.
### **Beispiel**
In diesem Beispiel wird der Produktname in einer Variablen gespeichert. An dieser Stelle wird jedoch noch nichts ausgegeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myVariableForProductname = $product.name }}
```
### Verwendung
Diese Syntax ist sinnvoll, wenn ein Wert zunächst nur weiterverarbeitet oder für eine spätere Ausgabe vorbereitet werden soll.
Sie sollte verwendet werden, wenn:
* eine Variable gesetzt wird
* ein Wert zwischengespeichert wird
* eine Anweisung nur der Template-Logik dient
* an dieser Stelle keine direkte Ausgabe im HTML gewünscht ist
***
## Ausgabe mit Escaping
Mit `{{= … }}` wird ein Wert ausgegeben und dabei automatisch escaped. Diese Schreibweise ist der Standard für die Ausgabe im Template, wenn Inhalte im HTML erscheinen sollen.
Einfache `(')` und doppelte `(")` Anführungszeichen innerhalb von `{{= … }}` sind gleichwertig. Der Unterschied wirkt sich nur auf das Syntax-Highlighting im Code-Editor aus.
Escaping sorgt dafür, dass Sonderzeichen nicht als HTML interpretiert werden. Dadurch bleibt die Ausgabe korrekt und Inhalte werden als Text behandelt.
### Beispiel
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $product.name }}
```
Enthält `$product.name` beispielsweise den Wert
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Tom & Jerry
```
wird daraus in der HTML-Ausgabe
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<b>Tom & Jerry</b>
```
Die Zeichen werden also so ausgegeben, dass sie im Browser korrekt dargestellt werden und nicht als HTML-Markup interpretiert werden.
### Verwendung
Diese Syntax sollte für normale Ausgaben im Template grundsätzlich bevorzugt werden.
Sie sollte verwendet werden, wenn:
* Text im HTML ausgegeben werden soll
* Inhalte aus Variablen ausgegeben werden
* nicht ausdrücklich gewünscht ist, dass HTML unverändert übernommen wird
* eine sichere Standardausgabe benötigt wird
In der Praxis ist `{{= … }}` in den meisten Fällen die richtige Wahl.
***
## Escaping für einen Bereich festlegen
Mit `autoescape` kann für einen zusammenhängenden Bereich festgelegt werden, wie Ausgaben escaped werden sollen. Das ist vor allem dann relevant, wenn Inhalte nicht im normalen HTML-Kontext ausgegeben werden, sondern beispielsweise innerhalb von JavaScript.
### Beispiel
```javascript theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ autoescape "js" }}
const productName = "{{= $product.name }}";
{{ /autoescape }}
```
In diesem Beispiel wird der Escaping-Modus für JavaScript gesetzt. Dadurch werden Ausgaben innerhalb dieses Bereichs passend für diesen Kontext behandelt.
Enthält `$product.name` zum Beispiel den Wert `Damen-Jacke "Alpine"` , wird daraus `"Damen-Jacke \"Alpine\"` , sodass die Anführungszeichen den JavaScript-String nicht unterbrechen.
### Verwendung
Diese Syntax sollte verwendet werden, wenn die Ausgabe in einem speziellen Ausgabekontext erfolgt, für den ein anderer Escaping-Modus erforderlich ist.
Das ist insbesondere sinnvoll, wenn Inhalte innerhalb von JavaScript, JSON oder vergleichbaren Kontexten ausgegeben werden.
***
## Ausgabe ohne Escaping
Mit `{{! … !}}` wird ein Wert unverändert ausgegeben. Es erfolgt kein automatisches Escaping. Die Ausgabe wird also genau so in das generierte Dokument übernommen, wie der Wert vorliegt.
Das ist nur dann sinnvoll, wenn der Inhalt bewusst ungeescaped ausgegeben werden soll, etwa weil er bereits korrekt als HTML formatiert wurde.
### Beispiel
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{! $product.name !}}
```
Enthält `$product.name` beispielsweise den Wert
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Tom & Jerry
```
wird dieser Inhalt in der HTML-Ausgabe auch als HTML übernommen
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Tom & Jerry
```
### Verwendung
Diese Syntax sollte nur gezielt und mit Vorsicht verwendet werden.
Sie sollte verwendet werden, wenn:
* Inhalte bewusst als HTML ausgegeben werden sollen
* der auszugebende Wert bereits korrekt aufbereitet ist
* kein zusätzliches Escaping mehr erfolgen darf
Sie sollte nicht verwendet werden, wenn gewöhnlicher Text ausgegeben werden soll. In solchen Fällen ist `{{= … }}` die richtige Wahl.
# Blöcke
Source: https://dokumentation.websale.de/frontend/referenz/blocke
Blöcke als Grundstruktur von Templates: Header, Footer und Navigation in benannte Bereiche teilen und unabhängig erweitern oder überschreiben.
Blöcke bilden die grundlegende Struktur eines [Templates](/frontend/die-basics/template-theme) und ermöglichen eine flexible Anpassung der Storefront. Sie unterteilen das Layout in klar benannte, isolierte Bereiche wie Header, Footer oder Navigation, die unabhängig voneinander angepasst werden können.
Diese Seite behandelt alles, was es über Blöcke im Detail zu wissen gibt: was sie können, was sie nicht können und wie man sie sinnvoll einsetzt.
## Grundprinzip
Blöcke bauen auf dem Zusammenspiel von Basis- und View-Templates auf. Das [Basis-Template](/frontend/die-basics/template-theme#2-basis-template-layout-template) definiert das übergeordnete Seitenlayout mit allem, was auf jeder Seite gleich bleibt - wie Header, Footer, Navigation oder eingebundene Skripte. Das [View-Template](/frontend/die-basics/template-theme#4-view-templates-seiten-templates) ist das Template einer konkreten Seite - es bindet das Basis Template per `{{ extends }}` ein und befüllt einzelne Bereiche mit seitenspezifischem Inhalt.
Ein Block ist ein benannter Bereich innerhalb eines Templates, der durch `{{ block “name” }}` geöffnet und durch `{{ /block }}` geschlossen wird. Er ist sowohl ein Struktur- als auch ein Inhaltsbaustein. Im Basis-Template legt er fest, welche Bereiche eine Seite hat und wo sie sich befinden, inklusive eines Standardinhalts, der angezeigt wird, solange ein View-Template diesen Block nicht explizit überschreibt. Im View-Template füllt er genau diese Bereiche mit seitenspezifischem Inhalt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ block "header" }}
Standard-Header
{{ /block }}
```
***
## Blöcke überschreiben
Ein View-Template greift einen Block auf, indem es ihn mit demselben Namen erneut definiert. Dabei gibt es drei Möglichkeiten:
1. Der Standardinhalt wird vollständig ersetzt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ extends "layouts/default.htm" }}
{{ block "header" }}
Willkommen im Shop!
{{ /block }}
```
2. Mit `append` - der neue Inhalt wird hinter dem Standardinhalt eingefügt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ block "header" append }}
Versandkostenfreiheit ab 50 €
{{ /block }}
```
3. Mit `prepend` - der neue Inhalt wird vor dem Standardinhalt eingefügt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ block "header" prepend }}
Kostenloser Versand heute!
{{ /block }}
```
Der Basis-Block bleibt in allen Fällen unverändert. `append` und `prepend`sind praktisch, wenn der Standardinhalt eines Blocks grundsätzlich passt, aber auf einzelnen Seiten um zusätzliche Inhalte ergänzt werden soll.
***
## Verwendung von Blöcken in Templates
Blöcke können nicht in jedem Template-Typ definiert oder überschrieben werden. Es kommt darauf an, welche Rolle ein Template im System übernimmt:
* **Basis-Templates** (Layout-Templates) sind der einzige Ort, an dem Blöcke definiert werden. Sie legen fest, welche Bereiche einer Seite existieren und welche Standardinhalte diese haben.
* **View-Templates** (Seiten-Templates) und **E-Mail-Templates** können Blöcke eines Basis-Templates überschreiben oder erweitern. Beide binden ein Basis-Template per `{{ extends }}` ein. Dabei gilt eine wichtige Einschränkung: Ein Template mit `{{ extends }}` darf ausschließlich aus Blockanweisungen bestehen. Kein HTML, kein Code, kein Include darf außerhalb eines Blocks stehen.
Typische Blöcke, die das Standard-Layout bereitstellt:
| **Block** | **Typischer Inhalt** |
| -------------- | ------------------------ |
| `header` | Kopfbereich der Seite |
| `content_main` | Hauptinhalt der Seite |
| `footer` | Fußbereich der Seite |
| `scripts` | JavaScript am Seitenende |
***
## Blöcke und andere Konstrukte
Im Template-System gibt es mehrere Möglichkeiten, Code zu strukturieren und wiederzuverwenden. Blöcke sind dabei nur eines von mehreren Werkzeugen.
Blöcke reservieren benannte Platzhalter im Layout, die ein View-Template später mit seitenspezifischem Inhalt füllen kann. Sie funktionieren von oben nach unten - das Basis-Template gibt den Rahmen vor, das View-Template füllt ihn. Blöcke sind das Bindeglied zwischen Layout und Seiteninhalt.
[Includes](/frontend/die-basics/template-theme#5-components-includes) binden eine separate Template-Datei an einer bestimmten Stelle ein - ähnlich wie ein Baustein, der an mehreren Stellen eingesetzt werden kann. Ein Breadcrumb oder eine Fehlermeldung sind typische Beispiele - der Code wird einmal geschrieben und überall dort eingebunden, wo er gebraucht wird. Anders als Blöcke können Includes Variablen entgegennehmen und sind damit flexibel in ihren Parametern.
[Module](/frontend/referenz/module) wie `$wsBasket` oder `$wsProducts` stellen Daten bereit. Sie sind keine Template-Bausteine sondern serverseitige Datenquellen, auf die man im Template zugreift.
In der Praxis greifen alle drei ineinander. Ein Block definiert den Bereich der Seite, innerhalb des Blocks werden Includes eingebunden - diese greifen über Module auf die benötigten Daten zu.
***
## Erlaubter Inhalt
### HTML und Template-Syntax
Innerhalb eines Blocks sind erlaubt:
* Beliebiges HTML
* Variablendeklarationen (`{{ var ... }}`) und Ausgaben (`{{= ... }}`)
* Kontrollstrukturen wie `{{ if }}`, `{{ foreach }}`, `{{ switch }}`
* Includes (`{{ include ... }}`)
* Modulzugriffe (`$wsBasket.items`, `$wsCheckout.sum.total` etc.)
### JavaScript und CSS
Blöcke wie `head` oder `scripts` können ohne Einschränkungen `
{{ /if }}
{{ /block }}
```
### Block, der einen anderen Block enthält
Im Basis-Template können Blöcke ineinander verschachtelt werden. Jeder innere Block (hier `sidebar` und `main`) ist dabei unabhängig überschreibbar.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{# Basis-Template #}}
{{ block "content" }}
{{ block "sidebar" }}
{{ /block }}
{{ block "main" }}
Standard-Inhalt
{{ /block }}
{{ /block }}
```
### Negativbeispiel
Ein View-Template, das `{{ extends }}` verwendet, darf ausschließlich aus Blockanweisungen bestehen. Code oder HTML außerhalb eines Blocks ist ungültig und führt zu Fehlern.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{# Ungültig – Code außerhalb eines Blocks #}}
{{ extends "layouts/default.htm" }}
Dieser Text steht außerhalb eines Blocks – das funktioniert nicht.
{{ block "content_main" }}
Das hier ist korrekt.
{{ /block }}
```
# Components
Source: https://dokumentation.websale.de/frontend/referenz/components
Components der WEBSALE Template-Sprache: wiederverwendbare Bausteine für strukturierte, modulare Frontend-Komponenten im Shop-Template.
# Conditions
Source: https://dokumentation.websale.de/frontend/referenz/conditions
Conditions in der WEBSALE Template-Sprache: Bedingungen formulieren und Ausgaben oder Template-Logik abhängig von Werten und Status steuern.
# Datentypen
Source: https://dokumentation.websale.de/frontend/referenz/datentypen
Basisdatentypen der WEBSALE Template-Sprache: String, Zahl, Bool, Listen und Maps korrekt notieren und im Template sicher verarbeiten.
Man unterscheidet folgende Basisdatentypen:
## String
Ein String ist eine Zeichenkette, d. h. eine Folge von Zeichen (z. B. Buchstaben, Ziffern, Sonderzeichen und Steuerzeichen). Strings müssen immer zwischen zwei Hochkommas oder Anführungszeichen notiert werden.
| | |
| ------------------------------ | -------------------------------------- |
| `"Wert1, Wert2, Wert3, Wert4"` | String |
| `'Wert1, Wert2, Wert3, Wert4'` | String |
| `Wert1, Wert2, Wert3, Wert4` | kein String (Anführungszeichen fehlen) |
## Konkatenation
Mit dem `+`-Operator ist es möglich mehrere Strings zusammenzustellen.
In diesem Beispiel erstellen wir Variablen für eine Begrüßung und stellen wir zusammen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $greeting = "Willkommen " }}
{{ var $customer = "Neukunde"}}
{{ var $genericGreeting= $greeting + $customer}}
{{= $genericGreeting}} // Wilkommen Neukunde
```
Nur Strings können konkateniert werden. Dennoch ist es möglich andere Variablen in ein String zu konvertieren um sie mit einem String zu konkatenieren.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $menge = 1}}
{{ var $text = "Anzahl: " + string($menge) + "!" }}
{{= $text}} // Anzahl: 1!
```
Es können andere Basistypen in String konvertiert werden:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Boolean: {{= string(true) }} // "true"
Integer: {{= string(1) }} // "1"
Float: {{= string(1.1) }} // "1.1"
```
## Integer
Integer sind Ganzzahlen (Zahlen ohne Nachkommastellen).
| | |
| ------- | ----------------------------------------- |
| `10` | Integer |
| `20.00` | kein Integer (Nachkommastellen vorhanden) |
## Float
Floats sind Fließkommazahlen mit einem **Punkt** als Dezimaltrenner.
| | |
| ------- | ------------------------------------------------------- |
| `10.25` | Float |
| `10,25` | kein Float (ungültige Syntax: Komma als Dezimaltrenner) |
### Float konvertieren
Es können andere Basistypen in Float konvertiert werden
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
String: {{= float("1.1")}} // 1.1
Integer: {{= float(1) }} // 1.0
Boolean: {{= float(true) }} // 1.0
```
## Boolean/Bool (true/false)
Ein Bool ist ein Wahrheitswert und kann nur *true* (wahr) oder *false* (falsch) sein.
| | |
| -------- | ------------------------------------------- |
| `true` | Wahrheitswert true |
| `false` | Wahrheitswert false |
| `"true"` | kein Wahrheitswert (falsche Syntax: String) |
Boolesche Werte werden meistens in Kombination mit [Vergleichsoperatoren](/frontend/referenz/operatoren) erzeugt. Wenn man beispielsweise einen Wert mit einem anderen vergleicht, ist das Ergebnis entweder wahr oder falsch.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $quantity == 1 }}
Wird angezeigt, wenn der Wert der Variable $quantity gleich 1 ist.
{{ /if }}
```
### truthy und falsy
Nicht nur Werte vom Datentyp Bool enthalten einen Wahrheitswert. Objekte aller anderen Datentypen haben ebenfalls eine Werte-Eigenschaft, die man als *truthy* oder *falsy* bezeichnet. In Zusammenhang mit logischen Operatoren und Verzweigungen ist es wichtig zu wissen, wann ein Wert als wahr oder falsch angesehen wird.
Hier eine Auflistung aller Werte die *falsy* sind und deshalb als *false* behandelt werden:
▪\_null\_, der Wert des Datentyps Null
▪\_false\_
▪die Zahl 0 (*Integer*) oder 0.0 (*Float*)
▪ein leerer *String " "*
▪eine leere *List \[ ]*
▪eine leere *Map*
Alle anderen Werte werden als *truthy* behandelt.
### Boolean konvertieren
Es können andere Basistypen in Boolean konvertiert werden
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
String: {{= bool(" ")}} // true
String: {{= bool("")}} // false
Integer: {{= bool(1) }} // true
Integer: {{= bool(0) }} // false
Float: {{= bool(1.0) }} // true
Float: {{= bool(0.0) }} // false
```
## List
Eine List ist eine Reihe von Werten, die kommasepariert zwischen eckigen Klammern stehen. Eine leere List wird mit eckigen Klammern ohne Inhalt geschrieben.
| | |
| ----------- | ------------- |
| `[1, 2, 3]` | gefüllte List |
| `[ ]` | leere List |
Die Leerzeichen zwischen den Werten sind optional.
## Distinct
Wenn in einer Liste mehrere Einträge gibt, die identisch sind, kann mit dieser Funktion alle doppelten Einträge entfernt werden.
**Argumente**
`list` - Liste, die verarbeitet werden soll
`key` - (Optional) Map-Key, der für den Vergleich mit anderen Maps hergenommen werden soll.
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $list = [ 1, 2, 3, 4, 3, 2, 5, 6, 1 ] }}
{{= distinct($list) }} // Ergebnis: [ 1, 2, 3, 4, 5, 6 ]
{{ $list = [ "a", 1, "b", true, 2, "a", true, true, {"x": 1, "y": 1}, {"x": 1, "y": 2} ] }}
{{= distinct($list) }} // Ergebnis: [ "a", 1, "b", true, 2, , {"x": 1, "y": 1}, {"x": 1, "y": 2} ]
```
Man kann bei für Objekte einen key angeben, mit dem definiert werden soll welches Feld zum Vergleich hergenommen werden soll.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $list = [ 1, {"x": 1, "y": 1}, {"x": 1, "y": 2}, {"x": 2, "y": 2} ] }}
{{= $list | distinct("x") }} // Ergebnis: [ 1, {"x": 1, "y": 1}, {"x": 2, "y": 2} ]
ähnliche Schreibweise ohne Pipe:
{{= distinct($list, "x") }}
```
## Merge
Es können zwei Listen jeweils miteinander vereint werden.
Zusätzliche Information: Neben der Verwendung von einer Funktion kann auch der `+`-Operator (`$list1 + $list2`) verwendet werden.
**Argumente**
`target` - Liste, die für das Zusammenführen als Basis hergenommen werden soll
`source` - Liste, um die das `target` erweitert werden soll
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $list1 = [ 1, 2, 3 ] }}
{{ var $list2 = [ 3, 4, 5] }}
{{ var $list3 = merge($list1, $list2) }}
{{= $list3 }} // Ergebnis: [1, 2, 3, 3, 4, 5]
```
## Map
Eine Map ist eine Liste von Schlüssel-Wert-Paaren, die innerhalb einfacher geschweifter Klammern geschrieben werden. Der Schlüssel und sein Wert werden durch Doppelpunkt getrennt. Die einzelnen Schlüssel-Wert-Paare werden durch Kommas getrennt. Eine leere Map wird mit geschweiften Klammern ohne Inhalt geschrieben.
| | |
| ------------------------------------------------------------ | ---------------------------- |
| `{ name: "Shirt", price: "12.95", image: "shirt-blue.jpg" }` | gefüllte Map |
| `{ "404": "Not found", "301": "Moved Permanently" }` | gefüllte Map |
| `{ "Name, Description , Price, Zusatzinfos" }` | keine Map (ungültige Syntax) |
| `{ }` | leere Map |
Wenn ein Schlüssel andere Zeichen enthält als Ziffern (0-9), Buchstaben (a-z, A-Z) oder Unterstriche (\_) oder mit einer Ziffer/Unterstrich beginnt, muss dieser als String in Anführungszeichen angegeben werden.
Bei der Ausgabe von Maps wird die Reihenfolge der einzelnen Schlüssel-Werte-Paare nicht berücksichtigt.
### **Merge**
Es können zwei Maps jeweils miteinander vereint werden. Bei der Map wird bei unterschiedlichen Inhalten der Inhalt des zweite Eintrags verwendet. Dabei kann auch verschachtelte Maps berücksichtigt werden.
**Argumente**
`target` - Map, die für das Zusammenführen als Basis hergenommen werden soll
`source` - Map, um die das `target` erweitert werden soll
`deep` - Optionaler Flag ob ein die Verschachtelung von Maps berücksichtigt werden soll (default: `false`)
Beispiel - Merge von zwei Maps.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $map1 = { "a": 1, "b": 2, "c": { "x": 10, "y": 11 } } }}
{{ var $map2 = { "a": 2, "c": { "z": 12 }, "d": true } }}
{{ var $map3 = merge($map1, $map2) }}
{{= $map3 }} // Ergebnis: { "a": 2, "b": 2, "c":{ "z": 12 }, "d": true }
```
Beispiel - Deep Merge von zwei Maps:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $map1 = { "a": 1, "b": 2, "c": { "x": 10, "y": 11 } } }}
{{ var $map2 = { "a": 2, "c": { "z": 12 }, "d": true } }}
{{ var $map3 = merge($map1, $map2, true) }}
{{= $map3 }} // Ergebnis: { "a": 2, "b": 2, "c":{ "x": 10, "y": 11, "z": 12 }, "d": true }
```
# Funktionen
Source: https://dokumentation.websale.de/frontend/referenz/funktionen
Globale Template-Funktionen: Strings anpassen, Zahlen runden, Listen zusammenführen und Datumswerte vergleichen – inklusive Modifier-Nutzung.
Globale Template-Funktionen stehen in allen Templates zur Verfügung. Sie werden verwendet, um Werte zu verarbeiten, zu formatieren oder zu prüfen (z. B. Strings anpassen, Zahlen runden, Listen zusammenführen oder Datumswerte vergleichen).
Diese Seite beschreibt ausschließlich globale Funktionen. Funktionen, die an ein Modul gebunden sind (z. B. Methoden von `$wsAccount` oder `$wsExternalData`), werden in der jeweiligen [Modul-Referenz](../referenz/module.mdx) dokumentiert.
Viele Funktionen können alternativ auch als [Modifier](../referenz/modifiers.mdx) (Filter) verwendet werden.
***
## Grundlagen
Funktionen werden mit runden Klammern aufgerufen. Werte, die an eine Funktion übergeben werden (sogenannte Parameter), werden durch Kommas getrennt. Funktionsnamen sind case-sensitive (Groß - und Kleinschreibung muss also genau beachtet werden).
### Schreibweise
Damit das Ergebnis einer Funktion im Template ausgegeben wird, wird die Ausgabe-Schreibweise verwendet:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= (...) }}
```
Das Ergebnis der Funktion muss nicht zwingend sofort im Template ausgegeben werden, sondern kann auch in einer eigenen Variable gespeichert werden, um es später weiter zu verwenden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myVariable = (...) }}
```
### Parameterübergabe und Reihenfolge
Standardmäßig werden Parameter positionsbasiert übergeben (in der Reihenfolge der Signatur).
Wenn die Reihenfolge der Parameter geändert werden soll, müssen benannte Parameter verwendet werden (Name laut Signatur + `=`). Entscheidend sind dann die Parameternamen – nicht die Position.
**Beispiel**
Ein Gutschein soll über die Funktion `replace` umbenannt werden. Aus `GUTSCHEIN_buy10` soll `GUTSCHEIN_sale10` werden.
Die Signatur lautet: `replace(content, search, replace)`. Bei positionsbasierter Übergabe ist die Reihenfolge daher:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= replace("GUTSCHEIN_buy10", buy", "sale") }}
```
Sobald Parameter benannt übergeben werden (`name="..."`), ist die Reihenfolge frei:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= replace(search="buy", replace="sale", content="GUTSCHEIN_buy10") }}
```
\= In beiden Fällen ist das Ergebnis
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
GUTSCHEIN_sale10
```
### Funktionen kombinieren (verkettete Verarbeitung)
Mehrere Funktionen können auch nacheinander angewendet werden, indem die erste Funktion als Argument der zweiten Funktion verwendet wird.
**Beispiel**
Die VersandkostenID „versand\_kostenfrei“ soll sprechend in „VERSAND KOSTENFREI“ umbenannt und die Schreibweise in Versalien (Großschreibung) geändert werden.
Es werden die Funtkionen `upper` und `replace` verwendet:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= upper(replace("versand_kostenfrei", "_", " ")) }}
```
\=
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
VERSAND KOSTENFREI
```
### Texte und Listen zusammenfügen
Mit dem `+`-Operator könne zwei Texte (Strings) direkt zu einem neuen String zusammengefügt werden. Für Listen kann `+` alternativ zu `merge()` verwendet werden, um zwei Auflistungen zu vereinen.
Es können nur Werte desselben Typs mit `+` verbunden werden. Zahlen oder andere Typen müssen vorher mit der Funktion `str()` in einen Text umgewandelt werden.
**Beispiele**\
Artikelnummer aus Präfix und ID zusammensetzen:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $prefix = "ART-" }}
{{ var $productId = "10452" }}
{{ var $articleNumber = $prefix + $productId }}
{{= $articleNumber }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
ART-10452
```
Bestellmenge in einen Hinweistext einbinden - Zahlen müssen vor der Zusammensetzung mit einem String mit `str()` in einen Text umgewandelt werden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $quantity = $wsCart.info.itemCount }}
{{ var $message = "Anzahl Artikel im Warenkorb: " + str($quantity) }}
{{= $message }}
```
***
## Liste der Funktionen
### abs
Die Funktion `abs` gibt den Absolutwert einer Zahl zurück – also den Wert ohne Vorzeichen. Eine negative Zahl wird dadurch positiv, eine positive Zahl bleibt unverändert.
**Anwendungsbeispiel**\
Nützlich, um z. B. Rabattbeträge oder Preisdifferenzen im Shop immer als positive Zahl darzustellen – unabhängig davon, ob der Wert in den Daten ein Minus-Vorzeichen hat.
**Signatur**\
`abs(value)`
**Parameter**
* `value` - Die Zahl, deren Absolutwert ermittelt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel mit negativem Wert**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= abs(-7.5) }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
7.5
```
**Beispiel mit positivem Wert**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= abs(3) }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
3
```
**Beispiel - Preisdifferenz immer positiv darstellen**\
Der aktuelle Preis eines Produkts wird im Feld `price` gespeichert (hier: `79.95`), der ursprüngliche Preis im Feld `setOrgPrice` (hier: `99.95`). Die Differenz zwischen beiden kann je nach Rechenrichtung negativ ausfallen. Mit `abs` wird sichergestellt, dass der angezeigte Betrag immer positiv ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myProduct = $wsProducts.load("100-12345") }}
Sie sparen: {{= currency(abs($myProduct.price - $myProduct.setOrgPrice)) }} €
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Sie sparen: 20,00 €
```
***
### ceil
Die Funktion `ceil` rundet eine Zahl immer auf die nächste ganze Zahl auf – egal, wie klein der Nachkommaanteil ist. `ceil(1.1)` ergibt also `2`, genauso wie `ceil(1.9)`.
**Anwendungsbeispiel**\
Hilfreich, wenn Werte im Shop immer „zugunsten" einer ganzen Einheit aufgerundet werden sollen – z. B. Stückzahlen, Verpackungseinheiten oder berechnete Mengen.
**Signatur**\
`ceil(value)`
**Parameter**
* `value` – Die Zahl, die aufgerundet werden soll.
**Verwendbar als Modifier:**\
ja
**Beispiel mit Dezimalzahl resp. Dezimalbruch**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= ceil(1.3) }}
```
**Ausgabe** (aufgerundet auf die nächste ganze Zahl)
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
2.000000
```
**Beispiel mit ganzer Zahl (Ganzzahl)**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= ceil(2) }}
```
**Ausgabe** (ganze Zahl bleibt unverändert)
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
2.000000
```
Um die Darstellung der Nachkommastellen anzupassen benutzen Sie `ceil(2) | preparedFormat(“name“)`
\
**Beispiel - Berechnetes Produktgewicht aufrunden**\
Das Versandgewicht eines Produkts (in diesem Fall 2,3 kg) wird auf volle Kilogramm aufgerundet.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myProductWeight = $myProduct.custom.weight }}
Versandgewicht: {{= ceil($myProductWeight) | preparedFormat("amount") }} kg
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Versandgewicht: 3 kg
```
**Gegenstück**\
[floor](#floor)
***
### currency
Die Funktion `currency` formatiert einen numerischen Wert als Preisangabe gemäß den [Shop-Einstellungen zur Währung](/konfiguration/finance-wahrungen-steuern). Dazu gehören insbesondere:
* Dezimaltrennzeichen (z. B. `,` statt `.`)
* Anzahl der Nachkommastellen (z. B. 2 bei vielen Währungen)
* kaufmännisches Runden auf die konfigurierte Nachkommastellen-Anzahl
Die Funktion berechnet keine Preise (z.B. Steuern, Rabatte oder Versandkosten), sondern formatiert ausschließlich den übergebenen Wert für die Ausgabe.
**Anwendungsbeispiel**\
Eignet sich für die Ausgabe von Beträgen wie Einzelpreisen, Rabatten, Zwischensummen und Gesamtsummen.
**Signatur**\
`currency(price)`
**Parameter**
* `price` - Die Zahl, die als Preis formatiert werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel mit Nachkommastellen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= currency(3.1475) }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
3,15€
```
**Beispiel mit Ganzzahl**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= currency(12) }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
12,00€
```
Soll ein Zahlenwert unabhängig von der Währung in einem bestimmten Format ausgegeben werden (z.B. mit einer anderen Anzahl an Nachkommastellen), ist [preparedFormat()](#preparedformat) die passende Funktion.
**Beispiel - Produktpreis formatiert ausgeben**\
Der Preis eines Produkts wird als Dezimalzahl gespeichert (hier: `89.95`). Mit `currency` wird er gemäß den Shop-Einstellungen formatiert.
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
89.95€
```
***
### dateFmt
Die Funktion `dateFmt` bringt ein Datum oder einen Zeitpunkt in ein gewünschtes Anzeigeformat. Der Eingabewert muss im ISO-8601-Format vorliegen (z. B. `2018-03-11T11:20:11.000Z`) – dieses Format wird von den meisten Systemen automatisch verwendet.
**Anwendungsbeispiel**\
Damit lassen sich z. B. Bestelldaten, Liefertermine oder Aktionszeiträume im Shop leserlich darstellen (z. B. als „11.03.2018" oder „11:20:11").
**Signatur**\
`dateFmt(isoDate, fmt[, tz])`
**Parameter**
* `isoDate` – Datum/Zeit im ISO-8601-Format (z. B. `2018-03-11T11:20:11.000Z`)
* `fmt` – Formatangabe, die festlegt, wie die Ausgabe aussehen soll
* Die wichtigsten Platzhalter im Überblick
* `%d` = Tag (01–31)
* `%m` = Monat (01–12)
* `%Y` = Jahr (4-stellig)
* `%H` = Stunde (00–23)
* `%M` = Minute (00–59)
* `%S` = Sekunde (00–60)
* Damit können Sie die folgenden Formate einfach „zusammenbauen“, z. B.:
* `"%d.%m.%Y"` → `11.03.2018`
* `"%H:%M:%S"` → `11:20:11`
* `tz` (optional) – Zeitzone, in der die Zeit ausgegeben werden soll (z.B. "`Europe/Berlin`"). Ohne Angabe wird die im Shop konfigurierte Zeitzone verwendet (Konfiguration [general.general](https://dokumentation.websale.de/konfiguration/general-allgemeine-shopeinstellungen#general-general-allgemeine-basiseinstellungen), auch über [\$wsSubshop.timeZone](/frontend/referenz/module/wssubshop#wssubshop-timezone) abrufbar). Gültige Werte sind die Namen der IANA-Zeitzonendatenbank, [eine gut lesbare Übersicht finden Sie hier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
**Verwendbar als Modifier**\
ja
**Beispiel zur Ausgabe des Bestelldatums aus der “Bestellzeit”**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= dateFmt("2018-03-11T11:20:11.000Z", "%d.%m.%Y") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
11.03.2018
```
**Beispiel zur Ausgabe der Uhrzeit aus der “Bestellzeit”**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= dateFmt("2018-03-11T11:20:11.000Z", "%H:%M:%OS") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
11:20:11
```
**Beispiel mit Ausgabe der Zeitzone**\
Derselbe UTC-Zeitstempel wird in der Zeitzone `Europe/Berlin` ausgegeben. Im März gilt dort die Mitteleuropäische Zeit (UTC+1), die Uhrzeit liegt daher eine Stunde später als in der UTC-Eingabe.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= dateFmt("2018-03-11T11:20:11.000Z", "%H:%M", "Europe/Berlin") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
12:20
```
**Beispiel - aktuelle Jahreszahl ausgeben**\
In Kombination mit [\$wsSubshop.currentTime](/frontend/referenz/module/wssubshop) (aktueller Zeitstemple im ISO-8601-Format) lässt sich z.B. die aktuelle Jahreszahl ausgeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsSubshop.currentTime | dateFmt("%Y") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
2026
```
**Beispiel - Bestelldatum und Uhrzeit formatiert ausgeben**\
Das Bestelldatum ist in diesem Beispiel in folgendem Format gespeichert - `2024-06-15T14:32:05.000Z`. Mit `dateFmt` wird es für eine Bestellbestätigung in ein lesbares Datum und eine separate Uhrzeit umgewandelt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{var $myOrder = $wsOrderHistory.load($wsViews.current.params.orderHistorySelect)}
Bestellt am: {{= dateFmt($myOrder.general.dateTime, "%d.%m.%Y") }}
Uhrzeit: {{= dateFmt($myOrder.general.dateTime, "%H:%M") }} Uhr
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Bestellt am: 15.06.2024
Uhrzeit: 14:32 Uhr
```
***
### dateGreaterThan
Die Funktion `dateGreaterThan` vergleicht zwei Datumswerte (als Strings) miteinander und liefert `true`, wenn das erste Datum nach dem zweiten Datum liegt.
**Anwendungsbeispiel**\
Damit lässt sich im Template z. B. prüfen, ob ein Liefertermin in der Zukunft liegt oder ob ein Zeitraum bereits überschritten ist.
**Signatur**\
`dateGreaterThan(firstDate, secondDate)`
**Parameter:**
* `firstDate` – Erstes Datum (zu prüfender Wert)
* `secondDate` – Zweites Datum (Vergleichswert)
**Verwendbar als Modifier**\
ja
**Beispiel eines Datumsvergleichs**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= dateGreaterThan("2019-03-11T11:20:11.000Z", "2017-07-11T11:20:11.000Z") }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
true
```
**Beispiel - Prüfen, ob eine Bestellung nach einem bestimmten Stichtag aufgegeben wurde**\
Mit `dateGreaterThan` lässt sich prüfen, ob die Bestellung nach einem festen Stichtag liegt - z.B. um nur Bestellungen ab dem 01.01.2025 für eine Rückgabeaktion zu berücksichtigen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myOrder = $wsOrderHistory.load("12345") }}
{{ var $stichtag = "2025-01-01T00:00:00.000Z" }}
{{ if (dateGreaterThan($myOrder.general.dateTime, $stichtag)) }}
Diese Bestellung ist für die Rückgabeaktion qualifiziert.
{{ /if }}
```
**Ausgabe, wenn das Bestelldatum nach dem 01.01.2025 liegt**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Diese Bestellung ist für die Rückgabeaktion qualifiziert.
```
**Gegenstück**\
[dateLessThan](#datelessthan)
***
### dateLessThan
Die Funktion `dateLessThan` vergleicht zwei Datumswerte (als Strings) miteinander und liefert `true`, wenn das erste Datum **vor** dem zweiten Datum liegt.
**Anwendungsbeispiel**\
Damit lassen sich im Template z. B. Fristen oder Zeiträume prüfen - etwa ob ein Datum bereits überschritten ist oder ob ein Ereignis noch bevorsteht.
**Signatur**\
`dateLessThan(firstDate, secondDate)`
**Parameter**
* `firstDate` – Erstes Datum (zu prüfender Wert)
* `secondDate` – Zweites Datum (Vergleichswert)
**Verwendbar als Modifier**\
ja
**Beispiel eines Datumsvergleichs**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= dateLessThan("2020-03-11T11:20:11.000Z", "2021-07-11T11:20:11.000Z") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
true
```
**Beispiel - Hinweis anzeigen, wenn eine Bestellung vor einem Stichtag aufgegeben wurde**\
Mit `dateLessThan` lässt sich prüfen, ob die Bestellung vor einem festen Stichtag liegt - z.B. um drauf hinzuweisen, dass die Rückgabefrist bereits abgelaufen ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myOrder = $wsOrderHistory.load("12345") }}
{{ var $fristEnde = "2025-01-01T00:00:00.000Z" }}
{{ if (dateLessThan($myOrder.general.dateTime, $fristEnde)) }}
Die Rückgabefrist für diese Bestellung ist abgelaufen.
{{ /if }}
```
**Ausgabe, wenn das Bestelldatum vor dem 01.01.2025 liegt**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Die Rückgabefrist für diese Bestellung ist abgelaufen.
```
**Gegenstück**\
[dateGreaterThan](#dategreaterthan)
***
### decode
Die Funktion `decode` wandelt einen kodierten String zurück in seinen ursprünglichen Klartext. Unterstützte Formate sind `base64` und `hex`. Wenn der übergebene Wert kein gültiger kodierter String im angegebenen Format ist, gibt die Funktion `null` zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. extern kodiert übermittelte Produktdaten, Gutscheincodes oder Konfigurationswerte vor der Weiterverarbeitung im Template zu dekodieren.
**Signatur**\
`decode(content, format)`
**Parameter**
* `content` - Der kodierte String, der dekodiert werden soll.
* `format` - Das Kodierungsformat, das beim Dekodieren verwendet werden soll. Gültige Werte: `“base64”`, `“hex”`.
**Verwendbar als Modifier**\
ja
**Beispiel - Dekodierung eines Base64-Strings**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= decode("d2Vic2FsZQ==", "base64") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
websale
```
**Beispiel - Dekodierung eines Hex-Strings**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= decode("776562 73616c65", "hex") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
websale
```
**Beispiel - Fehlerhafte Eingabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= decode("kein-gültiger-base64-wert!!!", "base64") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
null
```
**Gegenstück**\
[encode](#encode)
***
### distinct
Die Funktion `distinct` entfernt doppelte Einträge aus einer Auflistung und gibt eine neue Auflistung zurück, in der jeder Wert nur einmal vorkommt. Bei Auflistungen von Datenobjekten (Maps) kann optional ein Schlüssel angegeben werden, anhand dessen verglichen wird. Die Angabe des Schlüssels wird nur auf der obersten Ebene einer Map berücksichtigt.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Duplikate aus einer Liste von Produktkategorien, Variantenmerkmalen oder Filterwerten zu entfernen, bevor sie im Template angezeigt werden.
**Signatur**\
`distinct(list[, key]`
**Parameter**
* `list` - Die Auflistung, aus der Duplikate entfernt werden sollen.
* `key (optional)` - Schlüssel eines Datenobjekts, der für den Vergleich verwendet wird.
**Verwendbar als Modifier**\
ja
**Beispiel - Doppelte Größenangaben aus einer Variantenliste entfernen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $sizes = ["S", "M", "L", "M", "XL", "S"] }}
{{= distinct($sizes) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
["S", "M", "L", "XL"]
```
***
### encode
Die Funktion `encode` kodiert einen String ein ein angegebenes Format. Unterstützte Formate sind `base64` und `hex`. Der Rückgabewert ist immer vom Typ String.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Gutscheincodes, Produkt-Kennungen oder andere Werte für die Weitergabe an externe Dienste oder in URLs sicher zu kodieren.
**Signatur**\
`encode(content, format)`
**Parameter**
* `content` - Der String, der kodiert werden soll.
* `format` - Das Zielformat der Kodierung. Gültige Werte: `“base64”`, `“hex”`.
**Verwendbar als Modifier**\
ja
**Beispiel - Kodierung als Base64**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= encode("websale", "base64") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
d2Vic2FsZQ==
```
**Beispiel - Kodierung als hex**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= encode("websale", "hex") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
776562 73616c65
```
**Gegenstück**\
[decode](#decode)
***
### floor
Die Funktion `floor` rundet eine Zahl immer auf die nächste ganze Zahl ab – egal, wie groß der Nachkommaanteil ist. `floor(4.9)` ergibt also `4`, genauso wie `floor(4.1)`.
**Anwendungsbeispiel**\
Hilfreich, wenn Werte im Shop grundsätzlich abgerundet werden sollen – z. B. bei berechneten Mengen oder Zwischenergebnissen, die nur als ganze Zahl weiterverarbeitet werden dürfen.
**Signatur**\
`floor(value)`
**Parameter**
* `value` – Numerischer Wert, der abgerundet werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel mit Dezimalzahl resp. Dezimalbruch**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= floor(4.9) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
4.000000
```
**Beispiel mit ganzer Zahl**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= floor(2) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
2.000000
```
Um die Darstellung der Nachkommastellen anzupassen benutzen Sie `floor(4.9) | preparedFormat(“name”)`
**Beispiel - Berechnetes Produktgewicht abrunden**\
Das Versandgewicht eines Produkts (in diesem Fall 2,7 kg) wird auf volle Kilogramm abgerundet.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myProductWeight = $myProduct.custom.weight }}
Mindestgewicht: {{= floor($myProductWeight) | preparedFormat("amount") }} kg
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Mindestgewicht: 2 kg
```
**Gegenstück**\
[ceil](#ceil)
***
### ifnull
Die Funktion `ifnull` prüft, ob ein Wert vorhanden ist oder nicht (`null` bedeutet: „kein Wert vorhanden"). Ist der Wert `null`, wird stattdessen ein Ersatzwert ausgegeben. Ist ein Wert vorhanden, wird dieser selbst verwendet.
**Anwendungsbeispiel**\
Eignet sich z.B. für Fallback-Logiken im Shop - etwa um ein Ersatzbild anzuzeigen, wenn kein Produktbild vorhanden ist, oder um fehlende Produktdaten durch Standardwerte zu ersetzen.
**Signatur**\
`ifnull(object, value)`
**Parameter**
* `object` - Der zu prüfende Wert.
* `value` - Der Alternativwert, der ausgegeben wird, wenn `object` den Wert `null` hat.
**Verwendbar als Modifier**\
ja
**Beispiel mit** `null`**-Wert**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= ifnull(Null, "sale") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
sale
```
**Beispiel mit vorhandenem Wert**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= ifnull("web", "sale") }}
```
**Ausgabe** (der String `“web”` ist nicht `null`, daher wird er selbst ausgegeben).
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
web
```
**Beispiel mit Produktbild-Fallback**\
In der Variable `$myProduct` werden alle Informationen und Daten zu einem Produkt gespeichert. Wenn kein Produktbild gefunden wird (`$myProduct.custom.image.normal` ist `null`), dann wird das Ersatzbild `noImageNormal.png` angezeigt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myProduct = $wsView.info.product }}
```
***
### int
Die Funktion `int` wandelt einen Wert in eine ganze Zahl (Integer) um. Das ist vor allem dann nötig, wenn ein Zahlenwert als Text vorliegt (z.B. `“10”`) und als echte Zahl weiterverarbeitet werden soll - etwa für Berechnungen oder Vergleiche. Ist die Umwandlung nicht möglich (z.B. bei einem Wort), wird `null` zurückgegeben. Dezimalzahlen werden auf die ganze Zahl vor dem Komma gekürzt (nicht gerundet).
**Anwendungsbeispiel**\
Nutzbar, um z. B. Mengenangaben oder Artikel-IDs, die als Text vorliegen (z.B. “1043”), in eine Zahl umzuwandeln, bevor sie weiterverarbeitet werden.
**Signatur**\
`int(value)`
**Parameter**
* `value` - Der Wert, der in eine Ganzzahl konvertiert werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel mit einem String, der eine Zahl enthält**
Der Text “10” wird in die Zahl 10 umgewandelt. Mit der Ausgabe wurde der Text in eine Zahl konvertiert, mit der nun gerechnet werden kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= int("10") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
10
```
**Beispiel mit nicht konvertierbarem Wert**
Ein Wort (in diesem Fall “websale”) kann nicht ein eine Zahl umgewandelt werden - die Ausgabe ist `null`.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= int("websale") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
null
```
**Beispiel mit Dezimalzahl**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= int(10.789) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
10
```
***
### isoToUnix
Die Funktion `isoToUnix` wandelt einen Zeitstempel im ISO-8601-Format in die Unix-Zeit um, also die Anzahl der Sekunden seit dem 1.Jahnuar 1970 (UTC).\
\
**Anwendungsbeispiel**\
Nutzbar, um z.B. Zeitstempel für Berechnungen, Vergleiche oder die Übergabe an externe Dienste in ein einheitliches numerisches Format zu bringen.\
\
**Signatur**\
`isoToUnix(isoDate)`
**Parameter**
* `isoDate` - Zeitstempel im ISO-8601-FOrmat (z.B. 2018-03-11T11:20:11.000Z)
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= isoToUnix("2018-03-11T11:20:11.000Z") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
1520767211
```
**Gegenstück**\
[unixToIso](https://dokumentation.websale.de/frontend/referenz/funktionen#unixtoiso)
***
### join
Die Funktion `join` fügt alle Einträge einer Auflistung zu einem String zusammen. Optional kann ein Separator (Trennzeichen) angegeben werden, der die Elemente voneinander trennt.
**Anwendungsbeispiel**\
Eignet sich z. B. um Produkteigenschaften, Variantenmerkmale oder Kategorien als zusammenhängenden Text auszugeben – etwa kommasepariert in einer Zeile.
**Signatur**\
`join(list[, "separator"])`
**Parameter**
* `list` - Die Auflistung, deren Einträge zusammengefügt werden sollen.
* `separator` (optional) - Trennzeichen zwischen den Einträgen. Standard: kein Trennzeichen.
**Verwendbar als Modifier**\
ja
**Beispiel ohne Separator**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= join(["S", "M", "L", "XL"]) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
SMLXL
```
**Beispiel mit Separator**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= join(["S", "M", "L", "XL"], ", ") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
S, M, L, XL
```
**Beispiel - verfügbare Farben eines Produkts als Text ausgeben**\
Die Varianten-Daten eines Produkts werden über `$wsProducts.variantInfo()` geladen. Das Attribut “Farbe” enthält eine Auflistung von Optionen (hier: `“Rot”`, `“Blau”`, `“Grün”`). Die Farbnamen werden in einer Schleife gesammelt, mit [push](#push) in einer Auflistung gesammelt und mit `join` zu einem lesbaren Text zusammengefügt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myVariants = $wsProducts.variantInfo("100-12345") }}
{{ var $colors = [] }}
{{ for $myOption in $myVariants.variantAttributes[0].options }}
{{ push($colors, $option.name) }}
{{ /for }}
Verfügbare Farben: {{= join($colors, ", ") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Verfügbare Farben: Rot, Blau, Grün
```
**Gegenstück**\
[split](#split)
***
### json
Die Funktion `json` gibt ein Datenobjekt in der technischen JSON-Schreibweise aus – einem standardisierten Textformat, das sich leicht maschinell verarbeiten lässt.
**Anwendungsbeispiel**\
Nützlich zum Fehlersuchen (Debugging) im Template oder bei der Weitergabe von Daten an externe Dienste (z. B. Tracking, Analytics).
**Signatur**\
`json(object)`
**Parameter**
* `object` - Das Objekt, das als JSON-String ausgegeben werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel - Ausgabe von Produktdaten zur Fehlersuche**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $product = $wsView.info.product }}
{{= json($product) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{"name":"Sneaker Classic","price":89.95,"sku":"SNK-001","sizes":["40","41","42"]}
```
Es werden nicht mehr als fünf Ebenen ausgegeben. Tiefere Ebenen werden als `“…”` dargestellt.
***
### keys
Die Funktion `keys` gibt alle Bezeichner (Schlüssel) eines Datenobjekts (Map) als Auflistung zurück. Eine Map besteht aus Paaren von Bezeichnern und Werten – z. B. `{name: "Topseller", price: 12.99}`. Mit `keys` lassen sich gezielt die Bezeichner auslesen.
**Anwendungsbeispiel**\
Nutzbar, um z. B. über alle Einträge eines Datenobjekts zu gehen und sowohl die Bezeichner als auch die zugehörigen Werte im Template anzuzeigen – etwa bei dynamisch aufgebauten Produktdaten oder Konfigurationseinstellungen.
**Signatur**\
`keys(object)`
**Parameter**
* `object` - Das Datenobjekt, dessen Bezeichner (Schlüssel) zurückgegeben werden sollen.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= keys({name: "Topseller", price: 12.99, description: "Beschreibung"}) }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
["description","price","name"]
```
***
### last
Die Funktion `last` gibt den letzten Eintrag einer Auflistung (List) zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. die letzte Bestellposition, den letzten Breadcrumb-Eintrag oder das letzte Element einer Variantenliste gezielt anzuzeigen.
**Signatur**\
`last(list)`
**Parameter**
* `list` - die Auflistung, deren letzter Eintrag zurückgegeben werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= last(["a", "b", "c", "d"]) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
d
```
**Beispiel - Letzten Breadcrumb-Eintrag als aktuelle Kategorie anzeigen**\
Der Kategoriepfad (Breadcrumb) wird über `$wsCategories.loadPath()` als Auflistung geladen. Mit `last` wird der letzte Eintrag gezielt ausgelesen, da dieser der aktuellen Kategorie entspricht.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myBreadcrumb = $wsCategories.loadPath($category.id) }}
Kategorie: {{= last($myBreadcrumb).name }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Sneaker
```
***
### len
Die Funktion `len` ermittelt die Länge, also die Anzahl der Zeichen bei einem Text, die Anzahl der Einträge bei einer Auflistung oder die Anzahl der Schlüssel-Wert-Paare bei einem Datenobjekt.
**Anwendungsbeispiel**\
Nutzbar, um z.B. die Anzahl von Produkten in einer Liste zu zählen, die Zeichenlänge einer Eingabe zu prüfen oder um festzustellen, wie viele Einträge ein Datenobjekt enthält.
**Signatur**\
**len(sequence)**
**Parameter**
* `sequence` - Text, Auflistung oder Datenobjekt, dessen Länge ermittelt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel mit Text**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= len("abc def. XYZ") }}
```
**Ausgabe** (Anzahl der Zeichen)
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
12
```
**Beispiel mit Auflistung**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= len([1, 2, 3]) }}
```
**Ausgabe** (Anzahl der Einträge)
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
3
```
**Beispiel mit Datenobjekt**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= len({name: "Produkt", price: 12.99}) }}
```
**Ausgabe** (Anzahl der Schlüssel-Wert-Paare)
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
2
```
**Beispiel - Anzahl der Produkte in einer Kategorie anzeigen**\
Die Produkte einer Kategorie werden über [\$wsCategories.loadProducts()](/frontend/referenz/module/wscategories#\$wscategories-loadproducts) geladen (hier: 24 Produkte in der Kategorie). Mit `len` wird die Anzahl ermittelt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $products = $wsCategories.loadProducts("100-12345") }}
{{= len($products) }} Produkte gefunden
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
24 Produkte gefunden
```
***
### lower
Die Funktion `lower` wandelt alle Buchstaben eines Textes in Kleinbuchstaben um.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Benutzereingaben, Gutscheincodes oder Produktkennungen einheitlich in Kleinschreibung darzustellen oder zu vergleichen.
**Signatur**\
`lower(content)`
**Parameter**
* `content` - der Text, der in Kleinbuchstaben umgewandelt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= lower("TOPSELLER") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
topseller
```
**Gegenstück**\
[upper](#upper)
***
### max
Die Funktion `max` gibt den höchsten Wert aus einer Auflistung von Zahlen zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. den teuersten Preis innerhalb einer Variantenliste oder die höchste verfügbare Menge zu ermitteln.
**Signatur**\
`max(list)`
**Parameter**
* `list` - die Auflistung mit Zahlenwerten.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= max([5, 13, -1, 3, 2, -7, 12]) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
13
```
**Beispiel - Höchsten Bestellwert aus der Bestellhistorie ermitteln**\
Die letzten Bestellungen eines Kunden werden über `$wsOrderHistory.loadList()` geladen. Jede Bestellung enthält u. a. das Feld `order.total` (Gesamtpreis). Die geladenen Bestellwerte werden mit [push](#push) in einer eigenen Auflistung gesammelt und anschließend mit `max` der höchste Wert ermittelt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myOrders = $wsOrderHistory.loadList() }}
{{ var $myTotals = [] }}
{{ for $myOrder in $myOrders }}
{{ push($myTotals, $myOrder.order.total) }}
{{ /for }}
Ihre höchste Bestellung: {{= max($myTotals) | currency }} €
```
**Ausgabe** (bei Bestellwerten `49.90`, `129.00`, `89.95`):
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Ihre höchste Bestellung: 129,00 €
```
**Gegenstück**\
[min](#min)
***
### merge
Die Funktion `merge` führt zwei Datenobjekte (Maps) zusammen. Die Einträge aus dem zweiten Objekt (`source`) werden in das erste Objekt (`target`) übernommen. Bei Listen werden die Einträge der zweiten Liste an die erste angehängt. Es wird kein neues Objekt erzeugt, das erste Objekt wird direkt verändert.
Für Maps steht optional der Parameter `deep` zur Verfügung. Bei `deep=true` werden verschachtelte Maps ebenfalls zusammengeführt, anstatt überschrieben zu werden.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Standardwerte für die Produktanzeige mit produktspezifischen Werten zusammenzuführen. So können z.B. Standardtext oder Fallback-Bilder definiert werden, die nur dann zum Einsatz kommen, wenn ein Produkt keinen eigenen Wert hat.
**Signatur**\
`merge(target, source[, deep=false])`
**Parameter**
* `target` - das Ziel-Objekt, in das die Einträge eingefügt werden.
* `source` - das Quell-Objekt, dessen Einträge übernommen werden.
* `deep` (optional) - nur für Maps. Bei `true` werden verschachtelte Maps ebenfalls zusammengeführt.
**Verwendbar als Modifier**\
ja
**Beispiel - Standardwerte mit produktspezifischen Daten zusammenführen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $defaults = {"badge": "Neu", "shipping": "Standardversand"} }}
{{ var $productData = {"badge": "Sale", "color": "rot"} }}
{{= merge($defaults, $productData) }}
```
**Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{"badge": "Sale", "shipping": "Standardversand", "color": "rot"}
```
Wenn beide Objekte denselben Bezeichner (Schlüssel) enthalten, wird der Wert aus dem ersten Objekt durch den Wert aus dem zweiten Objekt überschrieben.
**Beispiel - Produktdaten mit verschachtelten Standardwerten zusammenführen** (`deep merge`)
Standardwerte für ein Produkt enthalten auch verschachtelte Bilddaten (`image`). Mit `deep=true` werden diese beim Zusammenführen nicht vollständig überschrieben, sondern ebenfalls zusammengeführt - sodass nur die tatsächlich vom Produkt gelieferten Bildpfade übernommen werden, fehlende aber durch den Standardwert erhalten bleiben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $defaults = {"badge": "Neu", "shipping": "Standardversand", "image": {"normal": "noImageNormal.png", "thumb": "noImageThumb.png"}} }}
{{ var $productData = {"badge": "Sale", "image": {"normal": "sneaker-normal.png"}} }}
{{= merge($defaults, $productData, true) }}
```
**Ausgabe (das Thumbnail aus den Standardwerten bleibt erhalten, weil das Produkt keines mitliefert)**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{"badge": "Sale", "shipping": "Standardversand", "image": {"normal": "sneaker-normal.png", "thumb": "noImageThumb.png"}}
```
***
### min
Die Funktion `min` gibt den niedrigsten Wert aus einer Auflistung von Zahlen zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. den günstigsten Preis innerhalb einer Variantenliste oder den kleinsten Bestand zu ermitteln.
**Signatur**\
`min(list)`
**Parameter**
* `list` - die Auflistung mit Zahlenwerten.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= min([5, 13, -1, 3, 2, -7, 12]) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
-7
```
**Beispiel - Niedrigsten Bestellwert aus der Bestellhistorie ermitteln**\
Die letzten Bestellungen eines Kunden werden über [\$wsOrderHistory.loadList()](/frontend/referenz/module/wsorderhistory#\$wsorderhistory-loadlist) geladen. Jede Bestellung enthält u. a. das Feld `order.total` (Gesamtpreis). Die Bestellwerte werden mit [push](#push) in einer eigenen Auflistung gesammelt, anschließend wird mit `min` der niedrigste Wert ermittelt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myOrders = $wsOrderHistory.loadList() }}
{{ var $myTotals = [] }}
{{ for $myOrder in $myOrders }}
{{ push($myTotals, $myOrder.order.total) }}
{{ /for }}
Ihre niedrigste Bestellung: {{= min($myTotals) | currency }} €
```
**Ausgabe** (bei Bestellwerten `49.90`, `129.00`, `89.95`):
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Ihre niedrigste Bestellung: 49,90 €
```
**Gegenstück**\
[max](#max)
***
### preparedFormat
Die Funktion `preparedFormat` formatiert eine Zahl hinsichtlich Dezimaltrennzeichen und Nachkommastellen, basierend auf einem [im Shop hinterlegten Format](/konfiguration/general-allgemeine-shopeinstellungen#12-general-numberformat-zahlen-und-preisformatierung).
**Anwendungsbeispiel**
Nutzbar, um z.B. Mengenangaben, Gewichte oder andere Zahlenwerte shopgerecht darzustellen.
**Signatur**\
`preparedFormat(number, formatName)`
**Parameter**
* `number` - Die Zahl, die formatiert werden soll.
* `name` - Name des im Shop konfigurierten Formats (z.B. `“amount”`).
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= preparedFormat(3.5, "amount") }}
```
**Ausgabe** (`amount` formatiert hier auf ganze Zahlen)
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
4
```
**Beispiel - Produktgewicht formatiert ausgeben**\
Das Gewicht eines Produkts ist im Feld `$myProduct.custom.weight` als Dezimalzahl gespeichert (hier: `2.300000`). Mit `preparedFormat` wird es gemäß dem im Shop hinterlegten Format `"weight"` ausgegeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $weight = $myProduct.custom.weight }}
Gewicht: {{= preparedFormat($weight, "weight") }} kg
```
**Ausgabe** (bei einem Gewicht von `2.300000` und Format `"weight"` mit einer Nachkommastelle):
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Gewicht: 2,3 kg
```
***
### push
Die Funktion `push` fügt ein neues Element am Ende einer bestehenden Liste hinzu und gibt die neue Anzahl der Einträge in der Auflistung zurück. Die Liste wird dabei direkt verändert, es wird keine neue Liste erzeugt.
**Anwendungsbeispiel**\
Nutzbar, um z.B. in einer Schleife gezielt Einträge zu sammeln, etwa gefilterte Produkte, Fehlermeldungen oder dynamisch zusammengestellte Ausgabelisten.
**Signatur**\
`push(list, element)`
**Parameter**
* `list` - Die Auflistung, an die das neue Element angehängt werden soll.
* `element` - Der Wert, der hinzugefügt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel - Element hinzufügen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myWishlist = ["ART-100", "ART-205"] }}
{{ push($myWishlist, "ART-310") }}
{{= $myWishlist }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
["ART-100", "ART-205", "ART-310"]
```
**Beispiel - Rückgabewert nutzen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myWishlist = [] }}
{{ push($myWishlist, "ART-100") }}
{{ var $amount = push($myWishlist, "ART-205") }}
{{= $amount }}
```
**Ausgabe (Anzahl der Einträge nach dem Hinzufügen)**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
2
```
**Beispiel - Produkte einer Kategorie laden und Produkte aus einer anderen Kategorie ergänzen**\
Die Produkte einer Kategorie werden über `$wsCategories.loadProducts()` als Auflistung geladen. Mit `push` können Produkte aus einer zweiten Kategorie an die Liste angehängt werden - z.B. um Cross-Selling-Artikel in die Ausgabe aufzunehmen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myProducts = $wsCategories.loadProducts("100-12345") }}
{{ var $myCrossSelling = $wsCategories.loadProducts("100-99999") }}
{{ for $item in $myCrossSelling }}
{{ push($myProducts, $item) }}
{{ /for }}
{{ for $product in $myProducts }}
{{= $product.name }}
{{ /for }}
```
Die Auflistung `$myProducts` enthält nun alle Produkte der ersten Kategorie plus die Produkte aus der Cross-Selling-Kategorie.
***
### random
Die Funktion `random` erzeugt einen Zufallswert.
**Anwendungsbeispiel**\
Nutzbar, um z.B. zufällige Gutscheincodes zu Erzeugen.
**Hinweis**\
Die Funktion ist geplant, wird aber momentan noch nicht unterstützt.
***
### range
Die Funktion `range` erzeugt eine Auflistung von aufeinanderfolgenden ganzen Zahlen - vom Startwert bis zum Endwert. Standardmäßig wird in Einserschritten gezählt. Bei absteigenden Reihen muss eine negative Schrittweite angegeben werden.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Seitenumbrüche (Pagination), Mengenwähler oder nummerierte Ausgaben im Template zu erzeugen.
**Signatur**\
`range(start, stop[, step=1])`
**Parameter**
* `start` - Startwert der Zahlenreihe.
* `stop` - Endwert der Zahlenreihe.
* `step` (optional) - Schrittweite (Standard: 1). Für absteigend zählende Reihen einen negativen Wert verwenden.
**Verwendbar als Modifier**\
nein
**Beispiel für eine aufsteigende Reihe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= range(1, 5) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[1, 2, 3, 4, 5]
```
**Beispiel für eine absteigende Reihe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= range(10, 2, -2) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[10, 8, 6, 4, 2]
```
***
### raw
Die Funktion `raw` gibt einen Wert ohne automatische Bereinigung von HTML-Zeichen aus, sodass enthaltener HTML-Code vom Browser als Formatierung interpretiert wird, statt als reiner Text an gezeigt zu werden.
**Anwendungsbeispiel**\
Nutzbar, um z.B. formatierte Produktbeschreibungen oder CMS-Inhalte mit HTML-Markup unverändert im Shop darzustellen.
**Hinweis**\
Die Funktion ist geplant, wird aber momentan noch nicht unterstützt.
***
### replace
Die Funktion `replace` ersetzt in einem Text alle Vorkommen eines Suchbegriffs durch einen anderen Text.
**Anwendungsbeispiel**\
Nutzbar, um z.B. interne Bezeichnung für die Anzeige im Shop leserlicher zu machen.
**Signatur**\
`replace(string, search, replace)`
**Parameter**
* `content` - Der Ausgangstext.
* `search` - Der Text, der gesucht und ersetzt werden soll.
* `replace` - Der Text, der stattdessen eingesetzt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= replace("webbuy", "buy", "sale") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
websale
```
***
### reverse
Die Funktion `reverse` kehrt die Reihenfolge der Zeichen in einem Text oder der Einträge in einer Auflistung um.
**Anwendungsbeispiel**\
Nutzbar, um z.B. eine bestehende Sortierung umzukehren oder Einträge in umgekehrter Reihenfolge auszugeben (z.B. neueste Einträge zuerst).
**Hinweis**\
Die Funktion ist geplant, wird aber momentan noch nicht unterstützt.
***
### round
Die Funktion `round` rundet eine Zahl kaufmännisch auf oder ab. Optional kann die gewünschte Anzahl an Nachkommastellen angegeben werden. Ohne Angabe wird auf eine ganze Zahl gerundet.
**Anwendungsbeispiel**\
Nutzbar, um z.B. berechnete Zwischenwerte, Gewichte oder Mengen kaufmännisch gerundet im Template anzuzeigen.
**Signatur**\
`round(number[, precision=0])`
**Parameter**
* `number` - Die Zahl, die gerundet werden soll.
* `precision` (optional) - Gewünschte Anzahl an Nachkommastellen (Standard: 0).
**Verwendbar als Modifier**\
ja
**Beispiel ohne Nachkommastellen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= round(3.1415) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
3.000000
```
**Beispiel mit 2 Nachkommastellen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= round(1.2345, 2) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
1.230000
```
**Anzeige mit zwei Nachkommastellen**
Der Parameter `precision` steuert die mathematische Rundung (auf wie viele Nachkommastellen der Wert gerundet wird). Die Ausgabe zeigt jedoch systembedingt immer bis zu sechs Nachkommastellen an (z.B: `1.230000` statt `1.23`). Um die Darstellung anzupassen (z.B. nur 2 sichtbare Nachkommastellen), wird `round` in Kombination mit [preparedFormat](#preparedformat) verwendet:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= round(1.2345, 2) | preparedFormat("name") }}
```
***
### sort
Die Funktion `sort` sortiert die Einträge einer Auflistung (List). Standardmäßig wird aufsteigend sortiert. Mit dem optionalen Parameter `reverse` kann die Sortierung aber auch umgekehrt werden.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Produktlisten, Varianten oder Filteroptionen alphabetisch oder nach Zahlenwert zu sortieren.
**Signatur**\
`sort(list[, reverse=false])`
**Parameter**
* `list` - Die Auflistung, deren Einträge sortiert werden sollen.
* `reverse`(optional) - Bei `true` wird absteigend sortiert.
**Verwendbar als Modifier**\
ja
**Beispiel mit Zahlen**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= sort([5, 2, 8, 1, 4]) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[1.0, 2.0, 4.0, 5.0, 8.0]
```
**Beispiel mit Texten**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= sort(["Hose", "Accessoire", "Jacke"]) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
["Accessoire", "Hose", "Jacke"]
```
**Beispiel - Preise absteigend sortieren**
Wenn die Liste nur aus Zahlen besteht, werden alle Elemente nach der Sortierung den Typ `float` haben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $prices = [49.90, 129.00, 19.95, 89.95] }}
{{= sort($prices, true) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[129.000000, 89.950000, 49.900000, 19.950000]
```
**Beispiel - Verfügbare Farben eines Produkts alphabetisch sortieren**\
Die varianten-Daten eines Produkts werden über `$wsProducts.variantInfo()` geladen. Das Attribut “Farbe” enthält eine Auflistung von Optionen (hier: `Rot, Blau, Grün, Beige`). Da die Optionen als Objekte vorliegen (z.B. `{name: “Rot”}`), werden die Namen zunächst mit [push](#push) in einer eigenen Auflistung gesammelt. Anschließend werden sie mit `sort` alphabetisch sortiert und in einer Schleife ausgegeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myVariants = $wsProducts.variantInfo("100-12345") }}
{{ var $colors = [] }}
{{ for $myOption in $myVariants.variantAttributes.options }}
{{ push($colors, $myOption.name) }}
{{ /for }}
{{ var $sortedColors = sort($colors) }}
{{ for $color in $sortedColors }}
{{= $color }}
{{ /for }}
```
***
### split
Die Funktion `split` teilt einen Text anhand eines Trennzeichens in eine Auflistung (List) einzelner Einträge auf.
**Anwendungsbeispiel**\
Nutzbar, um z.B. kommaseparierte Werte aus Produktdaten, Konfigurationen oder externen Quellen in einzelne Einträge zu zerlegen und getrennt zu verarbeiten.
**Signatur**\
`split(content, separator)`
**Parameter**
* `content` - Der Text, der aufgeteilt werden soll.
* `separator` - Das Trennzeichen, an dem der Text aufgeteilt wird.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= split("vegan,glutenfrei,laktosefrei,bio", ",") }}
```
**Ausgabe**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
["vegan", "glutenfrei", "laktosefrei", "bio"]
```
**Gegenstück**\
[join](#join)
***
### startswith
Die Funktion `startswith` prüft, ob ein Text mit einer bestimmten Zeichenfolge beginnt und gibt `true` oder `false` zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Artikelnummern anhand ihrer Anfangszeichen zu unterscheiden und im Template darauf zu reagieren, etwa um Produkte bestimmter Produktgruppen unterschiedlich darzustellen (z.B. alle Artikelnummern, die mit `“TKK”` beginnen, als Tiefkühlprodukte zu kennzeichnen).
**Signatur**\
`startswith(str, prefix)`
**Parameter**
* `str` - Der Text, der geprüft werden soll.
* `prefix` - Die Zeichenfolge, auf die am Textanfang geprüft wird.
**Verwendbar als Modifier**\
ja
**Beispiel mit einem Treffer**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= startswith("TKK-40210", "TKK") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
true
```
**Beispiel ohne Treffer**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= startswith("BKL-10050", "TKK") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
false
```
**Beispiel - Produkte anhand der Artikelnummer einer Produktgruppe zuordnen**
Die Artikelnummer eines Produkts steht im Feld `itemNumber` (hier: `“TKK-40210”`). Artikelnummern, die mit `“TKK”` beginnen, gehören zur Produktgruppe Tiefkühlware. Mit `startswith` wird dies geprüft und ein entsprechendes Badge angezeigt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myProduct = $wsProducts.load("100-12345") }}
{{ if (startswith($myProduct.itemNumber, "TKK")) }}
Tiefkühlprodukt
{{ /if }}
```
**Ausgabe** (bei Artikelnummer `“TKK-40210”`)
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Tiefkühlprodukt
```
***
### static
Die Funktion `static` erzeugt den vollständigen Pfad zu einer statischen Datei (z.B. JavaScript, CSS, Bilder). Standardmäßig liegen solche Dateien unter `media/themes/default` auf dem Server des Shops.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Pfade zu statischen Dateien im Template korrekt einzubinden - auch, wenn sich der Speicherort später ändert.
**Signatur**\
`static(path)`
**Parameter**
* `path` - Pfad zur Datei, relativ zum Static-Verzeichnis des Shops.
**Verwendbar als Modifier**\
nein
**Beispiel**\
Statt eines fest eingetragenen Pfads:
```javascript theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
wird empfohlen, `static` zu verwenden:
```javascript theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
Durch die konsequente Nutzung von `static` kann der Speicherort der statischen Dateien jederzeit angepasst werden (z.B. auf einen Media-Server oder ein CDN), ohne dass die Templates geändert werden müssen. Bei Kategorie- oder Produktbildern wird `static` nicht benötigt - deren Pfade werden automatisch korrekt erzeugt.
***
### str
Die Funktion `str` wandelt einen Wert in einen Text (String) um. Das Ergebnis sieht bei Zahlen zwar identisch aus, ist intern aber ein String - also kein Zahlenwert mehr, mit dem gerechnet werden könnte. Stattdessen kann der Wert danach mit textbasierten Funktionen wie `replace`, `startswith` oder `split` weiterverarbeitet werden.
**Anwendungsbeispiel**\
Nutzbar, um z.B. eine Artikelnummer, die als Zahl vorliegt, in einen Text umzuwandeln, damit anschließend mit `startswith` geprüft werden kann, ob sie mit einer bestimmten Zeichenfolge beginnt.
**Signatur**\
`str(value)`
**Parameter**
* `value` - Der Wert, der in Text umgewandelt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel mit ganzer Zahl**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= str(42) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
"42"
```
**Beispiel mit Dezimalzahl**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= str(12.99) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
"12.99"
```
***
### striphtml
Die Funktion `striphtml` entfernt alle HTML-Formatierungen (Tags) aus einem Text und gibt nur den reinen Textinhalt zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. HTML-formatierte Produktbeschreibungen als reinen Text auszugeben.
**Signatur**\
`striphtml(content)`
**Parameter**
* `content` - Der Text, aus dem die HTML-Formatierungen entfernt werden sollen.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= striphtml("Unser Topseller im Shop!
") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Unser Topseller im Shop!
```
***
### take
Die Funktion `take` gibt die ersten Zeichen eines Textes oder die ersten Einträge einer Auflistung zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. nur die ersten Zeichen eines Produktnamens oder die ersten Einträge einer Produktliste anzuzeigen.
**Signatur**\
`take(content, count)`
**Parameter**
* `content` - Der Text oder die Auflistung, aus der die ersten Elemente entnommen werden sollen.
* `count` - die Anzahl der Zeichen bzw. Einträge, die vom Anfang genommen werden.
**Verwendbar als Modifier**\
ja
**Beispiel mit Text**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= take("websale", 3) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
web
```
**Beispiel mit Auflistung**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= take([1, 2, 3, 4, 5], 3) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[1, 2, 3]
```
**Beispiel - Nur die ersten 4 Produkte einer Kategorie anzeigen**\
Die Produkte einer Kategorie werden über [\$wsCategories.loadProducts()](/frontend/referenz/module/wscategories#\$wscategories-loadproducts) als Auflistung geladen (hier: `24 Produkte`). Mit `take` werden in diesem Beispiel nur die ersten 3 Einträge entnommen und in einer Schleife als Teaser ausgegeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myProducts = $wsCategories.loadProducts("100-12345") }}
{{ var $myTopProducts = take($myProducts, 3) }}
{{ for $product in $myTopProducts }}
{{= $product.name }}
{{ /for }}
```
**Ausgabe** (bei Produkten `"Sneaker Classic"`, `"Laufschuh Pro"`, `"Sandale Sport"`, `"Wanderstiefel"`, …)
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Sneaker Classic
Laufschuh Pro
Sandale Sport
```
**Gegenstück**\
[takelast](#takelast)
***
### takelast
Die Funktion `takelast` gibt die letzten Zeichen eines Textes oder die letzten Einträge einer Auflistung zurück.
**Anwendungsbeispiel**\
Nutzbar, um z.B. die letzten Zeichen einer Bestellnummer oder die letzten Einträge einer Liste gezielt anzuzeigen.
**Signatur**\
`takeLast(content, count)`
**Parameter**
* `content` - Der Text oder die Auflistung, aus der die letzten Elemente entnommen werden sollen.
* `count` - Die Anzahl der Zeichen bzw. Einträge, die vom Ende genommen werden.
**Verwendbar als Modifier**\
ja
**Beispiel mit Text**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= takeLast("12345", 2) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
45
```
**Beispiel mit Auflistung**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= takeLast([1, 2, 3, 4, 5], 2) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[4, 5]
```
**Beispiel - Die letzten 2 Ebenen des Breadcrumb-Pfads anzeigen**\
Der Kategoriepfad (`Breadcrumb`) wird über [\$wsCategories.loadPath()](/frontend/referenz/module/wscategories#\$wscategories-loadpath) als Auflistung geladen (hier: 4 Ebenen). Mit `takeLast` werden nur die letzten 2 Einträge entnommen - z.B. um in einer Unternavigation nur die aktuelle und die übergeordnete Kategorie anzuzeigen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $breadcrumb = $wsCategories.loadPath($category.id) }}
{{ var $lastTwo = takeLast($breadcrumb, 2) }}
{{ for $cat in $lastTwo }}
{{= $wsViews.url('Category', {id: $cat.id}) }}">{{= $cat.name }}
{{ /for }}
```
**Ausgabe** (bei einem Pfad “Startseite → Damen → Schuhe → Sneaker”):
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Schuhe
Sneaker
```
**Gegenstück**\
[take](#take)
***
### trim
Die Funktion `trim` entfernt überflüssige Leerzeichen am Anfang und Ende eines Textes.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Benutzereingaben, importierte Produktdaten oder externe Werte vor der Weiterverarbeitung von ungewollten Leerzeichen zu bereinigen.
**Hinweis**\
Die Funktion ist geplant, wird aber momentan noch nicht unterstützt.
***
### type
Die Funktion `type` Gibt den Datentyp eines Wertes als Text zurück - also z. B. ob es sich um einen Text (`string`), eine ganze Zahl (`int`), eine Dezimalzahl (`float`), eine Auflistung (`list`) oder ein Datenobjekt (`map`) handelt.
**Anwendungsbeispiel**\
Nutzbar, um z.B. auf Fehlersuche zu gehen (Debugging) oder um im Template zu prüfen, ob ein Wert den erwarteten Typ hat, bevor er weiterverarbeitet wird.
**Signatur**\
`type(object)`
**Parameter**
* `object` - Der Wert, dessen Datentyp ermittelt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel anhand eines Textes**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= type("Websale") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
String
```
**Beispiel anhand einer Kommazahl**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= type(1.27) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Float
```
***
### unixToIso
Die Funktion `unixToIso` wandelt eine Unix-Zeit (Anzahl der Sekunden seit dem 1. Januar 1970, UTC) in einen Zeitstempel im ISO-8601-Format um.
**Anwendungsbeispiel**\
Nutzbar, um z.B. eine von einem externen System gelieferte Unix-Zeit in das Shop übliche ISO-8601-Format zu bringen, das anschließend mit [dateFmt](https://dokumentation.websale.de/frontend/referenz/funktionen#datefmt) formatiert werden kann.
**Signatur**\
`unixToIso(timestamp)`
**Parameter**
* `timestamp` - Unix-Zeit (Anzahl der Sekunden seit dem 1. Januar 1970, UTC).
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= unixToIso(1520767211) }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
2018-03-11T11:20:11.000Z
```
**Gegenstück**\
[isoToUnix](https://dokumentation.websale.de/frontend/referenz/funktionen#isotounix)
***
### upper
Die Funktion `upper` wandelt alle Buchstaben eines Textes in Großbuchstaben um.
**Anwendungsbeispiel**\
Nutzbar, um z.B. Gutscheincodes, Versandarten oder Überschriften einheitlich und in Großschreibung darzustellen.
**Signatur**\
`upper(content)`
**Parameter**
* `content` - Der Text, der in Großbuchstaben umgewandelt werden soll.
**Verwendbar als Modifier**\
ja
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= upper("Topseller") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
TOPSELLER
```
**Gegenstück**\
[lower](#lower)
***
## Modifier
Viele Funktionen können alternativ auch als [Modifier (Filter)](/frontend/referenz/modifiers#modifiers) in der Filterschreibweise verwendet werden.
Dabei steht der erste Parameter links vom Pipe-Operator `|`, weitere Parameter werden in Klammern angegeben.
Alternativ kann eine Funktion auch mit dem Filter-Operator | (pipe) notiert werden (= Filterschreibweise). Dabei steht der erste Parameter links vom Operator.
**Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= "webbuy" | replace("buy", "sale") }}
```
**Ausgabe**
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
websale
```
# Kontrollstrukturen
Source: https://dokumentation.websale.de/frontend/referenz/kontrollstrukturen
Kontrollstrukturen und Boolean-Werte: Wahrheitswerte true und false sowie Bedingungen für die Steuerung von Template-Ausgaben einsetzen.
## Boolean/Bool (true/false)
Ein Bool ist ein Wahrheitswert und kann nur *true* (wahr) oder *false* (falsch) sein.
| | |
| -------- | ------------------------------------------- |
| `true` | Wahrheitswert true |
| `false` | Wahrheitswert false |
| `"true"` | kein Wahrheitswert (falsche Syntax: String) |
Boolesche Werte werden meistens in Kombination mit Vergleichsoperatoren erzeugt. Wenn man beispielsweise einen Wert mit einem anderen vergleicht, ist das Ergebnis entweder wahr oder falsch.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $quantity == 1 }}
Wird angezeigt, wenn der Wert der Variable $quantity gleich 1 ist.
{{ /if }}
```
## truthy und falsy
Nicht nur Werte vom Datentyp Bool enthalten einen Wahrheitswert. Objekte aller anderen Datentypen haben ebenfalls eine Werte-Eigenschaft, die man als *truthy* oder *falsy* bezeichnet. In Zusammenhang mit logischen Operatoren und Verzweigungen ist es wichtig zu wissen, wann ein Wert als wahr oder falsch angesehen wird.
Hier eine Auflistung aller Werte die *falsy* sind und deshalb als *false* behandelt werden:
▪*null*, der Wert des Datentyps Null
▪*false*
▪die Zahl 0 (*Integer*) oder 0.0 (*Float*)
▪ein leerer *String " "*
▪eine leere *List \[ ]*
▪eine leere *Map*
Alle anderen Werte werden als *truthy* behandelt.
## Boolean konvertieren
Es können andere Basistypen in Boolean konvertiert werden
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
String: {{= bool(" ")}} // true
String: {{= bool("")}} // false
Integer: {{= bool(1) }} // true
Integer: {{= bool(0) }} // false
Float: {{= bool(1.0) }} // true
Float: {{= bool(0.0) }} // false
```
# Loops
Source: https://dokumentation.websale.de/frontend/referenz/loops
Schleifen und Verzweigungen in Templates: if, elseif, else, switch sowie foreach für die bedingte und wiederholte Template-Ausgabe nutzen.
Mit Hilfe von Kontrollstrukturen kannst Du die Ausgabe abhängig machen von bestimmten Bedingungen. Man unterscheidet zwischen Verzweigungen mit *if* oder *switch* und der *foreach*-Schleife.
## if-Verzweigung
Mit einer *if*-Verzweigung werden eine oder mehrere Bedingungen geprüft. Je nachdem, welche Bedingung als erstes ein *true* zurückgibt, wird dieser Zweig angezeigt und die restlichen werden ignoriert. Eine *if*/*elseif*/*else*-Verzweigung muss immer aus einem *if*-Zweig und optional beliebig viele *elseif*-Zweige bestehen sowie optional einem einzigen *else*-Zweig.
Eine Verzweigung wird mit *if* eingeleitet und durch */if* abgeschlossen. *elseif*- und *else*-Zweige werden dagegen nicht explizit geschlossen.
Das folgende Beispiel zeigt die unterschiedlichen Anredeformen, wenn Bestandskunden im Shop angemeldet sind. Auf dem Template sei eine Variable *\$geschlecht* definiert, die sich das entsprechende Geschlecht aus den Kundendatensätzen holt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $geschlecht == "männlich" }}
Sehr geehrter Herr {{= $customer.lastName }},
{{ elseif $geschlecht == "weiblich" }}
Sehr geehrte Frau {{= $customer.lastName }},
{{ else }}
Sehr geehrte Damen und Herren,
{{ /if }}
```
## switch-Verzweigung
Alternativ zu *if*-Verzweigungen kannst Du auch *switch*, *case* und *default* verwenden. Mit *switch* leitest Du die Verzweigung ein und gibst an, welches Feld geprüft werden soll. Hinter *case* schreibst Du ohne *==* die unterschiedlichen Werte und *default* entspricht *else*.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ switch $geschlecht }}
{{ case "männlich" }}
Sehr geehrter Herr {{= $customer.lastName }},
{{ case "weiblich" }}
Sehr geehrte Frau {{= $customer.lastName }},
{{ default }}
Sehr geehrte Damen und Herren,
{{ /switch }}
```
## foreach-Schleife
Eine *foreach*-Schleife dient dazu, Codeabschnitte mehrfach zu wiederholen (*iterieren*). Die Schleife wird mit *foreach* eingeleitet und mit */foreach* geschlossen. Der umschlossene Bereich wird für jedes Element des iterierbaren Objekts einmal ausgeführt. Mit jedem Durchlauf wird das aktuelle Element des iterierbaren Objekts der sogenannten Laufvariable (im Beispiel unten *\$product)* ohne *var* zugewiesen.
Im folgenden Beispiel enthält *\$productList* eine List mit 3 Elementen. Mit jedem Durchlaufen der Schleife wird das jeweilige Element mit den HTML-Tags ausgegeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $productList = ["Hemd", "Bluse", "Hose"] }}
{{ foreach $product in $productList }}
Produkt: {{= $product }}
{{ /foreach }}
```
Es wird folgender HTML-Quellcode erzeugt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Produkt: Hemd
Produkt: Bluse
Produkt: Hose
```
Das Iterieren mit einer *foreach*-Schleife ist mit *Strings*, *Lists* und *Maps* möglich.
Die *foreach*-Schleife ist der einzige Schleifentyp der Template Engine. Andere Schleifen wie *for*, *while* oder *do-while* gibt es nicht.
### Schleifenzähler
Die Template Engine stellt innerhalb einer *foreach*-Schleife keine automatische Zählervariable bereit. Eine Variable wie `$loop.index` existiert nicht. Wenn Du die Position des aktuellen Elements benötigst, definierst Du vor der Schleife eine eigene Variable mit `var` und zählst sie am Ende jedes Durchlaufs hoch.
Das folgende Beispiel fügt nach dem zweiten Produkt (also an dritter Stelle) einen Platzhalter in die Produktliste ein. Danach läuft die Schleife normal weiter.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $index = 0 }}
{{ foreach $product in $productList }}
Produkt: {{= $product }}
{{ if $index == 1 }}
{{ /if }}
{{ var $index = $index + 1 }}
{{ /foreach }}
```
Da der Zähler bei `0` startet, entspricht `$index == 1` dem zweiten Element.
# Modifiers
Source: https://dokumentation.websale.de/frontend/referenz/modifiers
Modifiers (Filter) in der Template-Sprache: Werte bei der Ausgabe formatieren, Strings anpassen, Zahlen runden und Listen umwandeln.
Diese Seite beschreibt die Grundlagen und Schreibweise von Modifiers. Modifiers (auch Filter genannt) werden verwendet, um Werte im Template direkt bei der Ausgabe oder Weiterverarbeitung zu verändern, zu formatieren oder zu prüfen – zum Beispiel Texte anpassen, Zahlen runden oder Listen umwandeln.
***
## Grundlagen & Schreibweise
Modifiers werden nicht als eigenständiger Funktionsaufruf geschrieben, sondern auf einen bestehenden Wert angewendet.
Ein Modifier verarbeitet immer den Wert, der links von ihm steht. Das Ergebnis kann direkt ausgegeben oder in einer Variablen gespeichert und später weiterverwendet werden.
Modifiers werden mit dem Pipe-Operator `|` an einen Wert „angehängt“:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= | }}
```
Wenn ein Modifier zusätzliche Parameter benötigt, werden diese in runden Klammern angegeben:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= | (, , ...) }}
```
## Übersicht der Modifier
Eine vollständige Liste aller verfügbaren Modifiers wird hier nicht separat geführt, da nahezu alle globalen Funktionen aus der Referenzseite [Funktionen](/frontend/referenz/funktionen) zusätzlich auch als Modifier verwendet werden können.
## Beispiele
### **Beispiel** `upper`
Wert in Großbuchstaben ausgeben
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= "Sneaker Classic" | upper }}
```
\=
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
SNEAKER CLASSIC
```
### **Beispiel** `replace` und `lower`
Wert für URL/Slug vorbereiten (Leerzeichen ersetzen + Kleinschreibung)
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= "Sneaker Classic" | replace(" ", "-") | lower }}
```
\=
```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
sneaker-classic
```
# Module - Übersicht
Source: https://dokumentation.websale.de/frontend/referenz/module
Übersicht der WEBSALE-Module wie $wsAccount, $wsBasket oder $wsProducts: Variablen und Methoden für die Template-Ausgabe von Shopdaten.
Module sind von **WEBSALE** vorgegebene, global verfügbare Module (z. B. `$wsAccount`). Sie stellen Variablen (Eigenschaften) und Methoden bereit. In der Entwicklung werden sie teilweise auch als `View-Module` bezeichnet, da sie primär für die Ausgabe (Leseseite) verwendet werden.
Mit diesen Modulen stehen Shopdaten für die Template-Ausgabe zur Verfügung, z. B. zu Produkten, Kategorien oder Käuferdaten.
Eigene Module können nicht erstellt oder erweitert werden.
***
## Schreibweise & Zugriff
* **Schreibweise:** `$ws` (z. B. `$wsAccount`, `$wsBasket`, `$wsProduct`)
* Module enthalten Variablen (Eigenschaften) und Methoden
* Der Zugriff erfolgt über den Punkt-Operator (`.`), z. B. auf Eigenschaften oder Methoden eines Moduls
* Datenfelder und Funktionen werden einheitlich über `.` angesprochen
**Syntax-Beispiel**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
$ws. ???
```
Mehr Informationen zum [Datenzugriff](/frontend/datenzugriff-anzeige) finden Sie hier.
***
## Variablen & Methoden
Ein Modul stellt in der Regel beides bereit:
* Variablen (Eigenschaften)
* Methoden
### Variablen (Eigenschaften)
Über die Variablen liefert das Modul direkt den Wert, der direkt ausgelesen werden kann.
**Beispiel - Gibt an, ob der Benutzer eingeloggt ist**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ = $wsAccount.isLoggedIn }}
```
### Methoden
Die Methoden führen den Aufruf für das Modul aus (z. B. Laden von Daten) und liefern ein Ergebnis zurück.
**Beispiel - Lädt die Adresse mit der angegebenen Id**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ = $wsAccount.loadAddress(addressId) }}
```
Viele Module liefern strukturierte Daten (z. B. „Maps“/Objekte). Auf deren Felder wird am übersichtlichsten über benutzerdefinierte Variablen zugegriffen, die einmalig im Template belegt wird.
**Beispiel - Laden von den Daten des Produktes mit der ID 123456**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myVariable = $wsProducts.load(productId) }}
```
Über die benutzerdefinierte Variable `$myVariable` erfolgt der Zugriff auf einzelne Eigenschaften über `$myVariable.`:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ = $myVariable.name }}
{{ = $myVariable.descr }}
```
Variablen- und Methodenaufrufe können nicht beliebig verkettet werden. Der folgende Aufruf ist daher nicht möglich:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ $wsAccount.loadAddress(addressId).isLoggedIn }}
```
***
## Verfügbare Module
Hier finden Sie eine Übersicht aller Module, die im WEBSALE Shop grundsätzlich verfügbar sind:
* [\$wsAccount](/frontend/referenz/module/wsAccount)
* [\$wsActions](/frontend/referenz/module/wsactions)
* [\$wsAsse](/frontend/referenz/module/wsasse)
* [\$wsBasket](/frontend/referenz/module/wsbasket)
* [\$wsCategories](/frontend/referenz/module/wscategories)
* [\$wsCheckout](/frontend/referenz/module/wscheckout)
* [\$wsCmsPage](/frontend/referenz/module/wscmspage)
* [\$wsComputopHosted](/frontend/referenz/module/wscomputophosted)
* [\$wsConfig](/frontend/referenz/module/wsconfig)
* [\$wsConsent](/frontend/referenz/module/wsconsent)
* [\$wsCookies](/frontend/referenz/module/ws-cookie-browser-cookie)
* [\$wsDirectOrder](/frontend/referenz/module/wsdirectorder)
* [\$wsEmails](/frontend/referenz/module/wsemails)
* [\$wsExternalData](/frontend/referenz/module/wsexternaldata)
* [\$wsForm](/frontend/referenz/module/wsform)
* [\$wsInventory](/frontend/referenz/module/wsinventory)
* [\$wsLastSeenProducts](/frontend/referenz/module/wslastseenproducts)
* [\$wsMaintenance](/frontend/referenz/module/wsmaintenance)
* [\$wsNavigation](/frontend/referenz/module/wsnavigation)
* [\$wsNewsletter](/frontend/referenz/module/wsnewsletter)
* [\$wsOptIn](/frontend/referenz/module/wsoptin)
* [\$wsOrderHistory](/frontend/referenz/module/wsorderhistory)
* [\$wsPayPalCheckout](/frontend/referenz/module/wspaypalcheckout)
* [\$wsPayPalPlus](/frontend/referenz/module/wspaypalplus)
* [\$wsProducts](/frontend/referenz/module/wsproducts)
* [\$wsProductRating](/frontend/referenz/module/wsproductrating)
* [\$wsSecurity](/frontend/referenz/module/wssecurity)
* [\$wsSession](/frontend/referenz/module/wssession)
* [\$wsShipTrack](/frontend/referenz/module/wsshiptrack)
* [\$wsStore](/frontend/referenz/module/wsstore)
* [\$wsStores](/frontend/referenz/module/wsstores)
* [\$wsStripe](/frontend/referenz/module/wsstripe)
* [\$wsSubshop](/frontend/referenz/module/wssubshop)
* [\$wsTestMode](/frontend/referenz/module/wstestmode)
* [\$wsViews](/frontend/referenz/module/wsviews)
* [\$wsVoucher](/frontend/referenz/module/wsvoucher)
* [\$wsWatchList](/frontend/referenz/module/wswatchlist)
***
## Aktionen `$wsActions`
Parallel zu den Modulen gibt es Aktionen\*\*,\*\* die mit `$wsActions` beginnen.
Während Module Zustände und Daten anzeigen/auslesen, sind Aktionen die Gegenrichtung: Sie dienen dazu, Daten zu erstellen, zu ändern oder zu löschen – typischerweise ausgelöst durch eine Benutzerinteraktion (z. B. Link, Button, Formular).
Mehr Informationen dazu finden Sie unter [Referenz](/frontend/referenz) → [Aktionen](/frontend/referenz/aktionen)
***
## Weiterführende Links
* [Datenzugriff + Anzeige](/frontend/datenzugriff-anzeige)
* [Aktionen](/frontend/referenz/aktionen)
# $wsCookie - Browser-Cookies
Source: https://dokumentation.websale.de/frontend/referenz/module/ws-cookie-browser-cookie
Modul $wsCookie zum Lesen, Setzen, Aktualisieren und Löschen einzelner Browser-Cookies im Template, z.B. für Darkmode oder Begrüßung.
Mithilfe des `$wsCookie`-Moduls lesen, setzen, aktualisieren und löschen Sie [Browser-Cookies](/glossar#cookie) direkt im Template.
Cookies speichern pro Besucher Informationen über mehrere Seitenaufrufe hinweg, zum Beispiel eine gewählte Darstellungsvariante, eine persönliche Begrüßung oder ein gemerktes Einverständnis. Auf dieser Seite geht es nur um das Lesen und Schreiben der Cookies selbst. Wie Sie die [Einwilligung](/glossar#consent) des Nutzers prüfen, ist in [\$wsConsent](/frontend/referenz/module/wsconsent) beschrieben.
Hinweis: Das Setzen von Cookies kann je nach Art (technisch notwendig vs. Marketing/Tracking) eine Einwilligung des Nutzers erfordern. Prüfen Sie mit [\$wsConsent.checkAllowed()](/frontend/referenz/module/wsconsent#\$wsconsent-checkallowed) die Zustimmung, bevor Sie nicht-notwendige Cookies setzen.
***
## Grundkonzept
Cookies folgen immer demselben Ablauf: **Setzen → Lesen → Reagieren.** \
Bevor Sie einen Cookie lesen können, muss er zuerst gesetzt werden.
Gesetzt wird ein Cookie immer durch ein Ereignis. Typische Auslöser sind:
* eine Benutzeraktion (Klick auf einen Toggle oder Link),
* ein Zustand (der Kunde loggt sich ein),
* eine Abhängigkeit (ein bestimmtes Kundendatenfeld ist vorhanden),
* der Einstiegsweg (Aufruf über einen [Kampagnen-Link](/glossar#kampagnen-link) oder [Referrer](/glossar#referrer)).
Beim nächsten Seitenaufruf lesen Sie den Wert wieder aus und reagieren darauf, etwa mit einer anderen Darstellung oder einer persönlichen Begrüßung.
Wichtig zum Zeitpunkt der Ausführung: \
Der [Template-Code](/glossar#template-code) wird beim Seitenaufbau ausgeführt, nicht beim Klick. Ein Cookie wird also nicht im Moment des Klicks gesetzt, sondern erst dann, wenn der Klick eine neue Anfrage auslöst und das Template dabei erneut ausgeführt wird. Planen Sie das Setzen deshalb immer entlang eines Seitenaufrufs ein.
### Namensschema (gilt für alle Methoden)
Der Shop benennt eigene Cookies automatisch um, und zwar nach dem Schema `wsvx__cookie`. Aus `setCookie("test", …)` im Shop `example` wird im Browser das Cookie `wsvx_example_cookietest`. In den Methoden arbeiten Sie immer nur mit dem kurzen Namen (`test`), das Präfix ergänzt der Shop selbst. So vermeiden Sie Konflikte mit anderen Cookies.
Setzen und Lesen verwenden dasselbe Schema. Ein mit `setCookie("test", …)` gesetztes Cookie können Sie also direkt mit `getCookie("test")` wieder auslesen, ohne sich um den langen Namen kümmern zu müssen.
**Ausnahme: Extern gesetzte Cookies**\
Cookies, die nicht vom Shop gesetzt wurden (z.B. über eigenes JavaScript, ein Drittanbieter-Tool oder ein Cookie-Banner), behalten ihren Original-Namen. Das automatische Schema würde hier ins Leere greifen. Wenn Sie ein solches Cookie auslesen möchten, übergeben Sie bei [getCookie](/frontend/referenz/module/ws-cookie-browser-cookie#wscookie-getcookie) die Option `keepNameAsIs: true`, damit der Name unverändert verwendet wird. Zum Setzen, Aktualisieren oder Löschen ist diese Option nicht vorgesehen, da externe Cookies in der Regel von dem Tool verwaltet werden, das sie gesetzt hat.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsCookie`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCookie | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"deleteCookie": "ƒ()",
"getCookie": "ƒ()",
"setCookie": "ƒ()",
"updateCookie": "ƒ()"
}
```
Anmerkung: `"ƒ()"` kennzeichnet eine Funktion.
**Methoden in der Übersicht**
| **Methode** | **Rückgabe-Typ** | **Beschreibung** |
| ---------------- | ---------------- | -------------------------------------------------- |
| `getCookie()` | string | Liest den Wert eines Cookies anhand seines Namens. |
| `setCookie()` | – | Setzt ein neues Cookie. |
| `updateCookie()` | string | Aktualisiert den Wert eines bestehenden Cookies. |
| `deleteCookie()` | – | Löscht ein Cookie anhand seines Namens. |
***
## Templates
Alle vier Methoden sind Template-Funktionen und stehen in jedem `.htm`-Template zur Verfügung. Den typischen Ablauf (Setzen → Lesen → Reagieren) beschreibt der Abschnitt [Grundkonzept](#grundkonzept).
***
## Variablen
Für `$wsCookie` stehen keine Variablen zur Verfügung.
***
## Methoden
### \$wsCookie.getCookie()
Liest den Wert eines Cookies anhand seines Namens.
**Signatur**\
`$wsCookie.getCookie(name, [options])`
**Rückgabe**\
`string` – Wert des Cookies. Der Wert ist leer, wenn kein Cookie mit diesem Namen existiert.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Standard** | **Beschreibung** |
| --------- | ------- | ----------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | string | ja | – | Kurzer Name des Cookies, ohne Präfix. |
| `options` | map | nein | – | `keepNameAsIs` (bool) – verwendet den Namen unverändert, ohne das automatische Schema.
Nötig für extern gesetzte Cookies (siehe [Grundkonzept](#namensschema-gilt-für-alle-methoden)). |
**Beispiel,** das eine gespeicherte Darstellungsvariante liest.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $currentTheme = $wsCookie.getCookie("wsThemeColor") }}
```
### \$wsCookie.setCookie()
Setzt ein neues Cookie.
**Signatur**\
`$wsCookie.setCookie(name, value, [age])`
**Rückgabe**\
– (kein Rückgabewert)
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Standard** | **Beschreibung** |
| -------- | ----------------------------------- | ----------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | string | ja | – | Kurzer Name des Cookies, ohne Präfix. |
| `value` | string, int, float, list, map, bool | ja | – | Wert des Cookies. Komplexe Werte (list, map) werden intern automatisch als [JSON](/glossar#json) gespeichert. |
| `age` | int | nein | Session | Gültigkeitsdauer in Sekunden. Ohne Angabe wird ein [Session-Cookie](/glossar#session-cookie) gesetzt, das am Ende der Browser-Sitzung verfällt. Maximal 10 Jahre. Beispiel: `31536000` = 365 Tage. |
**Beispiel,** das eine Darstellungsvariante setzt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ $wsCookie.setCookie("wsThemeColor", "dark") }}
```
**Beispiel,** das ein Cookie mit einer Gültigkeitsdauer von 365 Tagen setzt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ $wsCookie.setCookie("welcomeBackName", $wsAccount.displayName, 31536000) }}
```
### \$wsCookie.updateCookie()
Aktualisiert den Wert eines bestehenden Cookies.
**Signatur**\
`$wsCookie.updateCookie(name, value)`
**Rückgabe**\
`string` – neuer Wert des Cookies.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Standard** | **Beschreibung** |
| -------- | ----------------------------------- | ----------- | ------------ | ------------------------------------- |
| `name` | string | ja | – | Kurzer Name des Cookies, ohne Präfix. |
| `value` | string, int, float, list, map, bool | ja | – | Neuer Wert des Cookies. |
**Beispiel,** das eine Darstellungsvariante aktualisiert.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ $wsCookie.updateCookie("wsThemeColor", "light") }}
```
### \$wsCookie.deleteCookie()
Löscht ein Cookie anhand seines Namens. Intern wird die Lebensdauer dabei auf `-1` gesetzt, wodurch der Browser das Cookie sofort verwirft.
**Signatur**\
`$wsCookie.deleteCookie(name)`
**Rückgabe**\
– (kein Rückgabewert)
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Standard** | **Beschreibung** |
| -------- | ------- | ----------- | ------------ | ------------------------------------- |
| `name` | string | ja | – | Kurzer Name des Cookies, ohne Präfix. |
**Beispiel,** das ein gesetztes Cookie löscht.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ $wsCookie.deleteCookie("wsThemeColor") }}
```
***
## Aktionen
Für `$wsCookie` stehen keine Aktionen zur Verfügung.
***
## Beispiele
Die folgenden Beispiele sind von einfachen zu komplexeren Fällen geordnet: vom Zustand über die Benutzeraktion und den Einstiegsweg bis hin zum extern gesetzten Cookie und einem vollständigen Conversion-Tracking, das ein externes Cookie mit einer Einwilligungsprüfung kombiniert.
### Persönliche Begrüßung (WelcomeBack-Cookie)
Auslöser ist hier der Zustand "Login". Der Kunde wird beim Aufruf des Shops persönlich begrüßt, auch wenn er nicht eingeloggt ist, sofern er sich zuvor einmal eingeloggt hat. So bleibt eine persönliche Note erhalten, ohne dass der Kunde dauerhaft angemeldet sein muss.
**Schritt 1: Cookie beim Login setzen**
Sobald sich der Kunde eingeloggt hat, wird sein Anzeigename im Cookie gespeichert. Fehlt der Anzeigename oder ist er leer, wird die E-Mail-Adresse verwendet. Der dritte Parameter gibt die Gültigkeitsdauer in Sekunden an (hier 365 Tage), damit die Begrüßung über einen längeren Zeitraum erhalten bleibt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
{{ var $welcomeName = $wsAccount.displayName }}
{{ if not $welcomeName }}
{{ $welcomeName = $wsAccount.email }}
{{ /if }}
{{ $wsCookie.setCookie("welcomeBackName", $welcomeName, 31536000) }}
{{ /if }}
```
**Schritt 2: Begrüßung auf einer beliebigen Seite anzeigen**
Auf einer beliebigen Seite, etwa der Startseite, lesen Sie den Namen aus und zeigen die entsprechende Begrüßung an. Wenn kein Cookie vorhanden ist, weil sich der Kunde beispielsweise nie eingeloggt hat oder das Cookie abgelaufen ist, wird nichts angezeigt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $name = $wsCookie.getCookie("welcomeBackName") }}
{{ if $name }}
Willkommen zurück, {{= $name }}!
{{ /if }}
```
**Ergebnis**\
Wiederkehrende Kunden sehen ihre persönliche Begrüßung, bis das Cookie abläuft oder gelöscht wird.
**Hinweis:** Dieses Cookie enthält personenbezogene Daten. Prüfen Sie die Einwilligung über [\$wsConsent.checkAllowed()](/frontend/referenz/module/wsconsent#\$wsconsent-checkallowed) und weisen Sie auf der Startseite auf die Cookie-Richtlinien hin.
### Darstellungsvariante (z. B. Darkmode) speichern
Auslöser ist hier eine Benutzeraktion, nämlich ein Klick. Da WEBSALE nicht mit einem Theme-System arbeitet, müssen Sie eine Darstellungsvariante selbst erstellen. Dazu legen Sie die Wahl des Nutzers in einem Cookie ab und laden beim Seitenaufbau das passende Stylesheet.
**Schritt 1: Auslöser bereitstellen**
Der Nutzer wählt die Variante über einen Link. Der Klick löst einen Seitenaufruf aus, erst dabei kann der Wert gesetzt werden (siehe [Zeitpunkt der Ausführung](#grundkonzept)).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Darkmode aktivieren
Darkmode ausschalten
```
**Schritt 2: Auswahl beim Seitenaufbau ins Cookie schreiben**
Die Gültigkeitsdauer von 365 Tagen (in Sekunden) sorgt dafür, dass die Auswahl über die Sitzung hinaus erhalten bleibt. Ohne diesen Wert wäre es nur ein Session-Cookie und die Einstellung wäre nach dem Schließen des Browsers verloren.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsViews.current.params.theme }}
{{ $wsCookie.setCookie("wsThemeColor", $wsViews.current.params.theme, 31536000) }}
{{ /if }}
```
**Schritt 3: Bei jedem Seitenaufruf lesen und passendes Stylesheet laden**
Das Cookie speichert lediglich die Auswahl. Die sichtbare Änderung entsteht erst durch das passende [Stylesheet](/glossar#stylesheet). Deshalb gibt es eine Weiche zwischen Dark- und Light-Variante.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $currentTheme = $wsCookie.getCookie("wsThemeColor") }}
{{ if $currentTheme == "dark" }}
{{ else }}
{{ /if }}
```
**Ergebnis**\
Die gewählte Variante bleibt über alle Seitenaufrufe hinweg erhalten, bis der Nutzer sie wechselt.
### Onsite-Personalisierung: zielgruppenspezifische Inhalte
Auslöser ist hier der Einstiegsweg, also ein Kampagnen-Link, über den der Besucher in den Shop kommt. Anders als die persönliche Begrüßung ist dies echte [Onsite-Personalisierung](/glossar#onsite-personalisierung): Sie spielen abhängig von einem Merkmal des Besuchers unterschiedliche Inhalte auf den Shop-Seiten aus.
Das Szenario: Ein Tierbedarfs-Shop verschickt getrennte Newsletter an Katzen- und Hundehalter. Über den Link im Newsletter merkt sich der Shop die Zielgruppe und zeigt fortan passende Inhalte.
**Schritt 1: Kampagnen-Link im Newsletter**
Die Links im Newsletter tragen die Zielgruppe als Parameter:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Zu unseren Katzen-Angeboten
Zu unseren Hunde-Angeboten
```
**Schritt 2: Zielgruppe beim Seitenaufbau ins Cookie schreiben**
Ruft der Besucher den Shop über den Link auf, liest das Template den Parameter aus und speichert die Zielgruppe. Die Gültigkeitsdauer von 30 Tagen (2592000 Sekunden) sorgt dafür, dass die Zuordnung auch bei späteren Besuchen erhalten bleibt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsViews.current.params.kundengruppe }}
{{ $wsCookie.setCookie("kundengruppe", $wsViews.current.params.kundengruppe, 2592000) }}
{{ /if }}
```
**Schritt 3: Auf jeder Seite die passenden Inhalte anzeigen**
Auf den Shop-Seiten ermitteln Sie die Zielgruppe und blenden die passenden Inhalte ein. Wichtig: Ein frisch gesetztes Cookie ist erst beim **nächsten** Seitenaufruf lesbar (siehe [Zeitpunkt der Ausführung](#grundkonzept)). Beim ersten Aufruf über den Kampagnen-Link greifen Sie deshalb auf den Parameter zurück und erst danach auf das Cookie. So sieht der Besucher schon beim Einstieg die richtigen Inhalte. Ist weder Parameter noch Cookie vorhanden, zeigen Sie einen neutralen Standardinhalt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $gruppe = $wsViews.current.params.kundengruppe }}
{{ if not $gruppe }}
{{ $gruppe = $wsCookie.getCookie("kundengruppe") }}
{{ /if }}
{{ if $gruppe == "katze" }}
Unsere Bestseller für Katzen
{{# hier die Banner und Produkte für Katzenhalter #}}
{{ else }}
{{ if $gruppe == "hund" }}
Unsere Bestseller für Hunde
{{# hier die Banner und Produkte für Hundehalter #}}
{{ else }}
Für Katzen- und Hundefreunde
{{# neutraler Standardinhalt, solange keine Zielgruppe bekannt ist #}}
{{ /if }}
{{ /if }}
```
**Ergebnis**\
Besucher aus dem Katzen-Newsletter sehen bei jedem Aufruf die Katzen-Inhalte, Besucher aus dem Hunde-Newsletter die Hunde-Inhalte. Alle anderen sehen den Standardinhalt.
Hinweis: Der Cookie-Wert ist im Browser lesbar und kann vom Nutzer verändert werden. Verwenden Sie die Zielgruppe daher nur zur Anzeige von Inhalten, nicht für sicherheitsrelevante Entscheidungen wie Preise oder Zugriffsrechte. Da es sich nicht um ein technisch notwendiges Cookie handelt, prüfen Sie zuvor die Einwilligung des Nutzers.
### Extern gesetztes Cookie lesen
Auslöser ist hier ein Cookie, das außerhalb des Shops gesetzt wurde, beispielsweise per eigenem JavaScript oder durch ein Tool eines Drittanbieters. Solche Cookies behalten ihren ursprünglichen Namen und werden nicht automatisch umbenannt. Um sie auszulesen, übergeben Sie `keepNameAsIs: true`. Andernfalls sucht der Shop nach dem umbenannten Namen und findet das Cookie nicht.
Im Beispiel hat ein per JavaScript gesetztes [Flag](/glossar#flag) vermerkt, dass ein Info-Popup bereits gesehen wurde:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{# Das Cookie wurde per JavaScript gesetzt:
document.cookie = "infoPopupSeen=true"
Im Template lesen wir es mit keepNameAsIs unverändert aus. #}}
{{ var $popupSeen = $wsCookie.getCookie("infoPopupSeen", { keepNameAsIs: true }) }}
{{ if $popupSeen != "true" }}
{{# Cookie nicht vorhanden, Info-Popup anzeigen #}}
{{ /if }}
```
**Ergebnis**\
Das Popup erscheint nur, solange das extern gesetzte Flag fehlt.
### Affiliate-Conversion-Tracking mit externem Cookie
Auslöser ist hier ein extern gesetztes Cookie in Kombination mit dem Kaufabschluss. Affiliate-Netzwerke (z. B. Awin) setzen beim Klick auf einen Partner-Link ein eigenes Cookie mit einer Klick-Kennung. Wird die Bestellung abgeschlossen, meldet der Shop die Conversion an das Netzwerk zurück und übergibt dabei diese Klick-Kennung, damit die Vermittlung dem richtigen Partner zugeordnet wird.
Zwei Dinge sind dabei für `$wsCookie` entscheidend: Das Netzwerk-Cookie wurde außerhalb des Shops gesetzt und wird deshalb mit `keepNameAsIs: true` gelesen. Und weil Conversion-Tracking dem Marketing dient, wird es erst nach der Einwilligung des Nutzers ausgeführt. Die Einwilligung prüfen Sie über [\$wsConsent](/frontend/referenz/module/wsconsent) – nicht über ein separat ausgelesenes Consent-Cookie.
**Schritt 1: Klick-Kennung aus dem externen Cookie lesen**
Das Cookie des Netzwerks (im Beispiel `awc`) behält seinen Original-Namen, daher `keepNameAsIs: true`. Fehlt es, bleibt der Wert leer.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $awcCookie = $wsCookie.getCookie("awc", { keepNameAsIs: true }) }}
```
**Schritt 2: Nur bei Marketing-Einwilligung tracken**
Statt ein fremdes Consent-Cookie auszulesen, prüfen Sie die Einwilligung über `$wsConsent`. Nur wenn die Marketing-Einwilligung vorliegt, werden der Tracking-Aufruf und das Zählpixel ausgegeben. Die übergebenen Bestelldaten (Summe, Bestellnummer, Gutschein, Währung) stammen aus dem Checkout.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{# Marketing-Einwilligung prüfen – genaue Kategorie/Signatur siehe $wsConsent #}}
{{ if $wsConsent.checkAllowed("marketing") }}
{{ var $eventData = join([
"&merchant=00000",
"&amount=", $wsCheckout.sum.totalNet,
"&ch=aw",
"&parts=DEFAULT:", $wsCheckout.sum.totalNet,
"&vc=", ifnull($wsVoucher.vouchers[0].id, ""),
"&cr=", $wsCheckout.sum.currency,
"&ref=", $wsCheckout.orderId,
"&testmode=0",
"&cks=", ifnull($awcCookie, "")
], "") }}
{{ $wsAsse.fire("dwintracking", $eventData) }}
{{ /if }}
```
**Ergebnis**\
Liegt die Marketing-Einwilligung vor, wird die Conversion inklusive der externen Klick-Kennung an das Affiliate-Netzwerk gemeldet. Ohne Einwilligung passiert nichts.
Hinweis: Der `merchant`-Wert (`00000`), das Event `dwintracking`, der Cookie-Name `awc` und die Awin-spezifischen Aufrufe sind netzwerk- bzw. shopspezifisch und hier nur beispielhaft. Der für `$wsCookie` relevante Teil ist das Lesen des externen Cookies mit `keepNameAsIs: true`; die Einwilligung wird über [\$wsConsent](/frontend/referenz/module/wsconsent) geprüft, nicht über ein eigenes Consent-Cookie.
***
## Weiterführende Links
* [\$wsConsent](/frontend/referenz/module/wsconsent) – Einwilligung des Nutzers prüfen, bevor Sie nicht-notwendige Cookies setzen.
# $wsOptions - Template-Optionen
Source: https://dokumentation.websale.de/frontend/referenz/module/ws-options-template-optionen
Werte von Template-Optionen im Frontend auslesen – global oder pro Konfigurationsknoten.
Mit dem `$wsOptions`-Modul lesen Sie im Frontend die Werte von Template-Optionen aus. Template-Optionen sind Einstellungen, die einmal im Template definiert werden und danach im Admin-Interface pflegbar sind - ohne dass das Template erneut angepasst werden muss. Damit lassen sich Darstellungs-Details umschalten (z. B. ob das Icon einer Zahlungsart im Footer erscheint), ohne ins Template einzugreifen.
Auf dieser Seite geht es um das Lesen der Optionswerte. Wie Optionen definiert werden (Typen, Wertgrenzen, `attachTo`, Darstellung im Admin-Interface), beschreibt [Template-Optionen definieren](/frontend/referenz/optionen).
***
## Grundkonzept
Eine Template-Option durchläuft immer denselben Ablauf: definieren → im Admin pflegen → im Template lesen.
* **Definieren:** Die Option wird in einem Template mit der Anweisung `{{ option … }}` angelegt (siehe [Template-Optionen definieren](/frontend/referenz/optionen)).
* **Verfügbar werden:** Definierte Optionen erscheinen im Admin-Interface, nachdem die Templates erfolgreich kompiliert wurden. Wird eine Option wieder aus den Templates entfernt, verschwindet sie erst nach erneuter Kompilierung aus dem Admin-Interface.
* **Pflegen:** Die Werte werden im Admin-Interface gesetzt. Bei an Konfigurationen gebundenen Optionen je Konfigurationsknoten unterschiedlich (siehe `attachTo`).
* **Lesen:** im Template über `$wsOptions.get(…)`.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsOptions`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsOptions | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"get": "ƒ()"
}
```
Anmerkung: `ƒ()` kennzeichnet eine Funktion.
**Methoden in der Übersicht**
| **Methode** | **Rückgabe-Typ** | **Beschreibung** |
| ----------- | ----------------------- | --------------------------------------------------------------------------- |
| `get()` | abhängig vom Optionstyp | Liest den Wert einer Template-Option (global oder je Konfigurationsknoten). |
***
## Templates
Template-Optionen lassen sich in jedem Template lesen.
***
## Variablen
Für `$wsOptions` stehen keine Variablen zur Verfügung. Der Zugriff erfolgt ausschließlich über die Methode `get()`.
***
## Methoden
### \$wsOptions.get()
Gibt den im Admin-Interface gepflegten Wert einer Template-Option zurück. Ohne zweiten Parameter wird eine globale Option gelesen. Bei Optionen, die mit `attachTo` an einen Konfigurationsknoten gebunden sind, geben Sie die Knoten-ID als zweiten Parameter an.
**Signatur**\
`$wsOptions.get(name, nodeId)`
**Rückgabe**\
Der gepflegte Wert der Option. Der Typ entspricht dem bei der Definition festgelegten Optionstyp (`String`, `Bool`, `Int`, `Float`, `Enum`).\
Wurde die Option im Admin-Interface noch nicht explizit gesetzt, wird `null` zurückgegeben. Prüfen Sie den Rückgabewert daher vor der Verwendung (z. B. mit `if`), damit das Template bei einer noch nicht gepflegten Option nicht ungewollt leer bleibt.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| -------- | ------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `name` | string | ja | Name der Option, wie im Template definiert. |
| `nodeId` | string | nein | ID des Konfigurationsknotens. Nur bei `attachTo`-Optionen anzugeben (siehe unten). Ohne Angabe wird der globale Wert gelesen. |
**Beispiel** – globale Option:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsOptions.get("intValue") }}
```
Gibt den Wert der Option `intValue` aus.
**Beispiel** – an einen Konfigurationsknoten gebundene Option:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsOptions.get("attached", "payment.payment.bill") }}
```
Gibt den Wert der Option `attached` für die Zahlungsart mit dem Konfigurationsknoten `payment.payment.bill` (z. B. „Vorkasse") zurück. Der zweite Parameter ist nötig, weil dieselbe Option bei frei erstellbaren Konfigurationen, etwa einer Konfiguration je Zahlungsart, pro Knoten unterschiedlich gesetzt sein kann (z. B. bei „Vorkasse" deaktiviert, bei „Google Pay" aktiviert).
#### nodeId – die ID des Konfigurationsknotens
Verwechseln Sie die **Konfigurationsknoten-ID** (`nodeId`) nicht mit dem Feld `id` innerhalb einer Konfiguration. Die Konfiguration `payment.payment` enthält beispielsweise ein eigenes Feld `id` (eine „technische ID") – dieses kann **nicht** als `nodeId` verwendet werden.
Damit Sie die korrekte Knoten-ID zur Hand haben, stellen die folgenden Objekte ein Feld `nodeId` bereit:
* [`$wsAccount`](/frontend/referenz/module/wsAccount): `addressFields`
* [`$wsAsse`](/frontend/referenz/module/wsasse): `asseConfigs`
* [`$wsCategories`](/frontend/referenz/module/wscategories): `fields`, `customFields`
* [`$wsConfig`](/frontend/referenz/module/wsconfig): `countries`, `payments`, `shippingMethods`, `shippingMethodGroups`, `currency`, `emails`, `listElements`, `redirects`
* [`$wsForm`](/frontend/referenz/module/wsform): `loadType` / `loadAllTypes` sowie deren `fields` / `loadField`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $payment in $wsConfig.payments }}
{{= $wsOptions.get("attached", $payment.nodeId) }}
{{ /foreach }}
```
Hier liefert `$payment.nodeId` die Knoten-ID der jeweiligen Zahlungsart, die direkt als zweiter Parameter übergeben wird.
***
## Aktionen
Für `$wsOptions` stehen keine Aktionen zur Verfügung.
***
## Beispiele
### Zahlungsarten je Zahlungsart im Footer ein- oder ausblenden
In diesem Beispiel wird eine an `payment.payment` gebundene Option definiert, die im Footer nur die Zahlungsarten anzeigt, für die die Option im Admin-Interface aktiviert wurde. So können Sie pro Zahlungsart entscheiden was angezeigt wird, ohne das Template anzupassen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ option "methodLocationFooter" with
{
"type": "Bool",
"attachTo": "payment.payment"
}
}}
{{ foreach $method in $wsConfig.payments }}
{{ if $wsOptions.get("methodLocationFooter", $method.nodeId) }}
{{= $method.name }}
{{ /if }}
{{ /foreach }}
```
**Ergebnis**\
Im Footer werden nur die Zahlungsarten angezeigt, für die die Option "`methodLocationFooter`" aktiviert ist. Da diese Option an `payment.payment` gebunden ist, wird sie pro Zahlungsart über deren `nodeId` gelesen. Wenn die Option für eine Zahlungsart nicht gesetzt ist, gibt `get()` den Wert `null` zurück und der `if`-Zweig wird nicht ausgeführt.
***
## Weiterführende Links
* [Template-Optionen definieren](/frontend/referenz/optionen) – Syntax, Typen, Wertgrenzen, `attachTo` und Darstellung im Admin-Interface.
* [\$wsConfig](/frontend/referenz/module/wsconfig) – liefert u. a. `payments` inklusive `nodeId`.
* [Konfiguration per Code](/frontend/die-basics/konfiguration-per-code) – Konfiguration direkt im Template.
* [Storefront API Optionen](/schnittstellen/storefront-api/storefront-api-optionen) - dieselben Optionswerte über die Storefront-API auslesen.
# $wsAccount - Account & Adressdaten
Source: https://dokumentation.websale.de/frontend/referenz/module/wsAccount
Account- und Adressdaten des eingeloggten Kunden im Frontend lesen, Login-Status prüfen und personalisierte Inhalte über Templates ausgeben.
Mit dem `$wsAccount`-Modul lesen Sie die Account- und Adressdaten des aktuell eingeloggten Kunden und zeigen sie im Template an.
Auf dieser Seite geht es ausschließlich um das Lesen und Anzeigen vorhandener Account- und Adressdaten. Alles, was Daten verändert (Adresse anlegen, bearbeiten, löschen, Passwort ändern), ist unter [Aktionen → Account](/frontend/referenz/aktionen/account) beschrieben, weil dort die auslösenden Aktionen und ihre Parameter dokumentiert sind.
Die meisten Werte von `$wsAccount` sind nur gefüllt, wenn der Kunde eingeloggt ist. Prüfen Sie deshalb vor dem Zugriff mit `$wsAccount.isLoggedIn`, ob ein Kunde angemeldet ist, sonst lesen Sie leere Werte aus und zeigen unbeabsichtigt leere Felder an.
***
## Grundkonzept
Die Arbeit mit `$wsAccount` folgt immer demselben Ablauf:
Login-Zustand prüfen → Kundendaten lesen → reagieren.
Bevor Sie Kundendaten lesen, müssen Sie wissen, ob überhaupt ein Kunde eingeloggt ist. Erst der eingeloggte Zustand füllt die Variablen mit Werten. Anschließend lesen Sie die gewünschten Daten (z. B. den Anzeigenamen oder eine Adresse) und reagieren darauf, etwa mit einer persönlichen Begrüßung oder der Anzeige des Adressbuchs.
**Wann die Daten verfügbar sind**
Wenn kein Kunde eingeloggt ist, geben die Account-Abfragen leere Werte zurück. Deshalb beginnt nahezu jedes Beispiel auf dieser Seite mit einer `isLoggedIn`-Prüfung.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsAccount`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsAccount | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"addressFields": [...],
"addresses": [...],
"autoLogInRestriction": "...",
"backInStockList": [...],
"customerData": { ... },
"defaultBillAddress": { ... },
"defaultDeliveryAddress": { ... },
"displayName": "...",
"email": "...",
"id": "...",
"isAccountVerified": true,
"isAutoLogInRestricted": true,
"isAutoLoggedIn": true,
"isLoggedIn": true,
"isPasswordResetRequired": true,
"lastLogin": "...",
"loadAddress": "ƒ()",
"hasPaymentVault": false,
"loginRequired": "ƒ()",
"pseudoCreditCards": [...],
"typeSeparation": { ... }
}
```
Anmerkung: `"ƒ()"` kennzeichnet eine Funktion (Methode).
**Variablen in der Übersicht**
| **Name** | **Rückgabe-Typ** | **Beschreibung** |
| ------------------------- | ---------------- | --------------------------------------------------------------------------------- |
| `addressFields` | array | Liste aller verfügbaren Adressfelder mit deren Konfiguration. |
| `addresses` | array | Liste aller gespeicherten Adressen des Kunden. |
| `autoLogInRestriction` | string | Status der Auto-Login-Einschränkung. |
| `backInStockList` | array | Produkte, für die der Kunde eine Verfügbarkeits-Benachrichtigung angefordert hat. |
| `customerData` | map | Kundenspezifische Felder (z. B. Label, Typ, Wert). |
| `defaultBillAddress` | map | Haupt-Rechnungsadresse als Adress-Map. |
| `defaultDeliveryAddress` | map | Standard-Lieferadresse als Adress-Map. |
| `displayName` | string | Anzeigename des Kunden. |
| `email` | string | E-Mail-Adresse des Kundenkontos. |
| `id` | string | Nutzer-ID des Kundenkontos. |
| `isAccountVerified` | bool | Prüft, ob das Kundenkonto verifiziert wurde. |
| `isAutoLoggedIn` | bool | Prüft, ob der Nutzer automatisch eingeloggt wurde. |
| `isAutoLogInRestricted` | bool | Prüft, ob beim automatischen Login nicht alle Shop-Funktionen verfügbar sind. |
| `isLoggedIn` | bool | Prüft, ob der Nutzer eingeloggt ist. |
| `isPasswordResetRequired` | bool | Prüft, ob das Passwort zurückgesetzt werden muss. |
| `lastLogin` | string | Datum des letzten Logins. |
| `pseudoCreditCards` | array | Gespeicherte Kreditkarten (pseudonymisiert). |
| `typeSeparation` | map | Informationen zur Adresstyp-Trennung. |
**Methoden in der Übersicht**
| **Methode** | **Rückgabe-Typ** | **Beschreibung** |
| ------------------- | ---------------- | --------------------------------------------------------------------------------- |
| `loadAddress()` | map | Lädt eine Adresse anhand ihrer ID. |
| `hasPaymentVault()` | bool | Prüft, ob für eine Zahlungsart eine Verknüpfung mit dem Zahlungsanbieter besteht. |
| `loginRequired()` | bool | Gibt zurück, ob eine bestimmte Aktion einen Login erfordert. |
***
## Templates
Die Daten eines eingeloggten Kunden können auf jedem Template geladen und angezeigt werden.
Im Standard-Ausliefershop befinden sich die Templates für die Seiten des Kundenkontos im Verzeichnis `views/account`. Sie dienen als Grundlage zur Anzeige und Bearbeitung der Kundendaten. Sie können diese Daten aber auch in anderen Templates nutzen. Voraussetzung ist, dass der Kunde eingeloggt ist (siehe [Grundkonzept](#grundkonzept)).
***
## Variablen
### \$wsAccount.isLoggedIn
Gibt zurück, ob der Nutzer eingeloggt ist.
Diese Prüfung steht am Anfang fast jeder Account-Auswertung, weil alle übrigen Variablen erst im eingeloggten Zustand sinnvolle Werte liefern.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
{{ else }}
{{ /if }}
```
### \$wsAccount.email
Gibt die E-Mail-Adresse des Kundenkontos zurück.
Im Checkout kann ein Kunde auch als Gast bestellen. Dann liegt keine Konto-E-Mail vor, sondern eine Gast-Mailadresse aus dem Checkout. Das folgende Beispiel deckt deshalb beide Fälle ab, damit immer die passende Adresse angezeigt wird:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.guestMail }}
{{= $wsCheckout.guestMail }}
{{ else }}
{{= $wsAccount.email }}
{{ /if }}
```
> `$wsCheckout.guestMail` stammt aus dem Modul [\$wsCheckout](/frontend/referenz/module/wscheckout) und ist nur während des Bestellvorgangs gefüllt.
### \$wsAccount.id
Gibt die Nutzer-ID des Kundenkontos zurück. Verwenden Sie sie, um einen Kunden eindeutig zu identifizieren, etwa für das Tracking.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
Nutzer-ID: {{= $wsAccount.id }}
{{ /if }}
```
### \$wsAccount.isAccountVerified
Gibt zurück, ob das Kundenkonto verifiziert wurde. Werten Sie das aus, wenn bestimmte Funktionen erst nach Verifizierung freigeschaltet werden sollen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isAccountVerified }}
{{ /if }}
```
### \$wsAccount.isAutoLoggedIn
Gibt zurück, ob der Nutzer automatisch eingeloggt wurde (über „Angemeldet bleiben"). Das ist relevant, weil ein automatischer Login eingeschränkt sein kann (siehe `isAutoLogInRestricted`).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isAutoLoggedIn }}
{{ /if }}
```
### \$wsAccount.isAutoLogInRestricted
Gibt zurück, ob beim automatischen Login nicht alle Shop-Funktionen verfügbar sind. Werten Sie das aus, bevor Sie einem automatisch eingeloggten Kunden sicherheitsrelevante Aktionen (z. B. Adressänderung) anbieten, denn diese können eine erneute Anmeldung erfordern.
Mehr dazu [in der Konfiguration](/konfiguration/accounts-benutzerkonten#6-accounts-autologin-angemeldet-bleiben).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isAutoLogInRestricted }}
{{ /if }}
```
### \$wsAccount.autoLogInRestriction
Gibt den Status der Auto-Login-Einschränkung als Zeichenkette zurück. Mehr dazu [in der Konfiguration](/konfiguration/accounts-benutzerkonten#6-accounts-autologin-angemeldet-bleiben).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.autoLogInRestriction }}
{{ /if }}
```
### \$wsAccount.lastLogin
Gibt das Datum des letzten Logins als Zeichenkette zurück.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.lastLogin }}
Letzter Login: {{= $wsAccount.lastLogin }}
{{ /if }}
```
### \$wsAccount.isPasswordResetRequired
Gibt zurück, ob das Passwort zurückgesetzt werden muss. Werten Sie das aus, um den Kunden gezielt zur Passwortänderung zu führen.
Mehr dazu [in der Konfiguration](/konfiguration/accounts-benutzerkonten#2-accounts-account-benutzerkonto).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isPasswordResetRequired }}
Bitte setzen Sie Ihr Passwort zurück.
{{ /if }}
```
### \$wsAccount.customerData
Gibt kundenspezifische Felder als `map` zurück (z. B. Label, Typ und Wert). Verwenden Sie diese Variable, um zusätzlich konfigurierte Kundenfelder anzuzeigen, ohne jedes Feld einzeln zu kennen.
Mehr dazu [in der Konfiguration](/konfiguration/accounts-benutzerkonten#5-accounts-addressfield-einzelne-adressfelder-definieren).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsAccount.customerData }}
{{= $field.value }}
{{ /foreach }}
```
### \$wsAccount.addressFields
Gibt eine Liste aller verfügbaren Adressfelder mit deren Konfiguration zurück. Jedes Element ist ein Objekt mit den Eigenschaften `name` (Feldname, z.B. `firstName` ), `label` (konfigurierte Beschriftung, kann leer sein) und `dataId` . Diese Liste kann benutzt werden, um Adressformulare dynamisch aus der Konfiguration aufzubauen.
Jeder Eintrag enthält zusätzlich das Feld `nodeId`, die ID des Konfigurationsknotens, nutzbar als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen) (siehe [Optionen](/frontend/referenz/optionen)).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsAccount.addressFields }}
{{= $field.name }} – {{= $field.label }}
{{ /foreach }}
```
### \$wsAccount.backInStockList
Gibt die Produkte zurück, für die der Kunde eine [Benachrichtigung bei Verfügbarkeit](https://dokumentation.websale.de/frontend/referenz/aktionen/inventory#backinstockactivatenotify) angefordert hat. Zeigen Sie die Liste beispielsweise im Kundenkonto an, damit der Kunde seine vorgemerkten Produkte sieht und verwalten kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $product in $wsAccount.backInStockList }}
{{= $product }}
{{ /foreach }}
```
### \$wsAccount.pseudoCreditCards
Gibt die gespeicherten Kreditkarten in [pseudonymisierter](/glossar#pseudonymisierung) Form zurück. Die Pseudonymisierung ist gewollt, denn Vollständige Kartendaten dürfen aus Sicherheits- und Datenschutzgründen nicht im Frontend angezeigt werden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $card in $wsAccount.pseudoCreditCards }}
{{= $card }}
{{ /foreach }}
```
### \$wsAccount.typeSeparation
Gibt Informationen zur Adresstyp-Trennung zurück. Über diese [Map](/glossar#map) können Sie prüfen, ob Rechnungs- und Lieferadressen getrennt verwaltet werden und welche Einschränkungen gelten.
#### Eigenschaften von `$wsAccount.typeSeparation`
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| ---------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- |
| `enabled` | bool | Prüft, ob die Adresstyp-Trennung aktiv ist. |
| `canCreateBillAddress` | bool | Prüft, ob noch eine neue Rechnungsadresse angelegt werden kann. |
| `maxBillAddresses` | int | Maximale Anzahl erlaubter Rechnungsadressen.
`0` = unbegrenzt
`-1` = Trennung deaktiviert. |
| `defaultBillAddressReadonly` | bool | Prüft, ob die Haupt-Rechnungsadresse schreibgeschützt ist. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.typeSeparation.enabled }}
{{ if $wsAccount.typeSeparation.canCreateBillAddress }}
{{ else }}
{{ /if }}
{{ /if }}
```
### \$wsAccount.defaultBillAddress
Gibt die Haupt-Rechnungsadresse des Kunden als Adress-Map zurück (einschließlich `id`), sofern eine als Standard markiert ist. Verwenden Sie sie, wenn gezielt die Haupt-Rechnungsadresse gebraucht wird. Die verfügbaren Eigenschaften entsprechen denen von `$wsAccount.addresses`.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.defaultBillAddress }}
Vorname: {{= $wsAccount.defaultBillAddress.firstName }}
Nachname: {{= $wsAccount.defaultBillAddress.lastName }}
{{ /if }}
```
### \$wsAccount.defaultDeliveryAddress
Gibt die Standard-Lieferadresse des Kunden als Adress-Map zurück (einschließlich `id`), sofern eine als Standard markiert ist. Verwenden Sie sie, wenn gezielt die Standard-Lieferadresse gebraucht wird. Die verfügbaren Eigenschaften entsprechen denen von `$wsAccount.addresses`.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.defaultDeliveryAddress }}
Vorname: {{= $wsAccount.defaultDeliveryAddress.firstName }}
Nachname: {{= $wsAccount.defaultDeliveryAddress.lastName }}
{{ /if }}
```
### \$wsAccount.addresses
Gibt die Liste aller gespeicherten Adressen des Kunden zurück. Verwenden Sie sie für ein Adressbuch oder wenn Sie über alle Adressen iterieren möchten.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $address in $wsAccount.addresses }}
{{= $address.firstName }} {{= $address.lastName }}
{{ /foreach }}
```
Jede Adresse aus `$wsAccount.addresses` (und ebenso aus `defaultBillAddress`, `defaultDeliveryAddress` und `loadAddress()`) stellt die folgenden Eigenschaften zur Verfügung.
#### Eigenschaften von `$wsAccount.addresses`
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| -------------------------- | ---------------- | ----------------------------------------------------------------- |
| `id` | string | Adress-ID |
| `salutationCode` | string | Anredecode |
| `titleCode` | string | Titelcode (z. B. Dr., Prof.) |
| `firstName` | string | Vorname |
| `lastName` | string | Nachname |
| `company` | string | Firmenname |
| `department` | string | Abteilung |
| `street` | string | Straße |
| `streetNumber` | string | Hausnummer |
| `additionalInfo` | string | Zusätzliche Adressinformationen |
| `zip` | string | Postleitzahl |
| `city` | string | Stadt |
| `state` | string | Bundesland / Region |
| `country` | string | Land |
| `phone` | string | Telefonnummer |
| `mobilePhone` | string | Mobiltelefonnummer |
| `fax` | string | Faxnummer |
| `businessPhone` | string | Geschäftliche Telefonnummer |
| `businessFax` | string | Geschäftliche Faxnummer |
| `dateOfBirth` | string | Geburtsdatum |
| `taxId` | string | Steuernummer |
| `addressType` | string | Typ der Adresse |
| `addressOwnerMemberId` | string | ID des Kunden, dem die Adresse gehört |
| `custom` | map | Benutzerdefinierte Adressfelder |
| `isBillAddress` | bool | Prüft, ob die Adresse als Rechnungsadresse verwendet werden kann. |
| `isDeliveryAddress` | bool | Prüft, ob die Adresse als Lieferadresse verwendet werden kann. |
| `isDefaultBillAddress` | bool | Prüft, ob es sich um die Haupt-Rechnungsadresse handelt. |
| `isDefaultDeliveryAddress` | bool | Prüft, ob es sich um die Standard-Lieferadresse handelt. |
| `isReadonly` | bool | Prüft, ob die Adresse schreibgeschützt ist. |
| `type` | string | Typ der Adresse (`"bill"` oder `"delivery"`). |
#### \$address.customLabel()
Gibt das benutzerdefinierte Label für ein bestimmtes Adressfeld zurück, abhängig vom Adresstyp. Nutzen Sie die Methode, um Formularbeschriftungen aus der Konfiguration zu übernehmen, statt sie fest im Template zu hinterlegen.
**Signatur** `$address.customLabel(fieldName, addressType)`
**Rückgabe** `string` – das konfigurierte Label für das Feld.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------- | ------- | ----------- | ------------------------------------------------------------------------------- |
| `fieldName` | string | ja | Name des Adressfeldes (z. B. `"firstName"`). |
| `addressType` | string | ja | Adresstyp: `"bill"` (Rechnung), `"delivery"` (Lieferung) oder `"both"` (beide). |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Vorname-Label: {{= $address.customLabel("firstName", "bill") }}
```
#### \$address.defaultValue()
Gibt den konfigurierten Standardwert für ein bestimmtes Adressfeld zurück, abhängig vom Adresstyp. Nutzen Sie die Methode, um Felder mit sinnvollen Vorgaben vorzubelegen.
**Signatur** `$address.defaultValue(fieldName, addressType)`
**Rückgabe** `string` – der konfigurierte Standardwert für das Feld.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------- | ------- | ----------- | ------------------------------------------------------------------------------------- |
| `fieldName` | string | ja | Name des Adressfeldes (z. B. `"company"`). |
| `addressType` | string | ja | Adresstyp:
`"bill"` (Rechnung), `"delivery"` (Lieferung) oder `"both"` (beide). |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $address.defaultValue("company", "delivery") }}
```
**Hinweis:** Die Methoden `customLabel()` und `defaultValue()` haben aktuell nur im Checkout eine Wirkung, sobald der Kunde eine Adresse ausgewählt hat. Im Kundenkonto unterscheiden sie noch nicht zwischen Liefer- und Rechnungsadresse. Das ist für eine künftige Version vorgesehen.
***
## Methoden
### \$wsAccount.loginRequired()
Gibt zurück, ob der Nutzer für eine bestimmte Aktion angemeldet sein muss. Werten Sie das aus, bevor Sie eine Aktion anbieten, damit Sie einen nicht angemeldeten Kunden vorab zum Login führen, statt ihn in eine abgelehnte Aktion laufen zu lassen. Mehr dazu [in der Konfiguration](/konfiguration/accounts-benutzerkonten#6-accounts-autologin-angemeldet-bleiben).
**Signatur** `$wsAccount.loginRequired(actionName)`
**Rückgabe** `bool` – `true`, wenn ein Login erforderlich ist, sonst `false`.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------ | ------- | ----------- | --------------------------------------------------------------------------------------------- |
| `actionName` | string | ja | Name der Aktion, für die geprüft wird, ob ein Login erforderlich ist (z. B. `"EmailUpdate"`). |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.loginRequired("EmailUpdate") }}
{{ /if }}
```
### \$wsAccount.loadAddress()
Lädt eine einzelne Adresse anhand ihrer ID und gibt sie als Adress-Map zurück. Verwenden Sie die Methode im Checkout, um die vom Kunden gewählte Rechnungs- oder Lieferadresse auszugeben.
**Signatur** `$wsAccount.loadAddress(addressId)`
**Rückgabe** `map` – die geladene Adresse mit den Eigenschaften aus`$wsAccount.addresses`.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ----------- | ------- | ----------- | ----------------------------------------------------------------------------- |
| `addressId` | string | ja | ID der zu ladenden Adresse (z. B. die im Checkout gewählte Rechnungsadresse). |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $billAddress = $wsAccount.loadAddress($wsCheckout.selectedBillAddress) }}
{{= $billAddress.firstName }} {{= $billAddress.lastName }}
```
`$wsCheckout.selectedBillAddress` stammt aus dem Modul [\$wsCheckout](/frontend/referenz/module/wscheckout) und liefert die ID der im Bestellvorgang gewählten Rechnungsadresse.
### \$wsAccount.hasPaymentVault()
Prüft, ob für den angemeldeten Kunden eine Verknüpfung mit dem Zahlungsanbieter der angegebenen Zahlungsart besteht. Rufen Sie die Methode auf einer Seite im Kundenkonto auf, um entweder die bestehende Verknüpfung mit einer Möglichkeit zum Aufheben anzuzeigen oder das Angebot zur Verknüpfung einzublenden.
Die Verknüpfung wird nicht der Zahlungsart selbst zugeordnet, sondern dem Zahlungsanbieter und dessen Merchant-ID. Mehrere Zahlungsarten, die denselben Zahlungsanbieter mit derselben Merchant-ID nutzen, teilen sich deshalb dieselbe Verknüpfung.
**Signatur** `$wsAccount.hasPaymentVault(paymentId)`
**Rückgabe** `bool` – `true` wenn eine Verknüpfung besteht, `false` wenn keine besteht. `null` wird zurückgegeben, wenn keine Prüfung möglich ist, beispielsweise wenn kein oder ein leerer `paymentID` - Wert übergeben wurde, die `paymentId` unbekannt ist oder die Zahlungsart grundsätzlich keine Verknüpfung unterstützt.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ----------- | ------- | ----------- | ------------------------------------------------ |
| `paymentId` | string | ja | ID der Zahlungsart, für die geprüft werden soll. |
**Beispiel,** das die Verknüpfung im Kundenkonto verwaltet. Die Unterscheidung mit `== true` bzw. `== false` ist hier bewusst gewählt, damit der `null`-Fall in keinen der beiden Zweige läuft.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $hasVault = $wsAccount.hasPaymentVault("paypal") }}
{{ if $hasVault == true }}
{{ elseif $hasVault == false }}
{{ /if }}
```
Ohne Anmeldung gibt die Methode `false` zurück, nicht `null` – prüfen Sie deshalb zuerst [`$wsAccount.isLoggedIn`](#wsaccount-isloggedin), bevor Sie aus `false` ableiten, dass der Kunde noch keine Verknüpfung angelegt hat.
Innerhalb des Bestellvorgangs verwenden Sie [\$wsCheckout.hasPaymentVault()](/frontend/referenz/module/wscheckout#wscheckout-haspaymentvault) – diese Methode prüft ohne Parameter gegen die im Checkout gewählte Zahlungsart und gibt immer einen Boolean zurück.
***
## Aktionen
`$wsAccount` selbst liest nur Daten. Aktionen, die Daten verändern (Adresse anlegen, bearbeiten, löschen, Passwort oder E-Mail ändern), sind separat dokumentiert: [Aktionen → Account](/frontend/referenz/aktionen/account).
***
## Beispiele
Die folgenden Beispiele sind nach Anwendungsfall geordnet: von der einfachen Zustandsprüfung über die persönliche Anrede bis zur Adressauflösung im Checkout. Alle Beispiele setzen einen eingeloggten Kunden voraus und prüfen das jeweils zu Beginn.
### Login-Zustand prüfen und Inhalt unterscheiden
Auslöser ist der Login-Zustand. Je nachdem, ob ein Kunde eingeloggt ist, zeigen Sie unterschiedliche Inhalte an.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
{{ else }}
{{ /if }}
```
**Ergebnis**
Eingeloggte Kunden sehen den persönlichen Bereich, nicht angemeldete Besucher das Login-Angebot.
### Persönliche Anrede eines eingeloggten Kunden
Auslöser ist der Login-Zustand. Ist ein Kunde eingeloggt, sprechen Sie ihn mit Vor- und Nachnamen aus seiner Rechnungsadresse an. Die `if`-Prüfung auf die Adresse verhindert leere Begrüßungen, falls noch keine Adresse hinterlegt ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
{{ var $address = $wsAccount.defaultBillAddress }}
{{ if $address }}
Willkommen, {{= $address.firstName }} {{= $address.lastName }}!
{{ /if }}
{{ /if }}
```
**Ergebnis**
Eingeloggte Kunden mit hinterlegter Rechnungsadresse werden namentlich begrüßt.
### Link zur Kundenkonto-Übersicht
Auslöser ist der Login-Zustand. Für eingeloggte Kunden erzeugen Sie einen Link zur Übersichtsseite. Die URL wird über [`$wsViews.viewUrl()`](/frontend/referenz/module/wsviews) gebildet, damit der Pfad zum Template korrekt aufgelöst wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
Zu Ihrer Kundenkonto-Übersicht
{{ /if }}
```
**Ergebnis**
Eingeloggte Kunden erhalten einen Link, der zuverlässig auf die Übersichtsseite zeigt.
### Rechnungsadresse anzeigen
Auslöser ist der Login-Zustand. Sie lesen die Haupt-Rechnungsadresse aus und zeigen sie mit einem Bearbeiten-Link an. Der Link übergibt die Adress-`id`, damit die Aktion die richtige Adresse bearbeitet.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
{{ var $address = $wsAccount.defaultBillAddress }}
{{ if $address }}
Ihre Rechnungsadresse
{{= $address.firstName }} {{= $address.lastName }}
{{= $address.street }} {{= $address.streetNumber }}
{{= $address.zip }} {{= $address.city }}
{{= $address.country }}
Bearbeiten
{{ /if }}
{{ /if }}
```
**Ergebnis**
Die Rechnungsadresse wird angezeigt und der Bearbeiten-Link führt zur richtigen Adresse.
### Adressbuch: über alle Adressen iterieren
Auslöser ist der Login-Zustand. Sie iterieren über alle gespeicherten Adressen und zeigen je Adresse einen Bearbeiten-Link. Die Schleifenvariable (`$address`) wird durchgängig verwendet, damit der Link genau die Adresse der aktuellen Iteration trifft.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsAccount.isLoggedIn }}
{{ foreach $address in $wsAccount.addresses }}
Adresse-ID: {{= $address.id }}
Bearbeiten
{{ /foreach }}
{{ /if }}
```
**Ergebnis**
Jede gespeicherte Adresse wird mit einem Bearbeiten-Link aufgelistet, der auf die Übersichtsseite der Adressen weiterleitet.
***
## Weiterführende Links
* [Aktionen → Account](/frontend/referenz/aktionen/account) - Adressen und Konto verändern (anlegen, bearbeiten, löschen), weil `$wsAccount` selbst nur liest.
* [\$wsCheckout](/frontend/referenz/module/wscheckout) - liefert die im Bestellvorgang gewählten Adress-IDs (`selectedBillAddress`, `selectedShippingAddress`) und die Gast-Mailadresse, die in den Beispielen verwendet werden.
* [Konfiguration: Accounts / Benutzerkonten](/konfiguration/accounts-benutzerkonten) - steuert Auto-Login, Verifizierung und Adressfelder, auf die mehrere Variablen verweisen.
# $wsActions - Aktionen
Source: https://dokumentation.websale.de/frontend/referenz/module/wsactions
Frontend-Aktionen wie Login, Adresspflege oder Newsletter-Anmeldung über Links oder Formulare auslösen und Erfolgs- und Fehlerergebnisse auswerten.
Mit dem `$wsActions`-Modul können Sie Aktionen im Frontend auslösen, beispielsweise ein Produkt in den Warenkorb legen, ein Formular absenden oder einen Kunden ein- bzw. ausloggen. Anschließend werten Sie das Ergebnis (Erfolg oder Fehler) aus.
Auf dieser Seite geht es um das Auslösen und Auswerten von Aktionen über das `$wsActions`-Modul. Welche Aktionen es gibt und welche Parameter eine einzelne Aktion (z. B. `BasketItemAdd` oder `Login`) erwartet, ist in der [Aktionen-Referenz](/frontend/referenz/aktionen) beschrieben. Dort finden Sie die fachliche Bedeutung der einzelnen Aktionsnamen.
***
## Grundkonzept
Eine Aktion durchläuft immer dieselben Schritte: Aktion vorbereiten → einbinden → auslösen → Ergebnis lesen → reagieren.
Sie bereiten die Aktion im Template vor, entweder als Link mit der Funktion `url()` oder als Formularobjekt mit der Funktion `create()`. Der Kunde löst die Aktion dann durch Klicken oder Absenden aus. Der Shop führt sie aus und baut die Zielseite neu auf. Auf dieser neuen Seite finden Sie das Ergebnis unter `$wsActions.current` und können entsprechend reagieren, beispielsweise mit einer Erfolgsmeldung oder der Anzeige von Fehlern.
**Wege, eine Aktion auszulösen**\
Für einen einfachen Klick, beispielsweise auf den Button „In den Warenkorb“, erzeugen Sie mit der Funktion `url()` einen Link. Wenn der Kunde etwas eingeben soll (z. B. ein Login mit Benutzername und Passwort), erzeugen Sie mit `create()` ein Aktions-Objekt und betten es in ein Formular ein. Der Unterschied liegt also darin, ob der Kunde noch Daten eingibt oder nicht.
**Zeitpunkt der Ausführung:** Der Template-Code läuft beim Seitenaufbau. `$wsActions.current` enthält daher das Ergebnis der Aktion, die in der Anfrage ausgeführt wurde, mit der diese Seite erzeugt wurde. Wurde keine Aktion ausgeführt, ist `current` `null` – prüfen Sie deshalb immer zuerst auf Vorhandensein, bevor Sie auf Ergebnisse zugreifen.
### CSRF-Schutz (gilt für alle Aktionen)
Jede Aktion muss ein gültiges [CSRF-Schutz-Token](/frontend/referenz/aktionen#3-2-aktionen-absichern) mitschicken, sonst lehnt der Shop die Anfrage ab. Das schützt davor, dass Aktionen von fremden Seiten heraus ungewollt ausgelöst werden.
Wenn Sie Aktionen über `url()` oder `create()` erzeugen, wird das Token automatisch eingebettet. Nur wenn Sie eine Anfrage von Hand zusammenbauen, müssen Sie das Token aus [`$wsActions.csrfToken`](#wsactions-csrftoken) selbst als Parameter `wscsrf` mitgeben.
### Verfügbarkeit von `current`
`$wsActions.current` ist nur gefüllt, wenn in derselben Anfrage eine Aktion ausgeführt wurde. Auf einer normal aufgerufenen Seite ist der Wert `null`. Deshalb beginnen die Ergebnisbeispiele unten mit einer Prüfung: `{{ if $wsActions.current }}`. Ohne diese Prüfung würden Sie auf null zugreifen.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsActions`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsActions | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"create": "ƒ()",
"csrfToken": "...",
"current": {
"csrf": "...",
"error": false,
"errors": [
{
"code": "...",
"field": "...",
"subCode": "...",
"text": "..."
}
],
"errorsByField": { },
"globalErrors": [],
"id": "...",
"name": "...",
"params": { },
"success": true,
"successInfo": { },
"tag": "..."
},
"url": "ƒ()"
}
```
Anmerkung: `"ƒ()"` kennzeichnet eine Funktion (Methode). `current` ist `null`, wenn keine Aktion ausgeführt wurde.
**Variablen und Methoden in der Übersicht**
| **Name** | **Rückgabe-Typ** | **Beschreibung** |
| ----------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| `csrfToken` | string | CSRF-Schutz-Token der aktuellen Sitzung; als Parameter `wscsrf` mitzusenden. |
| `current` | map | Ergebnis der gerade ausgeführten Aktion (Erfolg, Fehler, Meldungen). `null`, wenn keine Aktion lief. |
| `create()` | map | Erzeugt ein Aktions-Objekt zur Verwendung in Formularen. |
| `url()` | string | Erzeugt eine URL, die eine bestimmte Aktion ausführt (für Links). |
***
## Variablen
### \$wsActions.csrfToken
Enthält das [CSRF-Schutz-Token](/frontend/referenz/aktionen#3-2-aktionen-absichern) der aktuellen Sitzung. Sie benötigen es nur, wenn Sie eine Aktionsanfrage manuell zusammenstellen. In diesem Fall muss es als Parameter „`wscsrf`“ mitgesendet werden, damit der Shop die Anfrage akzeptiert. Bei `url()` und `create()` geschieht das automatisch.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
### \$wsActions.current
Enthält das Ergebnis der im aktuellen Aufruf ausgeführten Aktion, also Erfolg oder Fehler samt Meldungen. Der Wert ist `null`, wenn keine Aktion ausgeführt wurde.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current }}
{{ /if }}
```
#### Eigenschaften von `$wsActions.current`
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| --------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------- |
| `name` | string | Name der ausgeführten Aktion (z. B. `"BasketItemAdd"`). |
| `id` | string | Eindeutige ID der Aktion. Format: `:`, falls ein Tag vergeben wurde, sonst ``. |
| `csrf` | string | CSRF-Token der ausgeführten Aktion. |
| `tag` | string | Vergebenes Tag der Aktion, falls vorhanden. |
| `params` | map | Bereits übergebene Parameter-Werte der Aktion. |
| `success` | bool | Ob die Aktion erfolgreich war. |
| `successInfo` | map | Zusätzliche Informationen vom Shop bei Erfolg. |
| `error` | bool | Ob ein Fehler aufgetreten ist. |
| `errors` | list | Liste aller aufgetretenen Fehler (Struktur siehe unten). |
| `errorsByField` | map | Fehler, einem Feld zugeordnet (Schlüssel = Feldname). |
| `globalErrors` | list | Fehler, die keinem Feld zuzuordnen sind. |
Das Tag (`current.tag`) wird derzeit nicht ausgewertet. Sie können es über `create()` vergeben, um mehrere gleichartige Aktionen auf einer Seite auseinanderzuhalten.
#### Eigenschaften eines Fehlers (`current.errors[]`)
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| --------------- | ---------------- | --------------------------------------------------------------------- |
| `code` | string | Fehler-Code. |
| `subCode` | string | Optionaler Code zur genaueren Spezifikation von `code`. |
| `field` | string | Feld, bei dem der Fehler aufgetreten ist (leer bei globalen Fehlern). |
| `text` | string | Fehlertext aus der Konfiguration. |
**Name der Aktion auswerten**
Prüfen Sie vor der Verarbeitung des Ergebnisses, welche Aktion ausgeführt wurde. So reagieren Sie nicht versehentlich auf eine andere Aktion.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current and $wsActions.current.name == "Login" }}
{{ /if }}
```
**Erfolg auswerten**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.success }}
{{ /if }}
```
**Fehler je Feld anzeigen**
`errorsByField` ordnet Fehler einem Eingabefeld zu. Nutzen Sie das, um eine Fehlermeldung direkt neben dem betroffenen Feld auszugeben, statt nur eine allgemeine Meldung.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsActions.current.errorsByField.zip }}
{{ /if }}
```
**Alle Fehler auflisten**
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $error in $wsActions.current.errors }}
{{= $error.text }}
{{ /foreach }}
```
***
## Methoden
### \$wsActions.create()
Erzeugt ein Aktions-Objekt zur Verwendung in Formularen. Verwenden Sie `create()`, wenn der Kunde vor dem Auslösen noch Daten eingibt (z. B. Login-Daten). Das Objekt liefert die Werte (u. a. `id` und `csrf`), die Sie als versteckte Formularfelder einbinden können. Das Objekt hat dieselben Eigenschaften wie `$wsActions.current`.
**Signatur**\
`$wsActions.create(actionName, paramDefaults, target, tag)`
**Rückgabe**\
`map` – das Aktions-Objekt.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| --------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------ |
| `actionName` | string | ja | Name der auszuführenden Aktion (z. B. `"BasketItemAdd"`). |
| `paramDefaults` | map | nein | Vorbelegte Parameter, die beim Ausführen noch geändert werden können (z. B. eine Default-Menge). |
| `target` | string | nein | Zielseite nach erfolgreicher Ausführung. |
| `tag` | string | nein | Frei wählbare Bezeichnung, um mehrere Aktionen zu unterscheiden. |
**Beispiel**, das eine Warenkorb-Aktion erzeugt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $action = $wsActions.create("BasketItemAdd", { productId: "12345", quantity: 1 }) }}
ID: {{= $action.id }}
CSRF: {{= $action.csrf }}
```
### \$wsActions.url()
Erzeugt eine URL, die eine bestimmte Aktion ausführt. Verwenden Sie `url()` für einen Link, bei dem der Kunde keine weiteren Daten eingibt (z. B. „In den Warenkorb“ oder „Abmelden“).
**Signatur**\
`$wsActions.url(action, target, params)`
**Rückgabe**\
`string` – die URL, die die Aktion ausführt.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| -------- | ------- | ----------- | ----------------------------------------- |
| `action` | string | ja | Name der auszuführenden Aktion. |
| `target` | string | ja | Zielseite nach erfolgreicher Ausführung. |
| `params` | map | ja | Parameter der Aktion (z. B. `productId`). |
**Beispiel**, das einen Link zum Hinzufügen in den Warenkorb erzeugt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
In den Warenkorb
```
Die Funktion `$wsViews.current.url()` stammt aus dem Modul [\$wsViews](/frontend/referenz/module/wsviews) und liefert die aktuelle Seite als Ziel. Dadurch bleibt der Kunde nach dem Hinzufügen auf derselben Seite.
***
## Beispiele
### Produkt in den Warenkorb legen und Ergebnis auswerten
Dieses Beispiel zeigt den vollständigen Ablauf: Der Link löst die Aktion aus, nach dem Klick wird die Seite neu aufgebaut, und `current` wird ausgewertet.
`productId` ist ein Platzhalter und muss durch die ID eines existierenden Produkts ersetzt werden. Eine nicht existierende Produkt-ID führt nicht zu einem auswertbaren `current.error`, sondern kann die Anfrage serverseitig scheitern lassen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
In den Warenkorb
{{ if $wsActions.current and $wsActions.current.name == "BasketItemAdd" }}
{{ if $wsActions.current.success }}
Produkt wurde in den Warenkorb gelegt.
{{ else }}
{{ foreach $error in $wsActions.current.errors }}
{{= $error.text }}
{{ /foreach }}
{{ /if }}
{{ /if }}
```
**Ergebnis** \
Der Kunde bleibt nach dem Klick auf der Seite und sieht entweder eine Bestätigung oder die konkreten Fehlermeldungen der Aktion.
### Login-Formular mit Feldfehlern
Hier gibt der Kunde Daten ein, daher wird die Aktion mit `create()` vorbereitet und in ein Formular eingebettet. Nach dem Absenden werden Fehler direkt am betroffenen Feld angezeigt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $login = $wsActions.create("Login", { }, $wsViews.current.url()) }}
```
**Ergebnis** \
Stimmen die Daten nicht, erscheint die Fehlermeldung direkt unter dem betroffenen Feld.
***
## Weiterführende Links
* [Aktionen (Konzept und Referenz)](/frontend/referenz/aktionen) – was Aktionen sind, wie sie abgesichert werden und welche Aktionsnamen mit welchen Parametern es gibt. Diese Seite zeigt nur den Zugriff über `$wsActions`.
* [\$wsViews](/frontend/referenz/module/wsviews) – liefert mit `current.url()` und `viewUrl()` die Zielseiten, die `url()` und `create()` als `target` erwarten.
# $wsAsse - Asynchrone HTTP-Events (ASSE)
Source: https://dokumentation.websale.de/frontend/referenz/module/wsasse
Vorkonfigurierte Server-Side-Events auslösen, die im Hintergrund HTTP-Requests an externe URLs senden – z.B. Tracking, Webhooks oder Drittsysteme.
Mit dem `$wsAsse`-Modul lösen Sie aus einem Template heraus [**ASSE-Events**](/glossar#asse) (Asynchronous Server-Side Events) aus. Ein Event sendet im Hintergrund einen HTTP-Request an eine in der Konfiguration hinterlegte externe URL um Daten an einen externen Dienst zu übermitteln (z. B. Tracking nach einer Bestellung).
Auf dieser Seite geht es um das Auslösen vorkonfigurierter Events aus dem Template. Wie ein Event eingerichtet wird (Ziel-URL, HTTP-Methode, Wiederholungen, Erfolgsbedingungen), ist in der [ASSE-Konfiguration](/konfiguration/general-allgemeine-shopeinstellungen#4-general-asse-schnittstelle-für-asynchronous-server-side-events-asse) beschrieben.
***
## Voraussetzung
Bevor `$wsAsse` im Template etwas bewirkt, muss mindestens ein Event in der Konfiguration angelegt sein. Ohne ein konfiguriertes Event gibt es keine Event-ID, die Sie auslösen könnten, und [`fire()`](#wsasse-fire) liefert `false`.
Die [Konfiguration](/konfiguration/general-allgemeine-shopeinstellungen#4-general-asse-schnittstelle-für-asynchronous-server-side-events-asse) legt fest, welche URL aufgerufen wird, welche HTTP-Methode verwendet wird, wie oft bei Fehlern wiederholt wird und unter welchen Bedingungen ein Request als erfolgreich gilt.
***
## Grundkonzept
Ein ASSE-Event durchläuft immer denselben Ablauf: Event konfigurieren → im Template auslösen → Request läuft asynchron im Hintergrund.
Sie richten ein Event einmalig in der Konfiguration ein und vergeben ihm eine ID. Im Template lösen Sie es dann über [`fire()`](#wsasse-fire) unter dieser ID aus und geben optional Daten mit. Der Shop verschickt den HTTP-Request daraufhin selbstständig im Hintergrund.
### Asynchron: Rückgabe ist nicht gleich Erfolg
`fire()` gibt true zurück, sobald das Event gültig konfiguriert wurde und der Request eingereiht wurde. Dies bedeutet jedoch nicht, dass der externe Server den Request erfolgreich verarbeitet hat. Da ASSE die Requests asynchron versendet, erfolgt die tatsächliche Ausführung zeitversetzt. Verlassen Sie sich deshalb nicht auf den Rückgabewert, um den Erfolg der externen Verarbeitung zu prüfen.
### Auslösung beim Seitenaufbau
`fire()` wird ausgeführt, wenn das Template gerendert wird, also bei jedem Aufruf der entsprechenden Seite. Platzieren Sie den Aufruf daher nur auf der entsprechenden Seite (z. B. die Bestellbestätigung) und bedenken Sie: Wenn der Kunde die Seite neu lädt, wird das Event erneut ausgelöst. Stellen Sie bei zählrelevanten Events (z. B. Tracking) sicher, dass ein erneutes Auslösen keine Probleme verursacht.
### Daten übergeben
Den optionalen zweiten Parameter `data` hängt ASSE je nach HTTP-Methode an die URL an oder sendet ihn im Request-Body. Zwei Punkte sind dabei wichtig, damit die Daten korrekt ankommen:
* Der Wert wird nicht automatisch URL-kodiert. Enthält er Sonderzeichen, kodieren Sie ihn selbst.
* Übergeben Sie eine Liste oder ein Objekt, wird der Wert automatisch in ein JSON-Objekt umgewandelt.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsAsse`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsAsse | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"asseConfigs": [...],
"fire": "ƒ()"
}
```
Anmerkung: `"ƒ()"` kennzeichnet eine Funktion (Methode).
**Variablen und Methoden in der Übersicht**
| **Name** | **Rückgabe-Typ** | **Beschreibung** |
| ------------- | ---------------- | ---------------------------------------------------------- |
| `asseConfigs` | array | Liste aller konfigurierten Events mit ihren Einstellungen. |
| `fire()` | bool | Löst ein vorkonfiguriertes Event aus. |
***
## Variablen
### \$wsAsse.asseConfigs
Gibt eine Liste aller konfigurierten Events mit ihren Einstellungen zurück. Nutzen Sie sie, um zu prüfen, welche Events (und damit welche Event-IDs) verfügbar sind, bevor Sie eines auslösen. Ist die Liste leer (`[]`), ist kein Event konfiguriert. Die Events werden in der [Konfiguration](/konfiguration/general-allgemeine-shopeinstellungen#4-general-asse-schnittstelle-für-asynchronous-server-side-events-asse) angelegt.
Jeder Eintrag enthält zusätzlich das Feld `nodeId`, die ID des Konfigurationsknotens, nutzbar als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen) (siehe [Optionen](/frontend/referenz/optionen)).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsAsse.asseConfigs | json }}
```
***
## Methoden
### \$wsAsse.fire()
Löst ein vorkonfiguriertes Event aus. Dabei wird im Hintergrund ein HTTP-Request an die in der Konfiguration hinterlegte URL gesendet. Über den zweiten Parameter können Sie optional Daten für den aktuellen Vorgang übergeben. Je nach HTTP-Methode werden diese an die URL angehängt oder im Request-Body gesendet.
**Signatur**\
`$wsAsse.fire(eventId, data)`
**Rückgabe**\
`bool` - `true`, wenn das Event gültig konfiguriert ist und ausgelöst wurde, `false` bei einem Konfigurationsproblem, etwa wenn die `eventId` keinem konfigurierten Event entspricht. Beachten Sie das [asynchrone Verhalten](#asynchron-rückgabe-ist-nicht-gleich-erfolg): `true` sagt nichts über den Erfolg des externen Requests aus.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| --------- | ------- | ----------- | --------------------------------------------------------------------------------------------------- |
| `eventId` | string | ja | ID des auszulösenden Events. Muss einer gültigen ID aus der Konfiguration entsprechen. |
| `data` | string | nein | Zusätzliche Daten, die mit dem Request gesendet werden (siehe [Daten übergeben](#daten-übergeben)). |
**Beispiel**, das ein vorkonfiguriertes Event `myevent` mit der Nutzer-ID auslöst:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $eventData = "userid=" + $wsAccount.id }}
{{ $wsAsse.fire('myevent', $eventData) }}
```
\$wsAccount.id stammt aus dem Modul [\$wsAccount](/frontend/referenz/module/wsAccount) und liefert die ID des eingeloggten Kunden.
***
## Beispiele
### Awin-Tracking auf der Bestellbestätigungsseite auslösen
Ein häufiger Anwendungsfall ist das Senden von Tracking-Daten an einen externen Dienstleister nach einer erfolgreichen Bestellung. Dieses Beispiel baut die Bestelldaten (Bestellnummer, Warenwert, Währung) aus [\$wsCheckout](/frontend/referenz/module/wscheckout) zu einer Parameter-Zeichenkette zusammen und löst damit das Event `awintracking` aus.
Da dieser Aufruf bei jedem Seitenaufbau feuert (siehe [Auslösung beim Seitenaufbau](#auslösung-beim-seitenaufbau)), gehört er ausschließlich auf die Bestellbestätigungsseite.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $eventData = "&merchant=12345" }}
{{ var $eventData = $eventData + "&amount=" + $wsCheckout.sum.totalNet }}
{{ var $eventData = $eventData + "&ch=aw" }}
{{ var $eventData = $eventData + "&parts=DEFAULT:" + $wsCheckout.sum.totalNet }}
{{ var $eventData = $eventData + "&cr=" + $wsCheckout.sum.currency }}
{{ var $eventData = $eventData + "&ref=" + $wsCheckout.orderId }}
{{ var $eventData = $eventData + "&testmode=0" }}
{{ if $wsVoucher.vouchers[0] }}
{{ var $eventData = $eventData + "&vc=" + $wsVoucher.vouchers[0].id }}
{{ /if }}
{{ $wsAsse.fire('awintracking', $eventData) }}
```
In der Konfiguration muss dafür ein Event mit der ID `awintracking` angelegt sein, das auf die Awin-Tracking-URL verweist. `merchant=12345` ist ein Platzhalter und durch Ihre Awin-Merchant-ID zu ersetzen.
**Ergebnis** Nach Aufbau der Bestellbestätigungsseite wird der Tracking-Request im Hintergrund an Awin gesendet.
***
## Weiterführende Links
* [ASSE-Konfiguration](/konfiguration/general-allgemeine-shopeinstellungen#4-general-asse-schnittstelle-für-asynchronous-server-side-events-asse) – legt Ziel-URL, HTTP-Methode, Wiederholungen und Erfolgsbedingungen eines Events fest. Voraussetzung, damit `fire()` etwas bewirkt.
* [\$wsCheckout](/frontend/referenz/module/wscheckout) – liefert die Bestelldaten, die im Tracking-Beispiel übergeben werden.
* [\$wsAccount](/frontend/referenz/module/wsAccount) – liefert die im einfachen Beispiel verwendete Nutzer-ID.
# $wsBasket - Warenkorb
Source: https://dokumentation.websale.de/frontend/referenz/module/wsbasket
Warenkorbdaten im Frontend lesen: Positionen, Mengen, Beträge, Rabatte, Steuerinformationen und Werbemittelkennzeichen für Mini-Cart, Übersicht und Checkout.
Mit dem `$wsBasket`-Modul lesen Sie die Daten des aktuellen Warenkorbs im Frontend. Die enthaltenen Produkte (Positionen), deren Mengen und Preise sowie die berechneten Gesamtwerte und Steuerinformationen.
Auf dieser Seite geht es um das Lesen der Warenkorb-Daten. Alles, was den Warenkorb verändert (Produkt hinzufügen, Menge ändern, entfernen), ist unter [Aktionen → Basket](/frontend/referenz/aktionen/basket) beschrieben, weil dort die auslösenden Aktionen und ihre Parameter dokumentiert sind.
***
## Grundkonzept
Der Warenkorb speichert die vom Kunden ausgewählten Produkte und berechnet automatisch die Mengen, Preise und Steuern. Über dieses Modul können Sie diese Werte auslesen und anzeigen.
### Aufbau
Die Warenkorb-Daten sind in drei Ebenen verschachtelt:
* **Warenkorb** (`$wsBasket`) - die Gesamtwerte über alle Positionen hinweg, z. B. `total` oder [`totalQuantity`](#wsbasket-totalquantity).
* **Positionen** (`$wsBasket.items`) - eine Liste der Warenkorb-Einträge. Jeder Eintrag steht für ein Produkt im Warenkorb und hat eigene Werte wie Menge und Positionssumme.
* **Produkt** (`item.product`) - innerhalb jeder Position befindet sich auch das zugehörige Produkt mit seinen Stammdaten (Name, Bild, ID).
Sie lesen also Summen vom Warenkorb, positionsbezogene Werte von der jeweiligen Position und Produktdetails vom Produkt der Position.
### Steuerbefreiung
Mehrere Variablen bilden zusammen die Steuerbefreiung ab und gehören inhaltlich zusammen: [`isTaxExempt`](#wsbasket-istaxexempt) ist der primäre Schalter, [`totalTaxDeduction`](#wsbasket-totaltaxdeduction) und [`totalPreDeduction`](#wsbasket-totalprededuction) liefern die Beträge für eine „abzgl. MwSt."-Zeile, und [`usedExemptionRule`](#wsbasket-usedexemptionrule) zusammen mit [`billingCountry`](#wsbasket-billingcountry)/[`shippingCountry`](#wsbasket-shippingcountry) zeigt, welche Adressen für die Prüfung herangezogen werden. Prüfen Sie für Steuerhinweise immer zuerst `isTaxExempt`.
### Werbemittelkennzeichen
Ist die [Werbemittelkennzeichnung](/frontend/funktionsubersicht/werbemittelkennzeichnung) im Shop aktiviert, trägt jede Position zusätzlich das erfasste Werbemittelkennzeichen. Dafür gibt es zwei Felder: [`insert`](#wsbasket-items) liefert den reinen Code, [`itemNumberWithInsert`](#wsbasket-items) die fertig zusammengesetzte Anzeige aus Produktnummer und Code in der konfigurierten Reihenfolge und mit dem konfigurierten Trennzeichen. Ist kein Code gesetzt, enthält `itemNumberWithInsert` einfach die reine Produktnummer.
In der Regel reicht es, `itemNumberWithInsert` als Artikelnummer auszugeben - Position und Trennzeichen sind darin bereits berücksichtigt. Zusätzliche Ausgaben rund um das Werbemittelkennzeichen (beispielsweise ein separates Code-Label) gehören in `{{ if $wsConfig.inserts.enabled }} … {{ /if }}`, damit bei ausgeschalteter Funktion nichts erscheint. Die Einstellungen liefert [\$wsConfig.inserts](/frontend/referenz/module/wsconfig#wsconfig-inserts).
### Zeitpunkt und zuletzt geänderter Artikel
Der Template-Code läuft beim Seitenaufbau. `$wsBasket` enthält daher den Warenkorb-Zustand nach der zuletzt ausgeführten Aktion. [`lastBasketAction`](#wsbasket-lastbasketaction) und `lastUpdatedItem` beschreiben diese letzte Änderung. Nützlich, um beispielsweise direkt nach dem Hinzufügen eine Rückmeldung wie „Produkt X wurde hinzugefügt" anzuzeigen.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsBasket`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsBasket | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"billingCountry": "...",
"isTaxExempt": true,
"items": [
{
"discountPrice": 0.0,
"freeFields": { },
"id": "...",
"insert": "...",
"itemNumberWithInsert": "...",
"oneTimeFee": 0.0,
"orgPrice": 0.0,
"price": 0.0,
"product": { },
"quantity": 0.0,
"total": 0.0,
"totalGross": 0.0,
"totalNet": 0.0,
"totalTax": 0.0,
"voucherIds": [...]
}
],
"lastBasketAction": "...",
"lastUpdatedItem": {
"categories": [...],
"freeFields": { },
"id": "...",
"parentCategories": [...],
"price": 0.0,
"productNumber": "...",
"quantity": 0.0,
"taxId": "...",
"voucherIds": [...]
},
"shippingCountry": "...",
"total": 0.0,
"totalCommission": 0.0,
"totalGross": 0.0,
"totalNet": 0.0,
"totalQuantity": 0.0,
"totalTax": 0.0,
"totalTaxDeduction": 0.0,
"totalPreDeduction": 0.0,
"totalWeight": 0.0,
"usedExemptionRule": "..."
}
```
**Variablen des Warenkorbs (oberste Ebene)**
| **Variable** | **Rückgabe-Typ** | **Beschreibung** |
| ------------------- | ---------------- | ---------------------------------------------------------------------- |
| `totalQuantity` | float | Gesamtmenge aller Produkte im Warenkorb. |
| `total` | float | Gesamtbetrag des Warenkorbs. |
| `totalNet` | float | Nettobetrag des Warenkorbs. |
| `totalGross` | float | Bruttobetrag des Warenkorbs. |
| `totalTax` | float | Mehrwertsteuer des Warenkorbs. |
| `totalCommission` | float | Gesamt-Provision. |
| `totalWeight` | float | Gesamtgewicht aller Produkte im Warenkorb. |
| `lastBasketAction` | string | Letzte Aktion am Warenkorb (z. B. `"add"`, `"remove"`, `"update"`). |
| `lastUpdatedItem` | map | Zuletzt geänderter Artikel (Struktur siehe unten). |
| `items` | array | Liste aller Warenkorb-Einträge (Struktur siehe unten). |
| `isTaxExempt` | bool | Ob der aktuelle Warenkorb steuerbefreit ist. |
| `totalTaxDeduction` | float | Betrag der abgezogenen Steuer; nur > 0 bei aktiver Steuerbefreiung. |
| `totalPreDeduction` | float | Gesamtbetrag vor dem Steuerabzug. |
| `billingCountry` | string | Länderkennung der Rechnungsadresse (z. B. `"DE"`). |
| `shippingCountry` | string | Länderkennung der Lieferadresse (z. B. `"DE"`). |
| `usedExemptionRule` | string | Aktive Steuerprüfregel (`"shippingOnly"` oder `"shippingAndBilling"`). |
***
## Templates
Die Warenkorb-Daten lassen sich auf jeder Seite des Shops anzeigen. Übliche Darstellungen sind:
* **Offcanvas-Warenkorb:** in einer Sidebar, als Flyout oder als OffCanvas-Element, für einen schnellen Überblick.
* **Warenkorb-Seite:** eine detaillierte Übersicht mit Anpassungsmöglichkeiten.
* **Checkout und Bestellbestätigung:** Darstellung während des Kaufprozesses und in Bestätigungs-E-Mails.
***
## Variablen
### \$wsBasket.totalQuantity
Gibt die Gesamtmenge aller Produkte im Warenkorb aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Artikel im Warenkorb: {{= $wsBasket.totalQuantity }}
```
### \$wsBasket.total
Gibt den Gesamtbetrag des Warenkorbs aus. Verwenden Sie ihn für die Endsumme in Warenkorb und Checkout.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Gesamtbetrag: {{= $wsBasket.total | currency }}
```
### \$wsBasket.totalNet
Gibt den Nettobetrag des Warenkorbs aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Nettobetrag: {{= $wsBasket.totalNet | currency }}
```
### \$wsBasket.totalGross
Gibt den Bruttobetrag des Warenkorbs aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Bruttobetrag: {{= $wsBasket.totalGross | currency }}
```
### \$wsBasket.totalTax
Gibt die Mehrwertsteuer des Warenkorbs aus. Nutzen Sie sie für eine separate Steuerzeile in der Summenübersicht.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Mehrwertsteuer: {{= $wsBasket.totalTax | currency }}
```
### \$wsBasket.totalCommission
Gibt die Gesamt-Provision des Warenkorbs aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Provision: {{= $wsBasket.totalCommission | currency }}
```
### \$wsBasket.totalWeight
Gibt das Gesamtgewicht aller Produkte im Warenkorb aus. Nützlich, um z. B. einen Versandkosten- oder Gewichtshinweis anzuzeigen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Gesamtgewicht: {{= $wsBasket.totalWeight }}
```
### \$wsBasket.lastBasketAction
Gibt die zuletzt am Warenkorb durchgeführte Aktion aus (z. B. `"add"`, `"remove"`, `"update"`). Werten Sie sie aus, um nach einer Änderung eine passende Rückmeldung anzuzeigen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Letzte Aktion: {{= $wsBasket.lastBasketAction }}
```
### \$wsBasket.lastUpdatedItem
Gibt den zuletzt hinzugefügten oder geänderten Artikel aus. Verwenden Sie ihn zusammen mit `lastBasketAction`, um z. B. direkt nach dem Hinzufügen „Produkt X wurde hinzugefügt" anzuzeigen, ohne den ganzen Warenkorb durchsuchen zu müssen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Zuletzt geändert: {{= $wsBasket.lastUpdatedItem.id }}
Menge: {{= int($wsBasket.lastUpdatedItem.quantity) }}
```
#### Eigenschaften von `$wsBasket.lastUpdatedItem`
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| ------------------ | ---------------- | -------------------------------------------------- |
| `id` | string | Produkt-ID des Artikels. |
| `productNumber` | string | Artikelnummer des Artikels. |
| `price` | float | Preis des Artikels. |
| `quantity` | float | Menge des Artikels. |
| `taxId` | string | Steuersatz-ID des Artikels. |
| `categories` | array | Kategorie-IDs, in denen sich der Artikel befindet. |
| `parentCategories` | array | Übergeordnete Kategorie-IDs des Artikels. |
| `freeFields` | map | Freie Felder des Artikels. |
| `voucherIds` | array | Angewendete Gutschein-IDs für den Artikel. |
### \$wsBasket.items
Gibt die Liste aller Warenkorb-Einträge (Positionen) aus. Über diese Liste iterieren Sie, um jede Position einzeln anzuzeigen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $item in $wsBasket.items }}
Artikel: {{= $item.product.name }} – Menge: {{= int($item.quantity) }}
{{ /foreach }}
```
#### Eigenschaften eines Eintrags in `$wsBasket.items`
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| ---------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | string | Warenkorb-ID des Eintrags. |
| `product` | map | Das zugehörige Produkt des Eintrags (Stammdaten wie Name, Bild, ID). |
| `insert` | string | Das [Werbemittelkennzeichen](/frontend/funktionsubersicht/werbemittelkennzeichnung) des Eintrags. Leer, wenn kein Code gesetzt ist. |
| `itemNumberWithInsert` | string | Fertig zusammengesetzte Anzeige aus Produktnummer und Werbemittelkennzeichen in der konfigurierten Reihenfolge mit Trennzeichen. Ist kein Code gesetzt, enthält das Feld die reine Produktnummer. |
| `quantity` | float | Menge des Eintrags. |
| `price` | float | Einzelpreis des Eintrags. |
| `orgPrice` | float | Ursprünglicher Preis vor Rabatten. |
| `discountPrice` | float | Rabattierter Preis (falls ein Rabatt aktiv ist). |
| `oneTimeFee` | float | Einmalige Gebühr (z. B. Einrichtungskosten). |
| `total` | float | Gesamtbetrag des Eintrags (Positionssumme). |
| `totalNet` | float | Nettobetrag des Eintrags. |
| `totalGross` | float | Bruttobetrag des Eintrags. |
| `totalTax` | float | Mehrwertsteuer des Eintrags. |
| `freeFields` | map | Freie Felder (z. B. Beschriftungen, Kommentare). |
| `voucherIds` | array | Angewendete Gutschein-IDs für diesen Eintrag. |
### \$wsBasket.isTaxExempt
Gibt aus, ob der aktuelle Warenkorb steuerbefreit ist. Dies ist der primäre Indikator für eine Steuerbefreiung – nutzen Sie ihn, um z. B. einen Hinweis „Steuerbefreite Lieferung" einzublenden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsBasket.isTaxExempt }}
Dieser Warenkorb ist steuerbefreit.
{{ /if }}
```
### \$wsBasket.totalTaxDeduction
Gibt den Betrag der abgezogenen Steuer aus. Der Wert ist nur größer als 0, wenn eine Steuerbefreiung aktiv ist. In Brutto-Shops stellen Sie damit z. B. eine Zeile „abzgl. MwSt." dar.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsBasket.totalTaxDeduction > 0 }}
Steuerabzug: {{= $wsBasket.totalTaxDeduction | currency }}
{{ /if }}
```
### \$wsBasket.totalPreDeduction
Gibt den Gesamtbetrag vor dem Steuerabzug aus. Zusammen mit `totalTaxDeduction` zeigen Sie so den Betrag vor und nach dem Abzug.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Betrag vor Steuerabzug: {{= $wsBasket.totalPreDeduction | currency }}
```
### \$wsBasket.billingCountry
Gibt die Länderkennung der Rechnungsadresse aus (z. B. `"DE"` für Deutschland).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Rechnungsland: {{= $wsBasket.billingCountry }}
```
### \$wsBasket.shippingCountry
Gibt die Länderkennung der Lieferadresse aus (z. B. `"DE"` für Deutschland).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Lieferland: {{= $wsBasket.shippingCountry }}
```
### \$wsBasket.usedExemptionRule
Gibt die aktive Steuerprüfregel aus. Mögliche Werte: `"shippingOnly"` (nur die Lieferadresse wird geprüft) oder `"shippingAndBilling"` (Liefer- und Rechnungsadresse werden geprüft). So erkennen Sie, welche Adressen über die Steuerbefreiung entscheiden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsBasket.usedExemptionRule }}
Aktive Prüfregel: {{= $wsBasket.usedExemptionRule }}
{{ /if }}
```
***
## Methoden
Für `$wsBasket` stehen keine Methoden zur Verfügung.
***
## Aktionen
Aktionen, die den Warenkorb verändern (Produkt hinzufügen, Menge ändern, entfernen), sind separat dokumentiert: [Aktionen → Basket](/frontend/referenz/aktionen/basket).
***
## Beispiele für den Datenzugriff
### Prüfen, ob Produkte im Warenkorb liegen
Prüfen Sie zuerst, ob überhaupt Positionen vorhanden sind, bevor Sie den Warenkorb anzeigen, sonst zeigen Sie eine leere Liste.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsBasket.items }}
Im Warenkorb befinden sich {{= $wsBasket.items | len }} Positionen.
{{ else }}
Sie haben noch keine Produkte im Warenkorb.
{{ /if }}
```
**Ergebnis**
Bei gefülltem Warenkorb erscheint die Anzahl der Positionen, sonst ein Hinweis auf den leeren Warenkorb.
### Produkte im Warenkorb anzeigen
Sind Positionen vorhanden, iterieren Sie über `items` und zeigen je Position Produktname, Menge und Preise. Die Gesamtsummen stehen außerhalb der Schleife weil sie sonst für jede Position erneut ausgegeben werden würden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsBasket.items }}
{{ foreach $item in $wsBasket.items }}
Produktname: {{= $item.product.name }}
Art.-Nr.: {{= $item.itemNumberWithInsert }}
Menge: {{= int($item.quantity) }}
Einzelpreis: {{= $item.price | currency }}
Positionssumme: {{= $item.total | currency }}
{{ /foreach }}
Versandkosten: {{= $wsCheckout.sum.shippingCost | currency }}
Gesamtsumme: {{= $wsBasket.total | currency }}
{{ else }}
Sie haben keine Produkte im Warenkorb!
{{ /if }}
```
**Ergebnis**
Jede Position wird mit Bild, Name, Artikelnummer (inklusive Werbemittelkennzeichen, sofern erfasst), Menge und Preisen aufgelistet. Darunter erscheinen Versandkosten und Gesamtsumme einmalig.
### Werbemittelkennzeichen separat ausgeben
Soll der reine Code zusätzlich zur Artikelnummer als eigenes Feld erscheinen, prüfen Sie zuerst über [`$wsConfig.inserts.enabled`](/frontend/referenz/module/wsconfig#wsconfig-inserts), ob die Funktion aktiv ist, damit bei ausgeschalteter Funktion nichts erscheint.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConfig.inserts.enabled }}
{{ foreach $item in $wsBasket.items }}
{{ if $item.insert }}
Werbemittelcode: {{= $item.insert }}
{{ /if }}
{{ /foreach }}
{{ /if }}
```
**Ergebnis**
Der Werbemittelcode erscheint nur bei aktiver Funktion und nur für Positionen, die einen Code tragen.
### Link zur Warenkorbseite
Erzeugt einen Link auf die Warenkorbseite, die über das View-Template `basket.htm` umgesetzt ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Warenkorb ansehen
```
**Ergebnis**
Der Link führt zur Warenkorbseite des Shops.
***
## Weiterführende Links
* [Werbemittelkennzeichen](/frontend/funktionsubersicht/werbemittelkennzeichnung) – fachliche Übersicht der Werbemittelkennzeichnung: Erfassungswege, Auflösungslogik und Einrichtung.
* [Aktionen → Basket](/frontend/referenz/aktionen/basket) – den Warenkorb verändern (hinzufügen, ändern, entfernen), weil `$wsBasket` selbst nur liest.
* [\$wsCheckout](/frontend/referenz/module/wscheckout) – liefert ergänzende Werte wie die Versandkosten (`sum.shippingCost`) für die Summenanzeige.
* [\$wsViews](/frontend/referenz/module/wsviews) – erzeugt die in den Beispielen genutzten Produkt- und View-URLs.
* [Praxisbeispiele Warenkorb](/frontend/praxisbeispiele/warenkorb-funktionen) – durchgängige Praxisbeispiele für Warenkorb-Funktionen.
# $wsCategories - Kategorien
Source: https://dokumentation.websale.de/frontend/referenz/module/wscategories
Kategoriedaten im Frontend laden und anzeigen: Eigenschaften, Unterkategorien, Pfade und Produkte für Navigation, Listen und Kategorieseiten.
Mit dem `$wsCategories`-Modul laden Sie Kategoriedaten und zeigen sie im Frontend an - einzelne Kategorien, ihre Unterkategorien, den Kategoriepfad (Breadcrumb) und die enthaltenen Produkte.
Auf dieser Seite geht es um das Laden und Anzeigen von Kategoriedaten. Produktdetails sind in der Produkt-Referenz beschrieben; die Einrichtung der Kategorie-Navigation erfolgt im Admin-Interface (siehe [Template](#template)).
***
## Grundkonzept
`$wsCategories` ist ein Lade-Modul: Es stellt nur Methoden zum Laden von Kategorien bereit und hat selbst keine „aktuelle Kategorie". Ein Aufruf wie `$wsCategories.id` existiert daher nicht.
Sie arbeiten stattdessen immer mit einer Category-Map, also einem Objekt mit den [Eigenschaften einer Kategorie](#eigenschaften-einer-kategorie). Diese Map erhalten Sie auf zwei Wegen:
* **Aus dem aktuellen Seitenkontext** - auf einer Kategorieseite liegt die aktuelle Kategorie unter `$wsViews.current.info.category`:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsViews.current.info.category }}
```
* **Aus einer Lade-Methode** - z. B. eine bestimmte Kategorie über ihre ID oder die Unterkategorien einer Kategorie:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsCategories.loadCategory("100-12345") }}
```
In beiden Fällen weisen Sie die Map einer Variablen zu und greifen anschließend auf deren Eigenschaften zu (z. B. `$category.name`). Der Variablenname ist frei wählbar, auf dieser Seite heißt er durchgängig `$category`.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsCategories`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCategories | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"loadCategory": "ƒ()",
"loadCategoryMembershipPaths": "ƒ()",
"loadCategoryMemberships": "ƒ()",
"loadChildren": "ƒ()",
"loadPath": "ƒ()",
"loadProducts": "ƒ()"
}
```
Anmerkung: `"ƒ()"` kennzeichnet eine Funktion.
**Methoden in der Übersicht**
| **Methode** | **Rückgabe-Typ** | **Beschreibung** |
| ------------------------------- | ---------------- | ------------------------------------------------------------------------- |
| `loadCategory()` | map | Lädt eine einzelne Kategorie anhand ihrer ID. |
| `loadChildren()` | array | Lädt die direkten Unterkategorien einer Kategorie. |
| `loadPath()` | array | Lädt den Kategoriepfad (Breadcrumb) von der Wurzel bis zur Kategorie. |
| `loadProducts()` | array | Lädt die Produkte einer Kategorie. |
| `loadCategoryMemberships()` | array | Lädt alle Kategorien, in denen ein Produkt enthalten ist. |
| `loadCategoryMembershipPaths()` | array | Lädt die vollständigen Kategoriepfade für alle Kategorien eines Produkts. |
Die Eigenschaften, die jede geladene Kategorie bereitstellt, sind unter [Eigenschaften einer Kategorie](#eigenschaften-einer-kategorie) beschrieben.
***
## Template
Im Standard erfolgt die Anzeige von Kategorien über das Template `category.htm` (im Verzeichnisbaum unter `templates/views/category.htm`).
Kategoriedaten lassen sich aber auch flexibel anderswo nutzen, beispielsweise in Blogbeiträgen oder im Warenkorb. Dafür muss das jeweilige Template bereits im Verzeichnis `views` angelegt worden sein.
***
## Eigenschaften einer Kategorie
Die folgenden Eigenschaften stehen in jeder Category-Map zur Verfügung, unabhängig davon, ob Sie sie aus dem Seitenkontext oder mithilfe einer Lade-Methode erhalten haben.
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| ----------------------- | ---------------- | ------------------------------------------------------------------------------------------------------- |
| `id` | string | Eindeutige, vom Shop vergebene ID der Kategorie. |
| `name` | string | Name der Kategorie. |
| `descr` | string | Beschreibung der Kategorie. |
| `active` | string | Sichtbarkeitsstatus: `"always"` (immer sichtbar), `"test"` (nur Testmodus), `"never"` (nicht sichtbar). |
| `hidden` | bool | Ob die Kategorie versteckt ist (z. B. nicht in der Navigation angezeigt wird). |
| `productsCount` | int | Anzahl der Produkte in der Kategorie. |
| `custom` | map | Benutzerdefinierte (freie) Felder der Kategorie, z. B. Bilder oder SEO-Texte. |
| `timestampCreatedAt` | datetime | Erstellungszeitpunkt der Kategorie. |
| `timestampUpdatedAt` | datetime | Zeitpunkt der letzten Änderung. |
| `productAssignmentType` | string | Art der Produktzuordnung, z. B. `"manual"` (manuelle Zuordnung). |
| `productRules` | string | Regeln für die automatische Produktzuordnung; leer bei manueller Zuordnung. |
### name und descr
Name und Beschreibung sind die häufigsten Anzeigewerte. Mehr zur Konfiguration dieser Felder [in der Kategorie-Konfiguration](/konfiguration/content-katalog-kategorien-produkte#2-content-categoryfield-standard-kategoriefelder).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsViews.current.info.category }}
Kategoriename: {{= $category.name }}
Beschreibung: {{= $category.descr }}
```
### active
Werten Sie `active` aus, um nur sichtbare Kategorien anzuzeigen, beispielsweise in einer Navigation.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $category.active == "always" }}
{{ /if }}
```
### hidden
`hidden` blendet eine Kategorie gezielt aus der Navigation aus, ohne sie zu deaktivieren. Prüfen Sie es, bevor Sie einen Navigationseintrag erzeugen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if !$category.hidden }}
{{= $category.name }}
{{ /if }}
```
### custom
`custom` enthält die freien Felder der Kategorie. Anders als beim Produkt liegt das Kategoriebild unter `custom.image.category` (mit der WebP-Variante `custom.image.categoryWebp`); ein separates Navigationsbild liegt unter `custom.imageNavigation.category`. Prüfen Sie vor der Ausgabe, ob das gewünschte Feld vorhanden ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $category.custom.image.category }}
{{ /if }}
```
Neben den Bildern enthält `custom` unter anderem auch SEO-Felder (`metaTitle`, `metaDescription`, `seoName`) und Steuerungsfelder (`robotsNoIndex`, `robotsNoFollow`, `alternativeTemplate`).
### timestampCreatedAt und timestampUpdatedAt
Beide liefern einen Zeitstempel als ISO-8601-String (UTC, z. B. `2026-05-07T13:09:08.000Z`).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Aktualisiert: {{= $category.timestampUpdatedAt }}
```
***
## Methoden
### \$wsCategories.loadCategory()
Lädt eine einzelne Kategorie anhand ihrer ID. Verwenden Sie die Methode, um gezielt eine bestimmte Kategorie anzuzeigen - auch außerhalb einer Kategorieseite, beispielsweise auf der Startseite oder in einem Blogbeitrag.
**Signatur**\
`$wsCategories.loadCategory(categoryId)`
**Rückgabe**\
`map` – Category-Map mit allen [Kategorie-Eigenschaften](#eigenschaften-einer-kategorie).
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------ | ------- | ----------- | ----------------------------- |
| `categoryId` | string | ja | ID der zu ladenden Kategorie. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsCategories.loadCategory("100-12345") }}
{{= $category.name }}
```
### \$wsCategories.loadChildren()
Lädt die direkten Unterkategorien einer Kategorie. Nutzen Sie die Methode, um eine mehrstufige Navigation aufzubauen.
**Signatur**\
`$wsCategories.loadChildren(parentId)`
**Rückgabe**\
`array` – Liste von Category-Maps.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ---------- | ------- | ----------- | -------------------------------- |
| `parentId` | string | nein | ID der übergeordneten Kategorie. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $child in $wsCategories.loadChildren("100-12345") }}
{{= $child.name }}
{{ /foreach }}
```
Ohne Angabe einer `parentId` werden die Kategorien der obersten Ebene zurückgegeben. Das ist nützlich, um die Hauptnavigation aufzubauen, ohne eine Wurzel-ID kennen zu müssen.
### \$wsCategories.loadPath()
Lädt den Kategoriepfad (Breadcrumb) von der Wurzel bis zur angegebenen Kategorie. Verwenden Sie die Methode für eine Breadcrumb-Navigation, die dem Kunden zeigt, wo er sich befindet.
**Signatur**\
`$wsCategories.loadPath(categoryId)`
**Rückgabe**\
`array` – Liste von Category-Maps, von oben (Wurzel) nach unten (Zielkategorie).
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------ | ------- | ----------- | --------------------- |
| `categoryId` | string | ja | ID der Zielkategorie. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $step in $wsCategories.loadPath($category.id) }}
{{= $step.name }} /
{{ /foreach }}
```
### \$wsCategories.loadProducts()
Lädt die Produkte, die in einer Kategorie enthalten sind. Nutzen Sie die Methode, um eine Produktliste außerhalb einer Kategorieseite aufzubauen (auf der Kategorieseite selbst liegen die Produkte bereits unter `$wsViews.current.info.products`).
**Signatur**\
`$wsCategories.loadProducts(categoryId)`
**Rückgabe**\
`array` – Liste von Produkt-Maps.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------ | ------- | ----------- | ------------------------------------------------ |
| `categoryId` | string | ja | ID der Kategorie, deren Produkte geladen werden. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $products = $wsCategories.loadProducts("100-12345") }}
{{ foreach $product in $products }}
{{= $product.name }}
{{ /foreach }}
```
### \$wsCategories.loadCategoryMemberships()
Lädt alle Kategorien, in denen ein bestimmtes Produkt enthalten ist. Nützlich, um auf einer Produktseite anzuzeigen, welchen Kategorien das Produkt zugeordnet ist.
**Signatur**\
`$wsCategories.loadCategoryMemberships(productId)`
**Rückgabe**\
`array` – Liste von Category-Maps.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ----------- | ------- | ----------- | -------------------------------------------------- |
| `productId` | string | ja | ID des Produkts, dessen Kategorien gesucht werden. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $category in $wsCategories.loadCategoryMemberships($product.id) }}
{{= $category.name }}
{{ /foreach }}
```
### \$wsCategories.loadCategoryMembershipPaths()
Lädt die vollständigen Kategoriepfade (Breadcrumbs) für alle Kategorien, in denen ein Produkt enthalten ist. Im Unterschied zu `loadCategoryMemberships()` erhalten Sie nicht nur die Zielkategorien, sondern jeweils den kompletten Pfad. Nützlich, um die vollständige Einordnung eines Produkts darzustellen.
**Signatur**\
`$wsCategories.loadCategoryMembershipPaths(productId)`
**Rückgabe**\
`array` – Liste von Pfaden, jeder Pfad ist selbst eine Liste von Category-Maps.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ----------- | ------- | ----------- | ------------------------------------------------------ |
| `productId` | string | ja | ID des Produkts, dessen Kategoriepfade gesucht werden. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $path in $wsCategories.loadCategoryMembershipPaths($product.id) }}
{{ foreach $step in $path }}
{{= $step.name }} >
{{ /foreach }}
{{ /foreach }}
```
***
## Aktionen
Für `$wsCategories` stehen keine Aktionen zur Verfügung.
***
## Beispiele
Die Beispiele gehen davon aus, dass die anzuzeigende Kategorie zuvor einer Variablen zugewiesen wurde, beispielsweise auf einer Kategorieseite so:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsViews.current.info.category }}
```
### Name und Beschreibung anzeigen
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Kategoriename: {{= $category.name }}
Kategoriebeschreibung: {{= $category.descr }}
```
**Ergebnis** \
Name und Beschreibung der aktuellen Kategorie werden ausgegeben.
### Kategoriebild anzeigen
Prüfen Sie zuerst, ob ein Bild vorhanden ist, damit Sie kein leeres `img`-Tag erzeugen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $category.custom.image.category }}
{{ /if }}
```
**Ergebnis** \
Ist ein Übersichtsbild hinterlegt, wird es mit dem Kategorienamen als Alternativtext angezeigt.
### Unterkategorien anzeigen
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $child in $wsCategories.loadChildren($category.id) }}
{{= $child.name }} – {{= $child.descr }}
{{ /foreach }}
```
**Ergebnis** \
Alle direkten Unterkategorien der aktuellen Kategorie werden aufgelistet.
### Produkte der aktuellen Kategorie anzeigen
Auf einer Kategorieseite liegen die Produkte der Kategorie bereits im Seitenkontext.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $product in $wsViews.current.info.products }}
Produktname: {{= $product.name }}
{{ /foreach }}
```
**Ergebnis** \
Die Produkte der aktuellen Kategorie werden ausgegeben.
### Breadcrumb der aktuellen Kategorie
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $step in $wsCategories.loadPath($category.id) }}
{{= $step.name }} /
{{ /foreach }}
```
**Ergebnis** \
Der Pfad von der obersten Kategorie bis zur aktuellen wird als Folge verlinkter Namen ausgegeben.
### Eine Kategorie auf einer beliebigen Seite laden
Mit `loadCategory()` greifen Sie auch außerhalb einer Kategorieseite auf Kategoriedaten zu , beispielsweise auf der Startseite, in einem Blogbeitrag oder im Warenkorb.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $category = $wsCategories.loadCategory("101-12345") }}
Kategoriename: {{= $category.name }}
Kategoriebeschreibung: {{= $category.descr }}
```
**Ergebnis** \
Die angegebene Kategorie wird geladen und ihre Daten werden ausgegeben.
Die in den Beispielen verwendeten IDs (`100-12345`, `101-12345`) sind Platzhalter und durch echte Kategorie-IDs Ihres Shops zu ersetzen.
***
## Weiterführende Links
* [\$wsViews](/frontend/referenz/module/wsviews) – liefert über `current.info.category` und `current.info.products` die Daten der aktuellen Kategorieseite und mit `url('Category', {id})` die Kategorie-Links.
* [Kategorie-Konfiguration](/konfiguration/content-katalog-kategorien-produkte#2-content-categoryfield-standard-kategoriefelder) – legt die Standard-Kategoriefelder (Name, Beschreibung, freie Felder) fest.
##
##
# $wsCheckout - Checkout
Source: https://dokumentation.websale.de/frontend/referenz/module/wscheckout
Daten des Bestellvorgangs im Frontend lesen: Auswahl der Zahl- und Versandart, Adressen, Summen, Validierung und Fehler des aktuellen Checkouts.
Mit dem `$wsCheckout`-Modul lesen Sie alle Daten des Bestellvorgangs im Frontend aus. Darunter die gewählte Zahlungs- und Versandart, Rechnungs- und Lieferadresse, die Bestellsummen sowie den Validierungs- und Fehlerstatus.
Auf dieser Seite geht es um das Lesen der Checkout-Daten. Alles, was den Checkout **verändert** (Adresse wählen, Zahlungsart setzen, Bestellung auslösen), ist unter [Aktionen → Checkout](/frontend/referenz/aktionen/checkout) beschrieben.
***
## Grundkonzept
Der Checkout sammelt die Auswahl des Kunden (Zahlung, Versand, Adressen, Freifelder) und prüft fortlaufend, ob die Bestellung ausführbar ist. Über `$wsCheckout` lesen Sie diese Auswahl und den Prüfstatus, um den Bestellablauf zu gestalten und dem Kunden gezielt Rückmeldung zu geben.
### Validierung
Für das Prüf-Feedback gibt es drei Ebenen, die unterschiedlich genau sind. Wählen Sie die Ebene nach dem, was Sie anzeigen wollen:
* **Gesamtstatus** - `isValid` gibt an, ob die Bestellung insgesamt ausführbar ist. Nutzen Sie es beispielsweise, um den „Kaufen"-Button freizugeben oder zu sperren.
* **Feldzustand** - `fieldStates` liefert pro Feld einen Zustand (`untouched`, `empty`, `invalid`, `incompatible`, `valid`). Nutzen Sie es beispielsweise, um ein Feld optisch zu markieren.
* **Konkrete Fehler** - `problems` liefert je Bereich eine Liste von Fehlern mit Fehler-Code und dem Namen des fehlgeschlagenen Checks. Nutzen Sie es beispielsweise, um dem Kunden zu sagen, wie der Fehler konkret zu lösen ist.
### Sofort-Fehler und Fehler nach einer Aktion
Der Checkout kennt zwei Quellen für Fehler-Feedback:
* `$wsCheckout.problems.*` - wird angezeigt, sobald ein Feld angewählt bzw. verlassen wurde, sofern `show*BeforeSubmit` in der [Konfiguration](/konfiguration/checkout-bestellablauf#7-checkout-fielderrorvisibility-fehleranzeige) auf `true` steht. Nach dem ersten Kaufversuch werden die Fehler unabhängig von dieser Einstellung angezeigt.
* `actionResponse`-Fehler - stammen aus der Server-Antwort nach einer Aktion. Für die meisten Sektionen werden sie ungefiltert ausgegeben. Ausnahme: Bei Kundendatenfeldern und der [Draft-Adresse](/frontend/referenz/aktionen/checkout#checkoutsetdraftaddress) gibt es kein `problems.*`, dort werden die `actionResponse`-Fehler über `show*BeforeSubmit` gefiltert.
### Auswahl-IDs und Draft-Adressen
Die `selected*`-Variablen enthalten die ID der jeweils gewählten Option (z. B. die Adress-ID, die Sie an [`$wsAccount.loadAddress()`](/frontend/referenz/module/wsAccount#wsaccount-loadaddress) übergeben).
Legt der Kunde im Bestellablauf eine neue Adresse an, die noch nicht im Kundenkonto gespeichert ist (Draft-Adresse), wird sie unter einer **festen System-ID** geführt: `draftBillAddressId` bzw. `draftShippingAddressId`. Diese IDs sind **immer** vorhanden - auch wenn kein Entwurf existiert. Ob tatsächlich ein Entwurf vorliegt (und welche Daten er enthält), lesen Sie über die Maps [`draftBillAddress` / `draftShippingAddress`](#wscheckout-draftbilladdress-draftshippingaddress), die nur dann ausgegeben werden.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsCheckout`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCheckout | json }}
```
**JSON-Ausgabe** (gekürzt)
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"accountType": "...",
"customerData": { },
"draftBillAddressId": "...",
"draftShippingAddressId": "...",
"fieldStates": { },
"freeFields": [...],
"guestMail": "...",
"ineffectiveVoucherErrors": [...],
"isExpressCheckoutLocked": false,
"isOrderBlockedByIneffectiveVoucher": false,
"isPPCApplePayExpressCheckout": false,
"isPPCExpressCheckout": false,
"isPPCGooglePayExpressCheckout": false,
"isValid": false,
"paymentBlocked": false,
"paymentCaptchaRequired": false,
"paymentMethodAutoReset": false,
"problems": {
"billAddress": [...],
"clearing": [...],
"general": [...],
"payment": [...],
"shippingAddress": [...],
"shippingMethod": [...]
},
"selectedBillAddress": "...",
"selectedPayment": "...",
"selectedPseudoCC": "...",
"selectedShippingAddress": "...",
"selectedShippingMethod": "...",
"selectedStoreId": 0,
"shippingMethodAutoReset": false,
"sum": { },
"useAlternativeShippingAddress": false,
"verificationStatus": 0,
"verificationStatusOptions": [...],
"voucherAppliesPerItem": false,
"getAmountInSmallestUnit": "ƒ()",
"getShippingCost": "ƒ()",
"getShippingMethodDisabledErrors": "ƒ()",
"isFinished": "ƒ()",
"isPending": "ƒ()",
"isValidBillAddress": "ƒ()",
"isValidPayment": "ƒ()",
"hasPaymentVault": false,
"isValidShippingAddress": "ƒ()",
"isValidShippingMethod": "ƒ()",
"itemVoucherDiscount": "ƒ()"
}
```
Anmerkung: `"ƒ()"` kennzeichnet eine Funktion. Konditionale Variablen wie `orderId`, `orderCreatedAt`, `restUntilFreeDelivery`, `freeShippingMethod`, `draftBillAddress` und `draftShippingAddress` erscheinen nur, wenn sie gesetzt sind.
**Variablen in der Übersicht**
| **Variable** | **Rückgabe-Typ** | **Beschreibung** |
| -------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `accountType` | string | Kontotyp: `"guest"`, `"new"` oder `"registered"`. Leer (`""`), solange noch kein Kontotyp gewählt wurde. |
| `customerData` | map | Kundendaten-Felder, gruppiert und nach Zielgruppe aufgeteilt (u. a. `groupedFields`, `newCustomerFieldGroups`, `existingCustomerFieldGroups`; Struktur siehe unten). |
| `freeFields` | array | Freie Checkout-Felder (Struktur siehe unten). |
| `guestMail` | string | E-Mail eines Gastkontos. |
| `selectedPayment` | string | ID der gewählten Zahlungsart. |
| `selectedShippingMethod` | string | ID der gewählten Versandart. |
| `selectedBillAddress` | string | ID der gewählten Rechnungsadresse. |
| `selectedShippingAddress` | string | ID der gewählten Lieferadresse. |
| `draftBillAddressId` | string | Feste System-ID, unter der eine Draft-Rechnungsadresse geführt wird. Immer vorhanden. |
| `draftShippingAddressId` | string | Feste System-ID, unter der eine Draft-Lieferadresse geführt wird. Immer vorhanden. |
| `draftBillAddress` | map | Daten der Draft-Rechnungsadresse. Nur vorhanden, wenn ein Entwurf existiert. |
| `draftShippingAddress` | map | Daten der Draft-Lieferadresse. Nur vorhanden, wenn ein Entwurf existiert. |
| `selectedPseudoCC` | string | Pseudo-Kreditkarten-Token. |
| `selectedStoreId` | int | ID der gewählten Filiale (z. B. Click & Collect). |
| `useAlternativeShippingAddress` | bool | Ob eine abweichende Lieferadresse aktiv ist. |
| `orderId` | string | ID der Bestellung. Nur vorhanden, sobald in der Session eine Bestellung existiert. |
| `orderCreatedAt` | string | Erstellzeitpunkt der Bestellung (ISO 8601). Nur vorhanden, sobald eine Bestellung existiert. |
| `shippingMethodAutoReset`
(**zukünftiges Feature**) | bool | Gibt aus, ob die Versandart automatisch neu gesetzt wurde, weil die zuvor gewählte Versandart durch eine Änderung des Bestellkontexts (z.B. Wechsel des Lieferlandes) ungültig geworden ist.
Ob automatisch neu gewählt wird, steuert [`prevSelectionInvalidAutoSelect`](/konfiguration/checkout-bestellablauf). |
| `paymentMethodAutoReset`
(**zukünftiges Feature**) | bool | Gibt aus, ob die Zahlungsart automatisch neu gesetzt wurde, weil die zuvor gewählte Zahlungsart durch eine Änderung des Bestellkontexts (z.B. Wechsel des Lieferlandes) ungültig geworden ist.
Ob automatisch neu gewählt wird, steuert [`prevSelectionInvalidAutoSelect`](/konfiguration/checkout-bestellablauf). |
| `isValid` | bool | Prüft, ob die Bestellung insgesamt ausführbar ist. |
| `isExpressCheckoutLocked` | bool | Prüft, ob der Express-Checkout gesperrt ist (z. B. nach PayPal-Zahlung). |
| `isPPCExpressCheckout` | bool | Prüft, ob der PayPal-Commerce-Platform-Express-Checkout aktiv ist. |
| `isPPCApplePayExpressCheckout` | bool | Prüft, ob Apple Pay Express Checkout aktiv ist. |
| `isPPCGooglePayExpressCheckout` | bool | Prüft, ob Google Pay Express Checkout aktiv ist. |
| `problems` | map | Konkrete Fehler je Bereich (Struktur siehe unten). |
| `fieldStates` | map | Zustand je Checkout-Feld (Werte siehe unten). |
| `sum` | map | Preisinformationen zum Checkout (Struktur siehe unten). |
| `verificationStatus` | int | Verifizierungsstatus der Bestellung. |
| `verificationStatusOptions` | array | Verfügbare Verifizierungsstatus-Optionen. |
| `voucherAppliesPerItem` | bool | Prüft, ob Gutscheine pro Artikel angewendet werden. |
| `restUntilFreeDelivery` | float | Verbleibender Betrag bis zur Grenze für kostenlosen Versand (`0`, wenn erreicht). Nur vorhanden, wenn für den Warenkorb eine Gratisversand-Grenze ermittelbar ist. |
| `freeShippingMethod` | string | ID der Standard-Gratisversandart. Nur vorhanden, wenn `restUntilFreeDelivery` ausgegeben wird, noch keine Versandart gewählt ist und eine Standard-Gratisversandart konfiguriert wurde. |
| `isOrderBlockedByIneffectiveVoucher` | bool | Prüft, ob die Bestellung durch einen wirkungslosen Gutschein blockiert ist. |
| `ineffectiveVoucherErrors` | array | Fehler zu eingelösten Gutscheinen, die im aktuellen Warenkorb keine Wirkung entfalten. Leer, wenn alle Gutscheine greifen. |
| `paymentBlocked` | bool | Prüft, ob die Zahlung blockiert ist (Schutz vor wiederholten Zahlungsversuchen, IP- oder Session-basiert). |
| `paymentCaptchaRequired` | bool | Prüft, ob für die Zahlung ein Captcha erforderlich ist (Schutz vor wiederholten Zahlungsversuchen). |
**Methoden in der Übersicht**
| **Methode** | **Rückgabe-Typ** | **Beschreibung** |
| ----------------------------------- | ---------------- | ---------------------------------------------------------------------------- |
| `isValidPayment()` | bool | Prüft, ob eine Zahlungsart verfügbar ist. |
| `hasPaymentVault()` | bool | Prüft, ob für die im Checkout gewählte Zahlungsart eine Verknüpfung besteht. |
| `isValidShippingMethod()` | bool | Prüft, ob eine Versandart verfügbar ist. |
| `isValidBillAddress()` | bool | Prüft, ob eine Adresse als Rechnungsadresse gültig ist. |
| `isValidShippingAddress()` | bool | Prüft, ob eine Adresse als Lieferadresse gültig ist. |
| `isPending()` | bool | Prüft, ob ein Zahlungsvorgang aussteht. |
| `isFinished()` | bool | Prüft, ob eine Bestellung abgeschlossen wurde. |
| `getAmountInSmallestUnit()` | int | Wandelt einen Betrag in die kleinste Währungseinheit (z. B. Cent). |
| `getShippingMethodDisabledErrors()` | array | Gibt zurück, warum eine Versandart deaktiviert ist. |
| `getShippingCost()` | float | Versandkosten einer Versandart, bezogen auf den aktuellen Warenkorb. |
| `itemVoucherDiscount()` | float | Berechnet den Gutscheinrabatt für einen Artikel. |
***
## Templates
Der Checkout ist frei gestaltbar und kann eine oder mehrere Shopseiten umfassen. Die Reihenfolge der Elemente ist beliebig.
***
## Variablen
### \$wsCheckout.accountType
Gibt den Kontotyp aus: `"guest"` (Gast), `"new"` (neues Konto) oder `"registered"` (angemeldet). Solange der Kunde noch keinen Kontotyp gewählt hat, ist der Wert leer (`""`). Werten Sie ihn aus, um beispielsweise einem Gast die Konto-Erstellung anzubieten.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.accountType == "guest" }}
{{ /if }}
```
### \$wsCheckout.guestMail
Gibt die E-Mail-Adresse eines Gastkontos aus. Nur bei einer Gastbestellung gefüllt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
E-Mail: {{= $wsCheckout.guestMail }}
```
### \$wsCheckout.selectedPayment / selectedShippingMethod
Geben die ID der gewählten Zahlungs- bzw. Versandart aus. Werten Sie sie aus, um die getroffene Auswahl anzuzeigen oder zu prüfen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.selectedPayment == "stripe" }}
{{ /if }}
```
### \$wsCheckout.selectedBillAddress / selectedShippingAddress
Geben die ID der gewählten Rechnungs- bzw. Lieferadresse aus. Diese ID übergeben Sie z. B. an [`$wsAccount.loadAddress()`](/frontend/referenz/module/wsAccount#wsaccount-loadaddress), um die vollständige Adresse zu laden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $billAddress = $wsAccount.loadAddress($wsCheckout.selectedBillAddress) }}
{{= $billAddress.firstName }} {{= $billAddress.lastName }}
```
### \$wsCheckout.draftBillAddressId / draftShippingAddressId
Geben die **feste System-ID** aus, unter der eine im Bestellablauf neu angelegte, noch nicht im Kundenkonto gespeicherte Adresse (Draft-Adresse) geführt wird - z. B. um sie in der Adressauswahl als gewählte Adresse zu erkennen.
Beide IDs sind **immer** vorhanden, unabhängig davon, ob ein Entwurf existiert. Ob tatsächlich ein Entwurf vorliegt, prüfen Sie über die Maps [`draftBillAddress` / `draftShippingAddress`](#wscheckout-draftbilladdress-draftshippingaddress).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.selectedBillAddress == $wsCheckout.draftBillAddressId }}
{{ /if }}
```
### \$wsCheckout.draftBillAddress / draftShippingAddress
Geben die Daten der Draft-Rechnungs- bzw. Draft-Lieferadresse als Map aus. **Nur vorhanden, wenn ein Entwurf existiert** - damit eignen sie sich auch als Existenz-Prüfung.
Die Keys entsprechen den Adressfeldnamen (Standardfelder wie `firstName`, `lastName`, `street`, `zip`, `city`, `country` sowie [zusätzliche Adressfelder](/konfiguration/accounts-benutzerkonten#accounts-customaddressfield-weitere-adressdatenfelder)). Ausgegeben werden nur Felder mit nicht-leerem Wert.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.draftBillAddress }}
Neue Rechnungsadresse:
{{= $wsCheckout.draftBillAddress.firstName }} {{= $wsCheckout.draftBillAddress.lastName }},
{{= $wsCheckout.draftBillAddress.street }}, {{= $wsCheckout.draftBillAddress.zip }} {{= $wsCheckout.draftBillAddress.city }}
{{ /if }}
```
Eine Draft-Adresse wird über die Aktion [CheckoutSetDraftAddress](/frontend/referenz/aktionen/checkout#checkoutsetdraftaddress) angelegt.
### \$wsCheckout.useAlternativeShippingAddress
Gibt aus, ob eine von der Rechnungsadresse abweichende Lieferadresse verwendet wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.useAlternativeShippingAddress }}
{{ /if }}
```
### \$wsCheckout.selectedStoreId
Gibt die ID der gewählten Filiale aus (z. B. für Click & Collect). `0`, wenn keine Filiale gewählt ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.selectedStoreId > 0 }}
{{ /if }}
```
### \$wsCheckout.selectedPseudoCC
Gibt den Pseudo-Kreditkarten-Token der gewählten Zahlung aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Token: {{= $wsCheckout.selectedPseudoCC }}
```
### \$wsCheckout.orderId / orderCreatedAt
Geben die ID und den Erstellzeitpunkt (ISO 8601) der Bestellung aus. Beide Variablen sind **nur vorhanden, sobald in der aktuellen Session eine Bestellung existiert** - z. B. auf der Bestellbestätigungsseite.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.orderId }}
Ihre Bestellnummer: {{= $wsCheckout.orderId }} (erstellt: {{= $wsCheckout.orderCreatedAt }})
{{ /if }}
```
### \$wsCheckout.customerData
Gibt die konfigurierten Kundendaten-Felder aus - gruppiert und nach Zielgruppe aufgeteilt. Welche Felder enthalten sind, hängt vom Login-Status ab: Bei eingeloggten Kunden die Kontofelder, sonst die in der Bestellung gespeicherten Felder.
#### Struktur von `$wsCheckout.customerData`
| **Key** | **Typ** | **Beschreibung** |
| ----------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `groupedFields` | array | Feldgruppen mit ihren Feldern (Struktur siehe Gruppen-Objekt). Immer vorhanden. |
| `newCustomerFieldGroups` | array | Feldgruppen mit den Feldern für die [Neukundenregistrierung](/konfiguration/customer-kundendaten#customer-customerdatafieldsettings-feldkonfiguration). Immer vorhanden. |
| `existingCustomerFieldGroups` | array | Feldgruppen mit den Feldern für die Bestandskundenregistrierung. Immer vorhanden. |
| `ungroupedFields` | array | Felder ohne Gruppenzuordnung. Nur vorhanden, wenn `showUngroupedFields` in [`customer.customerDataFieldSettings`](/konfiguration/customer-kundendaten#customer-customerdatafieldsettings-feldkonfiguration) aktiv ist. |
| `newCustomerFields` | array | Felder der Neukundenregistrierung als flache Liste. Nur vorhanden, wenn `showUngroupedFields` aktiv ist. |
| `existingCustomerFields` | array | Felder der Bestandskundenregistrierung als flache Liste. Nur vorhanden, wenn `showUngroupedFields` aktiv ist. |
#### Gruppen-Objekt
Die Gruppen entsprechen der Konfiguration unter [`customer.customerDataGroup`](/konfiguration/customer-kundendaten#customer-customerdatagroup-gruppierung).
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ------------------------------------------------------------------------------------------------ |
| `name` | string | Technischer Name der Gruppe. |
| `label` | string | Anzeigename der Gruppe. |
| `hidden` | bool | Ob die Gruppe ausgeblendet werden soll (u. a. `true`, wenn sie keine sichtbaren Felder enthält). |
| `fields` | array | Die Felder der Gruppe (Struktur siehe Feld-Objekt). |
#### Feld-Objekt
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ----------- | ----------------------------------------------------------------------------- |
| `name` | string | Technischer Name des Feldes. |
| `label` | string | Anzeigename des Feldes. |
| `type` | string | Feldtyp (z. B. `text`, `number`, `date`, `checkbox`, `select`). |
| `association` | string | Speicherort gemäß `storageStrategy` (Konto, Bestellung oder beides). |
| `hidden` | bool | Ob das Feld ausgeblendet werden soll. |
| `readonly` | bool | Ob das Feld schreibgeschützt ist. |
| `touched` | bool | Ob das Feld vom Kunden bereits bearbeitet wurde. |
| `required` | bool | Ob das Feld ein Pflichtfeld ist. |
| `value` | string/bool | Aktueller Wert (bool bei `checkbox`, sonst string). |
| `externalId` | string | Externe Kennung des Feldes. Nur vorhanden, wenn konfiguriert. |
| `unit` | map | Einheiten-Informationen. Nur bei `number`-Feldern mit konfigurierter Einheit. |
| `options` | array | Auswahloptionen (`{value, label}`). Nur bei `select`-Feldern. |
**Beispiel,** das alle sichtbaren Feldgruppen mit ihren Feldern ausgibt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $group in $wsCheckout.customerData.groupedFields }}
{{ if not $group.hidden }}
{{ /if }}
{{ /foreach }}
```
### \$wsCheckout.freeFields
Gibt die freien Checkout-Felder aus (z. B. AGB-Checkbox, Kommentarfeld). Iterieren Sie über die Felder und werten Sie sie über ihre `id` aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsCheckout.freeFields }}
{{= $field.name }} ({{= $field.type }}, Pflicht: {{= $field.required }})
{{ /foreach }}
```
#### Eigenschaften eines freien Feldes
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| --------------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| `id` | string | ID des Feldes (z. B. `"agb"`, `"comment"`). |
| `name` | string | Anzeigename des Feldes (z. B. `"AGB"`). |
| `type` | string | Feldtyp (`"checkbox"`, `"text"`). |
| `required` | bool | Ob das Feld ein Pflichtfeld ist. |
| `default` | bool/string | Standardwert (bool bei Checkbox, string bei Textfeld). |
| `checked` | bool | Ob die Checkbox angehakt ist (nur bei `type == "checkbox"`). |
| `text` | string | Aktuell eingegebener Text (nur bei `type == "text"` und nur vorhanden, wenn ein Wert gesetzt wurde). |
### \$wsCheckout.isValid
Gibt aus, ob die Bestellung insgesamt ausführbar ist. Dies ist der Gesamtstatus über alle Felder – nutzen Sie ihn, um den „Kaufen"-Button frei- oder zu sperren.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValid }}
{{ /if }}
```
### \$wsCheckout.isExpressCheckoutLocked
Gibt aus, ob der Express-Checkout gesperrt ist – z. B. nachdem der Kunde über PayPal bezahlt hat und zur Bestätigung in den Shop zurückgeleitet wird. Werten Sie es aus, um in diesem Zustand das Bearbeiten des Warenkorbs zu unterbinden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isExpressCheckoutLocked }}
Die Bearbeitung Ihres Warenkorbs ist derzeit nicht möglich.
{{ /if }}
```
### \$wsCheckout.isPPCExpressCheckout / isPPCApplePayExpressCheckout / isPPCGooglePayExpressCheckout
Geben aus, ob der jeweilige Express-Checkout der PayPal Commerce Platform aktiv ist. Nutzen Sie sie, um den passenden Express-Checkout-Ablauf darzustellen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isPPCExpressCheckout }}
{{ /if }}
```
### \$wsCheckout.paymentCaptchaRequired / paymentBlocked
Schutz vor wiederholten Zahlungsversuchen (IP- oder Session-basiert): `paymentCaptchaRequired` gibt aus, ob vor dem nächsten Zahlungsversuch ein Captcha gelöst werden muss. `paymentBlocked` gibt aus, ob weitere Zahlungsversuche aktuell blockiert sind.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.paymentBlocked }}
Zu viele fehlgeschlagene Zahlungsversuche. Bitte versuchen Sie es später erneut.
{{ elseif $wsCheckout.paymentCaptchaRequired }}
{{ /if }}
```
### \$wsCheckout.isOrderBlockedByIneffectiveVoucher
Gibt aus, ob die Bestellung blockiert ist, weil ein eingelöster Gutschein im aktuellen Warenkorb keine Wirkung entfalten kann. Nutzen Sie es, um den Bestellbutton zu sperren.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isOrderBlockedByIneffectiveVoucher }}
Ein eingelöster Gutschein kann auf diesen Warenkorb nicht angewendet werden.
{{ /if }}
```
Das Flag meldet nur den Zustand. Um dem Kunden den konkreten Grund und den betroffenen Gutschein zu nennen, werten Sie zusätzlich [`ineffectiveVoucherErrors`](#wscheckout-ineffectivevouchererrors) aus. Ob die Bestellung überhaupt blockiert wird, steuert `disableOrderOnIneffectiveVoucher` in der [Checkout-Konfiguration](/konfiguration/checkout-bestellablauf#wirkungslose-gutscheine-blockieren).
### \$wsCheckout.ineffectiveVoucherErrors
Gibt eine Liste der Fehler zu eingelösten Gutscheinen aus, die im aktuellen Warenkorb keine Wirkung entfalten. Jeder Eintrag nennt den Grund und, soweit zuordenbar, den betroffenen Gutschein. Damit ersetzen Sie einen allgemeinen Hinweis durch eine konkrete Aussage. Greifen alle Gutscheine, ist die Liste leer.
Anders als bei [`problems`](#wscheckout-problems) enthalten diese Fehler bereits einen fertigen Text. Der Shop übersetzt dazu den Textbaustein, der im Konfigurationsknoten [`checkout.voucherErrors`](/konfiguration/checkout-bestellablauf#checkout-vouchererrors-fehlertexte-zu-wirkungslosen-gutscheinen) zum jeweiligen Fehlerfall hinterlegt ist.
#### Eigenschaften eines Fehlers
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| --------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `code` | string | Art des Fehlers (Werte siehe Tabelle unten). |
| `subCode` | string | Feinere Unterteilung des Fehlers. Aktuell immer leer (`""`). |
| `field` | string | Betroffenes Eingabefeld. Aktuell immer leer (`""`), weil in diesem Zusammenhang kein Eingabefeld beteiligt ist. |
| `text` | string | Übersetzter Fehlertext aus `checkout.voucherErrors`. |
| `details` | map | Zusatzangaben zum Fehler. Enthält den Key `voucherId` mit der ID des betroffenen Gutscheins, sofern der Fehler einem einzelnen Gutschein zuzuordnen ist. |
`subCode` und `field` sind vorhanden, damit alle Fehlerobjekte im Frontend denselben Aufbau haben. Sie werden hier derzeit nicht gefüllt, können aber später Werte erhalten. Werten Sie sie deshalb nur aus, wenn sie tatsächlich gefüllt sind.
#### Bedeutung der Fehler-Codes
| **Code** | **Bedeutung** |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"noValidProducts"` | Der Gutschein ist auf keine Position im Warenkorb anwendbar, beispielsweise weil er nur für bestimmte Produkte oder Kategorien gilt oder weil keine Position rabattfähig ist. |
| `"minOrderValueNotReached"` | Der Mindestbestellwert für den Gutschein ist unterschritten. |
Die Liste kann künftig weitere Codes enthalten. Sehen Sie im Template deshalb einen Fallback für unbekannte Codes vor, beispielsweise die Ausgabe von `text`.
`details.voucherId` ist **nicht** in jedem Fehler enthalten. Steht `minOrderValueCalculation` auf `sum` und wird erst die Summe aller Mindestbestellwerte nicht erreicht, gehört der Fehler zu keinem einzelnen Gutschein und kommt ohne ID. Prüfen Sie den Key deshalb immer, bevor Sie ihn ausgeben. Welcher Fehler wann entsteht, steht unter [Wann welcher Fehler entsteht](/konfiguration/checkout-bestellablauf#wann-welcher-fehler-entsteht).
**Beispiel,** das je Gutschein den konkreten Grund ausgibt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isOrderBlockedByIneffectiveVoucher }}
Gutscheine können nicht eingelöst werden:
{{ foreach $cError in $wsCheckout.ineffectiveVoucherErrors }}
-
{{ if $cError.details.voucherId }}
Gutschein {{= $cError.details.voucherId }}:
{{ /if }}
{{= $cError.text | ifNull($cError.code) }}
{{ /foreach }}
{{ /if }}
```
**Ergebnis**
Pro wirkungslosem Gutschein erscheint eine Zeile mit Gutschein-ID und Grund. Der Fehler aus der Summenprüfung erscheint als Zeile ohne ID.
### \$wsCheckout.verificationStatus / verificationStatusOptions
`verificationStatus` gibt den Verifizierungsstatus der Bestellung als Zahl aus. `verificationStatusOptions` listet den möglichen Status auf.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $option in $wsCheckout.verificationStatusOptions }}
{{= $option.id }}: {{= $option.name }}
{{ /foreach }}
```
### \$wsCheckout.voucherAppliesPerItem
Gibt aus, ob ein Gutschein pro Artikel (statt auf den Gesamtbetrag) angewendet wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.voucherAppliesPerItem }}
{{ /if }}
```
### \$wsCheckout.restUntilFreeDelivery / freeShippingMethod
`restUntilFreeDelivery` gibt den verbleibenden Betrag bis zur Grenze für kostenlosen Versand aus (`0`, wenn die Grenze erreicht ist). Die Variable ist **nur vorhanden, wenn für den Warenkorb eine Gratisversand-Grenze ermittelbar ist**. Nutzen Sie sie für einen Hinweis „Noch X bis zum kostenlosen Versand".
`freeShippingMethod` enthält zusätzlich die ID der konfigurierten Standard-Gratisversandart - aber nur, solange der Kunde noch keine Versandart gewählt hat und eine Standard-Gratisversandart konfiguriert ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.restUntilFreeDelivery > 0 }}
Nur noch {{= $wsCheckout.restUntilFreeDelivery | currency }} bis zum kostenlosen Versand!
{{ /if }}
```
### \$wsCheckout.fieldStates
Gibt eine Map mit dem Zustand jedes Checkout-Feldes aus (`payment`, `shippingMethod`, `billAddress`, `shippingAddress`). Damit markieren Sie einzelne Felder gezielt – z. B. ein noch nicht ausgefülltes Feld neutral, ein fehlerhaftes rot.
| **Wert** | **Beschreibung** |
| ---------------- | ----------------------------------------------------------------- |
| `"untouched"` | Das Feld wurde noch nicht bearbeitet oder ausgewählt. |
| `"empty"` | Das Feld wurde befüllt, der Wert wurde aber wieder entfernt. |
| `"invalid"` | Ein Wert ist vorhanden, hat die Validierung aber nicht bestanden. |
| `"incompatible"` | Der Wert ist gültig, im aktuellen Kontext aber nicht zulässig. |
| `"valid"` | Das Feld ist korrekt ausgefüllt und hat alle Prüfungen bestanden. |
Die Zustände bauen aufeinander auf. Geprüft wird der Reihe nach: angewählt (`untouched`) → Wert vorhanden (`empty`) → gültig (`invalid`) → im Kontext zulässig (`incompatible`). Erst wenn alle Prüfungen bestanden sind, gilt das Feld als `valid`. Der erste zutreffende Zustand wird ausgegeben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.fieldStates.payment == "valid" }}
{{ /if }}
```
### \$wsCheckout.problems
Gibt eine Map mit konkreten Fehlern je Bereich aus. Die Map enthält genau sechs Bereiche: `payment`, `shippingMethod`, `billAddress`, `shippingAddress`, `clearing` und `general`. Jeder Bereich ist eine Liste von Fehlern; sie ist gefüllt, wenn dort ein Problem vorliegt.
#### Eigenschaften eines Fehlers
Jeder Fehler ist ein Objekt mit genau zwei Eigenschaften:
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| --------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `code` | string | Fehler-Code (siehe Tabelle unten). |
| `check` | string | Name des fehlgeschlagenen Validierungsservices (z. B. `"voucherDeny"`). Bei `code == "missing"` ist `check` `null`. Im Bereich `clearing` enthält `check` stattdessen die Fehlermeldung des Zahlungsproviders. |
Einen sprechenden Fehlertext (`text`) oder das betroffene Feld (`field`) enthalten die Fehler-Objekte **nicht**. Formulieren Sie die Kundenmeldung im Template anhand von `code` und ggf. `check` (siehe Beispiel unten).
#### Bedeutung der Fehler-Codes
| **Code** | **Bedeutung** | **Beispiel** |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| `"missing"` | Kein Wert ausgewählt oder eingetragen. | Keine Zahlungsart gewählt. |
| `"checkFailed"` | Ein Wert ist vorhanden, hat die Validierung aber nicht bestanden. | Ungültige Adresse; in `general`: unzulässiger Kontotyp (`check` = `"accountType"`). |
| `"checkIncompatible"` | Der Wert ist gültig, im aktuellen Kontext aber nicht zulässig. | Zahlungsart für das Lieferland gesperrt. |
| `"clearingFailed"` | Die Zahlungsabwicklung beim Provider ist fehlgeschlagen. Nur im Bereich `clearing`; `check` enthält die Fehlermeldung des Providers. | Zahlung von Computop abgelehnt. |
**Beispiel,** das die Fehler der Zahlungsart kundenfreundlich ausgibt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $prob in $wsCheckout.problems.payment }}
{{ if $prob.code == "missing" }}
Bitte wählen Sie eine Zahlungsart aus.
{{ elseif $prob.code == "checkFailed" }}
Die gewählte Zahlungsart ist ungültig ({{= $prob.check }}).
{{ elseif $prob.code == "checkIncompatible" }}
Die gewählte Zahlungsart ist für Ihre Auswahl nicht verfügbar ({{= $prob.check }}).
{{ /if }}
{{ /foreach }}
```
Um auf einen einzelnen Fehler zuzugreifen, verwenden Sie den Index, z. B. `$wsCheckout.problems.payment[0].code`. Fehler zu freien Checkout-Feldern liefert `$wsCheckout.problems` nicht - diese werten Sie über die `actionResponse`-Fehler der jeweiligen Aktion aus (z. B. [CheckoutSetFreeFields](/frontend/referenz/aktionen/checkout)).
### \$wsCheckout.sum
Gibt eine Map mit den Preisinformationen zum Checkout aus. Für die Anzeige als Geldbetrag verwenden Sie den `currency`-Filter – er enthält bereits das Währungssymbol.
#### Eigenschaften von `$wsCheckout.sum`
| **Eigenschaft** | **Rückgabe-Typ** | **Beschreibung** |
| ------------------- | ---------------- | -------------------------------------------------------------- |
| `total` | float | Gesamtbetrag der Bestellung (inkl. Versand, Rabatte, Steuern). |
| `totalNet` | float | Nettobetrag. |
| `totalGross` | float | Bruttobetrag. |
| `totalTax` | float | Gesamte Mehrwertsteuer. |
| `totalPreDeduction` | float | Gesamtbetrag vor dem Steuerabzug. |
| `totalVoucher` | float | Wert der eingelösten Gutscheine. |
| `totalWeight` | float | Gesamtgewicht der Bestellung. |
| `shippingCost` | float | Versandkosten. |
| `paymentCost` | float | Kosten der Zahlungsart. |
| `surchargeCost` | float | Zusatzkosten / Aufschläge. |
| `currency` | string | Währungscode (z. B. `"EUR"`). |
| `totalTaxDeduction` | float | Betrag der abgezogenen Steuer (bei Steuerbefreiung). |
| `isTaxExempt` | bool | Ob die Bestellung steuerbefreit ist. |
| `usedExemptionRule` | string | Aktive Steuerprüfregel (z. B. `"shippingOnly"`). |
| `billingCountry` | string | Länderkennung der Rechnungsadresse. |
| `shippingCountry` | string | Länderkennung der Lieferadresse. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Gesamtbetrag: {{= $wsCheckout.sum.total | currency }}
Versandkosten: {{= $wsCheckout.sum.shippingCost | currency }}
```
***
## Methoden
### \$wsCheckout.isValidPayment()
Prüft, ob die Zahlungsart mit der angegebenen ID verfügbar ist. Dabei werden alle Validierungsregeln ausgeführt, die in der Konfiguration der Zahlungsart unter `validations` hinterlegt sind (siehe [`paymentValidation.*` - Zahlungsarten-Validierung](/konfiguration/validierungs-und-prufservices#paymentvalidation-%2A-zahlungsarten-validierung)) - z.B. Länderregeln, Bestellwertgrenzen oder der Ausschluss bei Gutscheinprodukten im Warenkorb (`paymentValidation.voucherDeny`). Zusätzlich wird geprüft, ob die Zahlungsart aktiv und für das Kundenkonto zugelassen ist.
Schlägt mindestens eine Regel fehl, gibt die Methode `false` zurück. Auf diese Weise wirken die konfigurierten Validierungsregeln im Frontend: Das Template blendet die Zahlungsart aus oder deaktiviert sie.
**Signatur**
`$wsCheckout.isValidPayment(paymentId)`
**Rückgabe**
`true / false` - Zahlungsart verfügbar / nicht verfügbar.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ----------- | ------- | ----------- | -------------------------------------------- |
| `paymentId` | string | ja | ID der Zahlungsart, die geprüft werden soll. |
**Beispiel,** das prüft, ob die Zahlungsart verfügbar ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidPayment("stripe") }}
// Stripe ist verfügbar
{{ /if }}
```
**Beispiel,** das alle Zahlungsarten als Auswahl anbietet und nicht verfügbare Zahlungsarten deaktiviert. Zahlungsarten, deren Validierung fehlschlägt (z.B. wegen `paymentValidation.voucherDeny` bei einem Gutscheinprodukt im Warenkorb), sind sichtbar, aber nicht wählbar.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $cPayment in $wsConfig.payments }}
{{ /foreach }}
```
Warum die aktuell ausgewählte Zahlungsart ungültig ist, lässt sich über [`$wsCheckout.problems.payment`](#wscheckout-problems) auswerten; das Feld `check` enthält dort den Namen des fehlgeschlagenen Validierungsservices.
### \$wsCheckout.hasPaymentVault()
Prüft, ob für den angemeldeten Kunden eine Verknüpfung mit dem Zahlungsanbieter besteht, bezogen auf die im Checkout aktuell gewählte Zahlungsart. Besteht eine Verknüpfung, wird die Bestellung direkt darüber bezahlt und der Kunde muss die Freigabe nicht erneut beim Zahlungsanbieter durchlaufen. Nutzen Sie diese Methode, um im Checkout entweder die gespeicherte Zahlungsquelle anzuzeigen oder das Angebot zur Verknüpfung einzublenden.
Die Methode gibt in allen Zweifelsfällen den Wert`false` zurück: wenn keine Zahlungsart gewählt wurde, wenn die gewählte Zahlungsart keine Verknüpfung unterstützt oder wenn der Kunde nicht angemeldet ist.
**Signatur**
`$wsCheckout.hasPaymentVault()`
**Rückgabe**
`true / false` - Verknüpfung vorhanden / nicht vorhanden.
**Beispiel,** das im Checkout zwischen gespeicherter Verknüpfung und Neu-Verknüpfung unterscheidet.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.hasPaymentVault() }}
{{ else }}
{{ /if }}
```
Für eine Prüfung außerhalb des Checkouts, beispielsweise auf einer Seite im Kundenkonto, auf der die Verknüpfung verwaltet wird, verwenden Sie die Methode [\$wsAccount.hasPaymentVault()](/frontend/referenz/module/wscheckout#wsaccount-haspaymentvault). Diese Methode erwartet die Zahlungsart als Parameter.
### \$wsCheckout.isValidShippingMethod()
Prüft, ob die Versandart mit der angegebenen ID verfügbar ist. Dabei werden alle Validierungsregeln ausgeführt, die in der Konfiguration der Versandart unter `validations` hinterlegt sind (siehe [`shippingMethodValidation.*` - Versandarten-Validierung](/konfiguration/validierungs-und-prufservices#shippingmethodvalidation-%2A-versandarten-validierung)) - z.B. Länderregeln, Warenwertgrenzen oder Produkttyp-Beschränkungen.
Schlägt mindestens eine Regel fehl, gibt die Methode `false` zurück. Das Template blendet die Versandart dann aus oder deaktiviert sie (gleiches Muster wie bei [`isValidPayment()`](#wscheckout-isvalidpayment)). Die Gründe für eine deaktivierte Versandart lassen sich über [`getShippingMethodDisabledErrors()`](#wscheckout-getshippingmethoddisablederrors) ausgeben.
**Signatur**
`$wsCheckout.isValidShippingMethod(shippingMethodId)`
**Rückgabe**
`true / false` - Versandart verfügbar / nicht verfügbar.
**Parameter**
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------------ | ------- | ----------- | ------------------------------------------- |
| `shippingMethodId` | string | ja | ID der Versandart, die geprüft werden soll. |
**Beispiel,** das prüft, ob die angegebene Versandart verfügbar ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidShippingMethod("dhl_standard") }}
// DHL Standard ist verfügbar
{{ /if }}
```
### \$wsCheckout.isValidBillAddress() / isValidShippingAddress()
Prüfen, ob die Adresse mit der angegebenen ID als Rechnungs- bzw. Lieferadresse gültig ist.
**Signatur**
`$wsCheckout.isValidBillAddress(addressId)` · `$wsCheckout.isValidShippingAddress(addressId)`
**Rückgabe**
`bool` – gültig / nicht gültig.
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ----------- | ------- | ----------- | ---------------------------- |
| `addressId` | string | ja | ID der zu prüfenden Adresse. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidBillAddress($wsCheckout.selectedBillAddress) }}
{{ /if }}
```
### \$wsCheckout.isPending() / isFinished()
`isPending()` prüft, ob ein Zahlungsvorgang noch aussteht, `isFinished()`, ob die Bestellung abgeschlossen wurde. Nutzen Sie sie, um den Status einer laufenden oder abgeschlossenen Bestellung zu erkennen.
**Signatur**
`$wsCheckout.isPending()` · `$wsCheckout.isFinished()`
**Rückgabe**
`bool`.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isPending() }}
{{ /if }}
```
### \$wsCheckout.getAmountInSmallestUnit()
Gibt einen Betrag in der kleinsten Währungseinheit zurück (z. B. Cent statt Euro). Nützlich für Zahlungs-APIs, die Beträge in Cent erwarten.
**Signatur**
`$wsCheckout.getAmountInSmallestUnit(amount)`
**Rückgabe**
`int` – Betrag in kleinster Einheit.
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| -------- | ------- | ----------- | --------------------------- |
| `amount` | float | ja | Betrag in der Hauptwährung. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cents = $wsCheckout.getAmountInSmallestUnit($wsCheckout.sum.total) }}
```
### \$wsCheckout.getShippingMethodDisabledErrors()
Gibt zurück, warum eine Versandart deaktiviert ist. Nutzen Sie es, um dem Kunden zu erklären, weshalb eine Versandart nicht wählbar ist.
**Signatur**
`$wsCheckout.getShippingMethodDisabledErrors(shippingMethodId)`
**Rückgabe**
`array` – Liste mit Fehlermeldungen.
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------------ | ------- | ----------- | ------------------------------- |
| `shippingMethodId` | string | ja | ID der zu prüfenden Versandart. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $error in $wsCheckout.getShippingMethodDisabledErrors("express") }}
{{= $error }}
{{ /foreach }}
```
### \$wsCheckout.getShippingCost()
Gibt die Versandkosten einer bestimmten Versandart zurück. Auch dann, wenn diese nicht ausgewählt ist. Der Wert bezieht sich auf den aktuellen Warenkorb. Nutzen Sie es beispielsweise, um die Versandkosten verschiedener Optionen vorab anzuzeigen.
**Signatur**
`$wsCheckout.getShippingCost(shippingMethodId)`
**Rückgabe**
`float` – Versandkosten der angegebenen Versandart.
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------------ | ------- | ----------- | ------------------------------------------------- |
| `shippingMethodId` | string | ja | ID der Versandart, deren Kosten ermittelt werden. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Versandkosten: {{= $wsCheckout.getShippingCost("dhl_standard") | currency }}
```
### \$wsCheckout.itemVoucherDiscount()
Berechnet den Gutscheinrabatt für einen einzelnen Warenkorb-Artikel. Übergeben Sie die ID eines [Warenkorb-Eintrags](/frontend/referenz/module/wsbasket#wsbasket-items).
**Signatur**
`$wsCheckout.itemVoucherDiscount(itemId)`
**Rückgabe**
`float` – Rabattbetrag für den Artikel.
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| -------- | ------- | ----------- | -------------------------- |
| `itemId` | string | ja | ID des Warenkorb-Eintrags. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Rabatt: {{= $wsCheckout.itemVoucherDiscount($item.id) | currency }}
```
***
## Aktionen
Aktionen, die den Checkout verändern (Adresse wählen, Zahlungsart setzen, Bestellung auslösen), sind separat dokumentiert: [Aktionen → Checkout](/frontend/referenz/aktionen/checkout).
***
## Beispiele
### Bestellbarkeit prüfen und Fehler anzeigen
Dieses Beispiel kombiniert die Validierungsebenen:
Ist die Bestellung gültig, wird der „Kaufen"-Bereich angezeigt, sonst werden die konkreten Probleme aufgelistet - anhand von `code` und `check`, da die Fehler-Objekte keinen fertigen Text enthalten.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValid }}
{{ else }}
{{ foreach $prob in $wsCheckout.problems.payment }}
{{ if $prob.code == "missing" }}
Bitte wählen Sie eine Zahlungsart aus.
{{ else }}
Die gewählte Zahlungsart ist nicht verfügbar ({{= $prob.check }}).
{{ /if }}
{{ /foreach }}
{{ foreach $prob in $wsCheckout.problems.shippingMethod }}
{{ if $prob.code == "missing" }}
Bitte wählen Sie eine Versandart aus.
{{ else }}
Die gewählte Versandart ist nicht verfügbar ({{= $prob.check }}).
{{ /if }}
{{ /foreach }}
{{ foreach $prob in $wsCheckout.problems.billAddress }}
Bitte prüfen Sie Ihre Rechnungsadresse ({{= $prob.code }}).
{{ /foreach }}
{{ /if }}
```
**Ergebnis**
Bei gültiger Bestellung erscheint der Kaufen-Bereich, sonst die offenen Punkte je Bereich.
### Summenübersicht
Eine vollständige Summenanzeige. Der `currency`-Filter enthält das Währungssymbol bereits.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Zwischensumme: {{= $wsCheckout.sum.totalNet | currency }}
Versandkosten: {{= $wsCheckout.sum.shippingCost | currency }}
Mehrwertsteuer: {{= $wsCheckout.sum.totalTax | currency }}
{{ if $wsCheckout.sum.totalVoucher > 0 }}
Gutschein: {{= $wsCheckout.sum.totalVoucher | currency }}
{{ /if }}
Gesamtbetrag: {{= $wsCheckout.sum.total | currency }}
```
**Ergebnis**
Eine aufgeschlüsselte Summenübersicht mit korrekt formatierten Geldbeträgen.
### AGB-Zustimmung prüfen
Prüft, ob das Freifeld `agb` angehakt ist, bevor die Bestellung erlaubt wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsCheckout.freeFields }}
{{ if $field.id == "agb" and not $field.checked }}
Bitte akzeptieren Sie die AGB.
{{ /if }}
{{ /foreach }}
```
**Ergebnis**
Ist die AGB-Checkbox nicht angehakt, erscheint der Hinweis.
### Gewählte Zahlungsart prüfen
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidPayment($wsCheckout.selectedPayment) }}
Gewählte Zahlungsart: {{= $wsCheckout.selectedPayment }}
{{ /if }}
```
**Ergebnis**
Die gewählte Zahlungsart wird angezeigt, sofern sie gültig ist.
***
## Weiterführende Links
* [Aktionen → Checkout](/frontend/referenz/aktionen/checkout) – den Checkout verändern (Auswahl setzen, Bestellung auslösen), weil `$wsCheckout` selbst nur liest.
* [\$wsBasket](/frontend/referenz/module/wsbasket) – der Warenkorb, auf dem der Checkout aufbaut; liefert die Artikel für `itemVoucherDiscount()`.
* [\$wsAccount](/frontend/referenz/module/wsAccount) – lädt über `loadAddress()` die vollständige Adresse zur `selectedBillAddress`/`selectedShippingAddress`.
* [Checkout-Konfiguration](/konfiguration/checkout-bestellablauf#7-checkout-fielderrorvisibility-fehleranzeige) – steuert mit `show*BeforeSubmit`, wann Fehler angezeigt werden.
* [Fehlertexte zu wirkungslosen Gutscheinen](/konfiguration/checkout-bestellablauf#checkout-vouchererrors-fehlertexte-zu-wirkungslosen-gutscheinen) – pflegt die Texte, die `ineffectiveVoucherErrors` ausgibt.
* [\$wsVoucher](/frontend/referenz/module/wsvoucher) – die eingelösten Gutscheine selbst, passend zu den IDs aus `ineffectiveVoucherErrors`.
# $wsCmsPage - CMS-Seite ausgeben
Source: https://dokumentation.websale.de/frontend/referenz/module/wscmspage
Modul $wsCmsPage: das Seitendokument einer CMS-Seite aus strapi im Template lesen.
Mit dem `$wsCmsPage` Modul können Sie im Template auf das Seitendokument der aktuell aufgerufenen CMS-Seite zugreifen. Das Modul liefert das JSON-Dokument aus dem Objektspeicher unverändert aus, ohne Umbenennung oder Umsortierung. Ein typischer Anwendungsfall ist das CMS-Seitentemplate, das die Inhalte einer in Strapi gepflegten Inhaltsseite ausgibt.
Das Modul wird ausschließlich auf CMS-Seiten gefüllt, also auf Seiten, die über den View-Controller `CmsPage` gerendert werden. Auf allen anderen Seiten ist `$wsCmsPage` leer (`null`).
Weiterführende Seiten zu diesem Thema:
* [Auslieferung von CMS-Seiten in den Shop](/strapi-cms/grundlagen-architektur-von-strapi#auslieferung-von-cms-seiten-in-den-shop) erklärt, wie die Seiten in den Objektspeicher kommen, wie die SEO-URL entsteht und welche Felder der Shop selbst auswertet.
* [Template Theme](/frontend/die-basics/template-theme#cms-seitentemplate) erklärt das CMS-Seitentemplate und die Einbindung in das Basis-Template.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsCmsPage`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCmsPage | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"contentType": "api::contentpage.contentpage",
"meta": {
"id": 92,
"documentId": "jyllb6ubw0dj62vndr0lh7z1",
"locale": "de",
"createdAt": "2026-06-26T08:00:00.000Z",
"updatedAt": "2026-07-16T09:00:00.000Z",
"publishedAt": "2026-07-16T09:03:00.000Z",
"url": "Zahlungsarten",
"metaTitle": "Zahlungsarten",
"metaDescription": "Beschreibung zu Zahlungsarten",
"robots": ["noindex", "nofollow"],
"hreflang": [
{
"language": "fr-fr",
"url": "myshop.fr/paiement",
"subshopId": "francais",
"default": false
}
]
},
"fields": [
{ "name": "Markup", "type": "richtext", "value": "AGB Content" },
{
"name": "content",
"type": "dynamiczone",
"value": [
{
"component": "elemente.ws-markup",
"id": 96,
"fields": [
{ "name": "FullWidth", "type": "boolean", "value": false }
]
}
]
}
]
}
```
**Variablen in der Übersicht**
| **Name** | **Rückgabe-Typ** | **Beschreibung** |
| ----------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------- |
| `contentType` | string | strapi-Kennung des Content-Typs, aus dem die Seite stammt. Wird vom Shop nicht ausgewertet. |
| `meta` | map | Verwaltungsdaten der Seite plus SEO-Block. |
| `meta.url` | string | URL der Seite, ohne führenden Schrägstrich. |
| `meta.metaTitle` | string | Meta-Title. Wird vom Shop zusätzlich als Seitentitel gesetzt und ist über `$wsViews.metaTitle()` verfügbar. |
| `meta.metaDescription` | string | Meta-Description. Wird vom Shop zusätzlich gesetzt und ist über `$wsViews.metaDescription()` verfügbar. |
| `meta.robots` | array | Robots-Angaben der Seite. Werden vom Shop zusätzlich in `$wsViews.current.robotOptions` zusammengeführt. |
| `meta.publishedAt` | string oder null | Zeitstempel der Veröffentlichung. `null` bei Entwürfen. |
| `meta.hreflang` | array | Alternativsprachen-Objekte (`language`, `url`, `subshopId`, `default`). Werden **nicht** automatisch ausgegeben. |
| `meta.id` | number | Interne numerische strapi-ID (pro Sprachversion). |
| `meta.documentId` | string | Stabile, sprachübergreifende Dokument-ID. |
| `meta.locale` | string | Sprache des Dokuments, beispielsweise `de`. |
| `meta.createdAt` / `meta.updatedAt` | string (ISO-8601) | Zeitstempel aus strapi. |
| `fields` | array | Die Inhaltsfelder der Seite, je `{ name, type, value }`. Unverändert aus strapi. |
## Methoden
Für `$wsCmsPage` stehen keine Methoden zur Verfügung.
***
## Variablen
### \$wsCmsPage.contentType
Gibt aus, aus welchem strapi-Content-Typ die aufgerufene Seite stammt. Der Content-Typ entspricht der Eingabemaske hinter der Seite und legt fest, welche Felder ein Redakteur ausfüllen kann.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCmsPage.contentType }}
```
### \$wsCmsPage.meta
Enthält die Verwaltungsdaten und den SEO-Block der Seite.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCmsPage.meta | json }}
```
Der Shop setzt Meta-Title und Meta-Description bereits selbst. Im Basis-Template werden sie üblicherweise über die Funktionen [\$wsViews.metaTitle()](https://dokumentation.websale.de/frontend/referenz/module/wsviews#\$wsviews-metatitle) und [\$wsViews.metaDescription()](https://dokumentation.websale.de/frontend/referenz/module/wsviews#\$wsviews-metadescription) ausgegeben, damit alle Seitentypen einheitlich behandelt werden. Der direkte Zugriff über `$wsCmsPage.meta` ist nur nötig, wenn Sie die Rohwerte an anderer Stelle benötigen.
Welche dieser Felder der Shop auswertet und welche Felder reine Verwaltungsdaten sind, steht unter [Der SEO-Block in meta](/strapi-cms/grundlagen-architektur-von-strapi#der-seo-block-in-meta).
### \$wsCmsPage.fields
Enthält die Inhaltsfelder der Seite. Jeder Eintrag hat die Schlüssel `name`, `type` und `value`.
Der Shop gibt diese Liste unverändert weiter und interpretiert sie nicht. Welche Feldnamen und Komponenten es gibt, ergibt sich aus der Strapi-Modellierung des jeweiligen Shops. Für den Zugriff wird die Liste einmalig in ein Name/Wert-Objekt überführt:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCmsPage }}
{{ var $cFields = {} }}
{{ foreach $cField in $wsCmsPage.fields }}
{{ $cFields[$cField.name] = $cField.value }}
{{ /foreach }}
{{= $wsCmsPage.meta.metaTitle }}
{{! $cFields.Markup }}
{{ /if }}
```
Das Muster gilt auf jeder Ebene, auch innerhalb von Komponenten (`value.fields`) und für die Blöcke von Inhaltsblöcken. Die Feldtypen und die Form der jeweiligen `value` sind unter [Die Feldtypen](/strapi-cms/migration-der-strapi-datenstruktur-v5#die-feldtypen) beschrieben, das Umstellen bestehender Feldzugriffe unter [Schritt 4](/strapi-cms/migration-der-strapi-datenstruktur-v5#schritt-4-feldzugriffe-umstellen) und [Schritt 5](/strapi-cms/migration-der-strapi-datenstruktur-v5#schritt-5-inhaltsblocke-dynamic-zone-anpassen).
Die Reihenfolge der `fields`-Liste folgt der Schema-Definition und ist für das Rendern bedeutungslos. Greifen Sie deshalb immer über `name` und nie über die Position auf Felder zu. Die Reihenfolge **innerhalb** eines Array-Werts (Inhaltsblöcke, wiederholbare Komponenten) entspricht dagegen exakt der Anordnung des Redakteurs und muss beim Rendern übernommen werden.
***
## Aktionen
Für `$wsCmsPage` stehen keine Aktionen zur Verfügung.
***
## Beispiele
### Gemeinsames Basis-Template auf CMS-Inhalte prüfen
Da `$wsCmsPage` auf allen anderen Seiten `null` ist, kann ein gemeinsames Basis-Template gefahrlos darauf prüfen:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCmsPage }}
{{# nur auf CMS-Seiten #}}
{{ /if }}
```
### Alternativsprachen ausgeben
`meta.hreflang` wird nicht automatisch in die hreflang-Angaben des Shops übernommen,[\$wsViews.current.getHreflangAutomatic()](https://dokumentation.websale.de/frontend/referenz/module/wsviews#\$wsviews-current-gethreflangautomatic) liefert für CMS-Seiten nichts. Für die Ausgabe im HTML-Head:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $cAlt in $wsCmsPage.meta.hreflang }}
{{ /foreach }}
```
### Unbekannte Komponenten im Testmodus sichtbar machen
Ohne einen `{{ else }}`-Zweig verschwindet eine neu angelegte, im Template nicht umgesetzte Komponente still aus der Seite:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $cItem in $cFields.content }}
{{ if $cItem.component == "elemente.ws-markup" }}
{{# … Ausgabe … #}}
{{ else }}
{{ if $wsTestMode.active }}
{{ /if }}
{{ /if }}
{{ /foreach }}
```
### Entwurf im Testmodus kennzeichnen
Ein Entwurf (`meta.publishedAt` ist `null`) wird nur bei aktivem [Testmodus](/frontend/referenz/aktionen/testmode) ausgeliefert. Das lässt sich im Template sichtbar machen:
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCmsPage && !$wsCmsPage.meta.publishedAt }}
Diese Seite ist ein Entwurf und öffentlich nicht erreichbar.
{{ /if }}
```
***
## Weiterführende Links
* [Auslieferung von CMS-Seiten in den Shop](/strapi-cms/grundlagen-architektur-von-strapi#auslieferung-von-cms-seiten-in-den-shop)
* [Template Theme - CMS-Seitentemplate](/frontend/die-basics/template-theme#cms-seitentemplate)
* [content.cmsTemplates](/konfiguration/content-katalog-kategorien-produkte#content-cmstemplates-cms-seiten)
* [Migration der strapi-Datenstruktur (Version 5)](/strapi-cms/migration-der-strapi-datenstruktur-v5)
* [\$wsViews](/frontend/referenz/module/wsviews)
* [\$wsTestMode](/frontend/referenz/module/wstestmode)
# $wsComputopHosted - Computop (gehostete Bezahlseite)
Source: https://dokumentation.websale.de/frontend/referenz/module/wscomputophosted
Daten für die Weiterleitung zur gehosteten Computop-Bezahlseite bereitstellen und Rückkehr sowie Zahlungsergebnis im Frontend auswerten.
Mit dem `$wsComputopHosted`-Modul wickeln Sie Zahlungen über die gehostete Computop-Bezahlseite ab. Das Modul liefert alle Daten, die Sie brauchen, um den Kunden per Formular zur Computop-Bezahlseite weiterzuleiten, und meldet nach der Rückkehr, ob die Zahlung erfolgreich war.
Auf dieser Seite geht es um das Bereitstellen der Formulardaten und das Auswerten des Ergebnisses. Die eigentliche Zahlungsabwicklung läuft auf der Computop-Seite, die Konfiguration der Schnittstelle (Händler-ID, Schlüssel) erfolgt in der Zahlungs-Konfiguration.
***
## Grundkonzept
Bei einer gehosteten Bezahlseite findet die Zahlung nicht im Shop statt, sondern auf einer Seite des Zahlungsdienstleisters. `$wsComputopHosted` liefert die Daten, mit denen Sie den Kunden dorthin weiterleiten.
Der Ablauf ist immer derselbe: Formular bauen → absenden → Computop wickelt ab → Rückkehr auswerten.
1. Sie bauen ein HTML-Formular, dessen `action` auf [`$wsComputopHosted.action`](#wscomputophosted-action) zeigt, und legen die übrigen Werte (`data`, `len`, `merchantID`, `encryptionType` …) als versteckte Felder ab.
2. Der Kunde sendet das Formular ab und gelangt auf die Computop-Bezahlseite.
3. Computop wickelt die Zahlung ab und leitet den Kunden zurück in den Shop.
4. Nach der Rückkehr werten Sie [`paymentCanceled`](#wscomputophosted-paymentcanceled), [`paymentFailed`](#wscomputophosted-paymentfailed) und [`error`](#wscomputophosted-error) aus, um dem Kunden eine passende Rückmeldung zu geben.
### Verschlüsselte Daten unverändert durchreichen
Die Felder `data`, `len` und `encryptionType` bilden die verschlüsselten Zahlungsdaten. Sie berechnen daran nichts selbst und verändern sie nicht, sie reichen die Werte unverändert an Computop weiter.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsComputopHosted`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsComputopHosted | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"action": "",
"data": "",
"encryptionType": "AES",
"error": "",
"freeFields": [],
"language": "",
"len": "0",
"merchantID": "",
"payType": "",
"paymentCanceled": false,
"paymentFailed": false,
"template": ""
}
```
**Anmerkung:** Konditionale Variablen erscheinen nur, wenn sie gesetzt sind: `hideSave`, `prefill` sowie die Daten einer gespeicherten Kreditkarte (`PCNr`, `PCNrBrand`, `PCNrYear`, `PCNrMonth`, `holder`).
**Variablen zum Aufbau des Formulars**
| **Variable** | **Typ** | **Beschreibung** |
| ---------------- | ------- | --------------------------------------------------------------------------------------------- |
| `action` | string | URL der Computop-Bezahlseite (als `action` des Formulars). |
| `data` | string | Verschlüsselte Zahlungsdaten. |
| `len` | string | Länge der verschlüsselten Daten (zur Prüfung bei Computop). |
| `encryptionType` | string | Verschlüsselungstyp: `"Blowfish"` oder `"AES"`. |
| `merchantID` | string | Händler-ID bei Computop. |
| `payType` | string | Zahlungsart (z. B. Kreditkarte). |
| `language` | string | Sprachcode für die Bezahlseite (z. B. `"de"`). |
| `template` | string | Name des Computop-Templates. |
| `hideSave` | string | Enthält `"hideSave"`, wenn die Speichern-Option ausgeblendet werden soll. Nur dann vorhanden. |
| `prefill` | string | Enthält `"on"`, wenn die Speichern-Option vorbelegt (angehakt) sein soll. Nur dann vorhanden. |
| `freeFields` | array | Freie Checkout-Felder, die an Computop übermittelt werden (Struktur siehe unten). |
**Variablen einer gespeicherten Kreditkarte** (nur vorhanden, wenn eine gespeicherte Pseudo-Kreditkarte gewählt ist)
| **Variable** | **Typ** | **Beschreibung** |
| ------------ | ------- | ---------------------------------------------------- |
| `PCNr` | string | Pseudo-Kartennummer (Token) der gespeicherten Karte. |
| `PCNrBrand` | string | Kartenmarke (z. B. Visa). |
| `PCNrYear` | string | Ablaufjahr der Karte. |
| `PCNrMonth` | string | Ablaufmonat der Karte. |
| `holder` | string | Karteninhaber. |
**Variablen zum Auswerten des Ergebnisses**
| **Variable** | **Typ** | **Beschreibung** |
| ----------------- | ------- | -------------------------------------------- |
| `paymentCanceled` | bool | `true`, wenn die Zahlung abgebrochen wurde. |
| `paymentFailed` | bool | `true`, wenn die Zahlung fehlgeschlagen ist. |
| `error` | string | Fehlermeldung bei einem Zahlungsproblem. |
***
## Templates
Das Weiterleitungsformular wird typischerweise im Checkout eingebunden, also auf der Seite, von der aus der Kunde zur Zahlung weitergeleitet wird. Die Ergebnis-Variablen werten Sie auf der Seite aus, auf die Computop nach der Zahlung zurückleitet.
***
## Variablen
### \$wsComputopHosted.action
Gibt die URL der Computop-Bezahlseite aus. Sie verwenden sie als `action`-Attribut des Formulars, mit dem der Kunde zur Zahlung weitergeleitet wird.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
### \$wsComputopHosted.data
Gibt die verschlüsselten Zahlungsdaten aus. Sie übermitteln sie als verstecktes Formularfeld – unverändert (siehe [Grundkonzept](#verschlüsselte-daten-unverändert-durchreichen)).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
### \$wsComputopHosted.len
Gibt die Länge der verschlüsselten Daten aus. Computop benötigt diesen Wert, um die übermittelten Daten zu prüfen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
### \$wsComputopHosted.encryptionType
Gibt den Verschlüsselungstyp aus, mit dem `data` verschlüsselt wurde: `"Blowfish"` oder `"AES"` - je nachdem, was in der Computop-Konfiguration eingestellt ist (Standard: Blowfish).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Verschlüsselung: {{= $wsComputopHosted.encryptionType }}
```
### \$wsComputopHosted.merchantID
Gibt die Händler-ID bei Computop aus. Sie wird mit dem Formular übermittelt, damit Computop die Zahlung dem richtigen Händlerkonto zuordnet.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
### \$wsComputopHosted.payType
Gibt die Zahlungsart aus (z. B. Kreditkarte).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Zahlungsart: {{= $wsComputopHosted.payType }}
```
### \$wsComputopHosted.language
Gibt den Sprachcode für die Bezahlseite aus. Damit erscheint die Computop-Seite in der Sprache des Kunden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Sprache: {{= $wsComputopHosted.language }}
```
### \$wsComputopHosted.template
Gibt den Namen des verwendeten Computop-Templates aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Template: {{= $wsComputopHosted.template }}
```
### \$wsComputopHosted.hideSave
Gibt den Wert zur Steuerung der Speichern-Option auf der Computop-Bezahlseite aus. Die Variable enthält den Text `"hideSave"` und ist **nur vorhanden, wenn die Option ausgeblendet werden soll** - in zwei Fällen:
* Der Kunde bezahlt mit einer bereits gespeicherten Kreditkarte (siehe [`PCNr`](#wscomputophosted-pcnr-pcnrbrand-pcnryear-pcnrmonth-holder)) - erneutes Speichern ist dann überflüssig.
* Das Speichern ist nicht möglich, weil der Kunde nicht eingeloggt ist oder das Speichern von Pseudo-Kreditkartendaten für den Shop nicht aktiviert ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsComputopHosted.hideSave }}
{{ /if }}
```
### \$wsComputopHosted.prefill
Enthält den Wert `"on"`, wenn die Speichern-Option auf der Computop-Bezahlseite standardmäßig angehakt sein soll (in der Computop-Konfiguration einstellbar). Nur dann vorhanden.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsComputopHosted.prefill }}
{{ /if }}
```
### \$wsComputopHosted.PCNr / PCNrBrand / PCNrYear / PCNrMonth / holder
Geben die Daten einer **gespeicherten Pseudo-Kreditkarte** aus, damit der Kunde nicht erneut seine Kartendaten eingeben muss. Die Variablen sind nur vorhanden, wenn alle Voraussetzungen erfüllt sind:
* Der Kunde ist eingeloggt,
* das Speichern von Pseudo-Kreditkartendaten ist für den Shop aktiviert,
* und der Kunde hat im Checkout eine gespeicherte Karte gewählt (siehe [`$wsCheckout.selectedPseudoCC`](/frontend/referenz/module/wscheckout#wscheckout-selectedpseudocc)).
`PCNr` (Pseudo-Kartennummer) ist dabei immer gesetzt; die übrigen Variablen erscheinen nur, wenn der jeweilige Wert bei der Karte hinterlegt ist. Ist `PCNr` vorhanden, wird zugleich [`hideSave`](#wscomputophosted-hidesave) gesetzt, da die Karte bereits gespeichert ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsComputopHosted.PCNr }}
Gespeicherte Karte: {{= $wsComputopHosted.PCNrBrand }} ({{= $wsComputopHosted.holder }}),
gültig bis {{= $wsComputopHosted.PCNrMonth }}/{{= $wsComputopHosted.PCNrYear }}
{{ /if }}
```
### \$wsComputopHosted.freeFields
Gibt die freien Checkout-Felder aus, die an Computop übermittelt werden. Übermittelt werden nur die [freien Checkout-Felder](/frontend/referenz/module/wscheckout#wscheckout-freefields), deren ID in der Computop-Zahlungskonfiguration unter `freeFields` eingetragen ist.
#### Eigenschaften eines freien Feldes
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ------------------------------------ |
| `id` | string | ID des freien Checkout-Feldes. |
| `value` | string | Aktueller Wert des Feldes. |
| `type` | string | Feldtyp: `"text"` oder `"checkbox"`. |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsComputopHosted.freeFields }}
{{= $field.id }}: {{= $field.value }} ({{= $field.type }})
{{ /foreach }}
```
### \$wsComputopHosted.error
Gibt eine Fehlermeldung aus, falls bei der Zahlung ein Problem aufgetreten ist. Werten Sie sie nach der Rückkehr auf die Bezahlseite aus, um dem Kunden den Grund zu nennen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsComputopHosted.error }}
{{= $wsComputopHosted.error }}
{{ /if }}
```
### \$wsComputopHosted.paymentCanceled
Gibt `true` zurück, wenn der Kunde die Zahlung abgebrochen hat. Nutzen Sie es, um nach dem Abbruch zur Zahlungsauswahl zurückzuführen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsComputopHosted.paymentCanceled }}
Sie haben die Zahlung abgebrochen.
{{ /if }}
```
### \$wsComputopHosted.paymentFailed
Gibt `true` zurück, wenn die Zahlung fehlgeschlagen ist. Im Unterschied zum Abbruch hat der Kunde die Zahlung versucht, sie wurde aber nicht erfolgreich abgeschlossen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsComputopHosted.paymentFailed }}
Die Zahlung ist fehlgeschlagen. Bitte versuchen Sie es erneut.
{{ /if }}
```
***
## Methoden
Für `$wsComputopHosted` stehen keine Methoden zur Verfügung.
***
## Aktionen
Für `$wsComputopHosted` stehen keine Aktionen zur Verfügung.
***
## Beispiele
### Weiterleitung zur Computop-Bezahlseite
Dieses Beispiel baut das vollständige Weiterleitungs-Formular: Es zeigt auf `action` und legt die verschlüsselten Daten sowie die Händler-ID als versteckte Felder ab. Beim Absenden gelangt der Kunde zur Computop-Bezahlseite.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
**Ergebnis** \
Beim Absenden wird der Kunde zur Computop-Bezahlseite weitergeleitet.
### Zahlungsergebnis nach der Rückkehr auswerten
Nachdem Computop den Kunden zurückgeleitet hat, prüfen Sie das Ergebnis und zeigen die passende Meldung.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsComputopHosted.paymentCanceled }}
Sie haben die Zahlung abgebrochen.
{{ elseif $wsComputopHosted.paymentFailed }}
Die Zahlung ist fehlgeschlagen.
{{ if $wsComputopHosted.error }}
Grund: {{= $wsComputopHosted.error }}
{{ /if }}
{{ else }}
Vielen Dank für Ihre Zahlung.
{{ /if }}
```
**Ergebnis** \
Je nach Ausgang sieht der Kunde eine Abbruch-, Fehler- oder Erfolgsmeldung.
***
## Weiterführende Links
* [Computop Hosted Payments (Konfiguration)](/konfiguration/payment-zahlungsmethoden#2-payment-computophosted-computop-hosted-payments) – richtet die Computop-Schnittstelle ein (Händler-ID, Schlüssel, Zahlungsarten). Voraussetzung, damit das Modul gefüllt ist.
* [\$wsCheckout](/frontend/referenz/module/wscheckout) – der Checkout, aus dem heraus zur Computop-Bezahlseite weitergeleitet wird; liefert mit `selectedPseudoCC` die gewählte gespeicherte Karte.
# $wsConfig - Konfiguration
Source: https://dokumentation.websale.de/frontend/referenz/module/wsconfig
Globale Konfigurationsdaten des Shops im Frontend lesen: Länder, Währungen, Zahlungs- und Versandarten, Anreden, Sprachen und weitere Stammdaten.
Mit dem `$wsConfig`-Modul lesen Sie die Konfigurationsdaten des Shops im Frontend, beispielsweise die verfügbaren Länder, die Währung, die Zahlungs- und Versandarten sowie die konfigurierten Anreden und Titel.
Auf dieser Seite geht es um das Lesen der Konfiguration. Die Konfiguration selbst wird im Admin-Interface bzw. [per Code](/frontend/die-basics/konfiguration-per-code) gepflegt, nicht über dieses Modul.
***
## Grundkonzept
`$wsConfig` ist ein reines Lese-Modul. Es spiegelt die im Shop hinterlegte Konfiguration zum Zeitpunkt des Seitenaufbaus wider. Die Werte ändern sich nur, wenn die Konfiguration geändert wird und nicht durch eine Aktion des Kunden.
Die Variablen lassen sich wie folgt gruppieren:
* **Listen für Formulare** – [`countries`](#wsconfig-countries), [`salutation`](#wsconfig-salutation), [`title`](#wsconfig-title), [`listElements`](#wsconfig-listelements): füllen z. B. Auswahlfelder in Adress- und Anmeldeformularen.
* **Checkout-Optionen** – [`payments`](#wsconfig-payments), [`shippingMethods`](#wsconfig-shippingmethods): die verfügbaren Zahlungs- und Versandarten.
* **Anzeige** – [`currency`](#wsconfig-currency): Währungssymbol und -codes.
* **Verhalten und Sicherheit** – [`passwordChecks`](#wsconfig-passwordchecks), [`passwordReset`](#wsconfig-passwordreset), [`directOrder`](#wsconfig-directorder), [`redirects`](#wsconfig-redirects), [`emails`](#wsconfig-emails).
* **Werbemittelkennzeichen** – [`inserts`](#wsconfig-inserts): Einstellungen der [Werbemittelkennzeichnung](/frontend/funktionsubersicht/werbemittelkennzeichnung) (aktiv, Trennzeichen, Position, Standardcode).
### Währung formatieren
Der `currency`-Filter (`| currency`) gibt einen Betrag bereits **mit** Währungssymbol aus (z. B. `1.500,00 €`). Verwenden Sie [`currency.symbol`](#wsconfig-currency) deshalb **nicht** zusätzlich zu `| currency` – sonst erscheint das Symbol doppelt. `currency.symbol` brauchen Sie nur, wenn Sie einen Wert selbst formatieren oder das Symbol einzeln anzeigen.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsConfig`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsConfig | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"countries": [ { "isoAlpha2": "...", "isoAlpha3": "...", "isoNum": "...", "name": "..." } ],
"currency": { "symbol": "...", "isoCode": "...", "isoNum": "..." },
"directOrder": { "initialNumber": 0, "maximalNumber": 0, "refreshedNumber": 0, "itemNumberFields": [...] },
"emails": [...],
"inserts": { "enabled": false, "separator": "...", "position": "...", "defaultInsertCode": "..." },
"listElements": { "bill": { }, "delivery": { }, "": { } },
"passwordChecks": { "maxLength": { "len": 0 }, "minLength": { "len": 0 } },
"passwordReset": { "checkLoginID": false, "checkOldPassword": false },
"payments": [ { "id": "...", "name": "...", "description": "...", "image": "..." } ],
"redirects": [...],
"salutation": { "codeList": [ { "code": "...", "text": "..." } ] },
"shippingMethods": [ { "id": "...", "name": "...", "description": "...", "image": "...", "link": "...", "type": "...", "group": "..." } ],
"shippingMethodGroups": [ { "id": "...", "name": "...", "description": "...", "image": "...", "link": "..." } ],
"title": { "codeList": [ { "code": "...", "text": "..." } ] }
}
```
**Variablen in der Übersicht**
| **Variable** | **Typ** | **Beschreibung** |
| ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `countries` | array | Konfigurierte Länder (Struktur siehe unten). |
| `currency` | map | Währungsdaten (Symbol, Codes). |
| `salutation` | map | Konfigurierte Anreden (unter `codeList`). |
| `title` | map | Konfigurierte Titel (unter `codeList`). |
| `payments` | array | Konfigurierte Zahlungsarten (Struktur siehe unten). |
| `shippingMethods` | array | Konfigurierte Versandarten (Struktur siehe unten). |
| `shippingMethodGroups` | array | Gruppen von Versandarten (Struktur siehe unten). |
| `listElements` | map | Konfigurierte Adresslisten für Formulare, gruppiert nach `bill` und `delivery`; Listen ohne `addressType` liegen direkt darunter. |
| `passwordChecks` | map | Passwort-Längenregeln. |
| `passwordReset` | map | Einstellungen zum Passwort-Reset. |
| `directOrder` | map | Einstellungen der Direktbestellung. |
| `emails` | array | E-Mail-Konfigurationen. |
| `redirects` | array | Weiterleitungs-Konfigurationen. |
| `inserts` | map | Einstellungen der Werbemittelkennzeichnung (aktiv, Trennzeichen, Position, Standardcode). |
| `b2bSubAccounts` | map | B2B-Unterkonten-Einstellungen (`subAccountsEnabled`, `adminCanEditMemberAddresses`). |
***
## Templates
Die Konfigurationsdaten können auf jeder Seite verwendet werden. Typische Einsatzgebiete: Formulare (Länder-, Anredeauswahl), Checkout (Zahlungs- und Versandarten) und Preisanzeige (Währung).
***
## Variablen
### \$wsConfig.countries
Gibt die konfigurierten Länder aus. Nutzen Sie die Liste, um beispielsweise ein Länder-Auswahlfeld in einem Adressformular zu füllen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $country in $wsConfig.countries }}
{{= $country.name }} ({{= $country.isoAlpha2 }})
{{ /foreach }}
```
#### Eigenschaften eines Landes
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nodeId` | string | ID des Konfigurationsknotens dieses Landes, als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen). |
| `name` | string | Name des Landes. |
| `isoAlpha2` | string | ISO-2-Ländercode (z. B. `"DE"`, `"AT"`). |
| `isoAlpha3` | string | ISO-3-Ländercode (z. B. `"DEU"`, `"AUT"`). |
| `isoNum` | string | ISO-Zifferncode (z. B. `"276"`, `"040"`). |
### \$wsConfig.currency
Gibt die Währungsdaten aus. Für die Anzeige eines Betrags verwenden Sie in der Regel den `currency`-Filter (siehe [Währung formatieren](#währung-formatieren)).
#### Eigenschaften von `$wsConfig.currency`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nodeId` | string | ID des Konfigurationsknotens der Währungs-Konfiguration, als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen). |
| `symbol` | string | Währungssymbol (z. B. `€`). |
| `isoCode` | string | ISO-Währungscode (z. B. `"EUR"`). |
| `isoNum` | string | ISO-Zifferncode der Währung (z. B. `"978"`). |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Währung: {{= $wsConfig.currency.isoCode }} ({{= $wsConfig.currency.symbol }})
```
### \$wsConfig.salutation
Gibt die konfigurierten Anreden aus. Die eigentliche Liste liegt unter `salutation.codeList`. Nutzen Sie sie beispielsweise, um ein Anrede-Auswahlfeld zu füllen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $salutation in $wsConfig.salutation.codeList }}
{{= $salutation.text }}
{{ /foreach }}
```
#### Eigenschaften eines Eintrags in `salutation.codeList`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | --------------------------------------------------------------- |
| `code` | string | Anrede-Code (z. B. `"1"`, `"2"`). |
| `text` | string | Anzeigetext (z. B. `"Herr"`, `"Frau"`, `"Familie"`, `"Firma"`). |
### \$wsConfig.title
Gibt die konfigurierten Titel aus. Die Liste liegt unter `title.codeList`. Aufbau analog zu `salutation`.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $title in $wsConfig.title.codeList }}
{{= $title.text }}
{{ /foreach }}
```
#### Eigenschaften eines Eintrags in `title.codeList`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ------------------------------------------------------- |
| `code` | string | Titel-Code (z. B. `"1"`). |
| `text` | string | Anzeigetext (z. B. `"Dr."`, `"Prof."`; kann leer sein). |
### \$wsConfig.payments
Gibt die konfigurierten Zahlungsarten aus. Nutzen Sie sie, um die verfügbaren Zahlungsarten anzuzeigen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $payment in $wsConfig.payments }}
{{= $payment.name }}: {{= $payment.description }}
{{ /foreach }}
```
#### Eigenschaften einer Zahlungsart
| **Eigenschaft** | **Typ** | **Beschreibung** |
| ----------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | string | ID der Zahlungsart (z. B. `"paypalCheckout"`, `"stripe"`). |
| `nodeId` | string | ID des Konfigurationsknotens dieser Zahlungsart, als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen). Nicht zu verwechseln mit `id`. |
| `name` | string | Name der Zahlungsart. |
| `description` | string | Beschreibung der Zahlungsart. |
| `longDescription` | string | Längere Beschreibung der Zahlungsart (lange Variante von `description`), gepflegt unter [`payment.payment`](/konfiguration/payment-zahlungsmethoden#3-payment-payment-zahlungsarten-anlegen). |
| `image` | string | Bild-URL der Zahlungsart. |
| `discount` | float | Rabatt der Zahlungsart. |
| `provider` | string | Anbieter der Zahlungsart. |
| `type` | string | Typ der Zahlungsart. |
| `labels` | array | Labels der Zahlungsart. |
| `displayInfo` | array | Zusätzliche Anzeigeinformationen (siehe Hinweis). |
`displayInfo` ist nur befüllt, wenn für die Zahlungsart der Parameter [displayPaymentTypes](/konfiguration/payment-zahlungsmethoden#3-payment-payment-zahlungsarten-anlegen) konfiguriert wurde. Jeder Eintrag enthält `name`, `description` und `image`.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $payment in $wsConfig.payments }}
{{ foreach $info in $payment.displayInfo }}
{{= $info.name }} – {{= $info.description }}
{{ /foreach }}
{{ /foreach }}
```
### \$wsConfig.shippingMethods
Gibt die konfigurierten Versandarten aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $shipping in $wsConfig.shippingMethods }}
{{= $shipping.name }} ({{= $shipping.type }})
{{ /foreach }}
```
#### Eigenschaften einer Versandart
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | string | ID der Versandart (z. B. `"dhl"`). |
| `nodeId` | string | ID des Konfigurationsknotens dieser Versandart, als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen). |
| `name` | string | Name der Versandart. |
| `description` | string | Beschreibung der Versandart. |
| `image` | string | Bild-URL der Versandart. |
| `link` | string | Link zur Versandart (z. B. Tracking-Seite). |
| `type` | string | Typ der Versandart (z. B. `"standard"`). |
| `group` | string | Zugeordnete Versandart-Gruppe (kann `null` sein). |
Die **Versandkosten** sind nicht Teil der Konfiguration. Sie hängen vom Warenkorb ab und werden über [`$wsCheckout.getShippingCost(shippingMethodId)`](/frontend/referenz/module/wscheckout#wscheckout-getshippingcost) ermittelt.
### \$wsConfig.shippingMethodGroups
Gibt die konfigurierten Versandarten-Gruppen aus. Über eine Gruppe lassen sich mehrere Versandarten zusammenfassen (z. B. nach Anbieter oder Lieferart). Welche Gruppe einer Versandart zugeordnet ist, steht im Feld `group` der jeweiligen Versandart (siehe [Eigenschaften einer Versandart](#eigenschaften-einer-versandart)).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $group in $wsConfig.shippingMethodGroups }}
{{= $group.name }}: {{= $group.description }}
{{ /foreach }}
```
#### Eigenschaften einer Gruppe
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | string | ID der Gruppen-Konfiguration. |
| `nodeId` | string | ID des Konfigurationsknotens dieser Gruppe, als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen). |
| `name` | string | Name der Gruppe. |
| `description` | string | Beschreibung der Gruppe. |
| `image` | string | Bild-URL (Link) der Gruppe. |
| `link` | string | Link der Gruppe. |
### \$wsConfig.listElements
Gibt die konfigurierten [Adresslisten](/konfiguration/general-allgemeine-shopeinstellungen#general-addresslistelements-adresslisten) für Formulare aus, beispielsweise Privat / Firma / Packstation. Nutzen Sie sie, um Auswahlfelder in Adressformularen zu füllen.
Jede Liste ist unter ihrem konfigurierten `name` erreichbar. Unter welchem Pfad sie liegt, bestimmt der Parameter `addressType` der jeweiligen Liste:
| **`addressType` in der Konfiguration** | **Pfad im Template** |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `"bill"` | `$wsConfig.listElements.bill.` |
| `"delivery"` | `$wsConfig.listElements.delivery.` |
| `"both"` | `$wsConfig.listElements.bill.` **und** `$wsConfig.listElements.delivery.` (dieselbe Liste, unter beiden Pfaden) |
| nicht gesetzt | `$wsConfig.listElements.` (direkt, **nicht** unter `bill`/`delivery`) |
Der Schlüssel ist der `name` der Liste, nicht deren `dataId`. Sind beide unterschiedlich gepflegt, ist die Liste im Template ausschließlich über `name` erreichbar. Die `dataId` wird dagegen in der [Feldvalidierung](/konfiguration/validierungs-und-prufservices#addresscheck-allowedselection-auswahl-listenelement) referenziert.
#### Eigenschaften eines Eintrags in `listElements`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| ---------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nodeId` | string | ID des Konfigurationsknotens dieser Liste, als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen). |
| `defaultValue` | string | Vorausgewählter Wert (z. B. `"1"`). Leer, wenn in der Konfiguration kein Standardwert gesetzt ist. |
| `values` | array | Auswählbare Optionen in Anzeige-Reihenfolge, je `{ name, value }`. |
| `values[].name` | string | Anzeigename der Option (z. B. `"Privat"`). |
| `values[].value` | string | Technischer Wert der Option (z. B. `"1"`). |
`values` enthält nur Optionen mit zulässigen Werten. Optionen, deren Wert Sonderzeichen enthält oder deren Name leer ist, werden beim Seitenaufbau übersprungen und fehlen hier ohne Fehlermeldung – siehe [`general.addressListElements`](/konfiguration/general-allgemeine-shopeinstellungen#general-addresslistelements-adresslisten). Wenn eine erwartete Option im Formular fehlt, prüfen Sie zuerst deren `value`.
**Beispiel,** das die Rechnungsadress-Liste `billAddressType` als Auswahlfeld ausgibt. Vorausgewählt wird der bereits gespeicherte Wert der bearbeiteten Adresse (`$myAddress`), andernfalls der konfigurierte `defaultValue`.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $myList = $wsConfig.listElements.bill.billAddressType }}
```
**Ergebnis**
Ein Auswahlfeld mit allen konfigurierten Optionen der Liste. Beim Bearbeiten einer bestehenden Adresse ist der gespeicherte Wert vorausgewählt, beim Anlegen einer neuen Adresse der Standardwert.
`$myAddress` steht im Beispiel für die Adresse, die im Formular bearbeitet wird – etwa eine Adresse aus [`$wsAccount.addresses`](/frontend/referenz/module/wsAccount#wsaccount-addresses) oder eine per [`$wsAccount.loadAddress()`](/frontend/referenz/module/wsAccount#wsaccount-loadaddress) geladene Adresse. Beim Anlegen einer neuen Adresse ist die Variable leer und der `else`-Zweig greift.
Sollen alle Listen eines Adresstyps dynamisch ausgegeben werden, iterieren Sie über die Map. Verwenden Sie dabei je Liste einen eigenen Feldnamen, damit die Werte beim Absenden unterscheidbar bleiben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $myListName, $myList in $wsConfig.listElements.bill }}
{{ /foreach }}
```
### \$wsConfig.passwordChecks
Gibt die Längenregeln für Passwörter aus. Nutzen Sie sie beispielsweise, um in einem Registrierungs- oder Passwort-Formular die erlaubte Länge anzuzeigen oder clientseitig zu prüfen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Passwortlänge: {{= $wsConfig.passwordChecks.minLength.len }} bis {{= $wsConfig.passwordChecks.maxLength.len }} Zeichen
```
#### Eigenschaften von `$wsConfig.passwordChecks`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ----------------------- |
| `minLength.len` | int | Minimale Passwortlänge. |
| `maxLength.len` | int | Maximale Passwortlänge. |
### \$wsConfig.passwordReset
Gibt die Einstellungen zum Passwort-Reset aus.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConfig.passwordReset.checkOldPassword }}
{{ /if }}
```
#### Eigenschaften von `$wsConfig.passwordReset`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| ------------------ | ------- | ----------------------------------------------------------------------------------------------------------- |
| `checkLoginID` | bool | Ob die Login-ID beim Reset geprüft wird. |
| `checkOldPassword` | bool | Ob zur Änderung des Passworts zusätzlich das bisherige Passwort abgefragt und auf Korrektheit geprüft wird. |
### \$wsConfig.directOrder
Gibt die Einstellungen der Direktbestellung aus (z. B. wie viele Eingabezeilen angezeigt werden).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Start-Zeilen: {{= $wsConfig.directOrder.initialNumber }}
Max. Zeilen: {{= $wsConfig.directOrder.maximalNumber }}
```
#### Eigenschaften von `$wsConfig.directOrder`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| ------------------ | ------- | ------------------------------------------ |
| `initialNumber` | int | Anzahl der initial angezeigten Zeilen. |
| `maximalNumber` | int | Maximale Anzahl von Zeilen. |
| `refreshedNumber` | int | Anzahl neu geladener Zeilen. |
| `itemNumberFields` | array | Artikelnummer-Felder der Direktbestellung. |
### \$wsConfig.inserts
Gibt die Einstellungen der [Werbemittelkennzeichnung](/frontend/funktionsubersicht/werbemittelkennzeichnung) aus. Nutzen Sie insbesondere `enabled`, um Ausgaben rund um das Werbemittelkennzeichen nur dann anzuzeigen, wenn die Funktion im Shop aktiv ist.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConfig.inserts.enabled }}
{{ /if }}
```
#### Eigenschaften von `$wsConfig.inserts`
| **Eigenschaft** | **Typ** | **Beschreibung** |
| ------------------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| `enabled` | bool | Ob die Werbemittelkennzeichnung im Shop aktiv ist. Nur dann werden Codes erfasst, aufgelöst und ausgegeben. |
| `separator` | string | Trennzeichen zwischen Produktnummer und Code (z. B. `-`). |
| `position` | string | Position des Codes relativ zur Produktnummer: `before` (davor) oder `after` (dahinter). |
| `defaultInsertCode` | string | Standardcode, der greift, wenn kein oder ein ungültiger Code erfasst wurde. Kann leer sein. |
### \$wsConfig.emails
Gibt die E-Mail-Konfigurationen aus. Jeder Eintrag enthält zusätzlich das Feld `nodeId`, die ID des Konfigurationsknotens, nutzbar als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen) (siehe [Optionen](/frontend/referenz/optionen)).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsConfig.emails | json }}
```
### \$wsConfig.redirects
Gibt die Weiterleitungs-Konfigurationen aus. Jeder Eintrag enthält zusätzlich das Feld `nodeId`, die ID des Konfigurationsknotens, nutzbar als zweiter Parameter für [`$wsOptions.get(name, nodeId)`](/frontend/referenz/module/ws-options-template-optionen) (siehe [Optionen](/frontend/referenz/optionen)).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsConfig.redirects | json }}
```
***
## Methoden
Für `$wsConfig` stehen keine Methoden zur Verfügung.
***
## Aktionen
Für `$wsConfig` stehen keine Aktionen zur Verfügung.
***
## Beispiele
### Länder-Auswahlfeld
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
**Ergebnis**
Ein Auswahlfeld mit allen konfigurierten Ländern. Der Wert ist der ISO-2-Code.
### Anrede-Auswahlfeld
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
```
**Ergebnis**
Ein Auswahlfeld mit allen konfigurierten Anreden.
### Zahlungsarten auflisten
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $payment in $wsConfig.payments }}
{{= $payment.name }} – {{= $payment.description }}
{{ /foreach }}
```
**Ergebnis**
Alle konfigurierten Zahlungsarten mit Name und Beschreibung.
### Währung korrekt anzeigen
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Zwischensumme: {{= $wsBasket.totalGross | currency }}
```
**Ergebnis**
Der Betrag wird mit Währungssymbol ausgegeben (z. B. `1.500,00 €`).
***
## Weiterführende Links
* [Konfiguration](/konfiguration) – wo die hier gelesenen Werte gepflegt werden.
* [Konfiguration per Code](/frontend/die-basics/konfiguration-per-code) – Konfiguration direkt im Template.
* [\$wsCheckout](/frontend/referenz/module/wscheckout) – ermittelt u. a. die Versandkosten je Versandart.
* [Werbemittelkennzeichen](/frontend/funktionsubersicht/werbemittelkennzeichnung) – Übersicht der Werbemittelkennzeichnung, deren Einstellungen `$wsConfig.inserts` liefert.
* [ISO-3166-1-Kodierliste](https://de.wikipedia.org/wiki/ISO-3166-1-Kodierliste) – Bedeutung der Ländercodes.
# $wsConsent - Cookies & Services
Source: https://dokumentation.websale.de/frontend/referenz/module/wsconsent
Cookie- und Service-Einwilligung des Kunden im Frontend auswerten, um Tracking, Drittanbieter-Skripte und eingebettete Inhalte rechtskonform zu steuern.
Mit dem `$wsConsent`-Modul lesen Sie die Einwilligung des Kunden zu Cookies und Services und steuern damit, welche Inhalte und externen Skripte geladen werden. Damit können Sie beispielsweise einen Tracking- oder Marketing-Service erst dann einbinden, wenn der Kunde ihm zugestimmt hat.
Auf dieser Seite geht es um das Lesen des Einwilligungsstatus. Das Setzen der Einwilligung (Zustimmen, Ablehnen, Auswahl speichern) erfolgt über Aktionen und ist separat unter [Aktionen → Consent](/frontend/referenz/aktionen/consent) dokumentiert. Die zugehörigen Cookies selbst behandelt das Modul [\$wsCookies](/frontend/referenz/module/ws-cookie-browser-cookie).
***
## Grundkonzept
Die Einwilligung ist zweistufig organisiert: Gruppen (z. B. „Statistik“, „Marketing“) bündeln einzelne Services (z. B. „Google Analytics“). Der Kunde kann entweder allen zustimmen („Alle erlauben") oder eine Auswahl pro Gruppe/Service treffen. Jeder Eintrag trägt ein „allowed“-Flag, das die Entscheidung widerspiegelt.
`$wsConsent` stellt diesen Status auf folgenden Wegen bereit:
* **Gesamtstatus** – [`alreadySet`](#wsconsent-alreadyset) (hat der Kunde überhaupt schon entschieden?) und [`allAllowed`](#wsconsent-allallowed) (hat er allem zugestimmt?). Damit steuern Sie, ob der Consent-Layer überhaupt angezeigt werden muss.
* **Strukturierte Liste** – [`groups`](#wsconsent-groups) mit ihren `services`, um einen Consent-Layer aufzubauen.
* **Gezielte Prüfung** – [`checkAllowed(serviceName)`](#wsconsent-checkallowed), um vor dem Laden eines bestimmten Skripts die Zustimmung zu prüfen. Das ist der empfohlene Weg zum Einbinden externer Skripte.
### Einwilligung entscheidet, ob das Skript überhaupt geladen wird
Template-Code läuft beim Seitenaufbau. Wenn Sie ein Skript mit `{{ if $wsConsent.checkAllowed(...) }}` umschließen, wird das Skript bei fehlender Zustimmung gar nicht erst in die Seite geschrieben, nicht nur ausgeblendet. So stellen Sie sicher, dass ein abgelehnter Service auch wirklich nicht lädt.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsConsent`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsConsent | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"alreadySet": false,
"allAllowed": false,
"groups": [
{
"name": "...",
"label": "...",
"description": "...",
"allowed": false,
"services": [
{ "name": "...", "label": "...", "description": "...", "allowed": false }
]
}
],
"services": [
{ "name": "...", "label": "...", "description": "...", "allowed": false }
],
"checkAllowed": "ƒ()"
}
```
Anmerkung: `"ƒ()"` kennzeichnet eine Funktion.
**Variablen in der Übersicht**
| **Variable** | **Typ** | **Beschreibung** |
| ------------ | ------- | ---------------------------------------------------- |
| `alreadySet` | bool | Ob der Kunde bereits eine Einwilligung gesetzt hat. |
| `allAllowed` | bool | Ob der Kunde allen Cookies/Services zugestimmt hat. |
| `groups` | array | Konfigurierte Gruppen, jeweils mit ihren `services`. |
| `services` | array | Flache Liste aller konfigurierten Services. |
**Eigenschaften eines Eintrags** (gilt für `groups[]` wie für `services[]`)
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ---------------------------------------------- |
| `name` | string | Technischer Name (für `checkAllowed()`). |
| `label` | string | Für den Kunden sichtbare Bezeichnung. |
| `description` | string | Beschreibung. |
| `allowed` | bool | Ob der Eintrag erlaubt (akzeptiert) ist. |
| `services` | array | Nur bei `groups[]`: die zugeordneten Services. |
**Methoden in der Übersicht**
| **Methode** | **Rückgabe-Typ** | **Beschreibung** |
| ---------------- | ---------------- | -------------------------------------------------- |
| `checkAllowed()` | bool | Prüft, ob ein bestimmter Service akzeptiert wurde. |
***
## Templates
Der Consent-Layer kann global aufgerufen werden und wird aus dem Template `consent.htm` geladen.
***
## Variablen
### \$wsConsent.alreadySet
Gibt aus, ob der Kunde bereits eine Cookie-/Service-Einwilligung gesetzt hat. Nutzen Sie es beispielsweise, um den Consent-Layer nur dann anzuzeigen, wenn noch keine Entscheidung vorliegt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if not $wsConsent.alreadySet }}
{{ /if }}
```
### \$wsConsent.allAllowed
Gibt aus, ob der Kunde allen Services zugestimmt hat (Schaltfläche „Alle erlauben").
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConsent.allAllowed }}
{{ /if }}
```
### \$wsConsent.groups
Gibt die konfigurierten Gruppen aus. Jede Gruppe trägt die [Eigenschaften eines Eintrags](#modulübersicht) und enthält unter `services` die zugeordneten Services. Nutzen Sie die Gruppen, um einen strukturierten Consent-Layer aufzubauen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $group in $wsConsent.groups }}
{{= $group.label }}
{{ foreach $service in $group.services }}
- {{= $service.label }}
{{ /foreach }}
{{ /foreach }}
```
### \$wsConsent.services
Gibt alle konfigurierten Services als Liste aus, unabhängig von der Gruppenzuordnung. Die Einträge tragen die [Eigenschaften eines Eintrags](#modulübersicht).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $service in $wsConsent.services }}
{{= $service.label }}: {{= $service.allowed }}
{{ /foreach }}
```
***
## Methoden
### \$wsConsent.checkAllowed()
Prüft, ob ein bestimmter Service vom Kunden akzeptiert wurde. Dies ist der empfohlene Weg, um vor dem Laden eines externen Skripts die Zustimmung zu prüfen, da das Skript bei fehlender Zustimmung gar nicht erst gerendert wird.
**Signatur**\
`$wsConsent.checkAllowed(serviceName)`
**Rückgabe**\
`bool` – `true`, wenn der Service akzeptiert wurde, sonst `false`.
| **Name** | **Typ** | **Pflicht** | **Beschreibung** |
| ------------- | ------- | ----------- | --------------------------------------------------------------- |
| `serviceName` | string | ja | Technischer Name des Services (das `name`-Feld eines Eintrags). |
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConsent.checkAllowed("googleAnalytics") }}
{{ /if }}
```
***
## Aktionen
Aktionen zu diesem Modul (Einwilligung setzen, ändern, speichern) sind separat dokumentiert: [Aktionen → Consent](/frontend/referenz/aktionen/consent).
***
## Beispiele
### Externes Skript einwilligungsabhängig laden
Bindet ein Skript nur ein, wenn der zugehörige Service akzeptiert wurde. Bei fehlender Zustimmung wird das Skript nicht in die Seite geschrieben.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConsent.checkAllowed("googleAnalytics") }}
{{ /if }}
```
**Ergebnis** \
Das Tracking-Skript erscheint nur im Quelltext, wenn der Kunde „Google Analytics" akzeptiert hat.
### Consent-Layer aus Gruppen und Services aufbauen
Durchläuft die Gruppen und je Gruppe ihre Services, was die typische Struktur eines Consent-Layers widerspiegelt.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $group in $wsConsent.groups }}
{{ /foreach }}
```
**Ergebnis** \
Pro Gruppe ein Block mit den enthaltenen Services; bereits akzeptierte Services sind angehakt.
### Inhalt nur bei Zustimmung anzeigen
Zeigt einen einwilligungspflichtigen Inhalt (z. B. ein eingebettetes Video) nur an, wenn der Service akzeptiert wurde, ansonsten einen Hinweis.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsConsent.checkAllowed("youtube") }}
{{ else }}
Um diese Inhalte zu sehen, akzeptieren Sie bitte den Service „Youtube Videos".
{{ /if }}
```
**Ergebnis** \
Bei Zustimmung erscheint der Inhalt, sonst der Hinweis.
***
## Weiterführende Links
* [Aktionen → Consent](/frontend/referenz/aktionen/consent) – die Einwilligung setzen und speichern (dieses Modul liest sie nur).
* [\$wsCookies](/frontend/referenz/module/ws-cookie-browser-cookie) – die durch die Einwilligung gesteuerten Cookies.
# $wsDirectOrder - Direktbestellung
Source: https://dokumentation.websale.de/frontend/referenz/module/wsdirectorder
Zustand einer Direktbestellung (Scan & Order, Bestellschein) im Frontend lesen: Eingabezeilen, erfasste Positionen und Validität der Eingaben.
Mit dem `$wsDirectOrder`-Modul lesen Sie den Zustand einer Direktbestellung. Bei der Direktbestellung legt der Kunde Produkte durch Eingabe ihrer Artikelnummern direkt in den Warenkorb, ohne sie einzeln im Shop zu suchen. Das Modul liefert die aktuelle Anzahl der Eingabezeilen und die bisher erfassten Positionen samt Gültigkeit.
Auf dieser Seite geht es um das Lesen des Direktbestell-Zustands. Das Hinzufügen und Löschen von Positionen erfolgt über die Aktionen `DirectOrderAdd` / `DirectOrderDelete`.
***
## Grundkonzept
Der Bestellschein ist ein Formular mit mehreren Eingabezeilen. In jede Zeile gibt der Kunde eine Artikelnummer (und eine Menge) ein. Beim Absenden prüft die Aktion `DirectOrderAdd`, ob die Nummer existiert, und legt das Produkt in den Warenkorb.
`$wsDirectOrder` stellt dabei den aktuellen Zustand bereit:
* [`currentLines`](#wsdirectorder-currentlines) – wie viele Eingabezeilen aktuell angezeigt werden. Der Wert stammt aus der Konfiguration ([`$wsConfig.directOrder`](/frontend/referenz/module/wsconfig#wsconfig-directorder): `initialNumber` bis `maximalNumber`).
* [`items`](#wsdirectorder-items) – die bereits erfassten Positionen, je mit `id`, `quantity` und `valid`.
### Gültigkeit
Das Feld [`valid`](#wsdirectorder-items) einer Position zeigt an, ob die eingegebene Artikelnummer im Shop existiert und bestellbar ist. Werten Sie es aus, um dem Kunden eine ungültige Eingabe direkt zurückzumelden.
***
## Modulübersicht
**Beispiel / Ausschnitt über** `$wsDirectOrder`
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsDirectOrder | json }}
```
**JSON-Ausgabe**
```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
"currentLines": 5,
"items": [
{ "id": "123-45678", "quantity": 1, "valid": true },
{ "id": "910-111213", "quantity": 1, "valid": false }
]
}
```
**Variablen in der Übersicht**
| **Variable** | **Typ** | **Beschreibung** |
| -------------- | ------- | -------------------------------------------------- |
| `currentLines` | int | Aktuelle Anzahl der angezeigten Eingabezeilen. |
| `items` | array | Erfasste Bestellpositionen (Struktur siehe unten). |
**Eigenschaften einer Bestellposition (`items[]`)**
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ------------------------------------------------------------ |
| `id` | string | Eingegebene Artikelnummer. |
| `quantity` | int | Eingegebene Menge. |
| `valid` | bool | `true`, wenn die Artikelnummer existiert und bestellbar ist. |
***
## Templates
Der Bestellschein liegt im Standard im Template `module/directOrder.htm`. Verlinken Sie ihn z. B. im Footer (siehe [Beispiel](#seite-im-footer-verlinken)).
***
## Variablen
### \$wsDirectOrder.currentLines
Gibt die aktuelle Anzahl der angezeigten Eingabezeilen aus. Der Wert wird über [`$wsConfig.directOrder`](/frontend/referenz/module/wsconfig#wsconfig-directorder) konfiguriert (`initialNumber` als Start, `maximalNumber` als Obergrenze). Nutzen Sie ihn beispielsweise, um genau so viele Zeilen zu erzeugen.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Aktuelle Zeilen: {{= $wsDirectOrder.currentLines }}
```
### \$wsDirectOrder.items
Gibt die erfassten Bestellpositionen aus. Über den Zeilenindex greifen Sie auf eine bestimmte Position zu (`items[$index]`).
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $item in $wsDirectOrder.items }}
{{= $item.id }} – Menge: {{= $item.quantity }} – gültig: {{= $item.valid }}
{{ /foreach }}
```
#### Eigenschaften einer Bestellposition
| **Eigenschaft** | **Typ** | **Beschreibung** |
| --------------- | ------- | ------------------------------------------------------------ |
| `id` | string | Eingegebene Artikelnummer. |
| `quantity` | int | Eingegebene Menge. |
| `valid` | bool | `true`, wenn die Artikelnummer existiert und bestellbar ist. |
***
## Methoden
Für `$wsDirectOrder` stehen keine Methoden zur Verfügung.
***
## Aktionen
`$wsDirectOrder` selbst stellt keine Aktionen bereit. Das Hinzufügen und Löschen von Positionen erfolgt über die [Aktionen](/frontend/referenz/aktionen/directorder).
***
## Beispiele
### Bestellschein-Template
Dieses Beispiel erzeugt für jede konfigurierte Zeile (`currentLines`) eine Eingabereihe. `range(0, currentLines - 1)` liefert die Indizes `0` bis `currentLines - 1`. Pro Zeile werden die Aktionen `DirectOrderAdd` und `DirectOrderDelete` mit dem Zeilenindex als `tag` erzeugt, damit Eingaben und Fehler der richtigen Zeile zugeordnet werden. Der Filter `ifNull('')` setzt einen leeren Wert, falls die Zeile noch nicht erfasst wurde.
```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ extends "layouts/layout.htm" }}
{{ block content_main }}
Direktbestellung
{{ foreach $cProduct in range(0, $wsDirectOrder.currentLines - 1) }}
{{ var $cActionDirectOrderAdd = $wsActions.create("DirectOrderAdd", tag=string($cProduct)) }}
{{ var $cActionDirectOrderDelete = $wsActions.create("DirectOrderDelete", tag=string($cProduct)) }}