> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Externe Inhalte einbinden

> Ausgaben fremder Programme nahtlos in Shop-Templates einbinden, ihre Erreichbarkeit prüfen, Adressdaten übergeben und ein Redaktionssystem anbinden.

Ein Produktkonfigurator, ein Blätterkatalog, die Artikel aus einem Redaktionssystem: Solche Inhalte liegen außerhalb des Shops, sollen aber aussehen, als gehörten sie dazu. Der übliche Weg über einen Link führt aus dem Shop heraus, Frames und Popups bringen eigene Nachteile mit. WEBSALE V8s bietet dafür zwei Verfahren, und die Wahl zwischen ihnen entscheidet mehr als nur den Aufwand.

| Verfahren | Wie es arbeitet | Was passiert, wenn das fremde System ausfällt |
| - | - | - |
| Externe Includes | der Shop holt die Inhalte beim Seitenaufbau in Echtzeit | die Seite verzögert sich oder der Inhalt fehlt |
| JSON-Schnittstelle | das fremde System legt die Inhalte vorab auf dem Shop-Server ab | nichts, die Daten liegen bereits da |

Für Inhalte, die sich selten ändern, ist der zweite Weg der bessere. Für alles, was im Moment des Aufrufs berechnet werden muss, bleibt nur der erste.

## Externe Includes

### Die beiden Tags

Zwei Tags binden die Ausgabe eines fremden Programms an der Stelle ein, an der sie stehen. Der Unterschied liegt darin, was der Shop dabei mitschickt.

| Tag | Wann |
| - | - |
| `WS-ExternInclude()` | wenn das fremde System Formulardaten braucht, die im Shop per POST oder GET angekommen sind |
| `WS-URLInclude()` | wenn nur die Adresse eingebunden werden soll, ohne Parameterumschreibung und ohne Formulardaten |

Bei `WS-ExternInclude()` werden alle vorhandenen GET- und POST-Parameter zusammengefasst und in den Parametern `getbuf` und `postbuf` übergeben. Formulardaten aus einem Formular im Shop gehen zusätzlich per POST an das fremde Programm.

Die Ausgabe des fremden Programms darf ihrerseits WEBSALE-Tags enthalten. Damit lassen sich Shopdaten innerhalb fremder Inhalte anzeigen.

### Die Adresse angeben

