Individualisierung und die XML-Import Schnittstelle
...
er Sinn der XML-Import Schnittstelle ist es, bestehende Inhalte mehrfach zu nutzen. Wenn Sie im Besitz eines Content-Management-Systems sind, können Sie XML-Files erstellen bzw. kann das System dies für Sie tun. Wichtig für das System ist die XML-konforme Struktur der Files. Diese spielen Sie in das Verzeichnis ~/XMLImport.
Die importierbaren XML-Files müssen wie das folgende Beispielfile aufgebaut sein:
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <FILE> <META NAME="FELDNAME1">Wert1</META> <META NAME="FELDNAME2">Wert2</META> </FILE> |
Die erste Zeile ist ein Standard-XML-Header und muss in jedem File, das importiert werden soll, enthalten sein. Als nächster XML-TAG steht der <FILE>-TAG, der zusammen mit dem abschließenden </FILE>-TAG die eigentlich zu importierenden Daten umschließt. Bitte achten Sie auf die Groß-/Kleinschreibung der TAGs, wenn Sie mit XML-TAGs und XML-Files arbeiten.
...
Mit Hilfe von GIS-API können Sie auf die, über die XML-Schnittstelle eingespielten, Inhalte zugreifen und diese nach bestimmten Regeln automatisch in Ihre Newsletter einarbeiten. Außerdem enthält die Sprache alle Elemente, um Conditionen wie IF ... THEN ... ELSE usw. zu verarbeiten. Dieses Kapitel richtet sich an den Systemadministrator/Programmierer. Wie oben bereits beschrieben, kann dieser den doch recht komplexen Funktionsumfang sehr elegant und einfach anwendbar durch die Funktionalität von GIS-SUBSTITUTION den Redakteuren zur Verfügung stellen. Mehr dazu lesen Sie im Kapitel GIS-SUBSTITUTION. Innerhalb von beliebigen Newslettern können Sie jederzeit GIS_API - Blöcke einfügen. Sämtliche GIS_API-Befehle stehen hierbei zwischen zwei Tags.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<GIS> Hier steht der Code </GIS> |
...
Zwischen dem Start-TAG (<GIS>) und dem End-TAG (</GIS>) stehen die eigentlichen Anweisungen von GIS_API. Diese werden im Folgenden detailliert erklärt. Das generelle Vorgehen besteht darin, bestimmte Feldwerte einzulesen, zu sortieren und zugehörige Daten formatiert auszugeben. Es folgt ein Beispiel, bei dem das Datenbankfeld "UEBERSCHRIFT" eingelesen wird und alle Daten nach Aktualität sortiert ausgegeben werden.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST FOREACH {PRINT "<<UEBERSCHRIFT>>" } </GIS> |
Dies ist ein erstes Beispiel. Im weiteren Verlauf gehen wir davon aus, dass die unten aufgeführten vier XML-Files in BACKCLICK importiert wurden.
File 1:
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <FILE> <META NAME="DIRECTORY">/a/b/c</META> <META NAME="FILENAME">ABC.HTML</META> <META NAME="UEBERSCHRIFT">ABC Ueberschrift 1</META> <META NAME="TEXT">ABC_TESTFILE.HTML</META> <META NAME="CONTENT_SOURCE">BACKCLICK</META> <META NAME="CONTENT_ID">1</META> </FILE> |
File 2:
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <FILE> <META NAME="DIRECTORY">/d/e/f</META> <META NAME="FILENAME">DEF.HTML</META> <META NAME="UEBERSCHRIFT">DEF Ueberschrift 1</META> <META NAME="TEXT">DEF_TESTFILE.HTML</META> <META NAME="CONTENT_SOURCE">BACKCLICK</META> <META NAME="CONTENT_ID">2</META> </FILE> |
File 3:
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <FILE> <META NAME="DIRECTORY">/g/h/i</META> <META NAME="FILENAME">GHI.HTML</META> <META NAME="UEBERSCHRIFT">GHI Ueberschrift 1</META> <META NAME="TEXT">GHI_TESTFILE.HTML</META> <META NAME="CONTENT_SOURCE">BACKCLICK</META> <META NAME="CONTENT_ID">3</META> </FILE> |
File 4:
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <FILE> <META NAME="DIRECTORY">/j/k/l</META> <META NAME="FILENAME">JKL.HTML</META> <META NAME="UEBERSCHRIFT">JKL Ueberschrift 1</META> <META NAME="TEXT">JKL_TESTFILE.HTML</META> <META NAME="CONTENT_SOURCE">BACKCLICK</META> <META NAME="CONTENT_ID">4</META> </FILE> |
Alle nun folgenden Beispiele werden sich immer wieder auf die Daten aus diesen vier Files beziehen. File 1 ist das älteste File und File 4 ist das jüngste. Um die Resultate selbst nachvollziehen zu können, müssen Sie in BACKCLICK die Files einzeln im Abstand von 2 Minuten ins System überspielen. Das garantiert eine zeitliche Einordnung der Datensätze.Nun müssen Sie in das Menü Newsletter schreiben wechseln und eine beliebigen Verteilerliste auswählen. In das Texteingabefeld geben Sie nun bitte folgendes ein:
Code Block |
---|
| |||||||
| |||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST FOREACH { PRINT "<<UEBERSCHRIFT>>\n" } </GIS> |
Bitte rufen Sie nun das Vorschaufenster auf. Sie werden bei aktiviertem personalisieren und individualisieren folgende Ausgabe sehen:
Grundlagen der GIS-API Sprache - Syntax
Der READ - Befehl:
Wie im oberen Beispiel deutlich wird, wird der READ-Befehl dafür verwendet, sämtliche Daten des Feldes <<UEBERSCHRIFT>> einzulesen. Die doppelten, spitzen Klammern zeigen GIS_API hierbei an, dass es sich um einen Feldnamen handelt. Dieses Feld wurde über die 4 XML-Files importiert und ist dem System somit verfügbar. Wie mit <<UEBERSCHRIFT>> kann auch mit allen anderen Feldnamen verfahren werden. Wenn zum Beispiel das Feld DIRECTORY eingelesen werden soll, geben Sie einfach
...
Nun bauen wir unser Beispiel von oben um einen weiteren Befehl aus. Angenommen, Sie möchten nicht alle vier Überschriften ausgeben, sondern nur die ersten beiden, dann haben Sie den Befehl SHRINK zur Verfügung. Dieser reduziert die Ergebnisliste, z. B.:
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST SHRINK "2" FOREACH { PRINT "<<UEBERSCHRIFT>>\n" } </GIS> |
Dies hat zur Folge, dass nur die zwei aktuellsten Überschriften ausgegeben werden. Die Ausgabe wäre dann:
...
Mit dem Befehl SHRINK BY "FELDNAME" können Sie die Ergebnisliste auf die Einträge reduzieren, die das Feld "FELDNAME" enthalten. Angenommen, File 4 hätte kein TEXT-Feld und Sie würden folgende Befehlssequenz eingeben:
Code Block |
---|
| |||||||
| |||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST SHRINK BY <<TEXT>> FOREACH { PRINT "<<UEBERSCHRIFT>> " } </GIS> |
So wäre die Ausgabe:
GHI Ueberschrift 1
...
SHRINK BY <<UEBERSCHRIFT>> IN "A" TO "D"
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST SHRINK BY <<UEBERSCHRIFT>> IN "A" TO "D" FOREACH { PRINT "<<UEBERSCHRIFT>>\n" } </GIS> |
Wenn Sie den Befehl wieder in das Beispiel einfügen, wird folgendes ausgegeben:
...
erzwingt nach jeder ausgegebenen UEBERSCHRIFT einen Zeilenumbruch. Sie können anstelle der Anführungszeichen auch geschweifte Klammern verwenden.
Code Block | |||||
---|---|---|---|---|---|
| |||||
| |||||
PRINT {<<UEBERSCHRIFT>><<TEXT>> } oder PRINT {<<UEBERSCHRIFT>>\n<<TEXT>>\n} |
Das ergibt eine Bildschirmausgabe (wenn Sie diese Befehlszeilen in das Beispiel einfügen), die wie folgt aussieht:
...
Nachdem eine Trefferliste über den READ-Befehl eingelesen wurde, kann man, nachdem die Liste nach beliebigen Kriterien sortiert (SORT) und gefiltert (SHRINK) wurde, diese Ergebnisliste mittels des FOREACH-Befehls durchgehen und Aktionen (PRINT) mit den jeweiligen Treffern durchführen.
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST SHRINK BY "TEXT" FOREACH {PRINT "<<UEBERSCHRIFT>>\n"} </GIS> |
Die FOREACH-Anweisung besteht immer aus dem eigentlichen Befehl FOREACH und den oben fett hervorgehobenen geschweiften Klammern. Die Trefferliste, die mit READ <<UEBERSCHRIFT>> gebildet wurde, wird innerhalb der geschweiften Klammern Eintrag für Eintrag in der entsprechend sortierten Reihenfolge durchgegangen. Alle Anweisungen innerhalb der geschweiften Klammern beziehen sich beim Durchlaufen auf den jeweiligen Eintrag der Trefferliste, das bedeutet, wenn alle Datensätze mit dem Feld <<UEBERSCHRIFT>> eingelesen werden und durch die FOREACH-Schleife gehen, haben Sie Zugriff auf alle Elemente eines Eintrages. So können Sie z. B. zusätzlich zu dem Feld <<UEBERSCHRIFT>> auch gleichzeitig auf alle anderen Datenfelder des jeweiligen Treffers zugreifen. Oben wurde bereits das Beispiel mit den <<TEXT>>-Feldern angeführt. Beim Durchlaufen der Ergebnisliste wird dann nicht nur die Überschrift eines jeden Datensatzes, sondern auch noch das <<TEXT>>-Feld ausgegeben. Sie können generell immer auf ALLE Felder eines Treffers zugreifen. FOREACH-Schleifen können Sie auch beliebig schachteln !!!
...
Um eine Trefferliste in umgekehrte Reihenfolge zu bringen (z. B. um die ältesten Beiträge zuerst oder alles in umgekehrt alphabetischer Reihenfolge auszugeben), benutzen Sie den Befehl VICE VERSA. Wenn wir das Beispiel folgendermaßen abändern:
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST VICE VERSA FOREACH { PRINT "<<UEBERSCHRIFT>>\n"} </GIS> |
...
Nachdem Sie eine Trefferliste erzeugt haben, haben Sie die Möglichkeit, mit Hilfe des Befehls COPYLIST eine temporäre Kopie zu erzeugen. Wenn Sie die reguläre Liste mit Hilfe des Befehls CLEAR löschen, können Sie die mit COPYLIST erzeugte Liste wieder mit Hilfe des Befehls READLIST zurücklesen. Das folgende Beispiel verdeutlicht die Funktionalität.
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<GIS> READ <<UEBERSCHRIFT>> SORT LATEST FIRST FOREACH {PRINT "<<UEBERSCHRIFT>>\n"} PRINT "\n" COPYLIST CLEAR READ <<TEXT>> SORT LATEST FIRST VICE VERSA FOREACH {PRINT "<<TEXT>>\n"} READLIST PRINT "\n" FOREACH {PRINT "<<UEBERSCHRIFT>>\n"} PRINT "\n" </GIS> |
Sie erhalten folgende Ausgabe:
...
Diese Ausgabe wird durch den COPYLIST- und den READLIST-Befehl bewirkt. Nach dem CLEAR-Befehl im Beispiel wird eine andere Liste in einer anderen Sortierreihenfolge eingelesen. Anschließend wird wieder die zuerst eingelesene Trefferliste durch READLIST reaktiviert und deren Inhalt erneut ausgegeben. Sie können auch die Datenfelder erneut über READ einlesen lassen, COPYLIST und READLIST sind jedoch um Größenordnungen schneller! Wenn Sie mehrere Listen parallel abspeichern möchten, so können Sie den Kopien auch Namen geben und anschließend gezielt auf einzelne Listen zugreifen. Angenommen, Sie haben eine Trefferliste eingelesen und möchten sie unter dem Namen "Liste1" abspeichern, so erfolgt dies durch die folgenden Befehlszeilen:
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<GIS> READ <<DIRECTORY>> COPYLIST "Liste1" SHRINK "2" FOREACH {PRINT "<<DIRECTORY>>\n"} PRINT "\n\n" READLIST "Liste1" FOREACH {PRINT "<<DIRECTORY>>\n"} </GIS> |
Die Ausgabe wäre folgende:
...
/a/b/c
Hier eine Variation:
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<GIS> READ <<DIRECTORY>> COPYLIST "Liste1" SHRINK "2" FOREACH {PRINT "<<DIRECTORY>>\n"} PRINT "\n\n" COPYLIST "Liste2" READLIST "Liste1" FOREACH {PRINT "<<DIRECTORY>>\n"} PRINT"\n\n" READLIST "Liste2" FOREACH {PRINT "<<DIRECTORY>>\n"} PRINT"\n\n" </GIS> |
Die Ausgabe wäre folgende
...
Hier ein Beispiel zur Ausgabe von Variablen-Werten:
Code Block |
---|
| |||||||
| |||||||
<GIS> VAR #C1# #0# PRINT "'#C1#' ist der Wert von C1\n" ADDVAR #C1# #2# PRINT "'#C1#' ist der Wert von C1\n" SUBVAR #C1# #1# PRINT "'#C1#' ist der Wert von C1\n" </GIS> |
Die Ausgabe wäre folgende:
...
Mit der Befehlssequenz #C1# LISTLENGTH können Sie der Variablen C1 die aktuelle Länge der Trefferliste zuweisen. Angenommen, Sie haben folgende Zeilen eingegeben:
Code Block |
---|
| |||||||
| |||||||
<GIS> READ <<DIRECTORY>> VAR #C1# LISTLENGTH PRINT "#C1# ist die Länge der Liste\n" </GIS> |
Diese Angaben hätten folgende Ausgabe zur Folge:
...
Eine Bedingung (CONDITION) ist eine unäre oder binäre Operation, deren Ergebnis entweder wahr (TRUE, >=1) oder unwahr (FALSE, <1) ist. Eine unäre Operation ist eine Operation mit nur einem Operanden. Eine binäre Operation ist ein Vergleich oder eine beliebige Operation mit zwei Operanden. Innerhalb von Bedingungen können Sie auf beliebige GIS_API -Variablen, auf Datenbank-Feldwerte, EVAL-Blöcke und EXPR-Ausdrücke zurückgreifen, diese beliebig schachteln (Rekursion) und durch Klammerpaare zu komplexeren Bedingungen gruppieren.
Mögliche Operanden: | Mögliche Operationen: | |
<<FELDNAME>> | AND (b) | |
#Wörter# #Buchstaben# | OR (b) | |
#Zahlen# | NOT (u) | |
#VARIABLEN# | EQUALS (b) | |
EXPR-Anweisungen | LT (less than) (b) | |
TRUE | LE (less equal) (b) | |
FALSE | GT(greater than) (b) | |
GE(greater equal) (b) | ||
MATCHES (b) | ||
STARTS (b) | ||
ENDS (b) |
Am besten werden diese Sachverhalte anhand folgender Beispiele deutlich:
Code Block |
---|
| |||||||
| |||||||
<GIS> READ <<DIRECTORY>> FOREACH { IF(<<TEXT>>){ PRINT {Der Artikel unter <<DIRECTORY>> enthält den Text \n <<TEXT>>} } ELSE{PRINT "Es gibt keinen Text zu <<DIRECTORY>>" } } </GIS> <GIS> READ <<FILENAME>> FOREACH { IF(<<DIRECTORY>> OR <<TEXT>>){ PRINT {Das File <<FILENAME>> enthält entweder Daten über das DIRECTORY oder den Text\n"} } ELSE{PRINT "Es gibt keine Daten zu <<FILENAME>>" } } </GIS> |
Schachteln von IF/ELSE-Bedingungen:
Wie schon kurz erwähnt, können Sie die Bedingungen mit Hilfe von Klammern beliebig schachteln.
Beispiel:
Code Block | |||||||
---|---|---|---|---|---|---|---|
| |||||||
| |||||||
<GIS> TRUE VAR #C1# #Testing funktioniert# IF( (#ABCDEF# ENDS #DEF#) OR (#123# GT #12#)){ PRINT "TRUE\n" IF(#C1# MATCHES #unktio#){ PRINT "Klappt alles \n\n" } } ELSE{PRINT "FALSE" } </GIS> |
Befehls-Übersicht zusätzliche GIS_API-Befehle
Alle kursiven Zeichen sind Namen (Bsp. #Testname#)
SKIP THIS RECIPIENT
Dieser Befehl sorgt dafür, dass der Newsletter nicht an den aktuellen Empfänger verschickt wird. (Dies kann sinnvoll sein, wenn für den Empfänger keine neuen Informationen vorliegen.)
PRINTDATE "FORMAT" "SPRACHE"
Dieser Befehl gibt das Datum eines Contentdatensatzes aus. Dies wird in dem Format ausgegeben, welches in "FORMAT" definiert wurde. Das Format wird in der Datei gis_cl.conf erläutert. "SPRACHE" gibt an, in welcher Sprache zum Beispiel Monatsnamen ausgegeben werden. Mögliche Werte sind 'de', 'en', 'nl', 'fr'.
...
Hier ein paar Beispiele:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
IF($$INTERESSEN$$ MATCHES "Sport"){ PRINT"Neues vom Fußball ......\n" } IF($$ANREDE$$ EQUALS "Frau"){ PRINT"Das neue Parfum von XY pour Femme wird Sie ....." } |
ACHTUNG: Bitte achten Sie bei bedingten Verzweigungen (IF/ELSE) darauf, Konditionen immer zu gruppieren! Das heißt, dass Sie Gruppen von Operand-Operator-Operand immer in Klammerpaare setzen müssen. Hier ein Beispiel:
Code Block | |||||
---|---|---|---|---|---|
| |||||
| |||||
IF( ($$VORNAME$$ MATCHES "Peter") AND ($$NAME$$ EQUALS "Test")){} |
...
Befehle, um Daten in das Profil zurück zu schreiben
...
Die folgenden Befehle werden dazu verwendet, während des Versands eines Newsletters über eine beliebige GIS-API-Logik Daten in das Profil des aktuellen Empfängers zurück zu schreiben. Dieser Mechanismus kann zum Beispiel dazu verwendet werden, im Abonnentenprofil zu speichern, welchen Content er bereits zugeschickt bekam.
...
Mit diesem Befehl kann man die Anzahl der Werte des Feldes FELDNAME auf eine bestimmte Anzahl (ZAHL) reduzieren. #VARIABLENWERT# muss hierbei eine Zahl sein! Die übrig gelassenen Werte sind die aktuellsten Werte. Dieser Befehl eignet sich z. B. gut dafür, um ein Feld, dem permanent aktuelle Werte zugeordnet werden, bei einer maximalen Anzahl aktueller Werte zu halten und so die Performance von GIS-API nicht linear zu senken.
Spezielle Variablen
Die spezielle Variable #CONTENTKEY# kann beliebig verwendet werden. In ihr steht immer der aktuelle, intern verwendete Schlüssel für einen Content-Datensatz, der in einer FOREACH-Anweisung bearbeitet wird. Diese Variable kann dazu verwendet werden, in das jeweils aktuelle Abonnentenprofil gespeichert zu werden und durch eine bedingte Verzweigung dabei anzuzeigen, ob ein Abonnent den jeweiligen Content schon gelesen hat oder nicht.Das folgende Beispiel hilft dies zu verdeutlichen. Es handelt sich um ein einfaches Beispiel, mit dem verhindert wird, dass ein Abonnent denselben Content mehrfach zugesendet bekommt. Dies ist besonders für vollautomatisch erstellte und versendete Newsletter sehr wichtig.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<GIS> READ <<DIRECTORY>> SORT LATEST FIRST SHRINK 100 VAR #TITEL# ## VAR #COUNTER# #1# FOREACH { IF(#COUNTER# le #10#){ IF( <<TITEL>> EQ ## ){} ELSE{ IF($$PREVCONTENT$$ EQ "#CONTENTKEY#"){ PRINT"Wir möchten Sie nicht mit Dingen belästigen, die Sie schon längst gelesen haben.\nDenn '<<TITEL>>' kennen Sie schon!\n\n" } ELSE{ INSERT $$PREVCONTENT$$, "#CONTENTKEY#" REDUCE $$PREVCONTENT$$, 100 PRINT "#COUNTER#. Diese Artikel haben Sie noch nicht gelesen:\n'<<TITEL>>'\n\n" ADDVAR #COUNTER# #1# } } } } </GIS> |
...