In das Argument gehört die Adresse des fremden Programms. Beide Tags erlauben Tag-in-Tag, der Wert eines anderen Tags kann also Teil der Adresse sein. Dabei werden die Tilde-Zeichen des inneren Tags durch Dollar-Zeichen ersetzt.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~WS-URLInclude(https://.../konfigurator.php?produktname=$PR-Name$&param=Wert)~

~WS-ExternInclude(https://.../konfigurator.php?produktname=$PR-Name$&param=Wert)~
```

Im zweiten Fall übergibt der Shop dieselben beiden Parameter zusätzlich URL-codiert im Parameter `getbuf`:

```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
getbuf=produktname%3dName%26param%3dWert
```

Die Verbindung zum fremden System baut der Shop serverseitig auf, über einen Proxy. Der Browser des Besuchers sieht davon nichts und ruft die fremde Adresse nicht selbst auf.

Referenz: [WS-ExternInclude()](https://dokumentation.websale.de/v8s/referenz/tags/ws/merkzettel-vergleich-upload-und-externe-dienste.md) · WS-URLInclude()

## Prüfen, ob das fremde System antwortet

Fällt das fremde System aus, steht an seiner Stelle im Shop nichts, und der Seitenaufbau verzögert sich bis zum Zeitablauf. Der LiveCheck prüft vorher, ob das System erreichbar ist, und lässt Sie darauf reagieren, etwa mit einem Ersatzinhalt.

### Einrichten

Die Prüfungen stehen im Abschnitt `<ExternSystemLiveChecks>` der `shop.config`, je Prüfung ein `<+Entry>`. Bis zu zehn Prüfungen sind möglich.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<ExternSystemLiveChecks>
   <+Entry>
      ID         = cms-available
      URL        = https://www.ihre-domain.de/system-livecheck/index.php
      Type       = 1
      CheckMode  = successPersistant
      Timeout    = 1000
   </+Entry>
</ExternSystemLiveChecks>
```

| Parameter | Bedeutung |
| - | - |
| `ID` | Kennung, mit der die Prüfung im Template aufgerufen wird |
| `URL` | Adresse, die geprüft wird |
| `Type` | Art der Prüfung, `1` stellt eine HTTP-GET-Anfrage |
| `CheckMode` | `always` prüft bei jedem Seitenaufruf neu, `successPersistant` und `failPersistant` merken das Ergebnis für die laufende Sitzung |
| `Timeout` | Zeitspanne in Millisekunden, innerhalb der geantwortet werden muss |

Referenz: [Abschnitt ExternSystemLiveChecks](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/externe-dienste-und-schnittstellen.md#externsystemlivechecks)

### Die Prüfdatei auf dem fremden Server

Bei einer Prüfung vom Typ 1 gilt die Antwort `OK` als Erfolg. Jede andere Antwort und jede ausbleibende Antwort gilt als Fehlschlag.

```php theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<?php
   echo "OK";
?>
```

Für eine aussagekräftigere Prüfung setzen Sie an dieser Stelle eigene Prüfungen ein, etwa auf die Erreichbarkeit einer Datenbank.

```php theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<?php
   // Eigene Prüfungen, dabei darf nichts ausgegeben werden.
   // Ergebnis in $result ablegen: true für erfolgreich, false für nicht erfolgreich.

   if ($result == true)
      echo "OK";
   else
      echo "Not OK";
?>
```

### Im Template abfragen

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{WS-ExternSystemLiveCheck(cms-available)}
   ~WS-ExternInclude(...)~
{/WS-ExternSystemLiveCheck(cms-available)}

{!WS-ExternSystemLiveCheck(cms-available)}
   Alternativer Inhalt, wenn das System nicht erreichbar ist
{/!WS-ExternSystemLiveCheck(cms-available)}
```

### Was dabei zu beachten ist

| Regel | Folge für die Praxis |
| - | - |
| Je Kennung und Seitenaufruf wird höchstens eine Anfrage gestellt | mehrfache Verwendung derselben Kennung auf einer Seite kostet nichts extra |
| Mit `successPersistant` oder `failPersistant` gilt das Ergebnis für die ganze Sitzung | eine zwischenzeitliche Erholung des Systems merkt der Shop dann nicht |
| Jede Anfrage dauert im Schnitt 300 Millisekunden | jede zusätzliche Prüfung verlängert den Seitenaufbau spürbar |
| Eine Kennung ohne gültige Konfiguration wird nicht ersetzt | ein Tippfehler in der Kennung fällt als stehengebliebenes Tag auf der Seite auf |

> [!WARNING]
>
> Die Zeitspanne in `Timeout` ist eine Abwägung. Zu kurz, und die Prüfung schlägt fehl, obwohl das System läuft. Zu lang, und jeder Ausfall des fremden Systems lähmt den Seitenaufbau für alle Besucher.

Um die Wirkung eines Ausfalls klein zu halten, klammern Sie den Bereich mit dem externen Include in eine AJAX-Sektion. Der Inhalt wird dann erst geholt, wenn der Besucher ihn anfordert, und nicht bei jedem Seitenaufruf.

Referenz: [WS-ExternSystemLiveCheck()](https://dokumentation.websale.de/v8s/referenz/tags/ws/merkzettel-vergleich-upload-und-externe-dienste.md#die-tags-im-uberblick)

Wegweiser: Funktionsweise von WEBSALE AJAX-Integrationen · Interne WEBSALE Suche bei Verwendung externer Suchdienstleister deaktivieren

## Adressdaten an ein fremdes System übergeben

Braucht das fremde System die Rechnungs- oder Lieferadresse, übergeben spezielle Tags sie in der Adresse des Aufrufs. Wie die Daten dabei geschützt werden, entscheidet ein Parameter.

### Codierung festlegen

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Basic>
   ...
   ExternalUserDataExchangePW = 1234567890123456
   ...
</Basic>
```

| Wert | Wirkung |
| - | - |
| leer | die Daten werden nur hexcodiert übertragen |
| `NOHEX` | die Daten werden uncodiert übertragen |
| 16 Zeichen | die Daten werden mit diesem Passwort per Blowfish verschlüsselt und anschließend hexcodiert |

> [!WARNING]
>
> Das Passwort muss genau 16 Zeichen lang sein. Bei jeder anderen Länge greift die Verschlüsselung nicht, und die Daten gehen lediglich hexcodiert hinaus.

### Die Tags

| Tag | Übergibt |
| - | - |
| `EXTDATA-A` | die Rechnungsadresse |
| `EXTDATA-D` | die Lieferadresse |
| `EXTDATA-U` | kundenspezifische Daten |
| `EXTDATA-ALL` | alle Daten zusammen |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<!-- Rechnungsadresse und Kundendaten unter eigenen Parameternamen -->
~WS-ExternInclude(https://domain.de/externalProg.cgi?data=$EXTDATA-A$&user=$EXTDATA-U$)~

<!-- alle Daten ohne eigene Parameternamen -->
~WS-ExternInclude(https://domain.de/externalProgXYZ.cgi?$EXTDATA-ALL$)~
```

Welche Parameternamen zu verwenden sind, bestimmt das empfangende System.

### Das Datenformat

Die Daten entstehen im XML-Format, die Feldnummer bildet dabei den Elementnamen:

```xml theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<1>Firma</1><3>Vorname</3><4>Nachname</4>
```

Übergeben wird nur, was in der `shop.config` für die jeweilige Adresse auch konfiguriert ist. Ein Feld, das der Shop nicht erhebt, taucht in der Übergabe nicht auf.

Die Felder für Rechnungs- und Lieferadresse überschneiden sich weitgehend:

| Nummer | Inhalt | Rechnungsadresse | Lieferadresse |
| - | - | - | - |
| 81 | Kundennummer | ja | nein |
| 1 | Firma | ja | ja |
| 2 | Anredecode aus `salutation.dat` | ja | ja |
| 3 | Vorname | ja | ja |
| 4 | Nachname | ja | ja |
| 5 | Titelcode aus `title.dat` | ja | ja |
| 6 | Straße 1 | ja | ja |
| 7 | Straße 2 | ja | ja |
| 8 | PLZ | ja | ja |
| 9 | Stadt | ja | ja |
| 10 | Bundesland oder Staat | ja | ja |
| 11 | dreistelliger ISO-Code des Landes | ja | ja |
| 13 | Telefon | ja | ja |
| 14 | Fax | ja | ja |
| 15 | E-Mail-Adresse | ja | ja |
| 16 | Telefon geschäftlich | ja | ja |
| 17 | Telefon mobil | ja | ja |
| 18 | Fax geschäftlich | ja | ja |
| 19 | Geburtsdatum als TT.MM.JJJJ | ja | ja |
| 20 | Postfach | nein | ja |
| 21 | Postfach | ja | nein |
| 23 bis 27 | Suffix 1 bis 5 | ja | ja |
| 28 | Departement | ja | ja |
| 29 | Kostenstelle | ja | ja |
| 30 bis 34 | Suffix 6 bis 10 | ja | ja |
| 36 | Postfach PLZ | ja | ja |
| 37 | USt-IdNr. | ja | nein |
| 78, 79, 89 | benutzerdefinierte Listen 1 bis 3 | ja | nein |

> [!WARNING]
>
> Das Postfach trägt in der Rechnungsadresse die Nummer 21 und in der Lieferadresse die Nummer 20. Wer die Felder im empfangenden System nach Nummern auswertet, muss beide Fälle unterscheiden.

Für die kundenspezifischen Daten gibt es zwei Felder:

| Nummer | Inhalt |
| - | - |
| 0 | UserIndex, bei `0` ist der Besucher nicht angemeldet |
| 17 | SuperUserID, leer bedeutet kein SuperUser |

## Ein Redaktionssystem anbinden

Dieses Kapitel wird überarbeitet. Bei Fragen wenden Sie sich bitte an Ihren WEBSALE Ansprechpartner.

Für Inhalte aus einem Redaktionssystem gibt es die beiden eingangs genannten Wege. Die Entscheidung fällt an der Frage, ob die Inhalte aktive Funktionen mitbringen.

| | JSON-Schnittstelle (empfohlen) | ExternInclude |
| - | - | - |
| Inhalte kommen | als Datei auf den Shop-Server | in Echtzeit aus dem System |
| Ausfall des Systems | ohne Auswirkung auf den Shop | die Seite bleibt leer |
| Geschwindigkeit | hoch | abhängig vom fremden System |
| Eigene Adressen und SEO | strukturiert möglich | eingeschränkt |
| Kommentare, Likes, Teilen-Funktionen | nicht möglich, nur statische Inhalte | möglich |
| Anpassung am Redaktionssystem nötig | Export im JSON-Format | Ausgabe ohne Kopf- und Fußbereich, diese liefert der Shop |

> [!WARNING]
>
> Von der Einbindung über ExternInclude raten wir ab. Die Anzeige hängt dann dauerhaft an der Erreichbarkeit des fremden Systems, und die Ladezeiten entsprechen nicht mehr dem Stand der Technik.

Jedes Redaktionssystem, das im JSON-Format exportieren kann, lässt sich anbinden.

### Wie es arbeitet

Das Redaktionssystem legt zwei Arten von Dateien auf dem FTP-Bereich des Shops ab: je Inhaltsseite eine JSON-Datei und dazu eine Mapping-Datei, die jeder Adresse ihre Datei zuordnet.

Die Adressen der Inhaltsseiten enthalten ein gemeinsames Verzeichnis, beispielsweise `/cms/`. Dieses Verzeichnis ist der Auslöser: Eine Serverregel erkennt Adressen, die damit beginnen, und leitet sie im Hintergrund auf ein Shop-Template um. Dabei wird die ursprünglich aufgerufene Adresse als One-Time-Parameter übergeben, und genau daran erkennt das Template, welche JSON-Datei es laden muss.

```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Aufruf:       https://www.ihr-shop.de/cms/Impressum
im Hintergrund: https://www.ihr-shop.de/?websale8=<Shop-ID>&tpl=tpl_cms.htm&otp1=cms/Impressum
```

Die sichtbare Adresse im Browser ändert sich dabei nicht.

### Schritt 1: Freischaltung und FTP-Zugang

Lassen Sie die JSON-Schnittstelle freischalten. Sie bekommen dafür einen eigenen FTP-Zugang für die Dateien aus dem Redaktionssystem. Auch die Adressregel muss von der WEBSALE-Systemadministration eingerichtet werden.

Drei Festlegungen gehören zu dieser Einrichtung. WEBSALE setzt dafür Standardwerte, abweichende Wünsche teilen Sie bei der Einrichtung mit:

| Festlegung | Standard |
| - | - |
| Template für die Anzeige der Inhalte | `tpl_cms.htm` |
| Verzeichnis in der Adresse | `/cms/` |
| One-Time-Parameter | `OTP1` |

Verwenden Sie `OTP1` bereits für etwas anderes, nennen Sie bei der Einrichtung einen anderen Parameter. Sonst überschreiben sich die beiden Verwendungen gegenseitig.

### Schritt 2: Inhalte exportieren

Je Inhaltsseite entsteht eine JSON-Datei, die in das FTP-Verzeichnis der Schnittstelle hochgeladen wird.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
   "id": 1,
   "attributes": {
      "wsContentHeadline": "Impressum",
      "wsTemplateName": "tpl_imprint",
      "locale": "de",
      "wsMetaInformation": {
         "wsMetaTitle": "Impressum des Demoshops",
         "wsMetaDescription": "Hier stehen weitere Informationen zum Impressum",
         "wsPageSeoURL": "cms/Impressum",
         "wsMetaRobots": "noindex,nofollow"
      },
      "wsContent": [
         {
            "__component": "elemente.ws-column",
            "wsContentColumn": [
               {
                  "wsContentColumnMarkup": "<p>Lorem ipsum dolor.</p>",
                  "wsClassList": "col-12"
               }
            ]
         }
      ]
   },
   "content_type": "contentpage"
}
```

### Schritt 3: Mapping-Datei exportieren

Die Mapping-Datei verbindet Adresse und Datei.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
   "mappings": [
      { "url": "cms/Impressum",   "file": "tpl_imprint.json" },
      { "url": "cms/Datenschutz", "file": "tpl_privacy.json" }
   ]
}
```

### Schritt 4: Das Template anlegen

Ein einziges Template genügt für alle Inhaltsseiten, weil der One-Time-Parameter und die Mapping-Datei die Steuerung übernehmen.

Zuerst wird die Mapping-Datei geladen und darin die aufgerufene Adresse gesucht:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(global,index-mapping.json,wsMapping)~
{EJD-DataOK(wsMapping)}
   ~EJD-SetUseID(wsMapping)~
   ~EJD-DA-TouchArrayElements(mappings)~
   ~DC-ZeroLoop1_set($EJD-LastValueAccessed$)~
   ~DC-Counter1_reset~
   {DC-ZeroLoop1}
      {@DC-ZeroLoop1}
         ~EJD-DA-TouchValue(mappings[$DC-ZeroLoop1_position$].url)~
         {DC-CompareStringInList($EJD-LastValueAccessed$,$WS-OTP1$)}
            ~EJD-DA-TouchValue(mappings[$DC-ZeroLoop1_position$].file)~
            ~DC-FPjsonData_set($EJD-LastValueAccessed$)~
         {/DC-CompareStringInList($EJD-LastValueAccessed$,$WS-OTP1$)}
      {/@DC-ZeroLoop1}
   {/DC-ZeroLoop1}
{/EJD-DataOK(wsMapping)}
```

Die Schleife läuft über alle Einträge der Mapping-Datei, vergleicht die Adresse mit dem One-Time-Parameter und legt bei einem Treffer den Dateinamen im freien Platzhalter `DC-FPjsonData` ab.

Danach wird diese Datei geladen und ausgelesen. Das folgende Beispiel setzt die Angaben für den Kopfbereich der Seite:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{DC-FPjsonData}
   ~EJD-LoadData(subshop,$DC-FPjsonData$,wsCMS)~
   ~EJD-SetUseID(wsCMS)~

   ~DC-FPjsonMeta_set(attributes.wsMetaInformation)~

   {!EJD-DA-IsNull($DC-FPjsonMeta$.wsMetaTitle)}
      <title>~EJD-DA-Value($DC-FPjsonMeta$.wsMetaTitle)~</title>
   {/!EJD-DA-IsNull($DC-FPjsonMeta$.wsMetaTitle)}

   {!EJD-DA-IsNull($DC-FPjsonMeta$.wsMetaDescription)}
      <meta name="description" content="~EJD-DA-Value($DC-FPjsonMeta$.wsMetaDescription)~">
   {/!EJD-DA-IsNull($DC-FPjsonMeta$.wsMetaDescription)}

   {!EJD-DA-IsNull($DC-FPjsonMeta$.wsMetaRobots)}
      <meta name="robots" content="~EJD-DA-Value($DC-FPjsonMeta$.wsMetaRobots)~">
   {/!EJD-DA-IsNull($DC-FPjsonMeta$.wsMetaRobots)}
{/DC-FPjsonData}
```

Daraus entsteht:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<title>Impressum des Demoshops</title>
<meta name="description" content="Hier stehen weitere Informationen zum Impressum">
<meta name="robots" content="noindex,nofollow">
```

Die Klammerung `{DC-FPjsonData}` prüft, ob überhaupt eine Datei gefunden wurde. Ohne sie versucht das Template, eine Datei ohne Namen zu laden.

Referenz: EJD-Tags für die JSON-Schnittstelle

Wegweiser: [JSON-Schnittstelle](https://dokumentation.websale.de/v8s/externe-dienste/json-schnittstelle.md)

## Verwandte Themen

* Wegweiser: [JSON-Schnittstelle](https://dokumentation.websale.de/v8s/externe-dienste/json-schnittstelle.md)
* Wegweiser: Funktionsweise von WEBSALE AJAX-Integrationen
* Wegweiser: [Daten mit externen Systemen austauschen](https://dokumentation.websale.de/v8s/externe-dienste/daten-mit-externen-systemen-austauschen.md)


## Related topics

- [Externe Dienste: Übersicht](https://dokumentation.websale.de/v8s/externe-dienste/externe-dienste.md)
- [Daten mit externen Systemen austauschen](https://dokumentation.websale.de/v8s/externe-dienste/daten-mit-externen-systemen-austauschen.md)
- [ContentControl- (Weiterleitungskonzept für Inhalte aus Drittsystemen)](https://dokumentation.websale.de/v8s/referenz/tags/contentcontrol.md)
- [WWS-Infodatenschnittstelle verwenden](https://dokumentation.websale.de/v8s/externe-dienste/wws-infodatenschnittstelle.md)
- [Integration von FINDOLOGIC](https://dokumentation.websale.de/v8s/externe-dienste/integration-von-findologic.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.