CMS Handbuch – Entwickler

Technische Referenz und Entwicklerdokumentation für das batix® CMS

Einführung & Grundlagen

Konzepte, Tag-Grundlagen, Filter, Datums-Patterns, Redakteurs-Tags.

Einführung & Grundlagen

Filter

Um mittels Code einfacher zu filtern, gibt es die Hilfsklasse Records (siehe Beschreibung).

Filter können z.B. in Zusammenhang mit bx:containerfilter oder Container-Filteraction verwendet werden, um bestimmte Datensätze anzuzeigen.

Aufbau eines Filters

Filter werden in XML angegeben. Der grundlegende Aufbau ist folgender:

<filter>
  <filter-object>
    ...
  </filter-object>
  <filter-object>
    ...
  </filter-object>
  <order/> <!-- ab Version 2.5.7 -->
  <limit/> <!-- ab Version 2.5.7 -->
  <status/> <!-- ab Version 2.6.1 -->
</filter>


Eine Mehrfachverwendung von "filter-object" bewirkt eine UND-Verknüpfung dieser Objekte.

Objekte

Ein "filter-object" ist folgendermaßen aufgebaut:

<filter-object [required="true"]>
  <field>...</field>
  <field>...</field>
  <type>...</type>
  [
   <request-value>...</request-value>
  |<static-value>...</static-value>
  |<special-value>...</special-value>
  |<request-attribute>...</request-attribute>
  |<session-attribute>...</session-attribute>
  ]
</filter-object>


Eine Mehrfachverwendung von "field" bewirkt eine ODER-Verknüpfung der Felder. Die optionale Angabe von required="true" bewirkt, dass ein Wert, der zum Vergleichen übergeben wird (z.B. bei "request-value") auch vorhanden sein muss, d.h. wenn nichts übergeben wird, wird die Bedingung auch nicht erfüllt.

field

Der Name des zu überprüfenden Feldes wird angegeben. Falls das Feld eine Verknüpfung darstellt (Untercontainer, Einzelverknüpfung, Mehrfachverknüpfung), kann auch der Wert eines Feldes der Verknüpfung abgefragt werden, dazu einfach das gesuchte Unter-Feld mit einem Schrägstrich anfügen.

<field>feldname</field>
<field>feldname/unterfeld</field>     <!-- Untercontainerfeld -->

type

Hier wird die Art des Vergleiches angegeben. Je nach Typ des Feldes, das geprüft wird, sind verschiedene Vergleiche möglich. Diese sind der folgenden Tabelle zu entnehmen. Verglichen wird dabei der Feldwert mit dem Testwert, so ließt sich z.B. die erste Zeile der Tabelle "Feldwert enthält Testwert" oder die Zeile bei Bildern/Dokumenten "Feldwert ist leer".

Feld-Typ Type Art des Vergleiches:
Feldwert ... [Testwert]
einzeiliger oder mehrzeiliger Text 1 enthält
2 beginnt mit
3 endet mit
4 ist gleich
5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
6 Mustervergleich (Regex)
7 enthält eines der Wörter von
(Wörter durch Leerzeichen oder Kommas trennen, findet auch Teilstrings)
8 ist eines der Wörter von
(Wörter durch Leerzeichen oder Kommas trennen, nur ganze Wörter)
9 enthält alle Wörter
(Wörter durch Leerzeichen oder Kommas trennen)
11 - 19 leer ODER Bedingung
Bedingung auch erfüllen, falls Feld leer ist (außer für type 5)

z.B.: type 14 für "ist gleich oder leer"
21 - 29 NICHT-Bedingung
kehrt die Bedingung um (außer für type 5)
z.B.: type 23 für "endet nicht mit"
31 - 39 leer ODER NICHT-Bedingung
Kombination von 11 - 19 und 21 - 29

z.B.: type 32 für "beginnt nicht mit oder ist leer"
Datum mit oder ohne Zeit 1 Feld ist größer (neuer) als übergebener Wert
2 Feld ist kleiner (älter) als übergebener Wert
3 ist gleich (Uhrzeit wird ignoriert)
4 ist ungleich (Uhrzeit wird ignoriert)
5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
6 ist im Jahr (vierstellig angeben)
7 ist im Monat (gültige Werte: 1-12)
8 ist am Tag (gültige Werte: 1-31)
11 Feld ist größer oder gleich als übergebener Wert
12 Feld ist kleiner oder gleich als übergebener Wert
21 Feld ist leer oder größer/gleich als übergebener Wert
22 Feld ist leer oder kleiner/gleich als übergebener Wert
31 Feld ist größer/gleich als heute + Testwert Tage
32 Feld ist kleiner/gleich als heute + Testwert Tage
nur (Uhr)Zeit 1 Feld ist größer (später)
2 Feld ist kleiner (früher)
3 Feld ist gleich
4 Feld ist ungleich
11 Feld ist größer/gleich
12 Feld ist kleiner/gleich
21 Feld ist leer oder größer/gleich
22 Feld ist leer oder kleiner/gleich
6 Feld ist in Stunde (0-23)
7 Feld ist in Minute (0-59)
8 Feld ist in Sekunde (0-59)
5 Feld ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
Zahl oder Preis 1 Feld ist größer gleich als übergebener Wert
2 Feld ist kleiner gleich als übergebener Wert
11 Feld größer als übergebener Wert
12 Feld kleiner als übergebener Wert
3 ist gleich
4 ist ungleich
5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
21 - 24 leer ODER Bedingung (1 bis 4)
31 - 32 leer ODER Bedingung (11 und 12)
Wahrheitswert (Boolean) 4 ist angehakt/gesetzt
5 ist leer (null)
Bild 1 bestimmte ID ist verknüpft
4 nicht-gelöschtes Bild ist verknüpft (ab v2.6.2)
5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
Dokument 5 ist leer
8 bestimmte ID ist verknüpft
Kartenkoordinaten 21 x ist gleich
26 y ist gleich
5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
Einzelverknüpfung 8 Datensatz-ID ist gleich
10 Datensatz-ID ist ungleich
Bei mehreren IDs, Filter mehrmals verwenden.
9 Datenlisten-ID ist gleich (nur bei alten Containern)
12 enthält eine der Datensatz-IDs von
(IDs durch Leerzeichen, Komma oder Semikolon trennen)
5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
4 ist verknüpft (ab 2.6.2)
3 ist aktiviert (ab 2.6.2)
Mehrfachverknüpfung 8 enthält Datensatz-ID
10 enthält Datensatz-ID nicht (ab v2.6.2)
12 enthält eine der Datensatz-IDs von
(IDs durch Leerzeichen, Komma oder Semikolon trennen)
14 enthält alle der angegebenen IDs
5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)
Untercontainer 5 ist leer (Feld soll leer sein: static-value: 1, Feld soll nicht leer sein: static-value: 0)

value

Der gesuchte Wert kann auf unterschiedliche Weise übergeben werden. Für <value>...</value> können die folgenden Abfragen eingesetzt werden.

request-value

Der Vergleich findet mit dem Wert eines Request-Parameters statt.

<request-value>Request-Parameter-Name</request-value>

request-attribute

Der Vergleich findet mit dem Wert eines Request-Attributes statt.

<request-attribute>Request-Attribut-Name</request-attribute>

session-attribute

Ein Session-Attribut wird mit dem Feld verglichen.

<session-attribute>Session-Attribut-Name</session-attribute>

static-value

Der Wert zum Vergleichen wird direkt übergeben.

<static-value>gesuchter Wert</static-value>

special-value

Es wird ein spezieller Wert zum Vergleich herangezogen.

TODAY Es wird mit dem heutigen Datum im Format dd.MM.yyyy verglichen. Um Tage dazu zu addieren (oder abzuziehen) kann das Attribut days verwendet werden (ganze Zahl, die auch negativ sein kann).
<special-value [days="n"]>TODAY</special-value>
NOW Es wird mit der aktuellen Zeit im Format dd.MM.yyyy mm:HH verglichen. Um Tage, Stunden oder Minuten dazu zu addieren (oder abzuziehen) können die Attribute days, hours oder minutes verwendet werden (ganze Zahl, die auch negativ sein kann).
<special-value [days="n"] [hours="n"] [minutes="n"]>NOW</special-value>
USERID Es wird mit der UserID des aktuellen (eingeloggten) Betrachters verglichen.
<special-value>USERID</special-value>
SESSIONID Die aktuelle SessionID wird abgeglichen.
<special-value>SESSIONID</special-value>
USERGROUPS Dieser Spezialwert erzeugt eine Zeichenkette, welche die ID des Users sowie die IDs der Gruppen, denen er angehört, enthält (jeweils durch Leerzeichen getrennt).
<special-value>USERGROUPS</special-value>
PARENTCONTAINER Es wird mit der ID des übergeordneten Containers verglichen.
<special-value>PARENTCONTAINER</special-value>

clipboard-value

Es wird ein spezieller Clipboard-Wert zum Vergleich herangezogen.

system-value

Es wird der Wert einer Systemvariablen zum Vergleich herangezogen. Die Systemvariable wird unter "Systemeinstellungen" angelegt und gespeichert.

order

Hier wird ein Sortierfeld definiert.

<order field="{Feldname}" [direction="{ascending|descending}"] />

Bei "field" wird der Feldname angegeben, nach dem sortiert wird. Sortiert werden kann nach einzeiligen Text, Datumtypen und Zahlentypen. Bei "direction" wird "ascending" für aufsteigende Sortierung, und descending für absteigende Sortierung angegeben. Bei weglassen der Sortierrichtung wird aufsteigend sortiert.

Diese Funktion ist ab v2.5.7 verfügbar

limit

Hier wird eine Startposition und ein überlauf in der Ergebnisliste definiert

<limit [index="{feste Startposition}"] [max="{Anzahl bis überlauf}"] />

Bei "index" wird die Startposition in der Ergebnisliste angegeben. Standardwert ist 0 für den ersten Datensatz. Bei max wird angegeben, wie viele Datensätze maximal (je Seite) angezeigt werden. Standardwert ist -1 für keine Einschränkung. Bei Angabe von max im bx:containerfilter wird diese Einstellung überschrieben.

Diese Funktion ist ab v2.5.7 verfügbar

status

Es kann angegeben werden, ob aktive und/oder inaktive Datensätze gefiltert werden sollen.

<status active="{false| true}" inactive="{false| true}" />

Erklärt sich - glaube ich - von selbst.

Diese Funktion ist ab v2.6.1 verfügbar

ID-Filter

zum Filtern der Datensatz-ID oder mehrerer IDs - getrennt durch Komma

<filter-id type="include" request-value="paramname" />
<filter-id type="include" request/session-attribute="paramname" />
<filter-id type="include" system/clipboard-value="paramname" /> <!-- ab v2.6.2 -->
<filter-id type="include">feste_id</filter-id>

Gegenteil von include: exclude (schließt diese ID(s) aus) (weitere Erläuterungen folgen noch)

Beispiele

Datumsvergleich

<filter>
  <filter-object>
    <field>Datum</field>
    <type>11</type>
    <special-value days="-1">TODAY</special-value>
 </filter-object>
</filter>

Es werden nur Datensätze angezeigt, die maximal einen Tag alt sind.

Suche

<filter>
  <filter-object>
    <field>Kategorie</field>
    <type>8</type>
    <request-value>kat</request-value>
  </filter-object>
  <filter-object>
    <field>Titel</field>
    <field>Text</field>
    <type>1</type>
    <request-value>search</request-value>
  </filter-object>
  <filter-object>
    <field>Archiv</field>
    <type>4</type>
    <static-value>0</static-value>
  </filter-object>
</filter>

Nur Datensätze, die folgenden Kriterien entsprechen werden ausgegeben:

Einführung & Grundlagen

Parameter-Werte (Präfixe)

Mit den folgenden Präfixen kann man auf verschiedene Variablen zugreifen:

Diese Präfixe können als Wert jedes Tag-Attributes verwendet werden.

Nur bei bx:containerfilter:

ab 2.6.2.

Einführung & Grundlagen

Pattern bei Datum

Pattern Entsprechung
d Tages im Monat ohne vorangestellter 0 bei einstelligen Zahlen (z.B. 5.12.2013)
dd Tages im Monat mitvorangestellter = (z.B. 05.12.2013)
M Monatsangabe ohne vorangestellter 0 bei einstelligen Zahlen (z.B. 12.5.2016)
MM Monatsangabe mit vorangestellter 0 (z.B. 12.05.2016)
MMM Monatsangebe als Text (z.B. 12.Mai.2016)
yy Zahresangabe zweistellig (z.B. 12.05.16), führt evtl. zu Missverständnissen (2016 oder 1916?)
yyyy Jahresangabe vierstellig (z.B. 12.05.2016)
EE Wochentagsausgabe als Text gekürzt (z.B. Mo, Di, Mi...)
EEE Wochentagsausgabe als Text ungekürzt (z.B. Montag, Dienstag, Mittwoch...)
H Ausgabe der Stunde ab 0 Uhr ohne vorangestellter 0 bei einstelligen Zahlen (z.B. 3:40 Uhr)
HH Ausgabe der Stunde ab 0 Uhr mit vorangestellter 0 (z.B. 03:40 Uhr)
mm augabe der minuten (z.B. 03:40 Uhr)
ss Ausgabe der Sekunden (z.B. 03:23:34 Uhr)

Weitere Infos und Ausgabemöglichkeiten auf der offiziellen JavaDoc-Seite

Beispiele

<bx:tools.datum pattern="dd.MM.yyyy HH:mm:ss"/>

Ausgabe eines Zeitstempels, z.B. 13.03.2016 13:48:33

Angebote im Monat <bx:recordfield.Datum pattern="MMM"/>

Ausgabe des Monatsnamen

Einführung & Grundlagen

Redakteurs-Tags

Titel

<bx:tag.{titel} />

Alle Unterstriche / Underscores ( _ ) im {titel} Platzhalter werden in der Verwaltung durch Leerzeichen ersetzt. Zum Beispiel wird dann aus

<bx:text.Haupt_Titel />

dieses Feld in der Verwaltung:

image2014-1-26 23:12:4.png

Mehrfachverwendung

Wird der gleiche {titel} mehrfach in einem Template oder in mehreren Templates im selben Menüpunkt verwendet, so stellt sich das Tag in der Verwaltung nur einmal dar. Der Redakteur muss den gewünschten Inhalt also nur an einer Stelle einpflegen. Alle gleichnamigen Tags werden dann mit diesem Inhalt versorgt.

Es ist darauf zu achten, nur gleichartige Tags mit dem selben {titel} zu versehen. So machen z.B. <bx:text.Titel /> und <bx:bild.Titel /> im selben Menüpunkt keinen Sinn.

Rechts neben dem Titel in der Verwaltung wird angezeigt, in welchen Templates ein Tag mit diesem Titel verwendet wird. Wird ein Tag in mehreren Templates verwendet, sieht dies z.B. so aus:

image2014-1-26 23:12:14.png

Es wird versucht etwaige Parameter der Tags sinnvoll zusammenzufassen. So wird z.B. bei bx:text der maximale Wert aller Tags für maxlength genommen.

Kommentar

<bx:tag.{titel} [comment="{kommentar}"] />

In {kommentar} kann ein zusätzlicher Beschreibungstext angegeben werden, der in der Verwaltung unterhalb des Titels angezeigt wird. Beispiel:

Eingabefeld mit Kommentar

<bx:text.Titel comment="Dies ist der große Titel direkt unter dem Headerbild." />

image2014-1-26 0:26:36.png

Admin-Mode

<bx:tagname.Titel admin-mode="config" /> 

Erzwingt, daß das Tag bei den Tageinstellungen (anstatt bei Dateneingabe) angezeigt wird. So sehen es die Redakteure nicht mehr und können es nicht mehr kaputtmachen. Bei <bx:containerfilter> wird das schon automatisch so gemacht. Jetzt lässt es sich auch per Parameter bei anderen Tags steuern.

Beispiele

<bx:text.farbcode admin-mode="config"/>
<bx:textarea.xml type="plain" wrap="off" admin-mode="config"/>
<bx:pageinclude.teaserpfad admin-mode="config"/>

Einige Beispiele, wo dies sinnvoll sein könnte.

Admin-Titel

<bx:tagname.Titel admin-title="{anderer Titel}" /> 

In Verwaltung wird ein anderer Titel ausgeben als der beim Tag angegebene.

Beispiele

<bx:bild.picture admin-title="Großes Logo"/>

genauere Bezeichnung des "picture"

<bx:textarea.Haedline admin-title="Headline"/>

im Nachhinein einen Schreibfehler zu korrigieren, wenn das Design schon oft in Gebrauch ist

Diese Tags können sich in der Verwaltung darstellen:

Batix-Tags Referenz

Vollständige Referenz aller bx: Tags, alphabetisch.

Batix-Tags Referenz

Batix-Tags Referenz

Hinweis für (fast) alle Tags: für Parameterwerte können auch Präfix-Variablen eingesetzt werden.

Kategorie Tags
Container-Tags bx:containerdata | bx:containerfilter
bx:containerloop | bx:containersearch
bx:record | bx:recordchoice
bx:recorddata | bx:recordfield
bx:tablechoice | bx:tabledata
bx:tablefield | bx:tablefilter
bx:tablekat | bx:tableloop
bx:tablerecord | bx:tablesqlfilter
bx:userrecord | bx:validation
Einfache Elemente bx:bild | bx:datum
bx:dezimal | bx:document
bx:email | bx:optional
bx:text | bx:textarea
bx:titel
Includes bx:cmpageinclude | bx:groovy
bx:include | bx:javainclude
bx:jspinclude | bx:pageinclude
Listen/Schleifen bx:designloop | bx:loop
bx:schleife
Navigation bx:browse | bx:internlink
bx:navigation | bx:navlink
bx:sitemap | bx:submenu
Zugriffskontrolle bx:access | bx:login
bx:userdata | bx:userrecord
Sonstige bx:admincomment | bx:barcode
bx:calendarfield | bx:calendarloop
bx:choice | bx:clipboard
bx:contact | bx:cookie
bx:directorylisting | bx:documentlist
bx:editbutton | bx:evaluate
bx:frame | bx:head
Bx:i18n | bx:if
bx:ignore | bx:json
bx:link | bx:mapping
bx:math | bx:option
bx:pagedata | bx:paypal
bx:plugin | bx:relativelink
bx:scanner | bx:secureform
bx:sessiondata | bx:statistik
bx:systemdata | bx:tools
bx:websearch | bx:xml
Veraltet/Deprecated bx:containerkat | bx:gif
bx:news | bx:search
bx:submenulist

Syntax-Konventionen

<bx:tag1.{command} static="value" [not] />
<bx:tag2 [optional="(option1 | option2)"] />
<bx:tag3 [first | last] />
<bx:tag4 required="(option1 | option2)">{content}</bx:tag> <!-- 'content' darf auch leer sein -->

Zur besseren Lesbarkeit steht ein Leerzeichen vor dem Ende selbstschließender Tags, also vor />.

Platzhalter sind mit { } umschlossen (siehe command und content). Im Beschreibungstext der Tags werden die Platzhalter genauer bestimmt, z.B. welche Werte oder Typen zugelassen sind.

Optionaler Code ist mit [ ] umschlossen (siehe notoptional und first / last). Dies bedeutet, dass dieser Bereich komplett weggelassen werden kann.

Pflichtauswahlen werden mit ( ) und Auswahlen, die auch komplett weggelassen werden können, werden mit [ ] umschlossen. Die jeweiligen Möglichkeiten sind durch | getrennt.

Falls unbedingt nötig, sind Kommentare in der Form <!-- Kommentartext --> eingefügt, diese Art der Beschreibung sollte allerdings nur in Ausnahmefällen auftauchen.

Diese Beispiele sind laut der obigen Definition valide:

<bx:tag1.replace static="value" />
<bx:tag2 />
<bx:tag2 optional="option1" />
<bx:tag3 />
<bx:tag3 first />
<bx:tag4 required="option2">Lorem Ipsum</bx:tag>

Die folgenden Beispiele sind allerdings nicht valide (das Kommentar hinter jedem Beispiel beschreibt warum):

<bx:tag1 static="value" />       <!-- der Platzhalter 'command' muss gefüllt werden -->
<bx:tag1.replace />              <!-- der Parameter 'static' muss exakt aus der Definition übernommen werden -->
<bx:tag2 optional="option3" />   <!-- 'option3' steht nicht zur Auswahl -->
<bx:tag2 optional="" />          <!-- es muss eine der Optionen gewählt werden -->
<bx:tag3 middle />               <!-- 'middle' steht nicht zur Auswahl -->
<bx:tag4 required=""></bx:tag>   <!-- es muss eine Option für 'required' gewählt werden, leerer Taginhalt ist laut Kommentar in Ordnung -->
Batix-Tags Referenz

bx:access

Der Inhalt des Tags access wird nur ausgegeben, wenn der Intranetbenutzer Zugriff auf einen gewählten Pfad besitzt.

<bx:access [ path="{pfad}" | current ] [not] [quiet]> Inhalt </bx:access>
<bx:access.{bez} [ size="{n}" ] [ maxlength="{n}" ] [not] [quiet]> Inhalt </bx:access.<bez>>

In der ersten Form wird der Pfad über den Parameter path festgelegt oder mit current der aktuelle Menüpunkt bezeichnet. Falls dieser aber über die Verwaltung eingegeben werden soll, muss die zweite Form benutzt werden. Mittels size und maxlength lassen sich dann Textfeldbreite und maximale Eingabelänge festlegen. In jedem Fall erfolgt die Angabe des Pfades relativ, d.h. ohne /www/webname/. not kehrt das Verhalten um, der Inhalt wird also nur angezeigt, wenn der User keine Berechtigung hat. quiet bewirkt, dass kein Fehler ausgegeben wird, falls der Pfad nicht gefunden wird. .

Batix-Tags Referenz

bx:admincomment

Mit dem Tag admincomment kann man in der Redakteursansicht in der Verwaltung einen Hinweistext zur Datenpflege ausgeben. Die Eingabe des Textes erfolgt auf der "Tag-Einstellungen"-Seite (wo die XML-Containerfilter stehen) in einem mehrzeiligen Textfeld. ab V 2.6.3 RC14

<bx:admincomment.Name headless type="html"/>

Möglichst weit oben einfügen, damit der Hinweistext auch ganz oben steht.

headless Überschrift (Name des Tags) wird weggelassen.
type Es kann HTML eingegeben werden.

in Schleifen

Das Tag funktioniert auch in Unterschleifen. Allerdings muß dann der Parameter loopable mit angegeben werden.

<bx:admincomment.Name loopable/>

Sollte erst ab v2.7.1 verwendet werden. Es gibt momentan keine "Tag-Einstellungen"-Ansicht in Unterschleifen. Bei <bx:containerfilter> mit loopable wird die XML-Konfig. deshalb in der Redakteursansicht gezeigt. Dieses Tag zeigt ab v2.7.1 für Redakteure nur den Text und für Admins die Bearabeiten-Ansicht an. "Redakteur" bedeutet in diesem Fall, daß das "Quelltexte"-Modul freigeschaltet ist.

als offenes Tag

Als offenes Tag mit Kommentar direkt im Design geht jetzt.

<bx:admincomment.Name>
  Kommentar
  zweite Zeile
</bx:admincomment.Name>

<bx:admincomment.Name type="html">
  <strong>Kommentar:</strong><br>
  zweite Zeile
</bx:admincomment.Name>
Batix-Tags Referenz

bx:barcode

Mit dem Tag barcode können verschiedene 1D und 2D-Codes erzeugt werden (Beispiele siehe unten). Ein Check auf Fehler ist mit bx:if möglich. Die Größe ist frei wählbar. Das erzeugte Format ist PNG (ggf. mit Transparenz)

Allgemeine Syntax

<bx:barcode.qr width="250" height="250" [type="path"] [rotate="90"]> Inhalt </bx:barcode.qr>

Parameter für alle Typen

width und height Geben die Größe des Barcodes an.
Ein weißer Rand ist teilweise automatisch enthalten und kann bei manchen Typen auch beeinflusst werden.
type image: (Standard) es wird ein img-Tag erzeugt, Parameter wie style oder class im Barcode-Tag werden in das img-Tag übernommen.
path: es wird nur der Pfad zum Bild ab "/" zurückgegeben (ohne Host, falls Haupthost-Haken im Projekt nicht gesetzt wurde).
url: es wird eine komplette URL zum Bild zurückgegeben (aufgerufener Host oder Projekt-Haupthost).
rotate Positive Werte drehen das erzeugte Bild im Uhrzeigersinn, negative Werte entgegen (in Grad, z.B. 90).
Die Größe des erzeugten Bildes wird neu berechnet, um den rotierten Barcode unterzubringen (Hintergrund ggf. transparent).

Es ist generell empfehlenswert einen minimalen Kontrast-Rand (z.B. in weiß) zu setzen, damit Barcodeleser den Code einfacher identifizieren können.

Es kann weitere Einschränkungen, je nach offizieller Spezifikation des jeweiligen Barcode-Types, geben, die hier nicht extra aufgeführt sind.Die Ausgabegröße des Barcode-Bilds musst nicht exakt der angegebenen `width` / `height` entsprechen (liegt aber zumindest nicht darüber). Falls eine pixelgenaue Ausgabe benötigt wird, sollte ein Container um das Bild gepackt werden.

Typ-spezifische Informationen

Die gezeigten Beispiele müssen nicht unbedingt den Anforderungen des jeweiligen Standards entsprechen! Es können also auch potentiell invalide Barcodes entstehen. Es ist die Spezifikation des jeweiligen Types zu Rate zu ziehen!

1-Dimensionale Codes

Bei allen 1-dimensionalen Codes kann der parameter margin verwendet werden. Dieser legt die Größe des Randes links und rechts fest (0 für keinen Rand, Standard ist 10).

Typ
Ausgabe
Einschränkungen
<bx:barcode.codabar> image2015-11-27 9:48:1.png"12345" Beginnt und endet mit einem Guard-Zeichen aus: ABCD.
ODER beginnt und endet mit einem Guard-Zeichen aus: TN*E.
Falls keine Guards gesetzt sind, wird automatisch A genommen.
Enthält nur Zeichen aus: 0123456789-$:/.+
<bx:barcode.code_39> image2015-11-27 9:54:42.png"BATIX" maximal 80 Zeichen aus: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%
<bx:barcode.code_93> image2015-11-27 10:23:18.png"BATIX" maximal 80 Zeichen aus: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*
<bx:barcode.code_128> image2015-11-27 10:26:21.png"BATIX" maximal 80 Zeichen
<bx:barcode.itf>
(Interleaved Two of Five)
image2015-11-27 10:32:32.png"123456" Weniger als 80 Ziffern, gerade Anzahl
Am besten 6, 10, 12, 14, 16, 24, oder 44 Ziffern
<bx:barcode.ean_8> image2015-11-27 10:34:44.png"12345678" genau 8 Ziffern
<bx:barcode.ean_13> image2015-11-27 10:36:37.png"1234567891118" genau 13 Ziffern
Prüfziffer muss stimmen
<bx:barcode.upc_a> image2015-11-27 10:40:2.png"12345678910" genau 11 Ziffern (ohne Prüfziffer, wird automatisch berechnet)
ODER genau 12 Ziffern (mit Prüfziffer)
<bx:barcode.upc_e> image2015-11-27 10:43:3.png"12345678" genau 8 Ziffern

2-Dimensionale Codes

<bx:barcode.qr>

Ausgabe

image2015-11-27 9:45:35.png
"http://batix.de"

Parameter

ecl
gibt das ErrorCorrectionLevel an:

Einschränkungen

Die Länge des verschlüsselten Strings kann die Ausgabe beeinflussen.


<bx:barcode.datamatrix>

Ausgabe

image2015-11-27 11:45:10.png image2015-11-27 11:50:45.png "http:/batix.de" (rechts mit shape=square)
image2015-11-27 11:47:0.png image2015-11-27 11:50:0.png "Lorem ipsum dolor sit amet" (rechts mit shape=rectangle)

Parameter

shape


<bx:barcode.aztec>

Ausgabe

image2015-11-27 12:35:47.png
"http://batix.de"

Parameter

ecl
gibt das ErrorCorrectionLevel an (in %, (0 - 100)), 25 sollte Minimum sein.

layers
gibt die Anzahl der Aztec-Layer an

charset
gibt den Zeichensatz an, der zur Codierung des Inhaltes verwendet werden soll.
Standard ist utf-8.


<bx:barcode.pdf_417>

Ausgabe

image2015-11-27 12:50:36.png
"BATIX"

Parameter

margin
legt die Größe des Randes rundherum fest

ecl
gibt das ErrorCorrectionLevel an.
0 - 8, Standard ist 2.

charset
gibt den Zeichensatz an, der zur Codierung des Inhaltes verwendet werden soll.
Standard ist utf-8.

compact
kompakten Modus benutzen? true oder false.
Standard ist false.

compaction
welcher Verdichtungsmodus benutzt werden soll.

dimensions

Fehlerabfrage

<bx:if><bx:barcode.ean_8>1234</bx:barcode.ean_8><bx:if.else>Es konnte leider kein Barcode erzeugt werden!</bx:if.else></bx:if>

Da bx:barcode im Fehlerfall nichts ausgibt, kann ein alternativer Text mittels bx:if ausgegeben werden.

Beispiele

<bx:barcode.qr>Hallo</bx:barcode.qr>
 
<bx:barcode.datamatrix shape="rectangle">Hallo</bx:barcode.datamatrix>
Batix-Tags Referenz

bx:bild

Das Tag bild fügt ein Bild aus der Bildergalerie in das Dokument ein und lässt vielfältige Möglichkeiten zur Formatierung. Falls dasselbe Bild mehrmals verwendet werden soll, kann { titel} mehrmals verwendet werden mit z.B. verschiedenen Größenangaben.

Dieses Tag kann sich in der Verwaltung darstellen.

Bild anzeigen mit Größenangabe und Ausrichtung

<bx:bild.{titel} [width="{n}"] [height="{n}"] [align="(left | right | leftright | rightleft)"] [alt="{text}"] [comment={komentar}] />
width, height Breiten- bzw Höhenangabe in Pixel; Bilder, die kleiner sind als diese Größenangaben werden jedoch nicht vergrößert. Ist keine Höhe und Breite angegeben, wird das Bild in Originalgröße dargestellt.
cover nimmt die größere Angabe, z.B. bei Querformat wird die Höhe, bei Hochformat die Breite genommen (ab V 2.6.3, ansonsten bei 2.6.2 reinkopieren)
cover="crop" Originalbild wird abgeschnitten und auch so gespeichert
align links- bzw. rechtsseitige Ausrichtung; leftright/rightleft: die Bilder werden abwechselnd ausgerichtet, beginnend links bzw rechts

Beispiele

einfache Anzeige mit Alt-Angabe

<bx:bild.Seitenbild width="700" height="150" alt="Seitenbild dieser Seite" />

Anzeige mit Kommentar in der Verwaltung

 <bx:bild.Seitenbild width="200" height="300" align="right" comment="nichts ausgewählt: Text zieht sich über die gesamte Breite" />

Ausgabeart festlegen

<bx:bild.{titel} [type="(path | url | origwidth | origheight | title | author | alt | calcwidth | calcheight | id | inline)"] />
path / url es wird nur der lokale Pfad bzw die URL zum Bild ausgegeben (z.B. Angabe im img-tag oder bei Wechsel der Grafik durch JavaScript)
origwidth / origheight schreibt nur die Originalbreite oder -höhe (z.B. für Popup-Fenster)
title der ursprüngliche Dateiname (gespeichert direkt in der Bildergalerie beim Bild)
author Autor, falls keiner angegeben "null" (gespeichert direkt in der Bildergalerie beim Bild)
alt der Alternativtext (gespeichert direkt in der Bildergalerie beim Bild)
calcwidth / calcheight die berechnete Größe (unter Beachtung von width und height) wird ausgegeben
empty Abfrage, ob ein Bild verknüpft wurde (ab v 2.7.0), not kehrt die Bedingung um
id ID in der Bildergalerie (ab v 2.6.2)
inline erzeugt img-Tag mit Binärdaten in src (ab 2.6.1), sinnvoll bei Newsletter, da steht das Bild direkt in der Seite, also nicht als Link oder Anhang
base64data Tagerweiterung für vcf (Outlook-Visitenkarte) mit Foto ab v2.6.6

Beispiele

Anzeige mit img-tag, Angaben kommen alle aus der Bildergalerie

<img src="<bx:bild.Seitenbild width="200" height="300" type="url"/>" alt="<bx:bild.Seitenbild type="alt"/>" 
  title="<bx:bild.Seitenbild type="title"/>, Autor:<bx:bild.Seitenbild type="author"/>" >

Weitere Angaben

<bx:bild.{titel} [hspace="{n}"] [vspace="{n}"] [kategorie="{kat}"] [force] [nogifshrink] [border="{n}"] [noborder] />
vspace, hspace Vertikal- bzw. Horizontalabstand einstellen (in Pixel)
nogifshrink falls das Bild ein GIF ist und es nicht automatisch verkleinert werden soll,  Animationen bleiben so erhalten
kat, force es kann der Name einer Kategorie der Bildergalerie angegeben werden, aus der das Bild gewählt werden kann. Wenn zusätzlich noch force gesetzt ist, kann die Kategorie in der Verwaltung nicht gewechselt werden.
border, noborder Einstellen der Rahmenbreite bzw. Rahmen abstellen
Batix-Tags Referenz

bx:browse

Das Tag browse gibt benachbarte Menüpunkte (ebenenübergreifend) zum Zweck des Blätterns aus.

<bx:browse.previous>Linktext</bx:browse.previous>
<bx:browse.previous (level="{level}" | root="{pfad}") [loop]>Linktext</bx:browse.previous>
<bx:browse.next>Linktext</bx:browse.next>
<bx:browse.next (level="{level}" | root="{pfad}"} [loop]>Linktext</bx:browse.next>
root übergeordneter Menüpunkt, der nicht verlassen werden soll; leer = alles
loop Erzeugen einer Endlosliste (wenn es in einer Richtung nicht mehr weiter geht, wird am anderen Ende neu begonnen)
level Ebenentiefe
Batix-Tags Referenz

bx:calendarfield

Mit dem Tag calendar kann man in einem Kalender Datumseinträge aus einem Container abbilden.

Beispiel eines Kalenders unter "Kalender bauen"

calendarfield.if

<bx:calendarfield.if prevmonth | nextmonth | currentmonth | weekend | today | activeday | firstweekday | lastweekday | mark [parametername="false"]> Inhalt </bx:calendarfield.if>

Nur in CalendarLoop Schleife zu verwenden. Bei Angabe mehrere Parameter werden diese mit „und" verknüpft. Die Angabe [Parametername]="false" negiert diesen.

prevmonth prüft, ob Datum zum vorhergehenden Monat gehört
nextmonth prüft, ob Datum zum nächsten Monat gehört
currentmonth prüft, ob Datum zum aktuellen Monat gehört
weekend prüft, ob Datum zu einem Wochenende gehört
today prüft, ob Datum gleich dem heutigen Datum ist
activeday prüft, ob Datum das Aktuelle ist
firstweekday prüft, ob Datum der erste Wochentag ist (Montag)
lastweekday prüft, ob Datum der letzte Wochentag ist (Sonntag)
mark prüft, ob Datum ein markiertes ist

Beispiele

...
<bx:calendarfield.if currentmonth="false">class="othermonth"</bx:calendarfield.if>
...

Abfrage der Tage, die nicht zum angezeigten Monat gehören(, um sie z.B. andersfarbig zu markieren) Siehe auch "Kalender bauen"

calendarfield.day

<bx:calendarfield.day [pattern="{pattern}"] [link]/>
<bx:calendarfield.day> Inhalt </bx:calendarfield.day>

Gibt den Tag aus. Auch als offenes Tag nutzbar, um auf die beinhalteten DS zuzugreifen z.B. <bx:calendarfield.day><bx:recordfield.Titel/></bx:calendarfield.day>

pattern Ausgabeformat angeben, Standard: dd
link Ausgabe erfolgt in Form activeday=dd.MM.yyyy (Wenn bei activedayrequest des CalendarLoop ein anderer Name definiert wurde erfolgt die Ausgabe mit diesem Namen.)

calendarfield.week

<bx:calendarfield.week [object="{loopname}"] [link={prev | next}] />

object Name der CalendarLoop Schleife, wenn außerhalb verwendet
link Ausgabe erfolgt in Form activeday=dd.MM.yyyy mit jeweils Tage +7 oder -7 (mit Kalender berechnet) (Wenn bei activedayrequest des CalendarLoop ein anderer Name definiert wurde erfolgt die Ausgabe mit diesem Namen.)

calendarfield.month

<bx:calendarfield.month [object="{loopname}"] [pattern="{pattern}"] [link={previous | next}] />

Gibt den aktuellen Monat aus.

object Name der CalendarLoop Schleife, wenn außerhalb verwendet
pattern Ausgabeformat angeben, Standard: MM
link Ausgabe erfolgt in Form activeday=dd.MM.yyyy mit jeweils Monat +1 oder -1 (mit Kalender berechnet) (Wenn bei activedayrequest des CalendarLoop ein anderer Name definiert wurde erfolgt die Ausgabe mit diesem Namen.)

calendarfield.year

<bx:calendarfield.year [object="{loopname}"] [pattern="{pattern}"] [link={previous | next}] />

Gibt das aktuelle Jahr aus.

object Name der CalendarLoop Schleife, wenn außerhalb verwendet
pattern Ausgabeformat angeben, Standard: yyyy
link Ausgabe erfolgt in Form activeday=dd.MM.yyyy mit jeweils Jahr +1 oder -1 (mit Kalender berechnet) (Wenn bei activedayrequest des CalendarLoop ein anderer Name definiert wurde erfolgt die Ausgabe mit diesem Namen.)

calendarfield.today

<bx:calendarfield.today [object="{loopname}"] [pattern="{pattern}"] [link] />

Gibt den heutigen Tag aus.

Ein anderes Datum als das heutige für today angeben: today="dd.MM.yyyy" angeben oder über den Request mit Angabe des Parameternamens mit todayrequest="" (Standard: today) - (Angabe in der Schleifendefinition)

object Name der CalendarLoop Schleife, wenn außerhalb verwendet
pattern Ausgabeformat angeben, Standard: dd.MM.yyyy
link Ausgabe erfolgt in Form activeday=dd.MM.yyyy, (Wenn bei activedayrequest des CalendarLoop ein anderer Name definiert wurde erfolgt die Ausgabe mit diesem Namen.)

calendarfield.activeday

<bx:calendarfield.activeday [object="{loopname}"] [pattern="{pattern}"] />

Gibt den aktiven Tag aus (Request). Ein anderes Datum als das heutige für den aktuellen Tag angeben: activeday="dd.MM.yyyy" angeben oder über den Request mit Angabe des Parameternamens mit activedayrequest="" (Standard: activeday) - (Angabe in der Schleifendefinition)

object Name der CalendarLoop Schleife, wenn außerhalb verwendet
pattern Ausgabeformat angeben, Standard: dd.MM.yyyy
Diese Funktionalität wurde umgesetzt mit Unterstützung unseres Partners Obtineo (www.obtineo.de).
Batix-Tags Referenz

bx:calendarloop

Das Tag calendarloop benötigt man zur Erzeugung eines Kalenders mit Container-Anbindung. Siehe auch Kalender bauen

<bx:calendarloop.{bezeichner} pool="{ID}" datestart="Datum_Beginn" dateend="Datum_Ende" [type="monthly | weekly"] [today="{dd.MM.yyyy}"] [todayrequest="{dd.MM.yyyy}"] [activeday="{dd.MM.yyyy}"] [activedayrequest="{dd.MM.yyyy}"]>
  Inhalt
</bx:calenderloop.{bezeichner}>

In der Administration kann zusätzlich ein Filter definiert werden, wie beim ContainerFilter Tag. Innerhalb der Schleife kann mit bx:calenderfield auf die einzelnen Felder zugegriffen werden.

pool ID des Containers (geht leider nicht mit Namensangabe)
datestart Angabe des Feldes mit dem Startdatum
dateend Angabe des Feldes mit dem Enddatum (kann weg gelassen werden)
type Monats- oder Wochenanzeige
today Festangabe eines Datums
todayrequest anderer Requestname als der Standardname (today)
activeday Festangabe eines Datums
activedayrequest anderer Requestname als der Standardname (activeday)
Diese Funktionalität wurde umgesetzt mit Unterstützung unseres Partners Obtineo (www.obtineo.de).
Batix-Tags Referenz

bx:choice

Das Tag choice zeigt seinen Inhalt abhängig vom aktuellen Hauptmenüpunkt an (z.B. für mehrsprachige Templates).

<bx:choice root="<nav>"> Inhalt </bx:choice>
Batix-Tags Referenz

bx:clipboard

Das Tag clipboard wird verwendet, um sich Werte oder (Quell)Texte zu merken und später auf der Seite wieder auszugeben. Ausgaben von anderen Tags, welche selbst keine Vergleichsfunktionen bieten, können so auch ausgewertet werden (dazu einfach die Ausgabe des Tags mit clipboard.cut abfangen und danach mit clipboard.if vergleichen).

clipboard.copy

<bx:clipboard.copy name="{name}" [trim]> Inhalt </bx:clipboard.copy>

Schreibt den Inhalt in das Clipboard und gibt ihn auch auf der Seite aus.

name Name des Clipboard, wird auch unter diesem Namen wieder eingefügt
trim Entfernt Leerzeichen und Zeilenumbrüchen an Anfang und Ende des gespeicherten und auch des anzuzeigenden Bereiches (ab v2.5.7)

clipboard.cut

<bx:clipboard.cut name="{name}" [trim]> Inhalt </bx:clipboard.cut>

Schreibt den Inhalt in das Clipboard und gibt ihn aber nicht aus. Erklärung der Parameter: siehe oben

clipboard.paste

<bx:clipboard.paste [encode="typ"] name="{name}"/>

Gibt den Inhalt des Clipboards aus.

encode Hiermit kann der ausgegebene Text für verschiedene Formate kodiert werden:htmljavascriptsql (zur Verwendung in SQL für Strings)sql-like (zur Verwendung in SQL mit LIKE)sql-rlike (zur Verwendung in SQL mit RLIKE und REGEXP)urlxml

clipboard.clear

<bx:clipboard.clear/>

Löscht alle Clipboard-Einträge. Um einen einzelnen Eintrag zu Löschen kann <bx:clipboard.cut name="Name"/> verwendet werden.

clipboard.append

<bx:clipboard.append [name="{bereich1}"] [trim]>...</bx:clipboard.append>

Fügt den Inhalt des Tags zu den bereits gespeicherten Daten hinzu, anstatt die Daten (wie bei cut) zu überschreiben. Der spätere paste-Befehl kann dann die zusammengetragenen Daten ausgeben.

Beispiele

<bx:clipboard.cut name="Test">Hallo </bx:clipboard.cut>
<bx:clipboard.append name="Test">Welt</bx:clipboard.append>
Ausgabe "<bx:clipboard.paste name="Test"/>"

Am Ende wird "Hallo Welt" ausgegeben.

clipboard.if

<bx:clipboard.if [name="{name}"] value="{text}" [not] [trim]> Inhalt </bx:clipboard.if>
<bx:clipboard.if [name="{name}"] value="clipboard:{name}" [not] [trim]> Inhalt </bx:clipboard.if>
<bx:clipboard.if [name="{name}"] contains="{text}" [not]> Inhalt </bx:clipboard.if>
<bx:clipboard.if [name="{name}"] regex="{regex}" [not] [trim]> Inhalt </bx:clipboard.if>
<bx:clipboard.if empty [name="{name}"] [not] [trim]>

Damit ist es möglich, einen bestimmten Inhalt abzufragen. (ab Version 2.5.9)

name Titel des Clipboards
value contains regex Clipboardinhalt wird mit text verglichen, Ausgabe des Tag-Inhalts bei Übereinstimmung (equals ist ein Alias von value) Ausgabe des Tag-Inhalts, wenn text im Clipboardinhalt enthalten ist Ausgabe des Tag-Inhalts, wenn der Clipboardinhalt dem regex entspricht (matches ist ein Alias von regex)
trim entfernt Leerzeichen und Zeilenumbrüchen an Anfang und Ende des Clipboard-Inhalts für die Prüfung
not kehrt die Funktionalität um
empty Abfrage, ob Clipboard leer oder nicht gesetzt ist

Beispiele

<bx:clipboard.copy name="text">Hallo Welt </bx:clipboard.copy>
<bx:clipboard.if name="text" value="hallo welt" trim>angezeigt</bx:clipboard.if>
<bx:clipboard.if name="text" contains="welt">angezeigt</bx:clipboard.if>
<bx:clipboard.if name="text" regex=".*Welt ">angezeigt</bx:clipboard.if>
Batix-Tags Referenz

bx:cmpageinclude

Mit dem Tag cmpageinclude können Sie andere CM-Seiten einbinden. Es ist eine Erweiterung von Bx:include. In der Administration kann aus einer Dropdown-Liste die gewünsche Seite ausgewählt werden (es muss keine URL angegeben werden).

Dieses Tag kann sich in der Verwaltung darstellen.

<bx:cmpageinclude.<bezeichner> navid="{navid}" [jsp] [sendnav] />
navid ID eines Menüpunktes, von dem die Unterpunkte auswählbar sein sollen
sendnav die NavID der Seite wird als Request-Parameter "nav" der einzubindenden Seite übergeben
jsp echter JSP-Include

Beispiele

<div id="teaser"> 
  <bx:schleife.Teaser list="Titel">
    <!-- <bx:text.Titel/> -->
    <bx:cmpageinclude.Teaser_auswaehlen navid="14304C19DD0"/>
  </bx:schleife.Teaser>
</div> 

Dynamische Teaserauswahl beliebig vieler Teaser auf einer Menüpunkt-Verwaltungs-Seite. Es wurde ein Menüpunkt Teaser (mit der Navid 14304C19DD0) angelegt mit den einzelnen Teasern als Unterpunkte, die dann auswählbar sind.

Batix-Tags Referenz

bx:contact

Mit Hilfe des Tags  contact kann ein Kontaktformular erstellt werden. Die Ziel-Adresse kann über die Administration eingegeben werden. Wenn nichts eingegeben wird, wird die EMail-Adresse aus den Kundendaten genommen.

<bx:contact.{bez} [comment="{text}"] [name="{form}"] [onSubmit="{js}"] [nextpage="{seite}"]> Inhalt </bx:contact.{bez}>

Die Gestaltung des Formulars erfolgt als Inhalt des Tags. Es müssen nur noch Textfelder, Erklärungen, Submit-Button etc. erstellt werden.

comment zeigt zusätzlichen Text in der Verwaltung an
name werden für das Formular übernommen
onSubmit werden für das Formular übernommen
nextpage Folgeseite
Batix-Tags Referenz

bx:containerdata

Das Tag containerdata zeigt zusätzliche Daten in bx:containerloop an. Wegen Systemkompatibilität unterstützt dieses Tag nicht das Interface ContainerLoop. Wenn Daten zu anderen Containerklassen benötigt werden kann bx:recorddata benutzt werden.

ID

<bx:containerdata.id />

Diese Funktion gibt die ID des Datensatzes aus.

Titel

<bx:containerdata.titel />

Es wird der Titel des Datensatzes angezeigt.

ID = Request-Parameter

<bx:containerdata.isrequest [name="{parametername}"]> Inhalt </bx:containerdata.isrequest>

Der Inhalt wird nur ausgegeben, wenn der Requestparameter <parametername> die ID des aktuellen Datensatzes enthält.

parametername Request-Parameter
Falls "name" nicht gesetzt ist, wird der Standardwert "recordid" benutzt.
Batix-Tags Referenz

bx:containerfilter

Mit dem Tag containerfilter kann man eine Containerliste (spezifiziert durch die Container-ID oder den Container-Namen) nach Bedingungen filtern und aktivierte Elemente, die zutreffen, in einer Schleife durchlaufen lassen. Der Tag-Inhalt wird dabei für jedes gefundene Element ausgeführt.

Falls {titel} angegeben ist, wird in der Administration ein Eingabefeld für die Filter-Bedingungen angezeigt (zu finden rechts in der Toolbox unter "Tag-Einstellungen"). Alternativ kann auch eine Bedingung direkt im Tag angegeben werden.

Dieses Tag kann unter Tag-Einstellungen konfiguriert werden.

mehrere Elemente (statische Angabe)

<bx:containerfilter.{titel} pool="(ContainerID | Containername)" force="list | top | standalone | match" [max="{n}"] [orderby="{feldname}"] [desc] [startindex="{n}"] [sql] [evalbx] [nulls-at-end] [id-descending-order] [force-parameter-reset] [loopable]>
  Inhalt
</bx:containerfilter.{titel}>

Die Parameter stehen statisch im Quelltext.

titel frei wählbarer Name des Filters
pool ID oder Name des Containers (ab Vers. 2.6.0)
force Eine passende Wahl des Modus anhand der gewünschten Funktionen (einer oder mehrere Datensätze, Filterung ja/nein, Blättern ja/nein) trägt erheblich zur Performance-Steigerung bei, falls im Container sehr viele Datensätze vorhanden sind. So empfiehlt sich z.B. immer ein Modus ohne Blättern zu wählen, falls das Blättern nicht gebraucht wird. Die folgende Tabelle gibt Aufschluss über die verschiedenen Modi und zeigt jeweils, ob die Datensätze anhand der Filterung eingeschränkt werden bzw. ob ein Blättern möglich ist.
Achtung: Fehlt die Modusangabe, wird bei Vorhandensein des Standard-Requestparameters recordid eine Detailausgabe (force=single) ausgegeben, ansonsten eine Liste (force=list). Eine explizite Angabe von force wird empfohlen!
force= Beschreibung
list Liste von Datensätzenfür Standard-Blätterlisten
top Liste von Datensätzen z.B. zur Anzeige der 3 aktuellsten News als Teaser
single ein einzelner Datensatz, Übergabe der ID im Request Detailseite mit Einzel-Blätterfunktion zu einer Standard-Blätterliste
match ein einzelner Datensatz, Übergabe der ID im Request geeignet für eine Detailseite mit Berechtigungs-Checks
standalone ein einzelner Datensatz, Übergabe der ID im Request funktioniert wie bx:record
max maximale Anzahl der auszugebenden Datensätze (z.B. max="5")
orderby Feldangabe, nach der die Ausgabe sortiert sein soll (Datum, Name etc.) siehe auch bei nulls-at-end oder id-descending-orderNEU: Der Parameter orderby nimmt jetzt mehrere Feldnamen, getrennt durch Komma, Leerzeichen, Semikolon oder Pipe an und es kann über eine Einzelverknüpfung sortiert werden (siehe Beispiel) (ab V2.7) Dem Feldnamen kann man ein Pluszeichen für aufsteigende Sortierung (A..Z) oder ein Minuszeichen für absteigende Sortierung (Z..A) voranstellen (wenn kein + oder - vorangestellt ist, wird nach desc geschaut)
startindex Stelle, an der die Ausgabe beginnen soll (Beginn bei 0)
desc dreht die Sortierrichtung um
sql evalbx statt Filterangaben kann in den Tag-Einstellungen eine SQL angegeben werden (siehe Beispiel) wenn angegeben, können in der SQL bx-Tags benutzt werden
nulls-at-end null-Felder werden am Ende ausgegeben
id-descending-order nach ID absteigend sortieren
force-parameter-reset bewirkt, daß bei einer Containerfilter-Schachtelung der innere Container bei jedem Durchlauf des äußeren neu initialisiert wird (intern, Debugging) ab v.2.6.6
loopable Filterangaben innerhalb eines Designloops

Beispiele

Containerfilter-Aufruf im Quelltext

<bx:containerfilter.Mitglieder pool="Mitglieder" force="list" max="10" orderby="Name" desc startindex="5">
  <bx:recordfield.Name/><br>
</bx:containerfilter.Mitglieder>

Es werden maximal 10 Namen der im Container "Mitglieder" gespeicherten Datensätze ausgegeben. Die Datensätze sind nach Name (orderby) sortiert, allerdings absteigend (z-a), da "desc" angegeben wurde. Die Ausgabe startet mit dem 5. Datensatz. Filterungen können dann beim Menüpunkt unter "Tag-Einstellungen" (rechts unter "Tools") vorgenommen werden. Siehe auch "Filter".

Beispiel: Folgender Filter gibt nur die Mitglieder aus, die im Vorstand sind (Verknüpfung mit einem Container, der "Rollen" enthält über das Feld "Rolle", ID ist die DS-ID der Rolle "Vorstand"):

zugehöriger Filter

<filter>
  <filter-object>
    <field>Rolle</field>
    <type>8</type>
    <static-value>12FF89E7458</static-value>
  </filter-object>
</filter>

gleiches Beispiel wie oben, nur mit einer SQL:

Containerfilter-Aufruf im Quelltext

<bx:containerfilter.Mitglieder pool="Mitglieder" sql>
  <bx:recordfield.Name/><br>
</bx:containerfilter.Mitglieder>

zugehöriger Filter

SELECT m.*
FROM bxc_mitglieder m
WHERE
  m.ACTIV = 'j'
  AND m.Rolle = '12FF89E7458'
ORDER BY m.Name DESC
LIMIT 5,10;

Wieder gleiches Beispiel, allerdings wird die Rolle über den Request angegeben

Containerfilter-Aufruf im Quelltext

<bx:containerfilter.Mitglieder pool="Mitglieder" sql evalbx>
  <bx:recordfield.Name/><br>
</bx:containerfilter.Mitglieder>

zugehöriger Filter

SELECT m.*
FROM bxc_mitglieder m
WHERE
  m.ACTIV = 'j'
  AND m.Rolle = '<bx:pagedata.request name="rolle"/>'
ORDER BY m.Name DESC
LIMIT 5,10;

mehrere Sortierparameter: ** (ab V2.7)**

Der Parameter orderby nimmt jetzt mehrere Feldnamen, getrennt durch Komma, Leerzeichen, Semikolon oder Pipe an. Dem Feldnamen kann man ein Pluszeichen für aufsteigende Sortierung (A..Z) oder ein Minuszeichen für absteigende Sortierung (Z..A) voranstellen.

zugehöriger Filter

<bx:containerfilter.Name orderby="-Datum,+Titel"> <!-- wenn kein + oder - vorangestellt ist, wird nach desc geschaut -->

<bx:containerfilter.Name orderby="-Datum,Titel" [asc]>
<bx:containerfilter.Name orderby="Datum,+Titel" desc>				<!-- ergeben die gleiche Sortierung wie das Beispiel oben -->

<bx:containerfilter.Name orderby="-Jahr -Monat -Tag">      
<bx:containerfilter.Name orderby="Jahr Monat Tag" desc>        <!-- ergeben auch beide die selbe Sortierung.

Sortierung über Einzelverknüpfung: (ab V2.7)Sortierung über Einzelverknüpfung ist auch für jedes Feld möglich:

zugehöriger Filter

<bx:containerfilter.Name orderby="Kategorie/Titel;-Preisgruppe/Nummer">

Dreimal anders und doch das Gleiche

zugehöriger Filter

<bx:containerloop orderby="-Datum,+Titel">
<bx:containerloop orderby="-Datum,Titel" [asc]>
<bx:containerloop orderby="Datum,+Titel" desc>

noch ein Beispiel

zugehöriger Filter

<bx:containerloop orderby="-Jahr -Monat -Tag"> ist das gleiche wie
<bx:containerloop orderby="Jahr Monat Tag" desc>

mehrere Elemente (dynamische Angaben im Request)

<bx:containerfilter.{titel} pool="(ContainerID | Containername)" [force="list"] [maxparam="{param}"] [orderbyparam="{param}"] [directionparam="{param}"] [indexparam="{param}"]> 
  Inhalt
</bx:containerfilter.{titel}>

Die Parameter werden im Request übergeben.

{titel} frei wählbarer Name des Filters
pool ID oder Name des Containers (ab Vers. 2.6.0)
force Ausgabemodus Liste
orderbyparam Parametername, mit dem das Sortierfeld übergeben wird, kann auch gleich mit der Sortierrichtung gekoppelt werden, z.B. "+Name" und "-Name" für Sortierung nach Name aufsteigend bzw. absteigend NEU: reagiert jetzt auch auf mehrfach vorkommende Request-Parameter (siehe Beispiel) (ab V2.7)
directionparam Parametername für die Sortierrichtung: + für aufsteigend, - für absteigend
maxparam Parametername für die maximale Anzahl der auszugebenden Datensätze (pro Seite)
indexparam Stelle, an der die Ausgabe beginnen soll (Standard: "index") NEU: wird nur noch beachtet wenn kein + (%2B) oder - im Request-Parameter vorangestellt sind (ab V2.7)

Beispiele

<bx:containerfilter.aktuelleAngebote pool="Artikel" force="list" maxparam="max" orderbyparam="titel" directionparam="direction" indexparam="index"> 
  <bx:recordfield.Titel/>&nbsp;<bx:recordfield.Preis pattern="0.00"/><br>
</bx:containerfilter.aktuelleAngebote>

Diesen Filter findet man oft auf blätterbaren (Angebots-)Seiten. In diesem Beispiel werden alle Artikel mit Preis gelistet. Dann kann der Kunde selbst entscheiden (Form mit entsprechenden Auswahlmöglichkeiten - fehlt im Beispiel), wieviele Datensätze pro Seite angezeigt werden sollen (maxparam), nach welchem Feld sortiert werden soll (orderbyparam), z.b. Name, Preis, Datum, ob auf- oder absteigend sortiert sein soll (directionsparam).

Beim Blättern zwischen den Anzeigeseiten wird noch der Parameter "indexparam" gebraucht. Im Zusammenhang mit "maxparam" werden dann die jeweils pro Seite aufzulistenden Datensätze ermittelt.

<bx:containerfilter.Name orderbyparam="sort"> 

Mit dem Query-String ?sort=Name&sort=Vorname wird nun nach beiden Feldern sortiert. (ab V2.7) Der Parameter directionparam wird nur noch beachtet wenn kein + (%2B) oder - im Request-Parameter vorangestellt sind.

ein bestimmtes Element (über Request)

<bx:containerfilter.{titel} pool="(ContainerID | Containername)" force="single" idfield="{param}" [dummy]>
  Inhalt
</bx:containerfilter.{titel}>

Der Inhalt des Tags wird dann nur ausgegeben, wenn das gesuchte Element in der Ergebnisliste auftaucht, außer man gibt "dummy" an.

{titel} frei wählbarer Name des Filters
pool ID oder Name des Containers (ab Vers. 2.6.0)
force Ausgabemodus Einzelausgabe
idfield Parametername, der die ID des Datensatzes enthält (Standard: "recordid")
dummy bei Fehlen des Parameters wird ein Datensatz simuliert (z.B. beim Erstaufruf von Formularen)

Beispiele

<bx:containerfilter.heimischeSingvoegel pool="Singvoegel" force="single" idfield="vogelid">
  <h1><bx:recordfield.Titel/></h1>
  <img src="<bx:recordfield.Bild width="250" height="180" type="path"/>" alt="<bx:recordfield.Titel/>">
  <bx:recordfield.Beschreibung/>
</bx:containerfilter.heimischeSingvoegel>

Typische Detailseite. Der Requestparameter "vogelid" enthält die ID des gewünschten Datensatzes. Möglicher Aufruf für dieses Beispiel: Elster

ein zufälliges Element

<bx:containerfilter.{titel} pool="(ContainerID | Containername)" force="random" [max="{n}"]> 
  Inhalt
</bx:containerfilter.{titel}>

Es wird ein zufälliges Element aus der Ergebnisliste ausgewählt. Ab Version 2.6.2 hat man auch die Möglichkeit, mehrere Random-Datensätze anzeigen zu lassen.

{titel} frei wählbarer Name des Filters
pool ID oder Name des Containers (ab Vers. 2.6.0)
force Ausgabemodus Random (zufälliges Element)
max Anzahl der auszugebenden Datensätze (ab Version 2.6.2) Standard: 1

Beispiele

<bx:containerfilter.Kopfbild pool="Bilder" force="random"> 
  <div class="kopfbild">
    <img src="<bx:recordfield.Bild width="850" height="2000" type="path"/>" alt="<bx:recordfield.Titel/>">
  </div>
</bx:containerfilter.Kopfbild>

Bei jeden Seitenaufruf wird ein anderes Kopfbild angezeigt.

Verknüpfte Tabelle filtern

<bx:containerfilter pool="(ContainerID | Containername)" base="{Anzeige-ID}" linkfield="{Verknüpfungsfeld}">

Durch diese Erweiterung kann auch eine mit der Haupttabelle verknüpfte Tabelle gefiltert werden.

pool ID oder Name des Containers (ab Vers. 2.6.0)
base ID des verknüpften Container (Name geht leider nicht)
linkfield Name des Feldes in der Haupttabelle, das mit der Anzeige-Tabelle verknüpft ist

Beispiele

<bx:containerfilter.ArtikelKategorien pool="Artikel" base="0123456789" linkfield="Kategorie">
  <a href="artikelliste.htm?kat=<bx:recorddata.id/>"><bx:recordfield.Titel/></a><br>
</bx:containerfilter.ArtikelKategorien>

Es sollen nur Kategorien (im Container mit der ID "0123456789") aufgelistet werden, mit der auch Artikel (über das Feld "Kategorie") verknüpft sind. Kategorien ohne Artikel werden ignoriert. Allerdings werden auch deaktivierte Kategorien angezeigt, wenn der entsprechende Artikel aktiv ist.

Bedingung im Tag

<bx:containerfilter pool="(ContainerID | Containername)" name="{Feldname}" type="{Vergleichsart}" value="{Vergleichswert}" [required] [dummy]>
  Inhalt
</bx:containerfilter>

WICHTIG: Der Filter darf keinen Bezeichner haben. Es können auch die Parameter force, max, orderby, startindex angegeben werden (siehe oben bei force).

{titel} frei wählbarer Name des Filters
pool ID oder Name des Containers (ab Vers. 2.6.0)
name Name des zu überprüfenden Feldes (siehe auch "Filter")
type Art des Vergleiches (siehe auch "Filter")
value gesuchter Wert (siehe auch "Filter") statisch: einfach gesuchten Wert angeben (z.B. eine ID) dynamisch: mit Präfix (siehe auch "Präfixe")
required wenn nicht vorhanden, dann wird nichts ausgegeben (ab Version 2.6.1)
dummy im Detailmodus: wird kein Datensatz gefunden, wird ein Datensatz simuliert (Inhalt wird ausgegeben) Details dazu oben bei force

Beispiele

<bx:containerfilter pool="Bilder" name="Kategorie" type="8" value="1234567890" orderby="Titel">
  <img src="<bx:recordfield.Bild width="850" height="2000" type="path"/>" alt="<bx:recordfield.Titel/>">
</bx:containerfilter>

Alle Datensätze aus dem Container "Bilder", die im Feld "Kategorie" mit dem Datensatz mit der ID "1234567890" verknüpft sind, werden angezeigt.

Bedingung im Clipboard

<bx:containerfilter pool="(ContainerID | Containername)" force="list" config="clipboard:config">
  Inhalt
</bx:containerfilter>

WICHTIG: Der Filter darf keinen Bezeichner haben.

{titel} frei wählbarer Name des Filters
pool ID oder Name des Containers (ab Vers. 2.6.0)
force Ausgabemodus Liste
config dynamische Konfiguration

Beispiele

<bx:clipboard.cut name="config" trim>
  <filter>
    <filter-object required="false">
      <field>Invalid</field>
      <type>4</type>
      <static-value>0</static-value>
    </filter-object>
    <filter-object required="false">
      <field>Anbieter</field>
      <type>8</type>
      <special-value>PARENTCONTAINER</special-value>
    </filter-object>
  </filter>
</bx:clipboard.cut>

Die Bedingung wird dynamisch zusammengestellt und im weiteren Verlauf für eine Container-Filterung genutzt.

Bedingung in Systemeinstellungen

<bx:containerfilter.KontaktFilter pool="Kontakte" force="list" orderby="Name" config="system:filter_kontakte">
...
</bx:containerfilter.KontaktFilter>

Die Filterbedingungen werden in den Systemeinstellungen gespeichert.

Batix-Tags Referenz

bx:containerkat

Das Tag containerkat listet Container, gefiltert nach einer verknüpften Kategorie.

** Deprecated - Veraltetes Feature** Die hier aufgeführten Informationen beziehen sich auf eine veraltete Funktion, die nicht mehr weiterentwickelt wird und ggf. in zukünftigen Versionen nicht mehr unterstützt wird. Diese Funktion sollte deshalb nicht mehr benutzt werden.

<bx:containerkat[.bezeichner] pool="{id}" kat="{id}" linkfield="{feld}" [listid="{id}" | katidfield="{feld}" | parent | listall] [max="{n}"] [orderby="{feld}"] [desc]>
  Inhalt
</bx:containerkat[.bezeichner]>
bezeichner wenn angegeben und kein Modus angegeben, dann erscheint in der Verwaltung ein Drop-Down zur Auswahl der einschränkenden Kategorie
pool ID oder Containername des zu listenden Containers
kat ID oder Containername des Containers, der die einschränkenden Kategorie enthält
linkfield Feldname, der die Verknüpfung zur Kategorie enthält
listid ID der Kategorie (Modus: "feste Kategorie")
katidfield Name des Requestfeldes, das die Kategorie-ID enthält  (Modus: "Kategorie aus Request")
parent ohne Value  (Modus: "Kategorie aus übergeordneter Schleife")
listall wenn Requestparameter fehlt, dann alle anzeigen, ohne listall wird nichts angezeigt
max maximal Anzeigen (Überlauf)
orderby Feld, nach dem sortiert wird
desc Sortierreihenfolge umdrehen

Beispiele

<bx:containerkat.AlleWeine pool="Weine" kat="Anbaugebiete" linkfield="Anbaugebiet" max="9" orderby="Titel">
  <bx:recordfield.Titel/>
</bx:containerkat.AlleWeine>

Es werden alle Datensätze aus dem Container "Anbaugebiete" in der Verwaltung gelistet. Das ausgewählte Gebiet wird genommen, um "Weine" zu filtern. Das Verknüpungsfeld in "Weine" zu "Anbaugebiete" heißt "Anbaugebiet".

<bx:containerkat pool="Weine" kat="Anbaugebiete" linkfield="Anbaugebiet" katidfield="gebiet" listall max="9" orderby="Titel">
  <bx:recordfield.Titel/>
</bx:containerkat>

Ähnliches Beispiel wie oben, nur daß die Wahl des einzuschränkenden Anbaugebiets über den Request kommt. Wenn der Request "gebiet" fehlt, werden alle angezeigt (wegen listall).

Batix-Tags Referenz

bx:containerloop

Das Tag containerloop listet Datensätze einer Datenliste.

In den unten aufgeführten Formen muss die ID eines vorhandenen Containers angegeben werden (<id>). Alternativ kann statt <bx:containerloop pool="<id>" auch <bx:containerloop.<bez> definition="<id>" verwendet werden. Hier muss dann ein Bezeichner (<bez>) angegeben werden, welcher in der Administration angezeigt wird. Ebenfalls wird hier die ID einer Container-Definition angegeben. In der Verwaltung wird dann eine Auswahlliste mit allen verfügbaren Containern angezeigt, die auf dieser Definition beruhen.

eine Anzahl an Elementen

<bx:containerloop pool="{id}" [force={single | list | random | choice}] [indexparam="{param}" | index="{param}" | forceindex="{n}"] [max="{n}"] [show="all"] [orderbyparam="[+|-]{param}" [directionparam="{param}"] | orderby="{feld}" [desc]] >
  Inhalt 
</bx:containerloop>

Es werden die Listenelemente ab einer bestimmten Position ausgegeben, diese wird über ein Request-Parameter (indexparam oder index) festgelegt oder direkt dem Tag übergeben (forceindex). Standardmäßig werden alle Elemente ausgegeben, falls max angegeben ist, dann maximal nur <n>.

pool enthält die Containerid bzw. den Containernamen
indexparam enthält den Request-Parameter-Namen, der die Startposition für die Ausgabe enthält
index enthält die Startposition für die Ausgabe
forceindex feste Angabe für die Startposition der Ausgabe
max maximal Anzahl ausgegebener DS im Schleifendurchlauf
show="all" auch Anzeige von inaktiven Elementen
orderbyparam Sortierungsfeldangabe über einen Request-Parameter (+ für aufsteigend und - für absteigend vor den Feldnamen) NEU: reagiert jetzt auch auf mehrfach vorkommende Request-Parameter (siehe Beispiel) (ab V2.7, siehe auch bei containerfilter)
directionparam Sortierrichtung über einen Request-Parameter (wenn nicht bei orderbyparam vorangestellt)
orderby Sortierfeld für die Anzeigereihenfolge (standardmäßig aufsteigend) NEU: Der Parameter orderby nimmt jetzt mehrere Feldnamen, getrennt durch Komma, Leerzeichen, Semikolon oder Pipe an und es kann über eine Einzelverknüpfung sortiert werden (siehe Beispiel) (ab V2.7)
desc kehrt die Sortierreihenfolge um
force list: Listenanzeige single: einzelner Datensatz random: Erzwinge Einzelanzeige eines Zufallsdatensatzes choice: Erzwinge Listenanzeige einer im Request übergebenen Auswahl von Datensätzen, braucht idfield=...  (oder der Requestparameter heißt recordid)

Beispiele

Containeranzeige: Listen- und Detailseite

Listenseite

<form>
  Sortierung nach:<br>
  Titel Preis
  
</form>

<bx:containerloop pool="Artikel" indexparam="anzeigeAb" max="10" orderbyparam="sortierfeld" directionparam="sortierrichtung" orderby="Titel">
  <a href="detail.htm?art=<bx:recorddata.id/>"><bx:recordfield.Titel/></a><br> 
</bx:containerloop>

In der Liste werden pro Seite 10 Artikel angezeigt (max).

Detailseite

<bx:containerloop pool="{id}" [indexparam="{param}" | index="{param}" | forceindex="{n}"] [max="{n}"] [show="all"] [orderbyparam="[+|-]{param}" [directionparam="{param}"] | orderby="{feld}" [desc]] >
  Inhalt 
</bx:containerloop>

mehrere Sortierparameter: ** (ab V2.7)**

Der Parameter orderby nimmt jetzt mehrere Feldnamen, getrennt durch Komma, Leerzeichen, Semikolon oder Pipe an. Dem Feldnamen kann man ein Pluszeichen für aufsteigende Sortierung (A..Z) oder ein Minuszeichen für absteigende Sortierung (Z..A) voranstellen.

zugehöriger Filter

<bx:containerloop orderby="-Datum,+Titel"> <!-- wenn kein + oder - vorangestellt ist, wird nach desc geschaut -->

<bx:containerloop orderby="-Datum,Titel" [asc]>
<bx:containerloop orderby="Datum,+Titel" desc>				<!-- ergeben die gleiche Sortierung wie das Beispiel oben -->

<bx:containerloop orderby="-Jahr -Monat -Tag">      
<bx:containerloop orderby="Jahr Monat Tag" desc>        <!-- ergeben auch beide die selbe Sortierung.

Sortierung über Einzelverknüpfung: (ab V2.7)Sortierung über Einzelverknüpfung ist auch für jedes Feld möglich:

zugehöriger Filter

<bx:containerloop orderby="Kategorie/Titel;-Preisgruppe/Nummer">

ein zufälliges Element

<bx:containerloop pool="<id>" force="random" [show="all"] >
  Inhalt </bx:containerloop>
id Objekt-ID
Es wird ein zufälliges Element der Liste ausgewählt. Falls show="all" gesetzt ist, werden auch inaktive Elemente in Betracht gezogen.

.

Beispiele

<bx:tag.feature param="value" />

ein bestimmtes Element

<bx:containerloop pool="<id>" force="single" [idfield="<param>"] >
  Inhalt </bx:containerloop>
id Objekt-ID
param Name eines Request-Parameters
Die ID des gewünschten Datensatzes wird durch ein Request-Parameter (festgelegt durch idfield, Standard ist "recordid") übergeben.

mehrere bestimmte Elemente

<bx:containerloop pool="<id>" force="choice" [idfield="<param>"] [id="<idlist>"] [boundary="<text>"] [show="all"]
  [oderbyparam="[+|-]<param>" [directionparam="<param>"] | orderby="<feld>" [desc]] >
  Inhalt </bx:containerloop>
id Objekt-ID
param Name eines Request-Parameters
text beliebiger Text
idlist Liste von IDs
idfield gibt den Request-Parameter an, in welchem die Auswahl an Datensätzen steht. Es kann entweder eine Liste an IDs (getrennt durch Komma oder anderen Zeichen laut boundary) angegeben werden oder es wird der gleiche Request-Parameter (gleicher Name) mehrfach spezifiziert (für jeden gewünschten Datensatz einmal mit der entsprechenden Datensatz-ID). Alternativ kann die Liste der IDs im Attribut id übergeben werden.

Um auch hier inaktive Elemente anzuzeigen, muss show="all" gesetzt sein.

Die Möglichkeiten zur Sortierung sind die selben, wie unter eine Anzahl an Elementen

Verweise auf diese Seite:

bx:recorddata bx:tableloop bx:tableloop bx:recorddata

(4 Verweise)

Batix-Tags Referenz

bx:containersearch

Das Tag containersearch gibt eine Liste von Containerdatensätzen aus, die einem Suchergebnis in diesem Container entspricht. In der Liste sind nur aktive Datensätze enthalten.

<!-- Listenseite -->
<bx:containersearch pool="{id}" fields="{felder}" [indexparam="{param}"] [searchparam="{param}"] max="{n}" [listall]  [orderby="{feld}"] [desc]>
  Inhalt
</bx:containersearch>
 
<!-- Detailseite -->
<bx:containersearch pool="{id}" fields="{felder}" [searchparam="{param}"] max="{n}" [listall] [singleidname="{param}"] [orderby="{feld}"] [desc]>
  Inhalt
</bx:containersearch>

Erklärungstext.

pool ID des Containers
fields die zu durchsuchenden Felder (durch Komma getrennt)
indexparam Parameter, der den aktuellen Index hält (Standard: searchidx)
searchparam gesuchter String (Standard: search)
max maximale Anzahl an angezeigten Elementen
listall Falls kein Suchbegriff angegeben wurde, wird nichts angezeigt, außer listall ist gesetzt
singleidname Detailseite: Parameter, in dem die DS-ID steht
orderby Feld, nach dem die Liste sortiert wird (Standard: nach Relevanz)
desc kehrt Sortierung um

Beispiele

Beispiel für eine Listen-/Detailseite mit einer Suche im Container

Listenseite

<form action="index.htm" method="post">
  <input type="text" name="suchbegriff" value="<bx:pagedata.request name="suchbegriff"/>">
  <input type="submit" value="suchen">
</form>

<bx:containersearch.News pool="139439682C3" fields="Titel,Anmoderation,Text" indexparam="seite" searchparam="suchbegriff" max="2" listall  orderby="Titel">
  <a href="detail.htm?detail=<bx:recorddata.id/>"><bx:recordfield.Titel/></a> - Ranking: <bx:containersearch.rank/><br>
</bx:containersearch.News>

<bx:recorddata.nav object="News">
  <bx:recorddata.previouslist/> | <bx:recorddata.nextlist/>
</bx:recorddata.nav>

Der Container wird komplett gelistet, wenn kein Suchbegriff angegeben wurde. Wenn doch, dann wird in den Feldern Titel, Anmoderation und Text nach diesem Wort gesucht.

Detailseite

<bx:containersearch.News pool="139439682C3" fields="Titel,Anmoderation,Text" singleidname="detail" searchparam="suchbegriff" max="2" listall  orderby="Titel">
  <h1><bx:recordfield.Titel/></h1>
  <em><bx:recordfield.Anmoderation/></em><br>
  <bx:recordfield.Text/>
</bx:containersearch.News>

<a href="index.htm?seite=<bx:pagedata.request name="seite"/>">zurück</a>

Angabe von singleidname, damit der richtige Datensatz angezeigt wird. Der Zurück-Knopf enthält die Seite, die auf der Listenseite wiederum durch den Parameter indexparam gefunden wird.

containersearch.rank

<bx:containersearch.rank/>

Innerhalb der obigen Schleife gibt dieses Tag den Rang des aktuellen Suchergebnisses zurück.

containersearch.relevanz

<bx:containersearch.relevanz/>

Dieses Tag gibt innerhalb der Suchschleife die Relevanz des aktuellen Ergebnisses aus.

Batix-Tags Referenz

bx:cookie

Mit diesem Tag können Cookies gesetzt/gelesen und Vergleiche angestellt werden. (verfügbar ab Version 2.6)

bx:cookie

<bx:cookie name="{meinCookie}" [not] />
<bx:cookie name="{meinCookie}" [not] > ...Inhalt... </bx:cookie>
<bx:cookie name="{meinCookie}" value="{meinWert}" [not]> Ausgabe </bx:cookie>

Die Ausgabe von Cookies erfolgt einfach durch die Angabe von name. Mit Zeile 2 kann überprüft werden, ob es den Cookie überhaupt gibt. Weiterhin kann der gespeicherte Wert verglichen werden.

name name des gesetzten Cookies
value Vergleichswert
not kehrt die Bedingung um

cookie.cut

<bx:cookie.cut name="{meinCookie}" value="{meinWert}" [domain="..."] [path="..."] [maxage="..."] [secure] />
<bx:cookie.cut name="{meinCookie}" [...]> Wert für Cookie </bx:cookie.cut>

Hiermit kann ein Cookie gesetzt werden. Der Wert kann entweder über den Tag-Inhalt oder über value übergeben werden.

cookie.copy

<bx:cookie.copy ... [...]

Funktioniert wie bx:cookie.cut, nur wird der Wert, der per Tag-Inhalt oder value gesetzt wird, noch zusätzlich ausgegeben.

cookie.delete

<bx:cookie.delete name="{meinCookie}" [domain="..."] [path="..."] />

Mit diesem Befehl kann ein Cookie gelöscht werden. Es kann zusätzlich path (Standardwert "/") und domain angegeben werden (Erklärung siehe oben bei cookie.cut).

Beispiele

<bx:cookie name="sprache" not >
  <bx:cookie.cut name="sprache">de</bx:cookie.cut>
</bx:cookie>

Keine Verweise gefunden.

Suchbegriffe

Cookies

Batix-Tags Referenz

bx:datum

Mit dem Tag datum kann ein Datum aus einem Kalender gewählt werden (z.B. um Verfallsdatum der Seite oder von einzelnen Elementen anzugeben).

Dieses Tag kann sich in der Verwaltung darstellen.

<bx:datum.{titel} [size="{n}"] [maxlength="{n}"] />

size - Feldgröße in der Administration

maxlength - maximale Eingabelänge des Feldes in der Administration

BspDatum1A.png

Batix-Tags Referenz

bx:designloop

Das Tag designloop erzeugt eine Schleife von sortierbaren Designbausteinen.

Früher mit Tabellen-Layout und alten Containern war das so gedacht

<table border=0>
<bx:recordloop.Schleifenname [showmeta=”Meta-Wert”]>
  <tr>
    <td><bx:recordloopelement/></td>
  </tr>
</bx:recordloop.Schleifenname>
</table>

<bx:recordloop.{Titel} [showmeta=”Meta-Wert”]> ist ein erweitertes bx:schleife

<bx:recordloopelement> ist ein Platzhalter für den einzufügenden Designbaustein

Jetzt das neu belebte bzw. eigentlich neue Tag mit neuen Containern:

<bx:designloop.Schleifenname [showmeta=”Meta-Wert”]>
  <div style=””>
    <bx: designloopelement [dummy]/>
  </div>
</bx:designoop.Schleifenname>

In der Verwaltung wird eine Schleife von sortierbaren Designbausteinen angezeigt

Bei Klick auf eine Detailseite wird eine Konfiguration des Bausteins mit Auswahl des Designs und eines Containerdatensatzes angezeigt

Neu bei designloop:

-          ein Titel für das Schleifenelement kann eingegeben werden

-          es kann ein Element ohne Containerverknüpfung angelegt werden wenn der Parameter dummy angegeben wird

Zusätzlich werden optionale vom jeweilgen Baustein abhängige Eingabefelder (Texte,Bilder,..) angezeigt

<bx:designloop.{Titel} [showmeta=”Meta-Wert”]> erweitertes bx:schleife
<bx:designloopelement [dummy]> Platzhalter für den einzufügenden Designbaustein
showmeta=”Meta-Wert” zeigt einen Meta-Datenwert in der Liste mit an (ich glaube, das hatten wir bei IHK- und/oder Kompetenzzentrum-Lehrgängen für eine Nummerierung der Kapitel gehabt z. B. „2.4.1“ als Meta-Wert) )
Schleifenname Titel der Schleife
dummy Element kann auch ohne containerverknüpfung angelegt werden
Zu beachten: Wird innerhalb eines Designloop eine Containerschleife verwendet in der wiederum ein bx:textarea o.ä. ausgegeben werden soll, dann muß ans bx:containerfilter loopable drangehängt werden.
<bx:record pool="test" id="12B10695FB1">
  <bx:containerfilter.Bild pool="test" force="list" loopable>
    <bx:recorddata.id/>: <bx:textarea.Titel/><br>
  </bx:containerfilter.Bild>
</bx:record>

Beispiele

<bx:designloop.Content_Container>
  <bx:designloopelement dummy />
</bx:designloop.Content_Container>

Designloop, wie er beim Epona-Design eingesetzt wurde (z.B. Stadtwerke, Fröbeldekade)

Beispiele One-Pager

als Navigation

<bx:schleife.Inhalte admin-mode="config">
  <a href="#<bx:loop.id/>"><bx:text.MenuTitel/></a>
</bx:schleife.Inhalte>

eigentliche Schleife

<bx:designloop.Inhalte>
  <a name="id<bx:loop.id/>"></a>
  <bx:clipboard.cut name="nichtAnzeigen"><bx:text.MenuTitel/></bx:clipboard.cut>
  <bx:designloopelement dummy />
</bx:designloop.Inhalte>

Keine Verweise gefunden.

Batix-Tags Referenz

bx:dezimal

Mit dem Tag dezimal kann in der Verwaltung eine Zahl mit Nachkommastellen eingegeben werden. Man kann bestimmte Begrenzungen für die Eingabe bestimmen.

Dieses Tag kann sich in der Verwaltung darstellen.

<bx:dezimal.{bezeichner} [size="{n}"] [maxlength="{n}"] [nachkomma="{n}"] [minnachkomma="{n}"] [maxnachkomma="{n}"] [noformat] />
Parameter für Anzeige in der Verwaltung Parameter für Anzeige im Frontend
bezeichner Name des Feldes in der Verwaltung nachkomma Anzeige auf der Website mit n Nachkommastellen, wird evtl. mit Nullen aufgefüllt wenn nicht angegeben, werden alle Kommastellen ausgegeben
size Größe des Eingabefeldes in der Verwaltung (Standard 20) minnachkomma alternativ: Minimum an Nachkommastellen
maxlength Maximale Eingebelänge für eine Zahl in der Verwaltung (Anzahl der Zeichen) maxnachkomma alternativ: Maximum an Nachkommastellen
noformat Zahl wird nach US Formatierung ausgegeben (z.B. 1,337.23 statt normal 1.337,23).

Beispiele

<bx:dezimal.Preis size="10" maxlength="5" nachkomma="2" />

Man kann in das Feld "Preis" in der Verwaltung, das eine Breite von 10 hat, nur bis zu 5 Zeichen eingeben (incl. Komma). Auch wenn man nur "10" eingibt, wird auf der Website 10,00 angezeigt.

Batix-Tags Referenz

bx:directorylisting

Mithilfe des Tags directorylisting lässt sich eine Verzeichnislistung der Dateiverwaltung darstellen.

bx:directorylisting

<bx:directorylisting type="{mixed | group | files | folders}" [limit="<n>"] [folder="<pfad>"]
  [listfolder="<pfadID>"]>
  Inhalt</bx:directorylisting>

Folgende Typen sind möglich:

mixed Es werden Dateien und Verzeichnisse sortiert nach Name ausgegeben. group Dateien und Verzeichnisse werden gruppiert. files Es werden nur Dateien ausgegeben. folders Es werden nur Verzeichnisse ausgegeben.

Falls ein bestimmter Ordner angezeigt werden soll, kann dieser mittels folder übergeben werden, ansonsten wird das Hauptverzeichnis angenommen. Die Verzeichnisebene, die als Root gelistet werden soll, wird mittels listfolder übergeben. Die Ausgabe je Element lässt sich im Inhalt des Tags festlegen. Dabei können Sie die folgenden Elemente verwenden.

directorylisting.isfile

<bx:directorylisting.isfile> Inhalt </bx:directorylisting.isfile>

Der Inhalt wird nur ausgegeben, wenn das aktuelle Element eine Datei ist.

directorylisting.isfolder

<bx:directorylisting.isfolder> Inhalt </bx:directorylisting.isfolder>

Der Inhalt wird nur ausgegeben, wenn das aktuelle Element ein Verzeichnis ist.

directorylisting.isparent

<bx:directorylisting.isparent> Inhalt </bx:directorylisting.isparent>

Der Inhalt wird nur ausgegeben, wenn das aktuelle Element das übergeordnete Verzeichnis ("..") ist.

directorylisting.link

<bx:directorylisting.link [target="<ziel>"] />
<bx:directorylisting.link [target="<ziel>"]>Linktext</bx:directorylisting.link>

Falls das Element ein Verzeichnis ist, wird die Navigation bei Klick dort fortgesetzt, andernfalls wird die Datei angezeigt bzw. heruntergeladen.

target Zielfenster im Browser

directorylisting.filename

<bx:directorylisting.filename/>

Falls das Element eine Datei ist, wird der Dateiname ausgegeben.

directorylisting.filesize

<bx:directorylisting.filesize unit="{b | k | m}" />

Falls das Element eine Datei ist, wird die Dateigröße ausgegeben.

unit bestimmt die Einheit ( Byte (b), Kilobyte (k), Megabyte (m) )

directorylisting.filedate

<bx:directorylisting.filedata [pattern="<format>"] />

Falls das Element eine Datei ist, wird das Uploaddatum ausgegeben.

pattern Ausgabeformat, Standard ist: "dd.MM.yyyy".

directorylisting.titel

<bx:directorylisting.titel />

Falls das Element eine Datei ist, wird der Dateiname ausgegeben.

directorylisting.description

<bx:directorylisting.description />

Falls das Element eine Date ist, wird die Beschreibung ausgegeben.

directorylisting.previous

<bx:directorylisting.previous/>
<bx:directorylisting.previous>Linktext</bx:directorylisting.previous>

Dieses Tag steht außerhalb der Schleife. Es erzeugt einen Link zur vorherigen Seite, falls limit überschritten wurde. Standard-Linktext ist "zurück".

directorylisting.next

<bx:directorylisting.next/>
<bx:directorylisting.next>Linktext</bx:directorylisting.next>

Dieses Tag steht außerhalb der Schleife. Es erzeugt einen Link zur nächsten Seite, falls limit übeschritten wird. Standard-Linktext ist "weiter".

Batix-Tags Referenz

bx:document

Mittels des Tags document kann in der Verwaltung ein Dokument zugeordnet werden. Als Ausgabe ist ein Downloadlink oder nur die URL zu diesem Dokument möglich.

Dieses Tag kann sich in der Verwaltung darstellen.

<bx:document.{titel} [type="(url | path | link | id | name | filename | size | description)"] [unit="(b | k | kb | m | mb | auto)"] [pattern=""] [locale=""] [disposition="attachment|inline|none"]/>
url Ausgabe der URL zum Dokument
path Ausgabe des Pfades zum Dokument
link Ausgabe als Link
id Ausgabe der Dokumenten-ID
name Ausgabe des Original-Dateiname
filename Ausgabe des Dateiname auf dem Server
size Ausgabe der Dokument-Größe
description Ausgabe der Description (Feld "Beschreibung" in der Dokumentenverwaltung)
unit (nur bei size-Angabe) Ausgabe in Byte (b), Kilobyte (kb oder k) oder Megabyte (mb oder m) bei auto: Angabe von pattern und locale möglich, Standard: unit="b"
pattern **(nur wenn bei size=auto angegeben wurde) **Ausgabemuster festlegen, Standard: pattern="#,##0"
locale **(nur wenn bei size=auto angegeben wurde) **Sprache festlegen, Standard: locale="de_DE"
disposition siehe Beispiel2

Beispiele

einfache Verwendung

Bewerbungsunterlagen als PDF: <bx:document.Bewerbungsunterlagen/>

Ausgabe innerhalb eines a-Tags

<a href="<bx:document.Protokoll type="path"/>">
  <bx:document.Protokoll type="name"/> | Größe: <bx:document.Protokoll type="size" unit="auto" pattern="#,###0.00" locale="en"/>
</a>

Ausgabe mit Nachkommastellen in englischer Schreibweise (Tausendertrenner ist Komma, Dezimaltrenner ist Punkt)

Beispiele attachment

<bx:recordfield.Dokument disposition="inline"/>

Ausgabe: http://domain/files/{Batix-ID}/{Dateiname}setzt content-disposition:inline; filename=“{Dateiname}“, wird als Standard genommen, wenn nichts angegeben wird

<bx:recordfield.Dokument disposition="attachment"/>

Ausgabe:http://domain/files/download/{Batix-ID}/{Dateiname} bewirkt bei PDFs einen Zwangsdownload anstatt eine Anzeige im Browser-Plugin, dasselbe auch durch http://domain/files/{Batix-ID}/{Dateiname}?dl=true

<bx:recordfield.Dokument disposition="none"/>

Ausgabe: http://domain/files/media/{Batix-ID}/{Dateiname}bewirkt bei MP4-Videos, die in Apple-Mobilgeräten abgespielt werden sollen, daß das funktioniert, weil der Header nicht geschrieben wird (scheint nur Apple-Geräte zu betreffen) Verweise auf diese Seite:

Keine Verweise gefunden.

Batix-Tags Referenz

bx:documentlist

Das Tag documentlist listet ein virtuelles Verzeichnis der Dokumentenverwaltung.

bx:documentlist

<bx:documentlist [limit="{n}"] {folder="{pfad}" | folderid="{pfadID}"}> Inhalt </bx:documentlist>

Der Inhalt legt die Ansicht pro Element fest. Es können die folgenden Befehle verwendet werden.

limit Maximum an Ausgaben
folder zu listendes Verzeichnis als Titel
folderid zu listendes Verzeichnis als ID

documentlist.id

<bx:documentlist.id />

Dieser Befehl gibt die ID des Eintrags aus.

<bx:documentlist.link [target="<fenster>"] />
<bx:documentlist.link [target="<fenster>"]>Linktext</bx:documentlist.link>
target Ziel-Browserfenster

documentlist.filename

<bx:documentlist.filename />

Der Dateiname aus dem System wird ausgegeben.

documenlist.filesize

<bx:documentlist.filesize [unit="b | k | m"] />

Die Dateigröße wird ausgegeben.

unit Größeneinheit ( Byte (b), Kilobyte (k), Megabyte (m) )

documentlist.filedate

<bx:documentlist.filedate [pattern="<format>"] />

Gibt das Uploaddatum der Datei aus.

pattern Anzeigeformat (Standard: "dd.MM.yyyy")

documentlist.titel

<bx:documentlist.titel />

Der Download-Dateiname wird geschrieben.

documentlist.description

<bx:documentlist.description />

Die Beschreibung der Datei wird ausgegeben.

documentlist.previous

<bx:documentlist.previous />
<bx:documentlist.previous>Linktext</bx:documentlist.previous>

Dieses Tag steht außerhalb der Schleife. Es erzeugt einen Link zur vorherigen Seite, falls limit überschritten wurde. Standard-Linktext ist "zurück".

documentlist.next

<bx:documentlist.next/>
<bx:documentlist.next>Linktext</bx:documentlist.next>

Dieses Tag steht außerhalb der Schleife. Es erzeugt einen Link zur vorherigen Seite, falls limit überschritten wird. Standard-Linktext ist "weiter".

Batix-Tags Referenz

bx:editbutton

Mit dem Tag editbutton kann man im Frontend Buttons oder Links anzeigen, mit denen man in die Verwaltung an die richtige Stelle springen kann. Die Verwaltung muß offen sein.

 

<bx:editbutton [style="{classname}"] [class="{classname}"] [form-style="{classname}"] [form-class="{classname}"] target="{targetangabe}" label="{text}"/>

<bx:editbutton[.link] type="{container}" field="Feldname" [weitere Attribute z.B. class, id oder style] />
<!-- Neuer Datensatz (ab v 2.6.8)-->
<bx:editbutton[.link] type="{container}" [pool | baseloop]="{containername | containerid}" [weitere Attribute z.B. class, id oder style] /> 
<bx:editbutton[.link] type="container" sub="BilderListe" label="neues Bild" />

<bx:editbutton[.link] [type="nav"] />
<bx:editbutton[.link] [type="nav"] navid="navid" />
<bx:editbutton[.link] [type="nav"] function="{copy | sort | sortroot}" />
<bx:editbutton[.link] [type="nav"] file="{jsp-Datei in Verwaltung}" />

<bx:editbutton[.link] [type="nav"] />

Schreibt einen Edit-Button in Form einer HTML-Form mit Hidden-Feldern und einem <input type=”submit”> in die Seite, der bei Abschicken in einem neuen Tab in der Verwaltung eine Seite öffnet, wenn der Benutzer Schreibzugriff (= Recht zum Speichern der Seite) auf den aktuellen Navigationspunkt hat.

Das type=“nav“ kann weggelassen werden (ist Defaultwert und wegen Kompatbilität)

Beispiele

``

<bx:editbutton label="&#10000;"> 

schreibt ein ✐ als Buttontext

<bx:containerloop pool="Galerien">
   ...
   <bx:editbutton[.link] type="container" sub="BilderListe" label="neues Bild" />
 </bx:containerloop>

http://www.meine-domain.de/verwaltung/?client=12E2D639293&table=12EE71ADC48&record=[[recordid]]

Anmeldeformular im Frontend (Anmeldung bei Verwaltung wird vermieden)

Folgendes Input-Feld muß ins Anmeldeformular:

<input type="hidden" name="editable" value="true">
Batix-Tags Referenz

bx:email

Das Tag email stellt in der Verwaltung ein Eingabefeld für eine Email-Adresse zur Verfügung. Auf der Webseite wird diese mit "mailto" verlinkt dargestellt.

Wenn keine Email-Adresse eingegeben wurde wird nichts angezeigt. Bei einer ungültigen Email-Adresse wird in der Verwaltung das Eingabefeld farblich markiert.

Dieses Tag kann sich in der Verwaltung darstellen.

<bx:email.{bezeichner} [size="{n}"] />
bezeichner Name des Feldes in der Verwaltung
size Größe des Eingabefeldes in der Verwaltung
.

Beispiele

<bx:email.Email size="<n>"] />

Wir in der Verwaltung in das Feld "Email" "test@batix.com" eingegeben, wird das zu: test@batix.com im Quelltext und auf der Website wird eine verlinkte Email-Adresse ausgegeben.

Batix-Tags Referenz

bx:evaluate

Der Body dieses Tags evaluate wird ausgewertet und das Ergebnis ein zweites Mal bx-Tag-mäßig ausgewertet.

Ab v2.6.3 ist folgender Anwendungsfall möglich: Ein Konfigurationscontainer enthält ein (Quell-)Textfeld mit HTML + bx-Tags. Eine CM-Seite enthält einen Daten-Datensatz und darin eine Schleife über Datensätze des Konfigurationscontainers. Nun kann mit <bx:evaluate><bx:recordfield.*Quelltextfeld* type="plain"/> eine Ausführung des bx-Codes bewirkt werden. Im Quelltext-Containerfeld können mit z. B. <bx:recordfield.*Feldname* baseloop="*Datenschleife*"/> Daten aus dem äußeren Datencontainer ausgegeben werden.

<bx:evaluate [charset="( utf-8 | iso-8859-1 )"]> Tag, das ein Tag zurückgibt </bx:evaluate>
charset iso oder utf8 (wenn es Probleme gibt)

Beispiele

Ein Tag steht im Container, z.B. die Formel zur Berechnung von Bezahlarten oder Versandkosten, die sich dynamisch gestalten. Damit wird die Auswahl über feste IDs innerhalb der Seite gespart.

Batix-Code im Container

<bx:evaluate><bx:recordfield.QuellcodeSnippet type="plain" /></bx:evaluate>

Darauf achten, dass Benutzer keine willkürlichen Quelltexte in dem Containerfeld speichern können!

Ein Tag wird im Request übergeben: `test.htm?datum=`

Batix-Code im Request (nicht empfohlen)

<bx:evaluate><bx:pagedata.request name="datum" /></bx:evaluate>

Dies ist gefährlich, da der Benutzer im Normalfall den Request-Parameter beliebig manipulieren und somit sämtlichen Batix-Code ausführen kann!

Batix-Tags Referenz

bx:frame

Das Tag frame stellt Funktionen für Framesets zur Verfügung.

<bx:frame default="{pfad}" />

Um andere Seiten im Inhalts-Frame zu laden muss der Request-Parameter "dir" an das Frameset übergeben werden.

default gibt an, welche Seite standardmäßig im Frameset geladen werden soll

frame.script

<bx:frame.script [frameset="{pfad}"] />

Hiermit wird JavaScript Code in die Seite geschrieben, welcher das Frameset durchläd und die Seite im Inhalts-Frame anzeigt, falls sie nicht im Frameset geöffnet wurde. Dies passiert z.B. beim Öffnen von Links in Suchmaschinen.

frameset Falls das Frameset nicht die Startseite des Webs ist (also nicht über http://IhreAdresse.de/www/webname/ aufgerufen wird), muss der Parameter frameset verwendet werden.
Batix-Tags Referenz

bx:gif

Das Tag gif funktioniert ähnlich wie Bx:bild, nur wird hier die Grafik in den Dokumentenvorlagen ausgewählt.

** Deprecated - Veraltetes Feature** Die hier aufgeführten Informationen beziehen sich auf eine veraltete Funktion, die nicht mehr weiterentwickelt wird und ggf. in zukünftigen Versionen nicht mehr unterstützt wird. Diese Funktion sollte deshalb nicht mehr benutzt werden.

<bx:gif.{titel} [type="url"] [name="{text}"] [border="{breitenangabe}"] [align="(top | middle | bottom)"] />

Falls type="url" angegeben ist, wird nur die URL zum Bild ausgegeben.

Batix-Tags Referenz

bx:groovy

Mittels bx:groovy kann innerhalb eines Template einfach Groovy-Code ausgeführt werden.

Groovy Code ausführen

<bx:groovy [includes="{Groovy-Bausteine}"] [nobody]> ... </bx:groovy>

Der Parameter includes (zur Kompatibilität auch include möglich) enthält einen oder mehrere (kommagetrennte) Titel von Groovy-Bausteinen. Diese werden in der angegebenen Reihenfolge zusammengesetzt. Danach wird noch der Groovy-Code im Tag-Body angehangen.

Die Angabe von nobody bewirkt, dass der Taginhalt nicht als Groovy-Code angesehen wird. Somit kann man selbst dynamische Sachen (via includeTag.computeBody()) auswerten.

Beispiele

Nur Code

<bx:groovy>
println("Hello, World")
</bx:groovy>

Include und Code

<bx:groovy includes="MyLib">
MyLib.doStuff()
</bx:groovy>

Nur Include

<bx:groovy includes="MyLib,OtherLib" />

Parameter übergeben und auslesen

<bx:groovy name="clipboard:myName" age="25">
def name = includeTag.getStringParameter("name")
def age = includeTag.getIntParameter("age", 0)
 
println("Hello, $name")
if (age < 18) println("no access!")
</bx:groovy>

nobody

<bx:groovy includes="CheckRole" role="Admin" nobody>
  <p>Herzlich willkommen in der Administration</p>
</bx:groovy>
 
// CheckRole Groovy (Auszug):
def requestedRole = includeTag.getStringParameter("role")
if (hasRole(requestedRole)) {
  println(includeTag.computeBody())
}

Verweise auf diese Seite:

Verwendungsmöglichkeiten Verwendungsmöglichkeiten

(2 Verweise)

Batix-Tags Referenz

bx:head

Der Befehl head schreibt diverse Angaben zum Projekt in den Headbereich.

head.style

<bx:head.style/>

head.setstatus

<bx:head.setstatus code="statuscode"/>

Setzt den Status-Code der Seite (normalerweise "200")

head.setheader

<bx:head.setheader [type="int|date"] name="Name" value="value"/>
  oder 
<bx:head.setheader [type="int|date"] name="Name"> Inhalt </bx:head.setheader>

Erlaubt es, einen HTTP-Header für die Seite zu setzen (z.B. content-disposition, wenn ein Download angeboten werden soll)

type Standard: String (wenn nicht angegeben)
name Name (des Tags???)
value Angaben, die in den Head geschrieben werden sollen

Beispiele

<bx:head.setheader name="Cache-Control" value="no-cache"/>

Angabe, daß die Seite nicht gecacht werden soll.

<bx:head.setheader name="Expires" type="date"><bx:tools.datum day="+7"/></bx:head.setheader>

head.cancelpage

<bx:head.cancelpage (redirect|forward)="{Weiterleitungspfad}" [clearbody] [intern]> [optional:Daten die in den Body des Redirects geschrieben werden] </bx:head.cancelpage>

Bricht die Tagauswertung der Seite ab und führt stattdessen ein Redirect oder Forward aus bzw. leitet auf eine Fehlerseite weiter.

redirect URL, auf die weitergeleitet werden soll (Adresse im Browser ändert sich)
forward URL, auf die im Hintergrund geforwarded werden soll (Adresse im Browser bleibt erhalten)
clearbody löscht den Inhalt des <body></body>
intern nur in Kombination mit redirect (nicht** forward**)stellt sicher, dass die angegebene URL nicht auf eine externe Seite verweist nützlich für dynamische Weiterleitungen (z.B. URL aus Request), um Sicherheitslücken zu vermeiden (Open Redirect)

Beispiele

<bx:recordfield.Artikel_verfügbar not>
  <bx:head.cancelpage redirect="liste.htm?info=ausverkauft"/>
</bx:recordfield.Artikel_verfügbar>

Wenn Artikel ausverkauft ist, wird von dieser Seite auf die Listenseite weitergeleitet.

<bx:recordfield.Artikel_verfügbar not>
  <bx:head.cancelpage forward="ausverkauft.htm"/>
</bx:recordfield.Artikel_verfügbar>

Wenn Artikel ausverkauft ist, wird eine Fehlerseite (ausverkauft.htm) angezeigt, aber nicht weitergeleitet.

<bx:userdata.in>
  <bx:head.cancelpage redirect="../intra/" clearbody> <body>
    This page has <a href="../intra/">moved</a>.</body>
  </bx:head.cancelpage>
</bx:userdata.in>

Wenn User eingeloggt (z.B. auf einer Login-Seite nach dem Login), wird der Body gelöscht und es wird ein Link für eine Weiterleitung angezeigt.

head.localblock

<bx:head.localblock/>

Schreibt die Angaben vom Feld "Include im Head" beim Projekt an die angegebene Stelle, anstatt direkt vor </head>.

head.metatags

<bx:head.metatags [hidden] />

Legt die Position im <head> fest, an der die Keywords und Description vom Nav-Punkt erscheinen. (ab V 2.6.5)

hidden Wenn man Keywords und Description eingegeben hat, aber sie bei einem Design nicht anzeigen will, weil sie dort speziell zusammengebaut werden (kann man an beliebiger Stelle ins Design schreiben)
Batix-Tags Referenz

Bx:i18n

Das Tag i18n ist zur Unterscheidung von Text in unterschiedlichen Sprachen.

<bx:i18n.{Schluesselwort}/>

Voraussetzungen:

Batix-Tags Referenz

bx:if

Das Tag if zeigt seinen Inhalt nur an, wenn eines oder mehrere innere Tags einen Inhalt besitzen.

<bx:if [type="{any | one | all}"] [trim] [rekursiv="{n}"] ] > Inhalt </bx:if>
<bx:if.1>...<bx:if.2>...<bx:if.else>...</bx:if.else>...</bx:if.2>...<bx:if.else>...</bx:if.else>...</bx:if.1> 

Bei mehreren geschachtelten Schleifen kann ein Bezeichner angegeben werden (ab Version 2.6.0.). Die else-Blöcke beziehen sich auf das jeweils direkt übergeordnete if. Ab Version 2.6.2 kann man auch trim angeben, damit störende Leerzeichen und Umbrüche ignoriert werden (auf die das if sonst anschlagen würde).

type="any" Inhalt nur anzeigen, wenn mindestens ein Tag einen Inhalt hat
type="one" Inhalt nur anzeigen, wenn genau ein Tag einen Inhalt besitzt
type="all" (Standard) Inhalt nur anzeigen, wenn alle Tags einen Inhalt haben
trim Check Leerzeichen und Umbrüche im zu prüfenden Inhalt (entspricht einem tools.trim um das zu prüfende Tag)
rekursiv Check auch verschachtelte Ebenen, n gibt die Ebene an (siehe Beispiel)

Beispiele

<bx:if recursive="1" type="any">
  <ul>
    <bx:recordfield.alleAnsprechpartner>
      <li><bx:recordfield.Name/></li>
    </bx:recordfield.alleAnsprechpartner>
  </ul>
</bx:if>

Alternativ bisher:
<bx:iF>
  <ul>
    <bx:recordfield.alleAnsprechpartner>
      <bx:if><li><bx:recordfield.Name/></li></bx:if>
    </bx:recordfield.alleAnsprechpartner>
  </ul>
</bx:iF>

Ansprechpartner (mit umgebenenden

<bx:if>
 zu prüfende <bx:tags>
 <bx:if.else [showalways]> 
  alternativer Text
 </bx:if.else> 
</bx:if> 

Der Inhalt dieses Tags wird immer dann ausgeführt, wenn die Bedingungen des übergeordneten Tests nicht zutreffen.

Kurzform:

<bx:if else=“keine Angabe“><bx:recordfield.Ansprechpartner/></bx:if> 

entspricht:

<bx:if>
  <bx:recordfield.Ansprechpartner/>
  <bx:if.else>
    keine Angabe
  </bx:if.else>
</bx:if> 
showalways Inhalt des else-Blocks wird immer ausgegeben* (ab *V2.6.1) siehe Beispiel

Beispiele

<bx:if>
  <a href="<bx:recordfield.Link />">
  <bx:if.else showalways> 
    <bx:recordfield.Bild />
  </bx:if.else>
  </a>
</bx:if> 

Hier wird in jedem Fall das Bild ausgegeben und nur falls Link gefüllt ist, wird ein a-Element um das Bild gesetzt.

if.elseif

<bx:if>
  zu prüfende <bx:tags>
  <bx:if.elseif> 
    weiterer zu prüfender Inhalt
    <bx:if.else>
      alternativer Inhalt
    </bx:if.else>
  </bx:if.elseif> 
</bx:if> 

Statt bx:if.else kann auch bx:if.elseif verwendet werden. Die Besonderheit liegt darin, dass dieses Tag dann wie eine verschaltete if-Verzweigung wirkt, es startet also eine eigene Auswertung seines Inhalts.

Beispiele

<bx:if>
  <bx:recordfield.Telefon/>
  <bx:if.elseif> 
    <bx:recordfield.Handy/>
    <bx:if.else>
      telefonisch nicht erreichbar
    </bx:if.else>
  </bx:if.elseif> 
</bx:if> 

Erst wird geprüft, ob eine Telefonnummer angegeben ist und wenn vorhanden ausgegeben. Wenn nicht, wird nach der Handynummer gefragt und wenn diese angegeben ist, ausgegeben. Wenn keine der beiden Felder ausgefüllt ist, wird der Text ausgegeben.

if.ignore

<bx:if>
  zu prüfende <bx:tags>
  <bx:if.ignore>
    <bx:recordfield.wird_nicht_geprueft />
  </bx:if.ignore>
</bx:if>

Um Bereiche innerhalb eines bx:if-Tags von der Inhaltsprüfung auszuschließen, kann bx:if.ignore verwendet werden. Der Inhalt dieses Tags wird ganz normal auf der Seite angezeigt.

Beispiele

<bx:if>
  <img src="<bx:recordfield.Bild type="path"/>" alt="<bx:if.ignore><bx:recordfield.Alt_Titel/></bx:if.ignore>">
</bx:if>

Wenn ein Bild angegeben ist, wird das img-Tag(Bild) angezeigt, der Alt-Titel, der erfahrungsgemäß nicht immer vorhanden ist, wird von der Prüfung ausgeschlossen, d.h. wenn er fehlt, bleibt der alt-Parameter leer, das Bild wird aber trotzdem ausgegeben.

filter

Um JSP-Bausteine als Filter eines bx:if- oder bx:if.elseif-Tags zu verwenden, geben Sie als zusätzlichen Parameter filter="<filtername>" an. Die Entscheidung, ob der Inhalt ausgegeben wird oder nicht, wird dann dem Script überlassen. Die vorhergehende Auswertung durch das Tag selbst wird im Request-Parameter attrValue übergeben, welche über jenen Parameter auch geändert werden kann.

Batix-Tags Referenz

bx:ignore

Um Bereiche eines Templates auszukommentieren kann das Tag ignore benutzt werden.

<bx:ignore> nicht auszuwertender Bereich </bx:ignore>

Bei einem auskommentierten Bereich im HTML-Code (mit ) wird der Quelltext dazwischen trotzdem vom CMS ausgewertet und in die Seite geschrieben. Dies führt zu einer schlechteren Performance. Deshalb ist die Verwendung von <bx:ignore> in solchen Fällen vorzuziehen.

Batix-Tags Referenz

bx:include

Das Tag include bietet die Möglichkeit ein Textbaustein oder eine HTML-Seite einzufügen. Hinweis: Um auswertbare Seiten einzubinden, benutzen Sie bitte bx:cmpageinclude oder bx:jspinclude.

<bx:include (modul="{modulname}" | file="{filename}") />

Inaktiv geschaltene Textbausteine werden ab Version 2.5.7 nicht mehr angezeigt. In der Vorschau (Preview) werden allerdings auch die inaktiven Textbausteine angezeigt, damit man schon mal testen kann.

Batix-Tags Referenz

bx:internlink

In der Administration bietet dieses Tag internlink die Auswahl eines Navigationspunktes und im Frontend zeigt es eine Verlinkung auf diesen Navigationspunkt an.

<bx:internlink.{bezeichner} [shortpath] [web="{projektname | ID des Projekts}"]/>
<bx:internlink.{bezeichner}> Linktext </bx:internlink.{bezeichner}>		<!-- es kann ein eigener Linktext angegeben werden -->
shortpath relativer Pfad wird ausgegeben (www wird weggelassen)
web Angabe des  Projektes, um Menüpunkte dieses anderen Projektes auszuwählen
Batix-Tags Referenz

bx:javainclude

Mithilfe des Tags javainclude kann eine JSP-Datei eingebunden werden, die über die Dokumentvorlagen gepflegt wird.

<bx:javainclude modul="{bez}" [evalbx | evalbody] [quiet] [trim] />

<bx:javainclude modul="{bez}">[Text mit bx-Tags]</bx:javainclude>				<!-- zeigt Ausgaben, die im JSP gemacht werden, an. Der Text im Body des Include-Tags wird nicht ausgegeben -->
<bx:javainclude modul="{bez}" evalbody>[Text mit bx-Tags]</bx:javainclude>	<!-- verwirft Ausgaben, die im JSP gemacht werden, aber zeigt den Text im Body des Include-Tags an -->
<bx:javainclude modul="{bez}" evalbx>[Text mit bx-Tags]</bx:javainclude>		<!-- Wertet die Ausgaben aus dem JSP mit dem bx-Parser aus. Der Text im Body des Include-Tags wird nicht ausgegeben -->
evalbx evalbody steuert, ob der zurückgegebene Text nochmals evaluiert wird
quiet es werden keine Fehlermeldungen ausgegeben
trim Text wird getrimmt (es werden Leerzeichen und Zeilenumbrüche am Anfang und Ende abgeschnitten)

Beispiele

Quelltext der Seite

 ...
 <bx:javainclude modul="Baustein-Name" maxdays="14"><div>neu!</div></bx:javainclude>
 ... 

Quelltext des JSP-Bausteins

<%@taglib uri="/batix" prefix="batix"%>
 <%@page import="com.batix.admin.container.Record,com.batix.enterprise.DAT"%>
 <%@page import="java.util.Date,java.util.Calendar,com.batix.tags.ContainerLoop"%>
 <batix:taginfo><%
 Date limitDate;
 //auslesen eines selbst definierten Parameters vom <bx:javainclude>
 int days = includeTag.getIntParameter("maxdays", -1);
 Calendar cal = Calendar.getInstance();
 if (days>0) {
   cal.add(Calendar.DATE, -days);
 }
 cal.set(Calendar.HOUR_OF_DAY, 0);
 cal.set(Calendar.MINUTE, 0);
 limitDate = cal.getTime(); //das Vergleichsdatum
 
 //umgebende Containerschleife auslesen
 ContainerLoop loop = (ContainerLoop)includeTag.findParent(ContainerLoop.class);
 Record dok = loop.getCurrentRecord(); //aktueller Datensatz im Schleifendurchgang
 //Datumsfeld namens 'erstellt' aus dem Containerdatensatz lesen
 DAT dat = (DAT)dok.loadPublicField("erstellt", includeTag.checkConnection());
 Date date = dat!=null ? dat.getDate() : null;
 //wenn das gespeicherte Datum neuer als der Vergleichswert ist...
 if (date!=null && date.after(limitDate)) {
   StringBuffer htmlData = new StringBuffer();
   //...den Body des bx:include auswerten...
   includeTag.computeFrontend(htmlData);
   out.print(htmlData.toString().trim()); // ...und in die Seite schreiben
   //oder ab v2.5.6: out.print(includeTag.computeBody());
 }
 %></batix:taginfo>

Zeige Inhalt an, wenn Datensatz neuer ist als x Tage

Batix-Tags Referenz

bx:json

Mit dem Tag bx:json können JSON Strukturen ausgelesen und einfach durchgegangen werden. Um schnell in tief verschachtelte Objekte zu gelangen, kann JsonPath genutzt werden.

JSON laden

<bx:json data="[1, 2, 3]">...</bx:json>
<bx:json data="clipboard:json_data">...</bx:json>
<bx:json url="http://server/..." [encoding="utf-8"]>...</bx:json>

Das JSON-Dokument kann entweder direkt als Text übergeben werden (wobei der Umweg über ein Clipboard oder Attribut möglich ist), es kann aber auch eine URL angegeben werden, von der die Daten geladen werden (encoding gibt dabei an, mit welchem Zeichensatz die Daten eingelesen werden, Standard ist utf-8).

Im URL-Modus sendet das JSON-Tag nicht das Session-Cookie mit, da meist externe URLs aufgerufen werden und die SESSIONID nicht ausversehen preisgegeben werden soll.Falls die Daten von einem internen, geschützten Menüpunkt geladen werden (auf den der aktuell eingeloggte Benutzer Zugriff hat), kann `bx:jspinclude` verwendet werden - dieses schickt das Session-Cookie mit:

<bx:clipboard.cut name="json_data"><bx:jspinclude>/intern/api.json</bx:jspinclude></bx:clipboard.cut>
<bx:json data="clipboard:json_data">
  ...
</bx:json>
Der JSON-Parser akzeptiert auch nicht RFC-konformeres JSON, also z.B. Kommentare oder Keys, die nicht mit Anführungszeichen umgeben sind (Details siehe hier).

Ist in den JSON-Daten ein Objekt kodiert, kann dieses mit geschachtelten Json-Tags durchgegangen werden; ein Array verhält sich wie eine Schleife; andere Datentypen haben ihre entsprechenden Funktionen (s.u.).

Falls die JSON selbst generiert wird, sollte zwecks Interoperabilität (z.B. Verwendung in JavaScript direkt) ein Objekt kodiert werden.Falls man nur einen String oder eine Zahl hat, kann man diese(n) einfach im Objekt unter einem Key angeben, also anstatt: 523 besser: { "data": 523 }

Eine fortgeschrittenere Möglichkeit des Daten-Ladens, kann über das Attribut `application` realisiert werden. Hier gibt man den Name eines Application-Attributes an, in dem ein `JsonElement` gespeichert ist. Dieses wird dann vom Tag benutzt und es entfällt das String-Parsen. Dies ist nützlich bei Caches, die man global in der Application vorhalten kann, und die sich nicht oft ändern. Ein `JsonElement` kann mittels `Gson` und der `toJsonTree` Methode erzeugt werden (z.B. aus einer Map, die man mit Groovy zusammenbaut).

JSON durchgehen

Die JSON-Struktur kann einfach via Tags durchgegangen werden:

<bx:json data="..."> <!-- Root-Tag -->
  <bx:json.Kunde> <!-- Sub-Tag -->
    Der Kunde heißt: <bx:json.Vorname /> <bx:json.Nachname />
    <bx:Json field="address home">
      Er wohnt in: <bx:json.Ort />
    </bx:Json>
  </bx:json.Kunde>
</bx:json>

Es ist jeweils die Angabe von encode=... möglich, um z.B. Ausgaben für URLs oder CSV zu encoden.

Das auszugebende Feld kann entweder im Tag-Titel (nach bx:json., also im Beispiel "Kunde") oder im Parameter field="" (oben z.B. "address home") angegeben werden. Die Angabe via field ist nötig, falls der Feldname Sonderzeichen / Leerzeichen enthält.

Ist das zu parsende JSON kein Objekt oder Array, sondern z.B. ein String oder eine Zahl, kann das Root-Element direkt ausgegeben werden:

<bx:json data="12345" /> <!-- gibt 12345 aus -->
<bx:json data="'testing'" contains="test" true="Pass" false="Fail" /> <!-- gibt Pass aus -->

Wird versucht auf ein Feld zuzugreifen, das nicht existiert, wird nichts ausgegeben. Es kann alternativ via dummy ein Alternativwert (im JSON-Format) angegeben werden, der stattdessen genommen wird. Je nach Typ des Wertes in dummy (wird wie ein neues JSON geparst), stehen die Typ-spezifischen Funktionen (s.u.) zur Verfügung.

<!-- falls es kein Feld missingNumber gibt, wird automatisch der Wert 5 genommen -->
<bx:json.missingNumber dummy="5" lt="10">...</bx:json.missingNumber>
 
<!-- es können auch komplexe Sachen als Dummy spezifiziert werden, hier empfiehlt sich ein Clipboard -->
<bx:clipboard.cut name="objdummy">
{
  x: 5,
  s: ""
}
</bx:clipboard.cut>
<bx:json.missingObject dummy="clipboard:objdummy">...</bx:json.missingObject>

Da JSON-Tags (sowohl Root-Tags als auch Sub-Tags von Objekten oder Arrays) mehrfach verschachtelt sein können und man manchmal Sachen von Über-Über-...-Elementen ausgeben will, kann man via Tag-Titel oder name die Tags benennen und via base diese referenzieren (der Parameter name hat beim Suchen des passenden Parent-Tags Vorrang vor dem Tag-Titel). Das entspricht der Funktionalität von baseloop bei Containern. Mittels base="$" kann das Root-Tag referenziert werden (das Tag, bei dem die Daten geladen wurden). Die Angabe von base kann immer zusätzlich zu allen anderen Parametern erfolgen (z.B. können base und path gleichzeitig benutzt werden).

<bx:json data="..."> <!-- Root-Tag -->
  <bx:json.Sub>
    <bx:json.SubSub name="Kunde">
      <bx:json.SubSubSub>
        <bx:json.Feld base="Sub">
          <!-- selber Kontext, als wenn man direkt innerhalb von <bx:json.Sub> wäre -->
        </bx:json.Feld>
        <bx:json.Feld base="Kunde">
          <!-- selber Kontext, als wenn man direkt innerhalb von <bx:json.SubSub> wäre -->
        </bx:json.Feld>
        <bx:json.Feld base="$">
          <!-- selber Kontext, als wenn man direkt innerhalb des Root-Tags wäre -->
        </bx:json.Feld>
      </bx:json.SubSubSub>
    </bx:json.SubSub>
  </bx:json.Sub>
</bx:json>

Je nach Datentyp ergeben sich unterschiedliche Funktionen, die benutzt werden können:

Null

Der Inhalt wird ausgeführt (oder nicht bei not), falls im JSON der Spezialwert null steht. Nicht vorhandene Elemente können so auch abgefragt werden (nicht vorhanden entspricht hier null).

<bx:json.Feld null>Feld war null oder nicht vorhanden</bx:json.Feld>
<bx:json.Feld null not>Feld war vorhanden und nicht null</bx:json.Feld>

Boolean

Boolesche Werte können ähnlich wie Häkchenfelder im Container abgefragt werden. Eine kurze Version (geschlossenes Tag) mit truefalse steht auch zur Verfügung.

<bx:json.Condition [not]>
  ...
</bx:json.Condition>
 
<bx:json.Condition [true=""] [false=""] />

Number

ausgeben / formatieren

Zahlen können formatiert ausgegeben werden. Ist kein pattern angegeben, werden Ganzzahlen ohne und Kommazahlen mit Nachkommastellen ausgegeben. Der Tausender- und Dezimal-Trenner kann mittels gs bzw. ds spezifiziert werden. Der Rundungsmodus ist standardmäßig HALF_UP (normales kaufmännisches Runden) und kann via rounding geändert werden (siehe Java-Docs für mögliche Werte).

<bx:json.Zahl [pattern=""] [locale=""] [gs=""] [ds=""] [rounding=""] />

locale sollte immer angegeben werden, da sonst die Standardeinstellung vom Server genutzt wird, die sich aber nach Updates oder Umzügen ändern kann.

vergleichen

Folgende Vergleiche sind möglich:

Parameter ausgeführter Vergleich
equals ==
gt >
gte >=
lt <
lte <=
Das Ergebnis kann jeweils mit not umgekehrt werden. Für alle Vergleiche ist auch eine verkürzte Variante mit truefalse möglich (hier wird der jeweilige Wert von true oder false ausgegeben).
<bx:json.Zahl [equals=""] [gt=""] [gte=""] [lt=""] [lte=""] [not]>
</bx:json.Zahl>
 
<bx:json.Zahl [equals=""] ... [true=""] [false=""] />

Date

Ab Version 2.6.8

Da es im JSON keinen nativen Datumstyp gibt, wird mittels dem Tag-Parameter date der vorhande String-Wert im JSON als Datum interpretiert.

Eingabeformat

Ist lediglich date ohne weiteren Wert im Tag angegeben, werden einige Standard-Patterns unterstützt:

<bx:json.mydate date />

Es wird folgende Liste in dieser Reihenfolge durchprobiert:

<bx:json.mydate date="dd/MM/yyyy" />

Es muss nicht der gesamte String matchen. Möchte man z.B. aus dem Wert "20.08.2018 um 08:50" nur das Datum ziehen, genügt das Pattern dd.MM.yyyy.

Ausgabeformat

Standardmäßig wird das geparste Datum anhand des Patterns dd.MM.yyyy HH:mm:ss ausgegeben. Es kann auch ein eigenes Pattern angegeben werden:

<bx:json.mydate date pattern="dd.MM. HH:mm" />

Werden z.B. Tages- oder Monatsnamen ausgegeben, wird über locale die gewünschte Sprache eingestellt:

<bx:json.mydate date="yyyy-MM-dd" pattern="EEEE, d. MMMM" locale="de" />

Datum/Zeit modifizieren

Durch die Angabe von verschiedenen Parametern können alle Teile des Ausgangsdatums angepasst werden. Es kann eine Zahl angegeben werden, um den entsprechenden Wert absolut zu setzen. Dabei kann dieser Zahl ein Plus (+) oder Minus (-) vorangestellt werden, um die Modifikation stattdessen relativ durchzuführen. Die möglichen Parameter sind (werden auch in dieser Reihenfolge angewandt):

Beispiel (Tag auf den 15. Februar setzen, zwei Stunden dazu zählen, zehn Jahre abziehen):

<bx:json.mydate date day="15" month="2" hour="+2" year="-10" />

Mögliche Werte beim Wochentag sind dabei folgende Werte (keine Zahlen erlaubt):

Trifft der angegebene Wochentag bereits auf das Ausgangsdatum zu, wird das Datum nicht geändert. Dieses Verhalten kann durch Angabe eines doppelten Plus (++) oder Minus (--) überschrieben werden (es wird dann auch gewechselt, falls der Wochentag schon zutrifft).

Zeitliche Abfrage

Eine weitere Funktion ist die Abfrage, ob das Ausgangsdatum (bzw. das modifizierte Datum) vor oder nach dem jetzigen Zeitpunkt (Zeit auf dem Server) bzw. heute liegt. Der Unterschied ist, dass beim Vergleich mit heute die Uhrzeit nicht beachtet wird, sondern nur der Datumsteil.

Die folgenden Abfragen sind möglich:

<bx:json.mydate date before-now>in der Vergangenheit</bx:json.mydate>
<bx:json.mydate date after-now not>auch in der Vergangenheit oder genau jetzt</bx:json.mydate>
 
<bx:json.mydate date before-today true="vor heute" />
<bx:json.mydate date after-today false="vor heute oder heute" />
 
<bx:json.mydate date today true="am heutigen Tag" false="nicht heute" />

String

ausgeben

Im einfachsten Fall wird der String ausgegeben und ggf. automatisch encoded (siehe Encodings für andere Encoding-Möglichkeiten).

<bx:json.Text />

vergleichen

Strings können auch verglichen werden. Die Angabe von ignoreCase bewirkt, dass Groß-/Kleinschreibung nicht beachtet wird, not kehrt das Ergebnis um.

Parameter Vergleich
matches Vergleich via RegEx (regulärem Ausdruck), String muss diesem komplett entsprechen
equals Gleichheit
contains der String muss den Wert das Parameters beinhalten
Auch hier ist eine verkürzte Variante mit true und false möglich.
<bx:json.Text [matches=""] [equals=""] [contains=""] [ignoreCase] [not]>
</bx:json.Text>
 
<bx:json.Text [matches=""] [equals=""] [contains=""] [ignoreCase] [true=""] [false=""] />

BatixRecord

Steht in den JSON-Daten im Feld eine Batix-ID, so kann hier auch ein Container angebunden werden. Das Tag verhält sich dann wie bx:record, es können innerhalb die normalen Container-Tags wie bx:recordfield oder bx:recorddata benutzt werden. Auch der Zugriff von außerhalb des Tags mit z.B. bx:recorddata.nav ist möglich.

Der Datensatz wird anhand des Feldes ID rausgesucht. Es kann aber auch via linkfield auf ein anderes Feld im Datensatz verwiesen werden (Text oder Einzelverknüpfung), hierbei wird der erste gefundene Datensatz genommen.

Wird kein Datensatz mit entsprechender ID (oder Wert im Feld) gefunden, wird nichts ausgegeben. Die Angabe von dummy bewirkt, dass stattdessen ein leerer Datensatz vorgehalten wird (der Tag-Inhalt wird ausgeführt, innere bx:recordfield-Tags etc. geben aber nichts aus, wie bei bx:record).

<bx:json.IDFeld pool="Container" [linkfield=""] [dummy]>
  <bx:recordfield... />
  <bx:recorddata.if... />
</bx:json.IDFeld >
 
<bx:recorddata.nav object="IDFeld">
  <bx:recorddata.total />
</bx:recorddata.nav>

Array

Ein Array funktioniert analog zu z.B. bx:containerfilter, für jedes Element wird der Tag-Inhalt einmal ausgeführt. Das Start-Element kann dabei mittels index (0-basiert) und die maximale Anzahl Durchläufe via max geregelt werden.

Um das aktuelle Element im Durchlauf auszugeben wird einfach <bx:json /> verwendet. Je nach Datentyp (in Arrays können auch verschiedene Datentypen vorhanden sein) können hier die entsprechenden Funktionen verwendet werden (z.B. formatierte Ausgabe bei Zahlen).

<bx:json.Liste [index="20"] [max="10"]>
  <bx:json />
</bx:json.Liste>

Es können die meißten Funktionen von bx:recorddata verwendet werden:

<bx:json.Liste>
  ...
</bx:json.Liste>
<bx:recorddata.nav object="Liste">
  Gesamt: <bx:recorddata.total/><br>
  <bx:recorddata.navlist max="5">
    ...

Ferner gibt es noch folgende Hilfsmethoden:

<bx:json.Liste>
  <bx:json {first|last} [not]>...</bx:json> <!-- Inhalt nur ausführen, wenn es das erste oder letzte Element ist -->
  <bx:json {first|last} [true=...] [false=...] /> <!-- dito, nur verkürzte true/false Schreibweise -->
  <bx:json index [add="5"] /> <!-- aktuellen Durchlauf-Index ausgeben, ggf. etwas dazu addieren -->
  <bx:json total /> <!-- Gesamtanzahl der Elemente ausgeben -->
  <bx:json empty [not]>...</bx:json> <!-- ausführen, falls das Array leer ist -->
  <bx:json empty [true=...] [false=...] /> <!-- dito, nur mit true/false -->
  <bx:json cols=...> <!-- funktioniert wie bx:recorddata.cols -->
</bx:json.Liste>

Für mehr Informationen zu cols siehe die entsprechende Passage bei bx:recorddata.

Datensätze

Befinden sich im Array Strings, welche Batix-IDs sind, kann mittels pool eine Schleife über Datensätze (wie z.B. bx:containerfilter) aufgemacht werden. Falls die ID in einem anderen Feld steht, kann dies wieder via linkfield referenziert werden. Innerhalb des Json-Tags sind alle normalen Datensatz-Tags verfügbar. dummy verhält sich im Falle eines leeren Arrays wie ein leerer Datensatz (ansonsten wird der Inhalt nicht ausgeführt).

Falls im Array (zusätzlich) nicht-Strings sind, wird im Log eine Warnung ausgegeben.

<bx:json.Kunden pool="Shop_Kunden" [linkfield=""] [dummy]>
  <bx:recordfield... />
  <bx:recorddata.if... />
</bx:json.Kunden>

Object

Um in ein JSON-Objekt tiefer einzusteigen, wird das Json-Tag (analog zu bx:recordfield bei Verknüpfungen) geschachtelt.

<bx:json data="...">
  <bx:json.Kunde>
    <bx:json.Name />
  </bx:json.Kunde>
</bx:json>

Objekt-Einträge durchgehen

ab Version 2.6.9

Ähnlich einem Array können die Elemente eines Objekts (jeweils Key und Value) durchgegangen werden. Das ist hilfreich, falls man die Struktur der Map (des Objektes) nicht direkt kennt (vor allem wenn die Keys dynamisch sind). Dies erfolgt durch Angabe von each, innerhalb dieser Schleife können dann <bx:json key> und <bx:json value> benutzt werden um auf den entsprechenden Bestandteil zuzugreifen.

Das Tag mit key hat dabei immer einen String im Hintergrund, wobei das Tag mit value den Typ des Unterelementes hat (entsprechend sind dort auch wieder die verschiedenen Operationen je Typ möglich).

<bx:json data="...">
  <bx:json.Kunde each>
    Feld '<bx:json key />' hat den Wert '<bx:json value />'
  </bx:json.Kunde>
</bx:json>

JsonPath

Mittels JsonPath-Expressions können relativ einfach verschachtelte Strukturen angesprochen werden. Das erspart lästiges Verschachteln von Json-Tags. Auf der GitHub Seite gibt es mehr Details zur Syntax, hier ist nur das Nötigste erwähnt.

Operator Bedeutung
$ aktuelle bx:json Node, der Startpunkt damit beginnen alle Expressions
@ aktuelle Node in der Expression in Filtern benutzt
* Wildcard für aktuelles Level
.. Wildcard für beliebige Sub-Level
.Name oder ['Name'] Feld Name
.Adresse.Ort Feld Ort im Unterobjekt Adresse
[x] / [x:y] Index bzw. Range im Array
[?(...)] Filter
Es sind auch Statistikfunktionen verfügbar (siehe Link, z.B. min()), diese sind aber nur auf reine Arrays aus Zahlen anwendbar. Mittels Filtern können Vergleiche angestellt und dabei sogar andere Felder referenziert werden. (z.B. Ist die Zahl in Feld X größer als die Zahl in Feld Y?)

Sobald etwas passendes gefunden wurde, können die Typ-spezifischen Funktionen verwendet werden. Wird nichts passendes zum Pfad gefunden, wird der Tag-Inhalt nicht ausgeführt (außer bei dummy).

Zu bemerken ist auch, dass path an beliebiger Stelle innerhalb verschachtelter Json-Tags verwendet werden kann, $ in der Pfadangabe entspricht dann dem direkten Parent-Objekt.

Beispiele:

<bx:json data="...">
  <bx:json path="$.Adresse.Name" equals="" false="nicht leer" />
  <!-- entspricht -->
  <bx:json path="$['Adresse']['Name']" equals="" false="nicht leer" />
  <!-- entspricht -->
  <bx:json.Adresse><bx:json.Name equals="" false="nicht leer" /></bx:json.Adresse>
  <!-- entspricht -->
  <bx:json.Adresse><bx:json path="$.Name" equals="" false="nicht leer" /></bx:json.Adresse>
 
  <!-- gibt das 2. Element im Array orders aus, je nach Datentyp der Elemente im Array können hier die spezifischen Typ-Funktionen genutzt werden -->
  <bx:json path="$.orders[1]" />
 
  <!-- gibt den höchsten Preis aus -->
  <bx:json path="$.prices.max()" pattern="0.00" locale="de" />
 
  <!-- gibt die Autoren aller Bücher aus -->
  <bx:json path="$.books[*].author">
    Autor: <bx:Json />
  </bx:json>
 
  <!-- dito, aber nur für Bücher mit einem Rating > 2 -->
  <!-- bei komplexen Expression empfiehlt sich ein Clipboard, gerade bei Sonderzeichen -->
  <bx:clipboard.cut name="expr">$.books[?(@.rating > 2)].author</bx:clipboard.cut>
  <bx:json path="clipboard:expr">
    Autor: <bx:Json />
  </bx:json>
 
  <!-- gibt die Preise aller Unterelemente (beliebige Tiefe) aus -->
  <bx:json path="$.store..price">
    Preis: <bx:Json locale="de" />
  </bx:json>
 
  <!-- gibt alle Preise aus, die kleiner als der Maximalpreis (ein Feld im JSON) sind -->
  <bx:clipboard.cut name="expr">$.store.articles[?(@.price < $.maxprice)]</bx:clipboard.cut>
  <bx:json path="clipboard:expr">
    Preis: <bx:Json locale="de" />
  </bx:json>
</bx:json>
Batix-Tags Referenz

bx:jspinclude

Das Tag jspinclude veranlasst den Server eine URL aufzurufen und den zurückgegebenen Text in die Seite einzufügen.

<bx:jspinclude (page="{url}" | file="{url}") [request | jsp] [charset="{enc}"] />
<bx:jspinclude [request | jsp] [charset="{enc}"]> aufzurufende URL </bx:jspinclude>

Als offenes Tag verwendet besteht die Möglichkeit den Inhalt dieses Tags auszuwerten und als URL das Ergebnis (sofern vorhanden) zu verwenden.

page file Übergabe der URL
request Übergabe des Request-Parameters der aktuellen CM-Seite (falls der Inhalt der URL mittels GET geholt wird)
jsp echter JSP-Include
charset Um die Zeichencodierung der einzubindenden Daten anzugeben, kann encoding verwendet werden, z.B. encoding="utf-8".

Es wird das Session-Cookie mit der SESSIONID mitgeschickt. Das Ziel sollte also vertrauenswürdig sein, da sonst eine Session durch Angreifer übernommen werden könnte.

Beispiele

Irgendwo im Body einen Datensatz raussuchen:
<bx:containerfilter.Aemter pool="1234567890" force="list" max="1">
  <bx:clipboard.cut name="amtid"><bx:recorddata.id/></bx:clipboard.cut>
</bx:containerfilter.Aemter>

...

Im Teaserbereich:
<bx:jspinclude>/teaser/ansprechpartner.htm?amt=<bx:clipboard.paste name="amtid"/></bx:jspinclude>

Es wird ein Teaser mit den Ansprechpartnern für dieses Amt im Teaserbereich aufgerufen mit der entsprechenden Amt-ID.

Batix-Tags Referenz

bx:link

Es wird ein relativer Link auf "detail.htm" erstellt, der die Seiten-ID als Parameter defaultLoop übergibt.

class CSS-Klasse
target Zielfenster im Browser

Diese Form schreibt einen relativen Link auf ein Unterverzeichnis mit dem selben Namen wie der aktuelle Menüpunkt. .

type="menu"
target Zielfenster im Browser Falls nicht angegeben, wird der Wert aus den Menüpunkt-Einstellungen benutzt

Es wird ein relativer Link auf "detail.htm" erstellt, der die Seiten-ID als Parameter defaultCatLoop übergibt. Über class und target lassen sich CSS-Klasse und Zielfenster des Links einstellen.

class CSS-Klasse
target Zielfenster im Browser
href aufzurufende URL

Dieses Tag steht innerhalb von bx:record und erzeugt einen Link aufurlbzw auf die aktuelle Seite, wenn href nicht angegeben wurde.

recordfield ID des Records
href URL
Batix-Tags Referenz

bx:login

Das Tag login zeigt seinen Inhalt nur an, falls der User ein- bzw. ausgeloggt ist.

<bx:login.if (in | out)> Inhalt </bx:login.if>

Falls in angegeben wurde, wird der Inhalt nur dargestellt, wenn sich der Client mittels vorherigem Login in einer gültigen Session befindet. out zeigt den Inhalt dagegen nur an, wenn der User ausgeloggt ist. .

Batix-Tags Referenz

bx:loop

Mithilfe des loop-Tags ist es möglich, sich wiederholende Inhalte mit gleichem Aufbau zusammenzufassen und ggf. zu sortieren.

Dieses Tag ist veraltet. Stattdessen sollte bx:schleife genommen werden - alle Funktionen bleiben gleich, eben nur mit bx:schleife statt bx:loop davor.

Loop erzeugen

** Deprecated - Veraltetes Feature** Die hier aufgeführten Informationen beziehen sich auf eine veraltete Funktion, die nicht mehr weiterentwickelt wird und ggf. in zukünftigen Versionen nicht mehr unterstützt wird. Diese Funktion sollte deshalb nicht mehr benutzt werden.

<bx:loop [loop="{name}"] [orderby="{feldname}"] [showmax="{anzahl}"]> Inhalt </bx:loop>

Mit loop kann der Schleife ein Name gegeben werden (Standard: "defaultLoop") und mit orderby kann das Feld festgelegt werden, nach dem sortiert wird. Als Inhalt steht die Formatierung für jedes Element der Schleife. Es können dabei die folgenden Sub-Tags benutzt werden. Die maximale Anzahl an Elementen, die ausgegeben werden, wird über showmax festgelegt.

Die folgenden Tags werden weiterhin in [bx:schleife](/books/cms-handbuch-entwickler/page/bx-schleife) genutzt

loop.count (ab v2.6.6. deprecated) --> neu: loop.index

<bx:loop.count [add="{anzahl}"] />

Hiermit lässt sich die aktuelle Position der Schleife ermitteln, also wieviele Wiederholungen schon erfolgt sind (z.B. für Nummerierung der Einträge, beginnt mit 0). Dem Ergebnis wird der Wert von "add" hinzuaddiert, sofern vorhanden.

loop.index (neu ab v2.6.6)

<bx:loop.index[add="{anzahl}"] />

Ist jetzt besser benannt. loop.count geht noch wegen Kompatibilität)

loop.id

<bx:loop.id />

Diese Funktion gibt die ID des aktuellen Datensatzes zurück.

loop.if

<bx:loop.if {first | notfirst | gerade | ungerade}> Inhalt </bx:loop.if>

Der Inhalt wird nur ausgewertet, wenn die entsprechende Bedingung zutrifft. Folgende Bedingungen können abgefragt werden:

Prüfen auf letztes Element

<bx:schleife.Inhalte>
  <bx:clipboard.cut name="LetztesElement"><bx:loop.id/></bx:clipboard.cut>
</bx:schleife.Inhalte>
      
<bx:schleife.Inhalte>
  <bx:clipboard.cut name="AktuellesElement"><bx:loop.id/></bx:clipboard.cut>
  <bx:clipboard.if name="AktuellesElement" value="clipboard:LetztesElement">{wird ausgeführt im Falle des letzten Elements}</bx:clipboard.if>
</bx:schleife.Inhalte>

Eine direkte Prüfung auf das letzte Element ist derzeit nicht möglich, kann aber mit einen Hilfs-Schleifendurchlauf und dem Clipboard simuliert werden.

loop.cols

<bx:loop.cols num="{anzahl der spalten}" equals="{welche spalte}" [not]> Inhalt </bx:loop.cols>

Hier wird der Inhalt nur angezeigt, wenn sich der Datensatz in einer bestimmten Spalte der Ausgabe befindet.

Achtung! Die Anzahl der Spalten wird von 1 bis n angegeben, aber die Angabe der betreffenden Spalte wird von Null aus gezählt. z. B. <bx:loop.cols num="3" equals="1"> Inhalt </bx:loop.cols> spricht die zweite Spalte an.

num gibt die Spaltenanzahl und equals die gesuchte Spalte an. not kehrt die Bedingung um.

loop.previous / loop.next

Diese Tags erzeugen einen Link zum vorherigen bzw. nächsten Element. Der Linktext kann dabei geändert werden (Standard: "zurück" bzw. "weiter").

Nur auf Detailseiten möglich!

<bx:loop.previous [loop="{schleifenname}"] />
<bx:loop.previous [loop="{schleifenname}"]>Linktext</bx:loop.previous>
<bx:loop.next [loop="{schleifenname}"] />
<bx:loop.next [loop="{schleifenname}"]>Linktext</bx:loop.next>

Über den Parameter loop kann eine andere Schleife angesteuert werden.

loop.previousid / loop.nextid

Diese Tags geben die ID des vorherigen bzw. nächsten Datensatzes aus.

Nur auf Detailseiten möglich!

<bx:loop.previousid [loop="{schleifenname}"] />
<bx:loop.nextid [loop="{schleifenname}"] />

Über den Parameter loop kann eine andere Schleife angesteuert werden

loop.showprevious / loop.shownext

Mit loop.count lässt sich die aktuelle Position der Schleife ermitteln, also wieviele Wiederholungen schon erfolgt sind (z.B. für Nummerierung der Einträge).

<bx:loop.showprevious [schleife="{schleifenname}"] [hidden] [indexparam="{parametername}"] /> zurück </bx:loop.showprevious>
<bx:loop.shownext [schleife="{schleifenname}"] [hidden] [indexparam="{parametername}"] /> vor </bx:loop.shownext>

Über den Parameter schleife kann eine andere Schleife angesteuert werden. indexparam gibt den Name des Request-Parameters an, welcher den aktuellen Index enthält. Mit hidden werden die Links ganz ausgeblendet, wenn sie nicht klickbar sind, ansonsten werden die Links ausgegraut.

loop.total

Dieses Tag gibt die Anzahl der in der Schleife angezeigten Datensätze aus. Es kann außerhalb der Schleife benutzt werden. (ab V2.6.6)

<bx:loop.total [object="{schleifenname}"] />

Über den Parameter object kann die jeweilige Schleife angesteuert werden.

loop.designtitle

Dieses Tag gibt den Titel des Designbausteins aus. (ab V2.6.6)

<bx:loop.total [object="{schleifenname}"] />

Wenn das umgebende Schleifentag keine Designschleife ist, wird eine Fehlermeldung  ausgegeben.

Batix-Tags Referenz

bx:mapping

Das Tag mapping kann sich Werte zu Schüsselwerten (values zu keys) merken und später können diese Werte wieder abgefragt und ausgegeben werden. Es ist eine Erweiterung von <bx:clipboard> mit der Erweiterung, daß bei jedem Befehl der Name einer Map angegeben werden muß. ab V 2.6.2

mapping.put

<bx:mapping.put map="{listname}"> key=value </bx:mapping.put>

Fügt ein Key-Value-Paar der angegebenen Liste hinzu. "=" ist der Trenner.

map Name der Liste, in der Keys und dazugehörige Values gespeichert werden sollen

Beispiele

<bx:mapping.put map="bewertung">1=super-spitzenmäßig</bx:mapping.put>
<bx:mapping.put map="bewertung">2=jo, paßt scho</bx:mapping.put>
<bx:mapping.put map="bewertung">3=grot-ten-schlecht</bx:mapping.put>

mapping.paste

<bx:mapping.paste map="{listname}" name="{key}"/>

Holt das Value anhand des Keys aus der angegebenen Liste.

map Name der Liste, aus der das entsprechende Value geholt werden soll
name Key-Wert

Beispiele

...
Ihre Bewertung: <bx:mapping.paste map="bewertung" name="request:note"/>
..

(siehe obiges Beispiel - das füllt die hier genutzte Liste ) reagiert auf den Requestparameter "note". So spart man sich dreimaliges pagedata.request-Gewurschtl.

Batix-Tags Referenz

bx:math

Das Tag math führt Berechnungen durch. Ab Version 2.5.9.

<bx:math pattern="..." locale="de" gs="." ds="," rounding="[ceiling|down|floor|half_down|half_even|half_up|up]">{Aufgabe}</bx:math>
pattern Formatierung festlegen (Standard bei Zahl: "0.#####", bei Preis: "0.00"). Tausender-Trennzeichen (gs) und Dezimal-Trennzeichen (ds) können ebenfalls festgelegt werden.
locale Sprachformatierung (z.B. "de" oder "en_US")
 locale sollte immer angegeben werden, da sonst die Standardeinstellung vom Server genutzt wird, die sich aber nach Updates oder Umzügen ändern kann.
Aufgabe z.Zt. unterstützte Operatoren: + (Addition) - (Subtraktion) * (Multiplikation) / (Division) ^ (Hochrechnung) % (Modulo)
rounding ceiling: Rundet zur nächsten Ganzzahl auf (in Richtung +unendlich) floor: Rundet zur nächsten Ganzzahl ab (in Richtung -unendlich) up: Rundet zur nächsten Ganzzahl auf (aus Richtung null) down: Rundet zur nächsten Ganzzahl ab (in Richtung null) half_down: Rundet bei ,5 nach oben auf half_even: Rundet bei ,5 bei geraden Zahlen ab, bei ungeraden Zahlen auf half_up: Rundet bei ,5 nach unten ab Resultat der jeweiligen Methode UPDOWNCEILINGFLOORHALF_UPHALF_DOWNHALF_EVEN5,565656562,532323221,621212221,121211111,01111111-1,0-1-1-1-1-1-1-1-1,1-2-1-1-2-1-1-1-1,6-2-1-1-2-2-2-2-2,5-3-2-2-3-3-2-2-5,5-6-5-5-6-6-5-6
Resultat der jeweiligen Methode
UP
5,5 6
2,5 3
1,6 2
1,1 2
1,0 1
-1,0 -1
-1,1 -2
-1,6 -2
-2,5 -3
-5,5 -6

Beispiele

<bx:math pattern="0.00">8*(-3+7)</bx:math>

gibt "32,00" aus

<bx:math pattern="#,##0.00"><bx:recordfield.Preis/>+<bx:recordfield.Versandkosten/></bx:math>

gibt einen Preis incl. Versandkosten aus

<bx:math pattern="0.00" locale="de">
 <bx:recordfield.Anzahl/>*<bx:recordfield.Nettoeinzelpreis/>*(1+<bx:recordfield.Steuersatz/>/100)
</bx:math>

gibt einen Bruttopreis aus.

Debug

<bx:math.debug pattern="">{Aufgabe}</bx:math.debug>

gibt nicht nur das Ergebnis aus, sondern die gesamte Formel

Beispiele

<bx:math.debug pattern="0.00">8*(-3+7)</bx:math.debug>

gibt "calc{8*(-3+7)}=32.0" aus

Rechnen mittels Datenbank

<bx:math.mysql pattern="...">{Aufgabe}</bx:math.mysql>

Rechenoperationen werden mittels einer SQL-Formel gemacht.

Beispiele

<bx:math.mysql pattern="0">POW(3,4)</bx:math.mysql>

gibt "81" aus ( 34 )

Vergleich von Zahlen

<bx:math.compare value1="{Wert1}" operator="{Operator}" value2="{Wert2}"> angezeigter Inhalt </bx:math.compare>

Zeigt Inhalt abhängig vom Vergleich zweier Zahlenwerte aus.(ab V 2.5.9)

value1 erster Vergleichswert es können auch Präfixe verwendet werden
operator Operator:e (gleich)gt (größer als)lt (kleiner als)lte (kleiner gleich)gte (größer gleich) sein
value2 zweiter Vergleichswert es können auch Präfixe verwendet werden

Beispiele

<bx:pagedata.setattribute mode="set" name="kathede1">3</bx:pagedata.setattribute>
<bx:pagedata.setattribute mode="set" name="kathede2">4</bx:pagedata.setattribute>
<bx:pagedata.setattribute mode="set" name="hypotenuse">5</bx:pagedata.setattribute>
<bx:clipboard.cut name="v1">
  <bx:pagedata.attribute name="kathede1"/>*<bx:pagedata.attribute name="kathede1"/>
  +<bx:pagedata.attribute name="kathede2"/>*<bx:pagedata.attribute name="kathede2"/>
</bx:clipboard.cut>
<bx:clipboard.cut name="v2">
  <bx:pagedata.attribute name="hypotenuse"/>*<bx:pagedata.attribute name="hypotenuse/>
</bx:clipboard.cut>
<bx:math.compare value1="clipboard:v1" operator="e" value2="clipboard:v2">rechtwinklig</bx:math.compare>

Vergleiche mit min und max

<bx:math.min [attribute|clipboard]="{name}"> {Vergleichszahl} </bx:math.min>			<!-- Wenn der Tag-Body einer kleineren Zahl entspricht, wird das gespeicherte Attribut aktualisiert. -->
<bx:math.max [attribute|clipboard]="{name}"> {Vergleichszahl} </bx:math.max>            <!-- Wenn der Tag-Body einer größeren Zahl entspricht, wird das gespeicherte Attribut aktualisiert. -->
<bx:math.[max|min] [attribute|clipboard]="{name}" extra-source="{text}" extra-target="[attribute|clipboard]:{name2}"> {Vergleichszahl} </bx:math.max>

Vergleicht den in Request-Attribut oder Clipboard-Objekt gespeicherten Zahlenwert mit dem Zahlenwert aus dem Tag-Body und ändert gegebenenfalls den Attributwert. Sinnvoll in Schleifen und den Min- bzw. Max-Wert zu ermitteln.

attribute/clipboard muß nicht zwangsläufig vorher vorhanden sein, kann aber, um einen Bestimmten Wert als Ausgangswert festzulegen
extra-source wenn angegeben, wird zusätzlich bei jeder Änderung der Variablen der source-Text in das angegebenen target-Objekt gespeichert.
extra-target Wohin der Text aus extra-source gespeichert werden soll (siehe Beispiel)

Beispiele

<bx:containerfilter.Fragen pool="Umfrage Elemente">
  <bx:math.max clipboard="maxSort"><bx:recordfield.Sortierung/></bx:math.max>
</bx:containerfilter.Fragen>
nächste Sortier-Position: <bx:math pattern="0"><bx:clipboard.paste name="maxSort"/>+1</bx:math>

Innerhalb einer Schleife wird die größte Sortierungsposition ermittelt

<bx:containerfilter.Produkt pool="Produkte" idield="pid">
  ...
  <bx:recordfield.Varianzen>
    <bx:clipboard.cut name="größe"><bx:recordfield.groesse/></bx:clipboard.cut>
    <bx:math.min clipboard="preis" extra-source="clipboard:größe" extra-target="clipboard:billigsteGröße"><bx:recordfield.NettoPreis/>*1.19</bx:math.min>
  <bx:recordfield.Varianzen>
  ...
  ab <bx:clipboard.paste name="preis"/> Euro (für Größe <bx:clipboard.paste name="billigsteGröße"/>)
  ...
</bx:containerfilter.Produkt>

Die Preise der Varianzen (hier: Größen) eines Produktes werden durchgegangen. Bei jedem Durchlauf wird im Clipboard "größe" die jeweilige Größe gespeichert. Ist der Wert im Recordfield NettoPreis nun kleiner als der im Clipboard "preis" schon gespeicherte, wird der Wert dieses Clipboards überschrieben und der Wert vom Clipboard "größe" ins Clipboard "billigsteGröße" gespeichert (muß nicht vorher angelegt werden) und kann dann am Ende ausgegeben werden.

[<bx:clipboard.cut name="gesamtPreis"></bx:clipboard.cut>] <!-- wird angelegt, wenn noch nicht vorhanden -->
<bx:containerfilter.Warenkorb pool="Warenkorb">
  <bx:math.add clipboard="gesamtPreis"><bx:recordfield.Preis/></bx:math.add>
</bx:containerfilter.Warenkorb >
Gesamtpreis: <bx:clipboard.paste name="gesamtPreis"/>

Addiert alle Preise im Warenkorb zusammen.

<bx:containerfilter.Warenkorb pool="Warenkorb">
  <bx:recordfield.MWST equals="7"><bx:math.add clipboard="7prozent" value="1"></bx:math.add><bx:recordfield.MWST>
  <bx:recordfield.MWST equals="19"><bx:math.add clipboard="19prozent" value="1"></bx:math.add><bx:recordfield.MWST>
</bx:containerfilter.Warenkorb >
Anzahl Artikel mit 7% Mwst: <bx:clipboard.paste name="7prozent"/>
Anzahl Artikel mit 19% Mwst: <bx:clipboard.paste name="19prozent"/>

Zählen in verschiedenen Kategorien

Hochzählen / Zusammenzählen

<bx:math.add [attribute|clipboard]="{name}"> {Wert} </bx:math.add>   <!-- addiert Werte innerhalb einer Schleife auf -->
<bx:math.add (attribute|clipboard)="{name}" [value="1"] />		   <!-- als geschlossenes Tag zum Hochzählen mit dem Wert in value -->

Beispiele

<bx:clipboard.cut name="gesamtPreis"></bx:clipboard.cut>] <!-- wird angelegt, wenn noch nicht vorhanden -->
<bx:containerfilter.Warenkorb pool="Warenkorb">
  <bx:math.add clipboard="gesamtPreis"><bx:recordfield.Preis/></bx:math.add>
</bx:containerfilter.Warenkorb >
Gesamtpreis: <bx:clipboard.paste name="gesamtPreis"/>

Addiert alle Preise im Warenkorb zusammen.

<bx:containerfilter.Warenkorb pool="Warenkorb">
  <bx:recordfield.MWST equals="7"><bx:math.add clipboard="7prozent" value="1"></bx:math.add><bx:recordfield.MWST>
  <bx:recordfield.MWST equals="19"><bx:math.add clipboard="19prozent" value="1"></bx:math.add><bx:recordfield.MWST>
</bx:containerfilter.Warenkorb >
Anzahl Artikel mit 7% Mwst: <bx:clipboard.paste name="7prozent"/>
Anzahl Artikel mit 19% Mwst: <bx:clipboard.paste name="19prozent"/>

Zählen in verschiedenen Kategorien

Formatieren von Zahlenwerten

<bx:math.format (attribute|clipboard)="{name}" pattern="#,##0.00" [ ds="," gs="." | locale="de" ] [rounding="half_up"] />

Formatiert den Zahlenwert im Request-Attribut/Clipboard und gibt das Ergebnis aus.

Vergleich von Datumsen

<bx:math.datecompare prior="{Wert1}" later="{Wert}" [pattern="{pattern}"] > angezeigter Inhalt </bx:math.datecompare>

Ein Vergleich der beiden übergebenen Datumswerte wird durchgeführt und der Inhalt nur ausgegeben, wenn der Wert prior zeitlich vor dem Wert later liegt.

prior zu prüfender Datumswert
later zu prüfender Datumswert
pattern Eingangsformat von prior und later, Standard ist "dd.MM.yyyy".

Beispiele

<bx:clipboard.cut name="Halloween">31.10.2011</bx:clipboard.cut>
<bx:clipboard.cut name="Allerheiligen">1.11.2011</bx:clipboard.cut>
<bx:math.datecompare prior="clipboard:Halloween" later="clipboard:Allerheiligen">immer angezeigt</bx:math.datecompare>
<bx:math.datecompare prior="clipboard:Allerheiligen" later="clipboard:Halloween">nie angezeigt</bx:math.datecompare>

Datum modifizieren

<bx:math.modifydate pattern="{pattern}" locale="{de,en,fr,...}" (in-pattern="{Muster}" out-pattern="{Muster}") (in-locale="{de,en,fr,...}" out-locale="{de,en,fr,...}") (year|month|day|hour|minute|second)="[+|-]{Zahlenwert}" > {Datum} </bx:math.modifydate>

Eine Funktion, um ein im Body übergebenes Datum zu modifizieren und wieder auszugeben.

pattern beide Muster sind gleich
in-pattern/out-pattern Muster unterscheiden sich
in-locale/out-locale Sprachen unterscheiden sich

Beispiele

<bx:math.modifydate in-pattern="yyyyMMdd" month="+1" day="15" out-pattern="dd. MMMM yy">20110922</bx:math.modifydate>

gibt „15. Oktober 11“ aus

<bx:clipboard.copy><bx:tools.datum pattern="EEE, MMM d yyyy" locale="en"/></bx:clipboard.copy>

gibt aus und speichert im Clipboard “Wed, Jan 3 2018

<bx:math.modifydate in-pattern="EEE, MMM d yyyy" out-pattern="EEEEEE, d. MMMMM yy" in-locale="en" out-locale="fr"><bx:clipboard.paste/></bx:math.modifydate> 

gibt aus “mercredi, 3. janvier 18

<bx:math.modifydate in-pattern="EEE, MMM d yyyy" out-pattern="EEEEEE, d. MMMMM yy" locale="ru" in-locale="en"><bx:clipboard/></bx:math.modifydate> 

gibt aus “среда**, 3. января 18**”

<bx:math.modifydate pattern="EEE, MMM d yyyy" in-locale="en" out-locale="es"><bx:clipboard/></bx:math.modifydate> 

gibt aus “mié, ene 3 2018

<bx:math.modifydate in-pattern="EEE, MMM d yyyy" out-pattern="EEEEEE, d. MMMMM yy" locale="en"><bx:clipboard/></bx:math.modifydate>

gibt aus “Wednesday, 3. January 18

Feiertagsausgabe (ab V 2.3.)

<bx:math.holiday [inpattern="{pattern}"] [outpattern=("pattern" | "")] [year|month|day|hour|minute|second)="[+|-]{Zahlenwert}"]> Datumsangabe im konfigurierten Format </bx:math.holiday>

Ausgabe des Namens eines (Thüringer) Feiertags (z.B. Silvester). Das zu prüfende Datum wird im Tagbody angegeben. Leerzeichen an Anfang und Ende werden ignoriert. Ist das Datum kein Feiertag, wird der Wochentagsname ausgegeben (Standard) oder ein in outpattern definierter Inhalt.

inpattern Eingangsformat (Standard ist "dd.MM.yyyy")
outpattern Art des ausgegebenen Inhalts (siehe Beispiel) oder Wochentagsname (Standard)

Beispiele

<bx:math.holiday>30.12.2015</bx:math.holiday> 		<!-- gibt "Silvester" aus -->

<bx:math.holiday inpattern="yyyy:dd MMM">2015:31 Dez</bx:math.holiday> 		<!-- gibt "Silvester" aus -->
<bx:math.holiday inpattern="yyyy:dd MMM">2015:30 Dez</bx:math.holiday> 		<!-- gibt "Mittwoch" aus -->

<bx:math.holiday outpattern="">30.12.2015</bx:math.holiday> 				<!-- gibt "" (nichts) aus <bx:if> verwendbar, ABER: -->
<bx:math.holiday outpattern="">31.12.2015</bx:math.holiday> 				<!-- gibt "Silvester" aus <bx:if> verwendbar -->

auch Datums-Modifizierer möglich: <bx:math.holiday day="+1">31.12.2015</bx:math.holiday> gibt "Neujahr" aus

Feiertagsabfrage (ab V 2.3.)

<bx:math.isholiday testdate="{datum]" [pattern="pattern"] [not]>Inhalt</bx:math.isholiday>

Testet, ob das übergebenen Datum ein Feiertag ist und gibt den Taginhalt aus.

testdate zu prüfendes Datum, über ein Präfix angegeben
pattern Eingangsformat (Standard ist "dd.MM.yyyy")
not kehrt die Bedingung um

Beispiele

<bx:math.isholiday testdate="request:pruefdatum" not pattern="dd.MM.yyyy">kein Feiertag</bx:math.isholiday>

beim Aufruf von ...detail.htm?pruefdatum=30.12.2015 würde "kein Feiertag" ausgegeben

<bx:math.isholiday testdate="request:pruefdatum" pattern="dd.MM.yyyy">Feiertag: <bx:math.holiday inpattern="dd.MM.yyyy"><bx:pagedata.request name="pruefdatum"/></bx:math.holiday></bx:math.isholiday>
  wär das gleiche wie 
<bx:if>Feiertag: <bx:math.holiday inpattern="dd.MM.yyyy" outpattern=""></bx:math.holiday> </bx:if>

Zwei Arten, einen Feiertag abzufragen.

auch Datums-Modifizierer möglich: <bx:clipboard><bx:tools.datum></bx:clipboard> <bx:math.isholiday testdate="clipboard:default" day="+1"> morgen ist ein Feiertag</bx:math.isholiday>

Tagesdifferenz zwischen zwei Daten

<bx:math.datetolong data="{wert}">        	// wandelt Datum in Millisekunden (seit 1970) und
<bx:math.datetolong> Wert </bx:math.datetolong>

<bx:math.longtodate>       					//wandelt Millisekunden zu Datum
<bx:math.longtodate> Wert <bx:math.longtodate>

Die Angabe von pattern ist jeweils optional möglich (Standard ist "dd.MM.yyyy").

Beispiele

<bx:clipboard name="datum1">25.3.2017</bx:clipboard>
<bx:clipboard name="datum2">2.4.2017</bx:clipboard>

<bx:math>(<bx:math.datetolong data="clipboard:datum2"/>-<bx:math.datetolong><bx:clipboard name="datum1"/></bx:math.datetolong>)/ 1000 / 3600 /24</bx:math>

Da wird „7.958333333333333“ Tage ausgegeben. Normalerweise glatte Zahl, aber hier ist Sommerzeitumstellung dazwischen. Wenn man bei <bx:math pattern=”0”> schreibt, rundet es auf 8 Tage.

Batix-Tags Referenz

bx:navdata

Das Tag navdata gibt zum aktuellen Menüpunkt des Schleifendurchlaufs Daten aus. Es kann innerhalb von <bx:navigation.[Nummer]> , <bx:sitemap.[Nummer]>, <bx:submenu.list>, <bx:navlink> verwendet werden.

navdata.id

<bx:navdata.id />

Die Id des Menüpunkts wird ausgegeben.

navdata.name

<bx:navdata.name [type="plain] />

Der Name des Menüpunkts wird ausgegeben. type="plain" z.B. für csv-Datei

navdata.dir

<bx:navdata.dir />

Der virtuelle Verzeichnisname des Menüpunkts wird ausgegeben.

navdata.path

<bx:navdata.path [follow] [no-encoding] />

Der ganze Pfad des Menüpunkts wird ausgegeben.

follow wenn der Zielmenüpunkt ein weitergeleiteter Menüpunkt ist, wird nicht auf den Punkt gelinkt, sondern auf das Ziel des Menüpunktes
no-encoding der Pfad wird nicht korrekt encoded, sondern direkt reingeschrieben z. B. mit Umlauten und russischen Zeichen. Es liegt dann am Browser das zu korrigieren.
follow wenn der Zielmenüpunkt ein weitergeleiteter Menüpunkt ist, wird nicht auf den Punkt gelinkt, sondern auf das Ziel des Menüpunktes
no-encoding der Pfad wird nicht korrekt encoded, sondern direkt reingeschrieben z. B. mit Umlauten und russischen Zeichen. Es liegt dann am Browser das zu korrigieren.

navdata.target

<bx:navdata.target/>

Das eventuell beim Menüpunkt eingetragene Target wird ausgegeben.

navdata.meta

<bx:navdata.meta name="{eigenschaftsname}" />	<!-- Metadaten zum Menüpunkt ausgeben werden ausgegeben -->
<bx:navdata.meta name="{eigenschaftsname} [value="{vergleichswert}"] [not]" />   <!-- Block abhängig vom Wert der entsprechenden Metadaten anzeigen -->

Metadaten zum Menüpunkt ausgeben werden ausgegeben oder zum Vergleich herangezogen.

navdata.index

<bx:navdata.index [add="{n}"]/>

Die laufende Nummer des Menüpunkts in der aktuellen Ebene wird ausgegeben.

add Ausgabe der aktuellen Nummer plus angegebener Wert. Standard ist 1, d.h., weil bei 0 angefangen wird, wird bei Nicht-Angabe des Add-Parameters bei 1 angefangen. Soll bei 0 angefangen werden, muß add="0" sein (heißt: zum Startwert 0 wird 0 hinzugezählt anstatt (Standard)1 ).

navdata.robots

Es wird behauptet, daß eine Seite mit jeden externen Link, der darauf ist, von Google schlechter gerankt wird, und die verlinkte Seite dafür besser. Deshalb sollen alle externen Links der Suchmaschine sagen, daß sie dort nicht draufgehen soll. Das Tag liest die Einstellungen in der Navigation, damit bei externen Links ein <a … rel=“nofollow“ angehängt werden kann.

<bx:navdata.robots [index] [follow] />

gibt "(no)index" bzw. "(no)follow" entsprechend der Menüpunkteinstellung aus. Wenn beide Parameter angegeben sind, werden die Werte beide, durch Komma getrennt, ausgegeben.

<bx:navdata.robots index|noindex|follow|nofollow> ... <bx:navdata.robots>

Zeigt den Inhalt an, wenn die angefragte Bedingung für den Menüpunkt zutrifft

Beispiele

<bx:sitemap.2>
  <a href="<bx:sitemap.path/>" <bx:navdata.robots nofollow>rel="nofollow"</bx:navdata.robots>> … </a>
</bx:sitemap.2>

navdata.visible

<bx:navdata.visible [not]> Inhalt </bx:navdata.visible>

Zeigt an, ob das Frontend-aktiv-Häkchen beim Nav-Punkt gesetzt ist. ab v2.6.6.

Beispiele

<bx:sitemap.0 showinactive>
  <a href="<bx:sitemap.path/>"<bx:navdata.visible not> style="color:grey;"</bx:navdata.visible>><bx:sitemap.name/></a>
</bx:sitemap.0>

Es werden aktive und inaktive Menüpunkte angezeigt, die inaktiven werden in Grau dargestellt.

navdata.if

<bx:navdata.if (open | closed | hasChilds | noChilds | self | notself | first | last | notfirst | notlast)> Inhalt </bx:navdata.if>
<bx:navdata.if (id="{id}" | parent="{id}" | path="{pfad}" | redirected [not])> Inhalt </bx:navdata.if>

Mit diesem Tag kann entschieden werden, ob ein bestimmter Quelltext ausgegeben werden soll.

pfad Menüpunkt-Pfad
open/closed Menüpunkt ist geöffnet (gilt auch für Überebenen)
hasChilds/noChilds Abfrage, ob Menüpunk Unterpunkte besitzt
self/notself aktueller Menüpunkt
first/last/notfirst/notlast erklärt sich selbst
id Vergleich des Menüpunkts mit einer ID (mehrere IDs mit Komma, Semikolon oder Leerzeichen getrennt ab v 2.6.2)
parent Vergleich des übergeordnete Menüpunkts mit einer ID
path Vergleich des Menüpunktes mit einem bestimmten Pfad
redirected wenn Menüpunkt weitergeleitet wird
Verweise auf diese Seite:

bx:navigation bx:navigation

(2 Verweise)

Batix-Tags Referenz

bx:navigation

Das Tag navigation wird verwendet, um eine Navigationsstruktur darzustellen.

Allgemeine Syntax

<bx:navigation.{level} [normal | protected | showcurrentinactive] [open]>Inhalt</bx:navigation.<level>>
level Navigationstiefe (beginnt mit 0 = Root-Ebene)
um darunterliegende Menüpunkte anzuzeigen, werden
bx:navigation
-Tags geschachtelt (jeweils das Level um 1 erhöhen)
normal protected showcurrentinactive nur nicht-geschützte Menüpunkte anzeigen nur geschützte (Intranet-)Menüpunkte anzeigen wird angezeigt, wenn man sich gerade in diesem inaktiven Menüpunkt befindet
open geöffnete Menüpunkte anzeigen

Ab Version 2.6.2 kann man auch auf Seiteninhalte zugreifen, so wie bei bx:submenu.

Beispiele

<bx:navigation.0>
  <a href="<bx:navigation.path/>"><bx:navigation.name/></a><br>
  <bx:navigation.1>
    <a href="<bx:navigation.path/>">-<bx:navigation.name/></a><br>
    <bx:navigation.2>
      <a href="<bx:navigation.path/>">--<bx:navigation.name/></a><br>
    </bx:navigation.2>
  </bx:navigation.1>
</bx:navigation.0>

Beispiel für geschachtelte Navigation

navigation.path

<bx:navigation.path/>

Der virtuelle Pfad wird ohne "/www/webname/" und ohne "/" am Ende ausgegeben (siehe Beispiel oben).

navigation.dir

<bx:navigation.dir/>

Es wird nur der aktuelle Verzeichnisname ausgegeben.

navigation.name

<bx:navigation.name/>

Dieses Tag gibt den angezeigten Name des Menüpunktes aus.

navigation.target

<bx:navigation.target [default="{ziel}"] />

Das Zielframe wird ausgegeben.

ziel Standard-Zielframe, wenn im Menüpunkt kein Zielframe angegeben wurde

navigation.id

<bx:navigation.id/>

Dieses Tag gibt die ID des Menüpunktes aus. Die ID der aktuellen Seite kann auch mit <a href="http://docs.batix.info/display/DEVS/bx%3Apagedata#bx:pagedata-pagedata.navid" target="_blank">bx:pagedata.navid</a> ausgegeben werden.

navigation.index

<bx:navigation.index/>

Es wird eine laufende Nummer innerhalb der Navigations-Schleife ausgegeben. Die Zählung beginnt bei 1 und startet in jedem Unterpunkt neu.

navigation.if

<bx:navigation.if (open | closed | hasChilds | noChilds | self | notself | first | last | notfirst | notlast)> Inhalt </bx:navigation.if>
<bx:navigation.if (id="{id}" | parent="{id}" | path="{pfad}" | redirected [not])> Inhalt </bx:navigation.if>

Mit diesem Tag kann entschieden werden, ob ein bestimmter Quelltext ausgegeben werden soll. Die ID der aktuellen Seite kann auch mit <a href="http://docs.batix.info/display/DEVS/bx%3Apagedata#bx:pagedata-pagedata.nav" target="_blank">bx:pagedata.nav</a> abgefragt werden.

pfad Menüpunkt-Pfad
open/closed Menüpunkt ist geöffnet (gilt auch für Überebenen)
hasChilds/noChilds Abfrage, ob Menüpunk Unterpunkte besitzt
self/notself aktueller Menüpunkt
first/last/notfirst/notlast erklärt sich selbst
id Vergleich des Menüpunkts mit einer ID (mehrere IDs mit Komma, Semikolon oder Leerzeichen getrennt ab v 2.6.2)
parent Vergleich des übergeordnete Menüpunkts mit einer ID
path Vergleich des Menüpunktes mit einem bestimmten Pfad
redirected wenn Menüpunkt weitergeleitet wird
<bx:navigation.link/>
<bx:navigation.link> Linktext </bx:navigation.link>   <!-- es kann ein eigener Linktext angegeben werden -->

Beispiele

<bx:navigation.0>
  <bx:navigation.link default="_blank"><span title="<bx:navigation.name/>"><bx:navigation.index/></span></bx:navigation.link><bx:navigation.if notlast> | </bx:navigation.if>
</bx:navigation.0>

Navigation mit Zahlen - ich weiß, issn blödes Beispiel

Ausgabe: 1 | 2 | 3 | 4    - beim Hover auf die Zahlen erscheint der Menüpunktname. Der letzte Trennstrich wurde ausgeklammert.

navigation.meta

<bx:navigation.meta name="{metaname}"/>											<!-- Ausgabe der Meta-Eigenschaft -->
<bx:navigation.meta name="{metaname}" [not]> Inhalt </bx:navigation.meta>	<!-- gibt den Inhalt nur aus, wenn die Meta-Eigenschaft existiert bzw. nicht existiert (not) -->

Dieses Tag gibt Meta-Daten zum aktuellen Menüpunkt aus oder prüft, ob diese vorhanden sind. Es kann auch bx:navdata benutzt werden.

Batix-Tags Referenz

bx:navlink

Innerhalb eines Navigations-Tags

<bx:navlink> Inhalt </bx:navlink>

sucht das nächste umgebende navigation-Tag (navigation, sitemap) und es können so Daten des Navigationspunktes abgerufen werden

Beispiele

<bx:navigation.0>
  <a href="<bx:navigation.path/>"><img src="<bx:navlink><bx:bild.Seitenbild width="100" height="100"/></bx:navlink>"></a>
</bx:navigation.0>

Statt des Menüpunktnamen wird als Navigations-Link das Seitenbild des jeweiligen Menüpunkts ausgegeben.

Außerhalb eines Navigations-Tags (ab v2.6.2)

Daten innerhalb des Tags werden vom angegeben  Menüpunkt geholt und haben kein Eingabefeld im aktuellen Menüpunkt.

Beispiele

Angabe der Menüpunkt-ID

Unsere Adresse: <bx:navlink navid="1234567890"><bx:text.Adresse/></bx:navlink>

Wiederkehrender Text (z.B. Adresse, Widerrufstext o.ä.) kann auf einer Konfigurationsseite abgelegt werden und überall im Web benutzt werden (ohne Container).

Angabe eines Pfads zum Menüpunkt

<strong>Achtung:</strong> <bx:navlink path="/konfigtexte/"><bx:text.Warnhinweis/></bx:navlink>
Batix-Tags Referenz

bx:news

Momentan nur für alte Container

<bx:news.loopyears pool="..." datumfield="Datum" archivfield="Archiv" desc>
  <li><a href="..."><bx:news.year/></a> (<bx:news.count/> Beiträge)</li>
<bx:news.loopyears>
Batix-Tags Referenz

bx:option

<bx:option.Auswahlbezeichner options="Option1,Option2,Option3" values="o1,o2,o3"/>

Stellt sich in der Verwaltung als Select dar. Ist momentan nicht standardmäßig im System integriert.

options werden im Dropdown angezeigt
value entsprechende Values zu den Options, Reihenfolge beachten!

Beispiele

<bx:clipboard.cut name="bildlage" trim>
  <bx:option.Bildlage options="kleines Bild links,kleines Bild rechts,großes Bild ganze Breite" values="li,re,ce"/>
</bx:clipboard.cut>

Im weiteren Verlauf der Seite kann man dann das Clipboard abfragen und entsprechende Designs ausliefern.

Batix-Tags Referenz

bx:optional

In der Administration stellt sich das Tag optional als Checkbox dar. Im Frontend wird der Inhalt nur angezeigt, wenn der Haken gesetzt ist. Sinnvoll, wenn für viele Seiten das gleiche Template benutzt wird, um die Darstellungsformen zu erhöhen (z.B. Bild anzeigen oder nicht, Bild rechts oder nicht, Anzeige eines Submenüs oder nicht... usw.)

Dieses Tag kann sich in der Verwaltung darstellen.

<bx:optional.{titel} [label="{text}"] [not]> Inhalt </bx:optional.{titel}>
<bx:optional.{titel} [label="{text}"] [true="{text}"] [false="{text}"] />

Die erste Form gibt den Inhalt nur aus, wenn der Haken gesetzt ist (not kehrt dies um).

In der zweiten Form kann je ein Text für beide Fälle gesetzt werden (Haken gesetzt bzw. nicht gesetzt).

label der Text neben der Checkbox in der Administration kann damit geändert werden (Standard: "Bereich anzeigen").
true, false Text, der für den jeweiligen Zustand ausgegeben werden soll

Beispiele

<img src="/static/<bx:pagedata.webdir/>/seitenbild_kontakt.png" alt="Seitenbild" align="<bx:optional.Anzeige_rechts>right</bx:optional><bx:optional.Anzeige_rechts not>left</bx:optional>">
Batix-Tags Referenz

bx:pagedata

Mithilfe des Tags pagedata lassen sich die verschiedensten Informationen die Seite betreffend ausgeben.

pagedata.parentnavid

<bx:pagedata.parentnavid/>

Es wird die Navigations-ID des Elternpunktes (oder leer) ausgegeben.

pagedata.webid

<bx:pagedata.webid/>
<bx:pagedata.customerid/>	<!-- veraltet -->

Gibt die ID des Webs (Projekts) aus

pagedata.webdir

<bx:pagedata.webdir/>
<bx:pagedata.customerdir/>	<!-- veraltet -->

gibt das virtuelle Verzeichnis des Webs aus.

pagedata.webhost

<bx:pagedata.webhost [addscheme]/>

(Verfügbar ab Version 2.7)

Der beim Projekt eingegebene Haupthost wird ausgegeben. Wenn "addscheme" angegeben ist, wird auch das beim Projekt eingestellte Protokoll ausgegeben. Dies ist bei Canonical-Angaben nützlich, wenn nicht der aktuelle Host (wie bei <bx:pagedata.hostname/>) gebraucht wird, sondern die Hauptdomain.

pagedata.virtualpath

<bx:pagedata.virtualpath [original]/>

Der virtuelle Pfad des Menüpunktes wird ausgegeben. z.B. von http://www.beispielseite.de/produkte/textiles/pullover/ wird ausgegeben: produkte/textiles/pullover

original es wird der ursprüngliche Pfad ausgegeben (bei forwards)

pagedata.navid

<bx:pagedata.navid [level="{n}"]/>							<!-- gibt nur die ID aus -->
<bx:pagedata.navid is="{id}"> Inhalt </bx:pagedata.navid>	<!-- Inhalt wird nur dann ausgegeben, wenn die ID des aktuellen Menüpunktes mit der ID von "is" übereinstimmt" -->

Navigations-ID des aktuellen Menüpunktes oder eines Elternpunktes Um auch mehrere IDs, die Eltern-ID oder den Pfad abfragen zu können, benutzen Sie bitte pagedata.nav.

level Ebene des gewünschten Navigationspunktes
Hauptmenüpunkt entspricht
level="0"
, Untermenüpunkte liegen jeweils eine Ebene höher
is vorgegebene ID
NOT funktioniert hier nicht, bitte pagedata.nav verwenden

pagedata.navpath

<bx:pagedata.navpath [previous | next] [active | inactive | all] />

Gibt den virtuellen Pfad des Menüpunktes aus, z.B. von http://www.beispielseite.de/produkte/textiles/pullover/ wird ausgegeben: pullover

previous
next
sucht den vorherigen bzw. nächsten Menüpunkt im gleichen Level
active
inactive
all
nur aktive anzeigen (Standard)
nur inactive anzeigen
alle anzeigen

Beispiele

<div style="float:left;width:100px;">
  <a href="<bx:pagedata.navpath previous/>">&laquo; vorherige Seite</a>
</div>
<bx:pagedata.navname />
<div style="float:right;width:100px;text-align:right;">
  <a href="<bx:pagedata.navpath/>">nächste Seite &raquo;</a>
</div>

Ein Blättern zwischen den (aktiven) Menüpunkten einer Ebene. Sieht dann ungefähr so aus:

« vorherige Seite Angebote für Juli nächste Seite »

pagedata.navname

<bx:pagedata.navname [level="{n}"] />

Gib den Name des Menüpunktes oder eines Elternpunktes aus.

level Ebene des gewünschten Navigationspunktes (nur höhere Ebenen vom aktuellen Menüpunkt aus)
Hauptmenüpunkt entspricht
level="0"
, Untermenüpunkte liegen jeweils eine Ebene höher

pagedata.nav

<bx:pagedata.nav {id="{id}" | parent="{id}" | path="{pfad}"} [not] [original]> Inhalt </bx:pagedata.nav>

Entscheidet, ob Inhalt ausgegeben wird anhand von ID(s) oder Pfad

id ID des gesuchten Menüpunktes
ab V 2.6.2: es können mehrere ID mit Komma getrennt angegeben werden
parent ID des Elternmenüpunktes (findet auch sich selbst als Punkt) ab V 2.7: es können mehrere ID mit Komma getrennt angegeben werden
path Pfad des aktuellen Menüpunktes
not kehrt die Bedingung um
original es wird die Angabe von der ursprünglichen Seite genommen (z.B. bei einem jsp-include )

pagedata.request

Ab V 2.6.3 RC14 wird in den meisten Fällen ein HTML-Encoding gemacht, wo kein encode-Parameter angegeben ist und auch kein <bx:tools.htmlencode> außen herum ist. Dies verursacht manchmal Probleme:

<bx:pagedata.request name="{param}" [boundary="{text}"] [empty] encode="{ html | javascript | sql | sql-like | sql-rlike | url | xml | plain}"/>	<!-- Ausgabe des Request-Parameters -->
<bx:pagedata.request name="{param}" value="<text>" [true="{text}"] [false="{text}"] />

<bx:pagedata.request name="{param}" [not] [empty]> Inhalt </bx:pagedata.request>					<!-- Auswertung des Request-Parameters -->
<bx:pagedata.request name="{param}" value="{text}" [not]> Inhalt </bx:pagedata.request>

Request-Parameter auswerten

<bx:pagedata.request ... encode="html|javascript|sql|sql-like|sql-rlike|url|xml">

javascript und url gibt's schon seit v2.3, den Rest ab v2.6.2

name Name des Request-Parameters
kann auch einen Platzhalter in der Form
name="[platz]id"
enthalten (siehe Beispiel)
encode Codierung des Wertes, für JavaScript-Code (Sonderzeichen werden escaped) oder als URL (%nn)
Hiermit kann der ausgegebene Text für verschiedene Formate kodiert werden:
- html - javascript - sql (zur Verwendung in SQL für Strings) - sql-like (zur Verwendung in SQL mit LIKE) - sql-rlike (zur Verwendung in SQL mit RLIKE und REGEXP) - url - xml - plain (überschreibt automatisches Encoding) - htmltext: siehe Beipspiel (3)
Das erspart ein bx:tools, was ansonsten um das bx:pagedata gepackt werden müsste.
boundary Falls der Parameter mehrfach vorkommt (?para=wert1&para=wert2) wird ohne Angabe von
boundary
nur der Erste ausgegeben,
andernfalls wird der Wert von
boundary
als Trennzeichen benutzt.
not
empty
Falls empty gesetzt ist, wird ein leerer Request-Parameter wie ein nicht vorhander behandelt.
| | seite.htm | seite.htm?p= | seite.htm?p=wert | | --- | --- | --- | --- | | <bx:pagedata.request name="p">... | leer | angezeigt | angezeigt | | <bx:pagedata.request name="p" not>... | angezeigt | leer | leer | | <bx:pagedata.request name="p" empty>... | leer | leer | angezeigt | | <bx:pagedata.request name="p" not empty>... | angezeigt | angezeigt | leer |
seite.htm
<bx:pagedata.request name="p">... leer
<bx:pagedata.request name="p" not>... angezeigt
<bx:pagedata.request name="p" empty>... leer
<bx:pagedata.request name="p" not empty>... angezeigt
value Text, den der Request-Parameter enthalten soll
true
false
Wenn der Wert des Parameters mit value verglichen wird kann entweder true (wird ausgegeben, wenn gleich) und/oder false (wird ausgegeben, wenn ungleich) verwendet werden oder man setzt den Inhalt, welcher dann bei Übereinstimmung ausgegeben wird (umkehrbar durch not).
ab v2.6.6: es kann auch abgefragt werden, ob der Parameter übergeben wurde oder nicht (siehe Beispiel)

Beispiele

Fall 1 true/false

<bx:pagedata.request name=“test“ value=“3“ true=”ist drei” false=”ist nicht drei” />

Fall 2 true/false

<bx:pagedata.request name=“test“ true=”test ist übergeben” false=”test ist nicht übergeben” />

es wird nicht der Wert abgefragt, sondern ob überhaupt der Parameter übergeben wurde

<bx:pagedata.request name=“test“ encode=”htmltext”/> 

Eingabe: test.htm?test=erste+Zeile%0azweite+Zeile   («%0a» ist ein Zeilenumbruch) →  schreibt «erste Zeile
zweite Zeile» und damit sieht man einen Zeilenumbruch im Browser

pagedata.attribute

Beispiele

speichern.act?feld=[]/Name[containerID]&containerID=12345

Bissl weit hergeholtes Beispiel: ... ich hab keine Ahnung!

speichern.act?feld=[]/Name[containerID]&containerID=12345
xml
test.htm?test=erste+Zeile%0azweite+Zeile  // "%0a" ist ein Zeilenumbruch

<bx:pagedata.request name="test" encode="htmltext"/> // schreibt erste Zeile<br>zweite Zeile und damit sieht man einen Zeilenumbruch im Browser
xml
<bx:pagedata.attribute name="{attrib}" />														<!-- schreibt den Wert des Attributes (falls vorhanden) in die Seite -->
<bx:pagedata.attribute name="{attrib}" [not]> Inhalt </bx:pagedata.attribute>					<!-- gibt den Tag-Inhalt aus, wenn das Attribut vorhanden ist -->
<bx:pagedata.attribute name="{attrib}" value="{text}" [not]> Inhalt </bx:pagedata.attribute>	<!-- vergleicht den Wert des Attributes mit dem Wert von value und gibt den Tag-Inhalt bei Übereinstimmung aus -->

Ein Request-Attribute, das z.B. durch JSP-Includes oder das bx:setattribute gesetzt wurde, kann ausgewertet werden.

name Name des Request-Attributs
value beliebiger Text, der mit dem Attribut übereinstimmen muß (oder auch nicht bei
not
)

pagedata.setattribute

<bx:pagedata.setattribute mode="[copy | set | remove]" name="{name}"> Inhalt </bx:pagedata.setattribute>

Ein Request-Attributekann gesetzt, geändert oder gelöscht werden.

name Name des Request-Attributs
mode copy: Zeigt den Taginhalt in der Seite an und kopiert ihn in das Request-Attribut set: Kopiert den Inhalt in das Request-Attribut aber zeigt ihn nicht in der Seite an remove: löscht das Request-Attribut (das Tag wird geschlossen verwendet)

pagedata.scriptattribute

<bx:pagedata.scriptattribute name="{attrib}" />																<!-- gibt den Wert des Script-Attributes (falls vorhanden) aus -->
<bx:pagedata.scriptattribute name="{attrib}" [not]> Inhalt </bx:pagedata.scriptattribute>					<!-- gibt den Tag-Inhalt aus, wenn das Script-Attribut vorhanden ist -->
<bx:pagedata.scriptattribute name="{attrib}" value="{text}" [not]> Inhalt </bx:pagedata.scriptattribute>	<!-- vergleicht den Wert des Script-Attributes mit dem Wert von value und gibt den Tag-Inhalt bei Übereinstimmung aus -->

Ein Script-Attribut, das z.B. durch Actions gesetzt wurde, kann ausgewertet werden.

name Name des Script-Attributs
value beliebiger Text, der mit dem Attribut übereinstimmen muß (oder auch nicht bei
not
)

pagedata.setscriptattribute

<bx:pagedata.setscriptattribute mode="[copy | set | remove]" name="{name}" [trim]> Inhalt </bx:pagedata.setscriptattribute>

Ein Script-Attribut kann gesetzt, geändert oder gelöscht werden.

name Name des Script-Attributs
mode copy: Gibt den Taginhalt aus und kopiert ihn in das Script-Attribut set: Kopiert den Taginhalt in das Script-Attribut aber zeigt ihn nicht an remove: löscht das Script-Attribut (das Tag wird geschlossen verwendet)

pagedata.listrequest

<bx:pagedata.listrequest/>

alle Request-Parameter werden als 'hidden' Formularfeld in die Seite geschrieben

pagedata.querystring

<bx:pagedata.querystring [original]/>

QueryString ausgeben

Ein '?' am Anfang ist in der Ausgabe nicht enthalten. GePOSTete Parameter sind nicht enthalten! Falls dieses Tag im HTML-Quelltext (z.b. für Links) verwendet wird, muss die Ausgabe noch durch bx:tool.urlencode umgewandelt werden.

original es wird der ursprüngliche QueryString ausgegeben (bei forwards)

pagedata.meta

<bx:pagedata.meta name="<meta>" />													<!-- schreibt den Wert der Meta-Eigenschaft (falls vorhanden) in die Seite -->
<bx:pagedata.meta name="<meta>" [not]> Inhalt </bx:pagedata.meta>					<!-- gibt den Tag-Inhalt aus, wenn die Meta-Eigenschaft vorhanden ist -->
<bx:pagedata.meta name="<meta>" value="<text>" [not]> Inhalt </bx:pagedata.meta>	<!-- vergleicht den Wert der Eigenschaft mit dem Wert von value und gibt den Tag-Inhalt bei Übereinstimmung aus -->

Metadaten auswerten

name Name der Meta-Eigenschaft
value beliebiger Text, der mit der Meta-Eigenschaft übereinstimmen muß (oder auch nicht bei
not
)

pagedata.cookie

<bx:pagedata.cookie name="{cookie}" />													<!-- schreibt den Wert des Cookies (falls vorhanden) in die Seite -->
<bx:pagedata.cookie name="{cookie}" [not]> Inhalt </bx:pagedata.cookie>					<!-- gibt den Tag-Inhalt aus, wenn der Cookie vorhanden ist -->
<bx:pagedata.cookie name="{cookie}" value="{text}" [not]> Inhalt </bx:pagedata.cookie>  <!-- vergleicht den Wert des Cookies mit dem Wert von value und gibt den Tag-Inhalt bei Übereinstimmung aus -->

Wertet vom Browser übergebene Cookies aus.

pagedata.hostname

<bx:pagedata.hostname [addscheme] />													<!-- gibt den Hostnamen des Servers aus (wenn Port != 80 Ausgabe = hostname:port -->
<bx:pagedata.hostname match="{regex}" [addscheme] [not]> Inhalt </bx:pagedata.hostname>	<!-- vergleich des Hostnames mit einem regulären Ausdruck (ab v2.5.5)-->

Der Hostname (und evtl. Port) der aktuellen Anfrage wird ausgegeben.

match Regulärer Ausdruck
addscheme gibt zusätzlich das Protokoll (http:// oder
https://)
des aktuellen Seitenaufrufs aus

Beispiele

Wenn man im Web von batix. com folgende Tags einbindet:

<bx:pagedata.hostname/>

wir ausgegeben: www.batix.com

<bx:pagedata.hostname addscheme/>

 wird ausgegeben: http://www.batix.com (ab v2.5.8)

<bx:pagedata.hostname match=".*\.[com|net]"> Sie haben unsere net- oder com-Domain aufgerufen.</bx:pagedata.hostname>

beim Aufruf von www.batix.de oder www.batix.eu wird der Text nicht ausgegeben, beim Aufruf von www.batix.com oder www.batix.net schon.

pagedata.sessionid

<bx:pagedata.sessionid/>

Die Session-ID wird ausgegeben. Wenn es noch keine Session gibt, dann wird eine erstellt und dann ausgegeben, außer man gibt "no-create" an* (ab V 2.6.9)*

pagedata.sessionurl

<bx:pagedata.sessionurl/>

Session-URL-Komponente (;jsessionid=) ausgeben, falls Cookies ausgeschaltet sind

pagedata.url

<bx:pagedata.url [encode="html"] />

Dieser Befehl schreibt die komplette Request-URL inklusive Query-String in die Seite. Falls encode="html" angegeben ist, werden <, >, ", & und ' durch ihre HTML-Umschreibungen ersetzt.

pagedata.filename

<bx:pagedata.filename [original]/> 															<!-- der Dateiname wird ausgegeben (z. B. "index.htm") -->
<bx:pagedata.filename equals="{vergleichsname}" [not] [original]> ... </bx:pagedata.filename>	<!-- Taginhalt wird nur ausgeführt, wenn der aktuelle Dateiname dem angegebenen Namen entspricht (ab v2.5.7) -->

Gibt den virtuellen Dateinamen aus der gerade aufgerufenen URL zurück. Wenn die Seite mit "/" aufgerufen wird, behandelt das Tag den Namen als "index.htm".

original es wird der ursprüngliche Dateiname ausgegeben (bei forwards)

pagedata.errortext

<bx:pagedata.errortext/>

Fehlertext in eine Fehlerseite schreiben. Der Befehl ist nur in der Fehlerseite "/www/[host-dir]/errorpage/index.htm" verfügbar. (ab* v2.3.15)*

pagedata.errorstacktrace

<bx:pagedata.errorstacktrace/>

Schreibt den Stacktrace einer Exception in die Fehlerseite. Der Befehl ist nur in der Fehlerseite "/www/[host-dir]/errorpage/index.htm" verfügbar. seit v2.5.8

pagedata.remoteip

<bx:pagedata.remoteip/>			<!-- schreibt die IP-Adresse des Clients (der die Abfrage macht) in die Seite. (z. B. um sie in einen Container zu speichern)  -->
<bx:pagedata.remoteip equals="{testip}" [not]> Inhalt </bx:pagedata.remoteip>		<!-- Vergleich der IP und entsprechende Ausgabe des Tag-Inhalts -->
<bx:pagedata.remoteip host="{hostname}" [not]> Inhalt  </bx:pagedata.remoteip>
<bx:pagedata.remoteip matches="{regex}" [not]> Inhalt  </bx:pagedata.remoteip>

(ab v2.5.7)

Beispiele

<bx:pagedata.remoteip matches="123\.210\.12\.[0-9]+">
 <a href="...">Intranet</a>
</bx:pagedata.remoteip>

 Inhalt nur für IP-Adressen im Bereich "123.210.12.*" zeigen

pagedata.scheme

<bx:pagedata.scheme/>

Gibt das Protokoll zurück. ("http" oder "https") (ab* v2.5.8*)

pagedata.compressed

<bx:pagedata.compressed />			<!-- es wird ".bxmin" ausgegeben* -->
<bx:pagedata.compressed>.bxmin</bx:pagedata.compressed>  <!-- der Inhalt des Body (im Beispiel ebenfalls ".bxmin")wird ausgegeben, ansonsten wird keine Ausgabe gemacht* -->

Unterscheidet abhängig vom Projektstatus die Einstellung der Scriptkomprimierung (ab* v2.6.2*). *Greift, wenn das Projekt auf Produktiv und "Style- und Script-Compressor" im Projekt angehakt ist.

pagedata.status

<bx:pagedata.status type="{dev | prod | debug}"> ... </bx:pagedata.status>

Zeigt abhängig vom Projektstatus den Taginhalt an (ab* v2.6.2*).

Beispiele

<script src="tools<bx:pagedata.status type="prod">.bxmin</bx:pagedata.status>.js"></script>

Wenn das System auf "Produktiv" gestellt ist, wird tools.bxmin.js ausgegeben, sonst tools.js

pagedata.charset

<bx:pagedata.charset />

Gibt den Zeichensatz aus, der beim Projekt bzw. beim Design angegeben wurde. Wenn bei beiden nichts angegeben wurde, wird nichts ausgegeben und es gilt der Standard der Servlet-API (iso-8859-1)

pagedata.writecontenttype

<bx:pagedata.writecontenttype/>  

Gibt folgendes aus: <meta http-equiv="Content-Type" content="[mimetype]; charset=[Zeichensatz]"> Bisher wird es immer von Hand reingeschrieben und bei Änderung des Seiteneincodngs passen die Zeichensätze nicht mehr zusammen.

pagedata.header

<bx:pagedata.header name="..." (value|matches|contains)="[Vergleichswert]" [not]>

Beispiele

<a href="<bx:pagedata.header name="Referer"/>">zurück</a>
<bx:pagedata.header name="Referer" not>Direkt eingetippt</bx:pagedata.header>
<bx:pagedata.header name="accept-language" contains="es">¡hola!</bx:pagedata.header>
<bx:pagedata.header name="User-Agent" matches=".*(google|bing|yahoo).*">Hallo Suchmaschine!</bx:pagedata.header>

Verweise auf diese Seite:

(8 Verweise)

Batix-Tags Referenz

bx:pageinclude

Das Tag pageinclude bindet eine JSP- oder CM-Seite in das aktuelle Design ein. Die einzubindende Seite wird in der Administration dynamisch über ein Textfeld bestimmt.

<bx:pageinclude.{bezeichner} [jsp] [onlyactive] />

Bei der Angabe des Pfades zur Datei (in der Administration) kann statt /www/webname/... auch /www/[webdir]/... als Platzhalter benutzt werden. Dieser wird dann mit dem virtuellen Pfad ersetzt.

jsp wenn angeforderte Datei ein JSP-Script ist
onlyactive Normalerweise wird die andere Seite eingebunden, egal ob sie aktiv oder inaktiv im Frontend ist (meistens wahrscheinlich inaktiv). Wenn man aber nach diesen Häkchen die Anzeige ein oder ausschalten will, kann man das onlyactive dranschreiben. ab v2.6.6.
Batix-Tags Referenz

bx:paypal

Mithilfe dieses Tags wird ein verschlüsselter Wert für ein <hidden>-Feld generiert, das an Paypal geschickt wird.

Nach dem Bestellprozeß wird ein Paypal-Button eingeblendet, der ein neues Fenster mit der Paypal-Website öffnet. Dies wird durch eine HTML-For ausgelöst:

<form action="https://www.paypal.com/cgi-bin/webscr" target="_blank" method="post">
 <input type="hidden" name="cmd" value="_s-xclick">
 <input type="text" name="encrypted" size=80 value="<bx:paypal.crypt pass="{Das Passwort}" cmdtext="cmd=_xclick,cert_id={Die ID von Paypal},business={Email-Adresse des Kunden},currency_code=EUR,item_name={Betreff}" paypalcert="{Zertifikat-Datei}" certfile="{Zertifikat-Datei}" keyfile="{Zertifikat-Datei}" price="{Betrag}"/>">
 <input type="image" style="margin-right:10px;" src="http://www.paypal.com/de_DE/i/btn/x-click-but6.gif" name="submit" alt="Zahlen Sie mit PayPal - schnell, kostenlos und sicher!">
</form>

Die Erzeugung der ID bei Paypal wird hier beschrieben: https://www.paypalobjects.com/de_DE/html/IntegrationCenter/ic_button-encryption.html (Schritt 2 und 3 muß der Kunde mit seinem Paypal-Zugang durchführen) siehe auch: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_encryptedwebpayments

Dort muß die .pem-Datei (Attribut certfile), die man mit Open-SSL erzeugt, hochladen und bekommt das öffentliche Zertifikat zurück (Attribut paypalcert). Der private Schlüssel im P12-Format wird ebenfalls mir OpenSSL generiert und bei Attribut keyfile ins Tag eingetragen. Das Passwort, das beim Erzeugen des P12-Schlüssels eingegeben wurde, muß im Attribut pass angegeben werden. Im Attribut cmdtext muß dann die ID von Paypal (nach Upload der .pem-Datei), die beim Erzeugen der Datei angegebene Email-Adresse und ein Infotext für die Buchung eingegeben werden.

Syntax:

<bx:paypal.crypt pass="..." cmdtext="..." paypalcert="..." certfile="..." keyfile="..." />

benötigte Tag-Parameter:

certfile eine Datei mit dem Public Cert (.pem)
keyfile eine Datei mit dem Private Key in PKCS12-Format (.p12)
paypalcert eine Datei mit PayPal's Public Cert
pass ein Passwort mit dem die Datei in Parameter keyfile verschlüsselt ist
cmdtext Format "cmd=_xclick,cert_id=[ID von Paypal],business=[email],currency_code=EUR,item_name=[infotext]"

Desweiteren wird ein Request-Attribut oder Request-Parameter namens 'price' benötigt.

Ein Request-Parameter namens 'orderid' kann an den Infotext für Paypal angehängt werden.

Beispiele

<bx:paypal.crypt pass="geheim"
  cmdtext="cmd=_xclick,cert_id=ABCD1234EF56,business=info@mustermann.de,currency_code=EUR,item_name=Bestellung bei Mustermanns" 
  paypalcert="133117E8C9D.txt" certfile="133117DCAB5.pem" keyfile="133117E4A90.p12" price="1234.50"/>
Batix-Tags Referenz

bx:plugin

Mit dem Tag plugin kann man sicherstellen, daß Pluginseiten genauso aussehen wie normale Verwaltungsseiten.

plugin.css

<bx:plugin.css/>

Es werden die nötigen Styles in den Head geschrieben, die der Pluginseite ihr Aussehen geben. und zwar:

plugin:headline

<bx:plugin.headline name="{titel1}" sub="{titel2"/>

<bx:plugin.headline name="{titel1}" sub="{titel2}">
  Inhalt
</bx:plugin.headline>

Die Überschrift der Seite wird generiert.

name Text, der in der oberen Zeile stehen soll
sub Text, der darunter stehen soll
als offenes Tag Inhalt, der oben rechts angezeigt werden soll (z.B. Link oder Drop-Down)

plugin.toolarea

<bx:plugin.toolarea>
  <bx:plugin.toolblock id="{id}" title="{text}" icon="{pfad}">
    Inhalt
  </bx:plugin.toolblock>
  ... evtl. weiterer toolblock
</bx:plugin.toolarea>

id frei wählbare id für die Box, muß auf der Seite eindeutig sein
title Titel der Box
icon Pfad:/verwaltung/control/imgnav/bildname.gif
open beim Aufruf der Seite geöffnet

Beispiele

Containerfilter-Aufruf im Quelltext

<html>
  <head>
  <title><bx:pagedata.navname/></title>
  <bx:plugin.css/>
  </head>
  
  <body>
    <bx:plugin.headline name="Umfragetool" sub="Frage erstellen/bearbeiten">
      <a href="liste.htm">zurück zur Liste</a>
    </bx:plugin.headline>

    <bx:plugin.toolarea>
      <bx:plugin.toolblock id="tools" title="Tools" icon="/verwaltung/control/imgnav/tools.gif">
        <a href="umfragedetail.htm?umfrageid=<bx:pagedata.request name="umfrageid"/>">zurück zur Umfrage</a>        
        <a href="detail.htmumfrageid=<bx:pagedata.request name="umfrageid"/>">NEU</a>
      </bx:plugin.toolblock>
      <bx:plugin.toolblock id="info" title="Information" open icon="/verwaltung/control/imgnav/information.gif">
        Datum: <bx:tools.datum/><br>
        Zeit: <bx:tools.datum pattern="HH.mm 'Uhr' zzz"/>
      </bx:plugin.toolblock>
    </bx:plugin.toolarea>
    <div class="content">
      ...
    </div>
  </body>
</html>

Batix-Tags Referenz

bx:record

Das Tag record stellt einen Datensatz einer Containerliste auf einer Seite dar. Es kann entweder ein Datensatz in der Verwaltung gewählt, oder direkt im Tag eine ID angegeben werden.

ein bestimmtes Element anzeigen

<bx:record.{name} pool="{id}" [id="{id}"] [sub="{name}"] [show="{active | inactive | all}"] [list="{all}"] [size="{n}"]>
  <bx:recordfield.{feldname}/>
</bx:record.{name}>
name Bezeichner
pool ID des betreffenden Containers
id eine ID kann direkt oder über ein Präfix angegeben werden** nicht angegeben:** bestimmter Datensatz kann in der Administration über ein Auswahlfeld gewählt werden angegeben: DS mit dieser ID wird ausgegeben und es erfolgt keine Auswahl in der Administration

Falls id verwendet wird, werden auch inaktive Datensätze angezeigt. Soll dies nicht sein, muss zusätzlich show="active" angegeben werden.

sub bestimmer Untercontainer kann als Basis für die Datensätze festgelegt werden
(gilt für alte Container)
show Anzeige von aktiven, inaktiven oder allen Datensätzen
list list=all: im Auswahlfeld in der Verwaltung werden auch die inaktiven DS angezeigt
size Größenangabe für das Select-Tag

Angabe eines Filters zur Auswahleinschränkung in der Verwaltung

<bx:record.Feldname pool="{Container-ID}" name="{Feldname}" type="{Vergleichsart}" value="{Vergleichswert}"> ... </bx:record.Feldname>

(ab V 2.7.) Erweiterung im Tag, vergleichbar mit dem Filter am Tag bei  <bx:containerfilter> und auch die Felder sind so genannt. Dies schränkt die angezeigte Liste in der Verwaltung entsprechend des Filters ein.

name Name des zu überprüfenden Feldes (siehe auch "
Filter
")
type Art des Vergleiches (siehe auch "
Filter
")
value gesuchter Wert (siehe auch "
Filter
")
statisch
: einfach gesuchten Wert angeben (z.B. eine ID)
dynamisch
: mit Präfix (siehe auch "
Präfixe
")

Beispiel

<bx:record.Beitrag pool="Seitentexte" name="Sprache" type="8" value="system:sprache"> <!-- ID für Sprache ist eine Systemvariable -->
  <a href="detail.htm?rid=<bx:recorddata.id/>"><bx:recordfield.Titel/></a>
</bx:record.Beitrag>

Es werden in der Verwaltung nur Beiträge zur Auswahl angezeigt, die die jeweilige Sprache haben. Die ID für die Sprache wird in einer Systemvariablen gespeichert.

Dummy-Element anzeigen

<bx:record.{name} pool="{id}" id="attribute:xx" dummy> Inhalt </bx:record.{name}>

Ist das id-Feld leer, wird ein Dummy-Datensatz angezeigt, d.h., die im Inhalt angebenen Felder sind leer.

Beispiel

<form action="save.act" method="post">
  <bx:record.Kontakt pool="11111111111" id="request:kontaktid" dummy>  
    <bx:if><input type="hidden" name="kontaktid" value="<bx:recorddata.id/>"></bx:if>
    <input type="text" name="Name" value="<bx:recordfield.Name/>">
    <input type="text" name="Vorname" value="<bx:recordfield.Vorname/>">
    <input type="text" name="Email" value="<bx:recordfield.Email/>">
    <input type="submit" value="abschicken">
  </bx:record.Kontakt >
</form>

Ein Formular muß nur einmal gebaut werden, da auch der Fall eines leeren Formulars damit abgedeckt ist. Allerdings darf dann die recordid als hidden-Field nicht mit übergeben werden (in ifs einschließen).

Mehrfach-Auswahl

<bx:multirecord.{name} pool="{id}" ...> Inhalt </bx:multirecord.{name}>

Dieses Tag funktioniert wie bx:record, es können aber mehrere Datensätze ausgewählt werden.

Batix-Tags Referenz

bx:recordchoice

Das Tag recordchoice dient dem Anzeigen eines verknüpften Containerdatenfeldes z. B. als Dropdownfeld oder Liste von Radiobuttons, wobei der aktuell zugewiesene Datensatz angewählt ist und die Liste durch Datensätze einer Containerliste gefüllt wird.

einfache, kurze Variante

<bx:recordchoice.if field="{feldname}" [baseloop="{name}"] current> Inhalt </bx:recordchoice.if>

Dies ist die schnellste und unkomplizierteste Methode für eine Recordchoice-Abfrage.* Nur für neue Container, ab Version 2.5.9 verfügbar*.

field Feldname im umgebenden Container
baseloop Name des betreffenden Containers (bei Schachtelungen nötig)
current aktueller Datensatz

Beispiele

Auflistung

<bx:containerfilter.Rezept pool="Rezepte" idfield="rid">
  ...
  Kategorien: <br>
  <bx:containerfilter.Kategorien pool="Rezeptkategorien">
    <div class="<bx:recordchoice.if field="Kategorie" current>aktiv</bx:recordchoice.if><bx:recordchoice.if field="Kategorie" current not>inaktiv</bx:recordchoice.if>">
    <bx:recordfield.Titel/>
  </bx:containerfilter.Kategorien>
  ... 
</bx:containerfilter.Rezept>

Auf der Detailseite des Rezepts werden alle Kategorien aufgelistet und die verknüpften bekommen die Klasse aktiv, die nicht verknüpten die Klasse inaktiv. Diese Klassen können dann beliebig gestylt werden, z. B. mit verschiedenen Hintergrundfarben usw.

Verwendung in einem Select-Feld

<form ...>
<bx:containerfilter.Rezept pool="Rezepte" idfield="rid">
  ...
  Kategorie:<br>
  <select name="Kategorie">
    <option value="">bitte wählen</option>
    <bx:containerfilter.Kategorien pool="Rezeptkategorien">
    <option value="<bx:recorddata.id/>"<bx:recordchoice.if field="Kategorie" current> selected</bx:recordchoice.if>><bx:recordfield.Titel/></option>
    </bx:containerfilter.Kategorien>
  </select>
  ...
</bx:containerfilter.Rezept>
</form>

Formular, um Rezepte einzugeben. Die Funktion würde hier beim Wiederaufruf nach fehlgeschlagener Validierung zum Tragen kommen oder wenn das Rezept geändert wird. Die Kategorien stehen im Container "Rezeptkategorien" und sind über das Feld "Kategorie" in den Rezept-Datensatz eingebunden.

noch ein Beispiel

<bx:containerfilter.Kontakt pool="12E28377495" idfield="recordid" force="single" dummy>
  <form action="save.act" method="post">
    <bx:if><input type="hidden" name="recordid" value="<bx:pagedata.request name="recordid"/>"></bx:if>
    <label class="label" for="Name">Name:</label><input class="input" id="Name" type="text" name="Name" value="<bx:recordfield.Name/>"><br>
    <label class="label" for="Email">E-Mail:</label><input id="Email" type="text" name="Email" value="" class="input">
    <label class="label" for="Hobbies">Ihre Hobbies:</label>
    <bx:containerloop.Hobbies pool="11111111111">
      <input type="checkbox" value="<bx:recorddata.id/>"<bx:recordchoice.if field="Hobbies" current> checked</bx:recordchoice.if>>&nbsp;<bx:recordfield.Titel/><br>
    </bx:containerloop.Hobbies>
    <textarea class="input" id="Text" rows="5" cols="40" name="Text"><bx:recordfield.Text/></textarea><bx:javainclude modul="Validator" field="Text" /><br>
    <input class="submit" type="submit" value="abschicken">
  </form>
</bx:containerfilter.Kontakt>

ausführliche Variante

<bx:recordchoice name="{feld}" pool="{id}"> Inhalt </bx:recordchoice>

Erklärungstext.

name Name des verknüpften Feldes im aktuellen Record
pool Datenliste, welche die zur Auswahl stehenden Datensätze enthält

Innerhalb dieses Tags können die folgenden Tags benutzt werden.

recordchoice.if

<bx:recordchoice.if (empty | unknown) [not]> Inhalt </bx:recordchoice.if>

Dieses Tag gibt seinen Inhalt nur bei bestimmten Bedingungen aus.

empty
unknown
Der Inhalt wird nur angezeigt, falls aktuell nichts oder ein unbekanntes/gelöschtes Objekt verknüpft ist.
not kehrt die Bedingung um

recordchoice.poolid

<bx:recordchoice.poolid/>

Die unter pool (im umgebenden Tag) angegebene ID wird ausgegeben.

recordchoice.loop

<bx:recordchoice.loop [list="active"] [orderby="{field}"] [desc] [max="{n}"]> Inhalt </bx:recordchoice.loop>

Es wird eine Schleife erzeugt, die jeden möglichen Datensatz auflistet. Innerhalb dieser Schleife kann z.B. mittels Bx:recorddata oder Bx:recordfield auf Daten zugegriffen werden. Hinweis: Es empfiehlt sich bx:recordchoice.loop durch z.B. Bx:containerloop oder Bx:containerfilter zu ersetzen, um größere Flexibilität zu erhalten. Das ist möglich, da diese Tags alle vom Typ Containerschleife sind.

list list="active" - zeigt nur aktive Datensätze an
orderby ein Feld, nach dem sortiert werden soll
desc kehrt die Sortierrichtung um
max es werden nur eine bestimmte Anzahl an Elementen angezeigt

Ebenfalls kann innerhalb der Schleife bx:recordchoice.if verwendet werden, allerdings mit einer anderen Bedeutung und anderen Parametern.

<bx:recordchoice.if [not] current value="<text>" />
<bx:recordchoice.if [not] current> Inhalt </bx:recordchoice.if>
current
value Der Inhalt bzw. der Text von
value
wird nur ausgegeben, wenn das Schleifenelement aktuell zugewiesen ist bzw. nicht ist (
not
).

Beispiele

Einzelverknüpfung

<label for="Branche">Branche</label><br/>
<select name="Branche" id="Branche">
  <bx:recordchoice name="Branche" pool="11111111111">
    <bx:containerloop pool="11111111111" orderby="Titel">
      <option value="<bx:recorddata.id/>" <bx:recordchoice.if current>selected="selected"</bx:recordchoice.if>>
        <bx:recordfield.Titel/>
      </option>
    </bx:containerloop>
  </bx:recordchoice>
</select>

Dieser Code erzeugt eine Dropdown-Liste zum Auswählen eines Elementes für die Einfachverknüpfung "Branche". Die möglichen Werte für die Auswahl stehen im Container 11111111111. Der aktuell zugewiesene Datensatz ist ausgewählt.

Mehrfachverknüpfung

<input type="hidden" name="Branchen.LINKLIST" value="22222222222">
<bx:recordchoice name="Branchen" pool="22222222222">
  <bx:containerloop pool="22222222222" orderby="Titel">
    <label>
      <input type="checkbox" name="Branchen.LINKRECORD" id="id_<bx:recorddata.id/>" value="<bx:recorddata.id/>"<bx:recordchoice.if current> checked="checked"</bx:recordchoice.if>>
    </label><br>
  </bx:containerloop>
</bx:recordchoice>

Es werden für jeden Datensatz aus dem Container 22222222222 Checkboxen erzeugt. Alle aktuell zugewiesenen Elemente sind angehakt. Das Hidden-Field Branchen.LINKLIST wird benötigt, da der Browser wenn keine Checkbox angehakt ist sonst nichts sendet.

Batix-Tags Referenz

bx:recorddata

Das Tag recorddata gibt zusätzliche Daten innerhalb einer Containerliste (z.B. bx:containerloop oder bx:containerfilter) aus oder steuert die Ausgabe von Daten in verschiedenen Abhängigkeiten.

recorddata.id

<bx:recorddata.id [level="<n>" | parent | parent="<n>" | baseloop="<base>"] [{filter="<name>" | dynamicfilter="<name>"} [quiet]] />

Gibt die ID eines Datensatzes innerhalb einer Containerliste aus.

level ID des DS in der angegebenen Ebene einer verschachtelten Containerliste wird zurückgegeben,
wobei "0" die äußerste Containerliste ist und alle weiteren inneren Containerlisten jeweils um 1 erhöht werden (0,1,2,...).
parent
parent=...
hat die selbe Wirkung wie
level
, nur dass hier von der aktuellen Containerliste mit "0" ausgegangen wird und für jede
weiter übergeordnete Containerliste 1 addiert wird (...,2,1,0).
parent
ist identisch mit
parent="1"
.
baseloop übergeordneten Containerliste direkt mit Namen ansprechen, vorausgesetzt, es wurde auch ein Name vergeben (siehe
Bx:containerloop
und
Bx:containerfilter
).
filter
dynamicfilter
es kann ein
JSP-Baustein
als Filter angegeben werden
quiet Fehlermeldungen des Filters wird unterdrückt

recorddata.creationdate

<bx:recorddata.creationdate  [pattern=""] [locale=""] />

Wandelt die ID in Datum um.

pattern Ausgabe-Pattern, Standard: dd.MM.yyyy
locale Sprachausgabe, Standard: de

recorddata.containerid

<bx:recorddata.containerid />

Gibt die Container-ID aus (ab Version 2.6.2).

recorddata.titel

<bx:recorddata.titel />

Gibt den Titel des aktuellen Datensatzes einer Containerliste aus. Der Titel ist der Selbe, der auch in der Containerdefinition als Anzeigeelement angegeben wurde.

recorddata.if

<bx:recorddata.if [first | last] [not] > Inhalt </bx:recorddata.if>
<bx:recorddata.if [request="{name}" | baseloop="{name}" | id="{ID}" | id="attribute:{Name}" | id="clipboard:{Name}" ] [not]> Inhalt </bx:recorddata.if>
<bx:recorddata.if ... [true="{Ausdruck}"] [false="{Ausdruck}"] />

Mit diesem Tag kann auf einen Request-Parameter der Seite reagiert werden, der die ID eines Datensatzes der Containerliste enthält. Außerdem kann auf die DS-ID reagiert werden und die erste bzw. letzte Position ermittelt werden.

first | last Abfrage, ob es der erste oder letzt DS der Datenliste ist
request Name des Request-Parameter, der die gesuchte ID enthält
{name}
kann auch einen Platzhalter in der Form
request="[platz]"
enthalten. In diesem Fall wird
[platz]
durch den Wert des Requestparameters
platz
ersetzt.
baseloop Angabe
id Angabe der gesuchten IDs (mit Komma oder Leerzeichen getrennt), entweder direkt oder mit einem Präfix Abfrage, ob Dummy-Datensatz: id=""
ab V2.5.9: Abfrage dummy mit #null
not kehrt die Bedingung um
true | false Im Tag ohne Inhalt wird der Wert von
true
bei Übereinstimmung ausgegeben, sonst der Wert von
false
.

Beispiele

<bx:containerfilter.Mitglieder pool="Mitglieder" force="list">
  <div style="border-top:1px solid black;<bx:recorddata.if last true="border-bottom:1px solid black;" false="margin-bottom:20px;"/>">
    <bx:recordfield.Titel/>
  </div>
</bx:containerfilter.Mitglieder>

Beim letzten DS der Liste soll die Anzeigeliste mit einem Strich abgeschlossen werden. Ansonsten wird ein Abstand zwischen den einzelnen Divs angezeigt.

<bx:containerfilter.Mitglieder pool="Mitglieder" force="list">
  <bx:recorddata.if request="[platz]">......<bx:recorddata.if>
</bx:containerfilter.Mitglieder>

Browseraufruf: http://www.musterseiten.de/menuepunkt1/?platz=id2&id1=xxxxxxx&id2=yyyyyyyy&id3=zzzzzzzzzz Es wird die id2 zur Überprüfung herangezogen.

Infos über Verhalten / Buginfo

v2.5.8 Inhalt wird ausgeführt, wenn die ID des Datensatzes der ID im Parameter entspricht:

<bx:recorddata.if id="{Batix-ID}" [not]> ... </bx:recorddata.if>
<bx:recorddata.if id="{Batix-ID}" [true="{angezeigter Text}"] [false="{angezeigter Text}"]/>

Inhalt wird ausgeführt, wenn man sich gerade in einem Dummy-Datensatz befindet:

v2.6.2 neu <bx:recorddata.if id="" [not]> ... </bx:recorddata.if>
v2.6.3 neu <bx:recorddata.if id="attribute:undefiniert" [not]> ... </bx:recorddata.if>
v2.6.3-v2.6.4.1** Bug** bei <bx:recorddata.if id="" [not]>
v2.7.1 neu <bx:recorddata.if id="#null" [not]> ... </bx:recorddata.if>

Inhalt wird ausgeführt, wenn die ID des Datensatzes einer der IDs im Parameter entspricht (oder #null):

v2.6.3 <bx:recorddata.if id="{Batix-ID1},{Batix-ID2}" [not]> ... </bx:recorddata.if>
v2.7.1 <bx:recorddata.if id="{Batix-ID1},{Batix-ID2},#null" [not]> ... </bx:recorddata.if>

Bug v2.6.3-v2.6.4.1: <bx:containerloop force=single dummy><bx:recorddata.if id="request:recordid">

'test.htm' [ok, ist dummy] 'test.htm?recordid=' [Dummy wird nicht mehr erkannt] 'test.htm?recordid=1234567ABCD' [ok, kein dummy] in v2.6.2 und v>2.6.4.1 geht es wieder

recorddata.currentindex

<bx:recorddata.currentindex [add="{n}"] [baseloop="{base}"] />

Gibt die Nummer des aktuellen Datensatzes einer Containerliste aus beginnend mit "1" für den Ersten. Auch wenn die Ausgabe über Blätterfunktionen eingeschränkt ist, wird immer die Nummer über die gesamte Liste ausgegeben, so als wären keine Beschränkungen da.

add bewirkt, dass immer die Ausgabe der aktuellen Nummer plus den Wert von
add
ausgegeben
Standard ist 1, d.h., weil bei 0 angefangen wird, wird bei Nicht-Angabe des Add-Parameters
bei 1 angefangen. Soll bei 0 angefangen werden, muß add="0" sein (heißt: zum Startwert 0
wird 0 hinzugezählt anstatt (Standard)1 ).
baseloop Index einer übergeordneten Liste abfragen

recorddata.pageindex

<bx:recorddata.pageindex [add="<n>"] />

funktioniert im Prinzip genau wie recorddata.currentindex, nur, dass hier die Nummerierung Seitenweise erfolgt. Das heißt, auch bei einer Blätterfunktion werden nur die aktuell sichtbaren Datensätze durchnummeriert, beginnend bei "1", unabhängig von der gesamten Anzahl an Datensätzen in der Containerliste.

recorddata.ifcontains

Diese Funktion ist entweder noch in Entwicklung oder sehr speziell. Bitte ggf. nachfragen!

recorddata.ifmatch

(zum Löschen vorgesehen)

Vergleicht den aktuellen Datensatz in der Eltern-Containerschleife mit dem Datensatz in der Großeltern-Containerschleife und führt den Taginhalt nur aus, wenn beide aktuellen Datensätze den selben Containerdatensatz darstellen.

recorddata.cols

<bx:recorddata.cols num="{n}" equals="{n}" [not] > ... </bx:recorddata.cols>
<bx:recorddata.cols num="{n}" equals="{n}" true="{Ausdruck}" false="{Ausdruck}" />
<bx:recorddata.cols num="{n}" [col]{n}="<Ausdruck>" />

Dieses Kommando zeigt Daten abhängig von der Spaltennummer der Containerschleife an.

num Anzahl an Spalten in der Ausgabe
equals aktuelle Position in der Spalte
not kehrt Bedingung um
true | false bei Zutreffen bzw. Nichtzutreffen der Bedingung wird der jeweils angegebenen Text ausgegeben
col[n] es kann jede einzelne Spalte angesprochen werden
(die Spalten können hier entweder 1, 2, 3 oder col1, col2, col3 heißen)

Beispiele

<div class="liste">
  <div class="item"<bx:recorddata.cols num="5" equals="5"> style="margin-right:0;"</bx:recorddata.cols>>
   <a href="detail.htm?id=<bx:recorddata.id/>"><bx:recordfield.Titel/></a>
  </div>
  <bx:recorddata.cols num="5" equals="5"><div class="clear"></div></bx:recorddata.cols>
</div>

Der letzte DS in der Reihe, die aus 5 Elementen besteht, soll keinen rechten Abstand haben. Danach soll ein Clear-Div stehen.

<div class="liste">
  <div class="item" style="<bx:recorddata.cols num="5" equals="5" not true="margin-right:10px" false="margin-right:0"/>;">
   <a href="detail.htm?id=<bx:recorddata.id/>"><bx:recordfield.Titel/></a>
  </div>
  <bx:recorddata.cols num="5" equals="5" true="<div class="clear"></div>"/>
</div>

Gleiches Beispiel wie oben, allerdings mit true|false

<div class="liste">
  <div class="item" style="background-color:<bx:recorddata.cols num="7" col1="red" col2="orange" col3="yellow" col4="green" col5="lightskyblue" col6="blue" col7="darkviolett"/>;">
   <a href="detail.htm?id=<bx:recorddata.id/>"><bx:recordfield.Titel/></a>
  </div>
  <bx:recorddata.cols num="7" equals="7" true="<div class="clear"></div>"/>
</div>

Die Spalten sollen Regenbogenfarben als Hintergrund bekommen (issn dämliches Beispiel, ich weiß - Vorschläge willkommen)

recorddata.active

<bx:recorddata.active [not]> ... </bx:recorddata.active>
<bx:recorddata.active [true="{Ausdruck}"] [false="{Ausdruck}"] />

führt den Ausdruck abhängig vom Aktivstatus des Containerdatensatzes aus (Häkchenfeld im DS im Container ganz oben. Man kann also auch inaktive DS anzeigen lassen. Auch dieses Tag kann entweder mit Inhalt (und optional mit not) versehen oder mit den Parametern true und/oder false verwendet werden.

Blätterfunktionen

Beispiel für eine Blätterfunktion

recorddata.nav

<bx:recorddata.nav [object="{bez}"] [labelname="{bez}"] [param="{bez}"] [indexparam="{bez}"] [filename="{bez}"]> ... </bx:recorddata.nav> 

Dieses Tag erzeugt keine Ausgabe, sondern fasst Parameter zusammen, die zur Navigation in Listen verwendet werden. Diese Parameter werden bei Tags, die .nav unterstützen nicht noch einmal aufgeführt! Beim Seitenblättern muss ein Anzeigelimit (Parameter max) bei der entsprechenden Liste definiert sein!

object
labelname
Name bzw. den Labelname des Containerloops
param Name des Request-Parameters mit der Datensatz-ID (bei Blättern Einzeldatensatz) Standard:
param
indexparam Name des Request-Parameter, der die Index-Position enthält (bei Listenblättern) Standard:
index
filename (nur für alte Container) bezeichnet die Datei, auf die verlinkt wird (z.B. bei
.previouslist
).

Beispiele

Listenblättern

<bx:containerfilter.Voegel pool="Tiere" force="list" max="10">
  <a href="detail.htm?vid=<bx:recorddata.id/>"><bx:recordfield.Titel/></a><br>
</bx:containerfilter.Voegel>
...
<bx:recorddata.nav object="Voegel" indexparam="pos">
  <bx:recorddata.previouslist/> | <bx:recorddata.nextlist/>
</bx:recorddata.nav> 

Blätterfunktion in einer Liste. Im Requestparameter pos steht dann beim Blättern die entsprechende Index-Position innerhalb der Liste. nextlist generiert einen Link, der ca. so aussieht: url/navpunkt/liste.htm?pos=11

DS-Blättern

<bx:containerfilter.Voegel pool="Tiere" idfield="vid" force="single">
  <a href="detail.htm?vid=<bx:recorddata.id/>"><bx:recordfield.Titel/></a><br>
</bx:containerfilter.Voegel>
...
<bx:recorddata.nav object="Voegel" param="vid">
  <bx:recorddata.previouselement/> | <bx:recorddata.nextelement/>
</bx:recorddata.nav> 

DS-Blättern auf der Detailseite. Im Requestparameter vid steht die DS-ID. previouselement generiert einen Link, der ca. so aussieht: url/navpunkt/detail.htm?vid=1111111111

Labelverwendung

<bx:containerfilter label="Voegel" pool="Tiere" force="list" max="10" name="Klasse" type="8" value="33333333333">
  <a href="detail.htm?vid=<bx:recorddata.id/>"><bx:recordfield.Titel/></a><br>
</bx:containerfilter>
...
<bx:recorddata.nav labelname="Voegel" indexparam="pos">
  <bx:recorddata.previouslist/> | <bx:recorddata.nextlist/>
</bx:recorddata.nav> 

Wenn der Container keine Bezeichnung hat (z.B. bei Bedingung im Tag), dann kann auch ein Label zur Zuordnung verwendet werden.

Seitenblättern

recorddata.previouslist

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.previouslist [type="link | url | index | if"] [plain] [show] [encode="plain | html"] [not] /> <!-- Link wird erzeugt, Standardtext: zurück -->
<bx:recorddata.previouslist Parameter siehe oben> Linktext </bx:recorddata.previouslist>  <!-- eigener Linktext kann ausgegeben werden -->

type="link" gibt einen Link aus (zurück) verwendbare Parameter: show
type="url" gibt nur den relativen Pfad aus (datei.htm?...) verwendbare Parameter: encode
type="index" gibt nur den neuen Index aus
type="if" gibt den Inhalt des Tags aus, wenn die vorherige Seite existiert verwendbare Parameter: not
plain setzt
type
auf
"url"
show zeigt den Text auch dann an, wenn keine Vorgängerseite existiert
encode kodiert jedes Zeichen des Links bei Angabe von
html
als &#nnn;
(ist standardmäßig gesetzt, um dies abzustellen
encode="plain"
angeben)
not kehrt den Effekt bei
type="if"
um

recorddata.nextlist

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

(identisch mit .previouslist, nur dass hier die nächste Seite verlinkt wird und der Linktext standardmäßig "weiter" lautet)

<bx:recorddata.nextlist [type="link | url | index | if"] [plain] [show] [encode="plain | html"] [not] />        <!-- Link wird erzeugt, Standardtext: weiter-->
<bx:recorddata.nextlist Parameter siehe oben> Linktext </bx:recorddata.nextlist >                                 <!-- eigener Linktext kann ausgegeben werden -->

recorddata.firstlist

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

(identisch mit .previouslist, nur dass hier die erste Seite verlinkt wird und der Linktext standardmäßig "erste Seite" lautet)

<bx:recorddata.firstlist[type="link | url | index | if"] [plain] [show] [encode="plain | html"] [not] /> <!-- Link wird erzeugt, Standardtext: erste Seite-->
<bx:recorddata.firstlist Parameter siehe oben> Linktext </bx:recorddata.firstlist>  <!-- eigener Linktext kann ausgegeben werden -->

recorddata.lastlist

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

(identisch mit .previouslist, nur dass hier die letzte Seite verlinkt wird und der Linktext standardmäßig "letzte Seite" lautet)

<bx:recorddata.lastlist[type="link | url | index | if"] [plain] [show] [encode="plain | html"] [not] /> <!-- Link wird erzeugt, Standardtext: letzte Seite-->
<bx:recorddata.lastlist Parameter siehe oben> Linktext </bx:recorddata.lastlist>  <!-- eigener Linktext kann ausgegeben werden -->

Datensatzweise blättern

recorddata.previouselement

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.previouselement [type="link | url | if | id | title"] [encode="html | plain"] [not] [show] [loop]/>      <!-- Link wird erzeugt, Standardtext: zurück-->
<bx:recorddata.previouselement Parameter siehe oben> Linktext </bx:recorddata.previouselement >                         <!-- eigener Linktext kann ausgegeben werden -->
<bx:recorddata.previouselement type="object"><bx:recordfield.Titel/></bx:recorddata.previouselement >

Diese Funktion generiert einen Link zum vorherigenElement der Liste (nur bei Detailansicht).

type="link" (Standard) produziert einen klickbaren Link wenn das entsprechende Element existiert (immer anzeigen mittels show)
type="url" gibt die relative URL aus
type="if" gibt den Inhalt des Tags nur aus, wenn das Element existiert (kann mit not umgekehrt werden)
type="id" zeigt nur die ID des Datensatzes an
type="title" zeigt nur den Name des Datensatzes an (so wie er in der Verwaltung angezeigt wird)
type="object" ab V 2.6.2: Tag wird als offenens Tag benutzt und ermöglich, direkt auf das erste Element (Datensatz) zuzugreifen,
um z.B. den Titel anzuzeigen. Sonst wird nur die ID übergeben und man hat keine Möglichkeit, die DS-Felder auszulesen.
encode encode="html"
(nur bei
type="url"
unterstützt) bewirkt, dass jedes Zeichen in &#nnn; umgewandelt wird (ist standardmäßig gesetzt, um dies abzustellen
encode="plain"
angeben).
loop signalisiert, dass es sich um eine Endlosliste handelt, d.h. Vorgänger vom ersten Element ist das letzte Element

recorddata.nextelement

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen. (identisch mit .previouselement, nur dass hier das nächste Element verlinkt wird und der Linktext standardmäßig "weiter" lautet, ebenfalls kann mit dem Parameter loop signalisiert werden, dass es sich um eine Endlosliste handelt, d.h. Nachfolger vom letzten Element ist das erste Element)

<bx:recorddata.nextelement [type="link | url | if | id | title"] [encode="html | plain"] [not] [show] [loop]/>      <!-- Link wird erzeugt, Standardtext: weiter-->
<bx:recorddata.nextelement Parameter siehe oben> Linktext </bx:recorddata.nextelement >                             <!-- eigener Linktext kann ausgegeben werden -->
<bx:recorddata.nextelement type="object"><bx:recordfield.Titel/></bx:recorddata.nextelement >

recorddata.firstelement

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen. (fast identisch mit .previouselement, nur dass hier das erste Element verlinkt wird und der Linktext standardmäßig "erster" lautet)

<bx:recorddata.firstelement [type="link | url | if | id | title"] [encode="html | plain"] [not] [show] />      <!-- Link wird erzeugt, Standardtext: erster-->
<bx:recorddata.nextelement Parameter siehe oben> Linktext </bx:recorddata.nextelement >                        <!-- eigener Linktext kann ausgegeben werden -->
<bx:recorddata.nextelement type="object"><bx:recordfield.Titel/></bx:recorddata.nextelement >

recorddata.lastelement

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen. (identisch mit .previouselement, nur dass hier das letzte Element verlinkt wird und der Linktext standardmäßig "letzter" lautet)

<bx:recorddata.firstelement [type="link | url | if | id | title"] [encode="html | plain"] [not] [show] />      <!-- Link wird erzeugt, Standardtext: letzter-->
<bx:recorddata.nextelement Parameter siehe oben> Linktext </bx:recorddata.nextelement >                        <!-- eigener Linktext kann ausgegeben werden -->
<bx:recorddata.nextelement type="object"><bx:recordfield.Titel/></bx:recorddata.nextelement >

Ausgabe von aktuellen Parametern und Positionen (oder wie könnte man das nennen???)

recorddata.total

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.total/>

Gibt die gesamte Anzahl an Datensätzen aus.

recorddata.startindex

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.startindex/>

gibt die Nummer des ersten Datensatzes aus, der auf der aktuellen Seite angezeigt wird bzw. die Nummer des aktuellen Detaildatensatzes innerhalb der angegebenen Filterung und Sortierung.

recorddata.endindex

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.endindex/>

gibt die Nummer des letzten Datensatzes auf der aktuellen Seite aus.

recorddata.listindex

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.listindex max="<n>" />

Mit diesem Kommando erhält man die Indexnummer, auf die man bei einem Link zurück zur Übersicht verlinken muss. max ist Pflicht.

Wenn z. B. Datensatz 14 angezeigt wird und auf der Listseite 6 Datensätze angezeigt werden, gibt dieses Tag 12 aus.

recorddata.currentpage

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.currentpage/>

Dieses Tag gibt die Nummer der aktuellen Seite (beginnend bei 1) aus.

recorddata.totalpages

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.totalpages/>

Dieses Tag gibt die Anzahl der Anzeigeseiten aus.

recorddata.navlist / recorddata.navdetail

<bx:recorddata.navlist [max="<n>"] [boundary="<text>"] />
<bx:recorddata.navlist [max="<n>"] [boundary="<text>"]> ... </bx:recorddata.navlist>
<bx:recorddata.navdetail [max="<n>"] [boundary="<text>"] />
<bx:recorddata.navdetail [max="<n>"] [boundary="<text>"]> ... </bx:recorddata.navdetail>

Mittels .navlist wird eine verlinkte Liste an benachbarten Seiten (.navlist) bzw. Detailseiten (.navdetail) ausgegeben.

max Wenn
max
nicht angegeben wird oder "0" ist, werden alle Seiten angezeigt
boundary legt das Trennzeichen zwischen den Zahlen fest (Standard: " | ")

Beispiel: Eine Liste besteht aus 23 Datensätzen und füllt wegen max="3" (Parameter der Containerliste, nicht von .navlist) 8 Seiten. Wir befinden uns auf Seite 5 und max von .navlist ist auf "2" gesetzt. Folgendes wird ausgegeben (mit entsprechender Verlinkung): 3 | 4 | 5 | 6 | 7

Um die Verlinkung individueller zu gestalten verwenden Sie die zweite Form dieses Tags. Der Inhalt wird dann für jede anzuzeigende Seite ausgegeben. Sie können eine Reihe von Unterelementen einbinden:

recorddata.navlistpage / recorddata.navdetailpage

<bx:recorddata.navlistpage/>
<bx:recorddata.navdetailpage/>

gibt die Nummer der Seite bzw. Detailseite aus

recorddata.navlistindex

<bx:recorddata.navlistindex/>

gibt die Indexnummer zurück, die zum Aufruf der im Schleifendurchlauf repräsentierten Seite benötigt wird

recorddata.navdetailid

<bx:recorddata.navdetailid/>

gibt die Datensatz-ID zurück, die zum Aufruf der im Schleifendurchlauf repräsentierten Detailseite benötigt wird

recorddata.navlistpath / recorddata.navdetailpath

<bx:recorddata.navlistpath [encoding="html | plain"] />
<bx:recorddata.navdetailpath [encoding="html | plain"] />

gibt den Pfad zurück, über den die im Schleifendurchlauf repräsentierte Seite bzw. Detailseite aufgerufen werden kan Mit encoding wird das Ausgabeformat gesteuert. Standard ist "html" (Zeichen werden durch &#nnn; ersetzt), wenn Sie normalen Text ausgeben wollen setzen sie encoding auf "plain".

recorddata.navlistcurrent / recorddata.navdetailcurrent

<bx:recorddata.navlistcurrent [not]> Inhalt </bx:recorddata.navlistcurrent>
<bx:recorddata.navdetailcurrent [not]> Inhalt </bx:recorddata.navdetailcurrent>

führt den Inhalt nur aus, wenn die anzuzeigende Zahl die aktuelle Seite bzw. Detailseite ist. not kehrt das Verhalten um.

recorddata.navlistfirst / recorddata.navdetailfirst

<bx:recorddata.navlistfirst [not]> Inhalt </bx:recorddata.navlistfirst>
<bx:recorddata.navdetailfirst [not]> Inhalt </bx:recorddata.navdetailfirst>

führt den Inhalt nur aus, wenn die anzuzeigende Zahl die erste Seite bzw. Detailseite ist. not kehrt das Verhalten um.

recorddata.navlistlast / recorddata.navdetaillast

<bx:recorddata.navlistlast [not]> Inhalt </bx:recorddata.navlistlast>
<bx:recorddata.navdetaillast [not]> Inhalt </bx:recorddata.navdetaillast>

führt den Inhalt nur aus, wenn die anzuzeigende Zahl die letzte Seite bzw Detailseite ist. not kehrt das Verhalten um.

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.navlink move="<n>" />
<bx:recorddata.navlink move="<n>"> Linktext </bx:recorddata.navlink>

Dieses Tag schreibt einen Link zu einer vorhergehenden oder nachfolgenden Seite (falls mehrere Seiten vorhanden sind).

<n> ganze Zahl

move gibt dabei die Schrittweite an (kann auch negativ sein). Falls die erste Form verwendet wird, ist der Linktext standardmäßig "...".

recorddata.detaillink

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.detaillink move="{n}" />							<!-- Linktext standardmäßig "..." -->
<bx:recorddata.detaillink move="{n}"> Linktext </bx:recorddata.detaillink>

Dieses Tag schreibt einen Link zu einem vorhergehenden oder nachfolgenden Datensatz (falls mehrere Dantesätze vorhanden sind).

move Schrittweite (kann auch negativ sein)

recorddata.navdetailobject

Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen.

<bx:recorddata.navdetailobject> ... </bx:recorddata.navdetailobject>

repräsentiert den jeweiligen Containerdatensatz. Funktioniert wie recorddata.nextelement type="object" (oder die anderen artverwanden Tags)

Beispiele

Beispiel 1

<bx:recorddata.navdetail max="3">
  <bx:recorddata.navdetailobject><bx:recordfield.Titel/></bx:recorddata.navdetailobject>
</bx:recorddata.navdetail>

Die Wirbeltierklassen (Säugetiere, Vögel, Amphibien, Reptilien, Fische) werden ausgegeben und in Klammern die Anzahl der Tiere aus dem Container "Tiere", die mit der jeweiligen Klasse verbunden sind.

recorddata.meta

<bx:recorddata.meta (key="{metakey}" | name="{metakey}") [date [pattern="{format}"]] />

Gibt den Inhalt eines Metawertes aus.

key | name Name einer Metaeigenschaft
date Datum soll angezeigt werden
pattern Datumsformatierung (Standard ist "EEEEEE, d. MMMMMM yyyy")

recorddata.katcount

<bx:recorddata.katcount pool="{liste}" field="<feld>" />
<bx:recorddata.katcount pool="{liste}" field="<feld>"> Text </bx:recorddata>

Dieses Tag gibt die Anzahl der Datensätze aus einer Recordliste zurück, welche dort über ein Feld mit dem Datensatz im aktuellen Schleifendurchlauf verknüpft sind. Ebenso kann auch ein Text ausgegeben werden, falls die Anzahl größer als Null ist.

pool ID oder Alias des Containers
field Name des Feldes (muss vom Typ Einzelverknüpfung sein)

Beispiele

Beispiel 1

<bx:containerfilter.Wirbeltierklassen pool="Klassen">
  <bx:recordfield.Titel/> ( <bx:recorddata.katcount pool="Tiere" field="Klasse"/> )<br>
</bx:containerfilter.Wirbeltierklassen >

Die Wirbeltierklassen (Säugetiere, Vögel, Amphibien, Reptilien, Fische) werden ausgegeben und in Klammern die Anzahl der Tiere aus dem Container "Tiere", die mit der jeweiligen Klasse verbunden sind.

recorddata.empty

<bx:recorddata.empty [object="{name}"] [not] > Inhalt </bx:recorddata.empty>

Der Inhalt wird nur ausgeführt, wenn in der Schleife keine Datensätze zum Anzeigen vorhanden sind. Wenn das Tag nicht innerhalb von <bx:recorddata.nav> verwendet wird müssen der Parameter object mit dem Namen der zugehörigen Containerschleife und evtl. auch der Parameter label mit angegeben werden. ab Version 2.5.6

object Name der Containerschleife
not kehr die Funktion um

Beispiele

Beispiel 1

<bx:recorddata.empty object="Newsliste">z. Z. keine Newsbeiträge vorhanden</bx:recorddata.empty>
<bx:recorddata.empty object="Newsliste" not><bx:recorddata.total/> News vorhanden:</bx:recorddata.empty>

oder

<bx:recorddata.nav object="Newsliste">
  <bx:recorddata.empty>z. Z. keine Newsbeiträge vorhanden</bx:recorddata.empty>
  <bx:recorddata.empty not><bx:recorddata.total/> News vorhanden:</bx:recorddata.empty>
<bx:recorddata.nav>

Beispiel 2

<bx:containerfilter.Suche_Tier pool="Tiere">
  ...
</bx:containerfilter.Suche_Tier>

<bx:recorddata.empty object="Suche_Tier">
  Leider wurde kein Tier mit dem gesuchten Begriff gefunden.
</bx:recorddata.empty>
Batix-Tags Referenz

bx:recordfield

Das Tag recordfield stellt ein einzelnes Element eines Container-Datensatzes dar. Dies kann ein simpler Typ wie z.B. Text, Datum oder Bild, aber auch eine Schleife über Untercontainer sein.

Allgemeine Syntax

<bx:recordfield.{field} [parent | parent="{n}"] [baseloop="{schleifenname}"] [level=".."] zusätzliche Parameter />
<bx:recordfield.{field} [parent | parent="{n}"] [baseloop="{schleifenname}"] [level=".."] zusätzliche Parameter [dummy]> Inhalt </bx:recordfield.{field}>

Je nach Feld-Typ stellt sich bx:recordfield unterschiedlich dar und akzeptiert verschiedene Parameter.

field Name des Feldes im Container
level level=".." - übergeordneter Container
Zugriff auf die Felder des übergeordneten Containers (zur Zeit nur direkt-übergeordnet möglich)
sollte nicht mehr verwendet werden, lieber
parent
baseloop Name der Containerschleife (wie er nach dem Punkt im Tag steht)
Bezug auf eine bestimmte Containerschleife (z.B. bei Verschachtelungen)
parent parent: Zugriff auf direkt übergeordneten Container parent="2": Zugriff auf n-ten übergeordneten Container
dummy bewirkt, daß, wenn noch kein DS verknüpft ist, ein neuer DS erzeugt wird
Dazu darf beim Speicher-Action weder ja noch nein bei createnew gewählt sein.

Beispiele

<bx:containerfilter.Kategorie pool="Kategorien" orderby="Titel">
  <h2><bx:recordfield.Titel/></h2>
  <bx:containerfilter.Artikel pool="Artikel" orderby="Titel">
    <a href="detail.htm?artikel=<bx:recorddata.id/>&amp;kat=<bx:recorddata.id baseloop="Kategorie"/>"><bx:recordfield.Titel/></a>
  </bx:containerfilter.Artikel>
  <br>
</bx:containerfilter.Artikel>

Linkaufruf mit Übergabe der Kategorie in der inneren Schleife. Zugriff auf die Kategorie-ID mit baseloop.

<bx:containerfilter.Anbieter pool="Anbieter" orderby="Titel">
  <h2><bx:recordfield.Titel/></h2>
  <bx:containerfilter.Kategorie pool="Kategorien" orderby="Titel">
    <h2><bx:recordfield.Titel/></h2>
    <bx:containerfilter.Artikel pool="Artikel" orderby="Titel">
      <a href="detail.htm?artikel=<bx:recorddata.id/>&amp;kat=<bx:recorddata.id parent="1"/>&amp;anbieter=<bx:recorddata.id parent="2"/>"><bx:recordfield.Titel/></a>
    </bx:containerfilter.Artikel>
    <br>
  </bx:containerfilter.Artikel>
</bx:containerfilter.Anbieter>

Ähnliches Beispiel wie oben mit zusätzlicher Ebene. Zugriff auf die Kategorie-ID und die Anbeiter-ID mit parent.

Filter

<bx:recordfield.{field} [filter="{name}" | dynamicfilter="{feldname}"] [quiet] .../>

Bei einfachen Typen (Text, Datum, Zahl, Wahrheitswert) lassen sich auch JSP-Filter einsetzen. Die Schnittstelle zum Filter bildet das Request-Attribut "attrValue". Über dieses wird dem Filter der Inhalt des Tags übergeben und aus diesem wird nach dem Filteraufruf auch der neue Tag-Inhalt gelesen.

filter Angabe eines Filters (direkt über JSP-Baustein)
dynamicfilter Angabe eines Feldes im Datensatz, wo der Name des Filters drin steht (dynamisch)
quiet Fehler werden nicht auf der Seite ausgegeben

Beispiele für Filter

Filtername im Feld

...
Preis ohne MWSt.: <bx:recordfield.Preis_netto/>
Preis incl. MWSt: <bx:recordfield.Preis_netto filter="Bruttopreis"/>
...

Innerhalb des Filters "Bruttopreis" wird der (Netto)Preis in Bruttopreis umgerechnet und anstelle des Wertes im Recordfield ausgegeben.

Filtername aus Container

...
Preis ohne MWSt.: <bx:recordfield.Preis_netto/>
Preis incl. MWSt: <bx:recordfield.Preis_netto dynamicfilter="Filter"/>
...

Gleiches Beispiel wie oben, nur daß der Filtername (also Bruttopreis) im Feld "Filter" steht und von dort genommen wird. Vorteil: es kann pro DS ein völlig anderer Filter bestimmt werden.

einzeiliger Text

<bx:recordfield.{field} [encode|type="(quoted-printable | javascript | url | plain | csvfield)"] [maxwords="{n}"] [maxchars="{n}" [ellipsis]]  />

Je nach Feld-Typ stellt sich bx:recordfield unterschiedlich dar und akzeptiert verschiedene Parameter.

encode | type Der Text wird (falls gewünscht umgewandelt) ausgegeben.** Standard: htmlencode quoted-printable:** das Format in einer Email, siehe entsprechenden Wikipedia-Eintrag javascript: Den Zeichen "\n \r \t " ' " wird ein Backslash vorangestellt. url: zum Kodieren von Request-Parametern. Es wird java.net.URLEncoder benutzt. urlpath: zum Kodieren von Pfadbestandteilen (z. B. Dateiname) plain: unformatierter Text csvfield: (ab v2.5.9) der Text wird mit " umgeben und allen " im Text wird ein zusätzliches " vorangestellt
maxwords nur eine bestimmte Anzahl an Wörtern ausgeben
maxchars nur bestimmte Anzahl Buchstaben ausgeben
ellipsis ohne Parameter: fügt "..." an den text an, wenn dieser abgeschnitten wurde.
ellipsis=" usw." (mit Parameterwert) fügt usw. an den Text an oder halt irgendwas anderes sinnvolles.

Feldinhalt vergleichen

<bx:recordfield.{field} matches="{regex}" [not]> Inhalt </bx:recordfield.{field}>
<bx:recordfield.{field} equals="{Vergleichs-Feldinhalt}" [not]> Inhalt </bx:recordfield.{field}>
<bx:recordfield.{field} contains="{Suchbegriff im Feld}" [not]> Inhalt </bx:recordfield.{field}>

Der Inhalt des Tags wird nur dann angezeigt, wenn der Inhalt des Container-Feldes mit den Testkriterien übereinstimmt (umkehrbar mit not).

matches Regulärer Ausdruck
auf "leer" prüfen:
matches="^$"(Achtung: es wird immer der gesamte String verglichen, "^" vor und "$" nach dem Ausdruck sind also implizit!)
equals String, der mit dem Feldinhalt übereinstimmen muß
contains String, der im Feldinhalt enthalten sein muß

Beispiele

<bx:recordfield.Email matches="^[_a-zA-Z0-9-](\.{0,1}[_a-zA-Z0-9-])*@([_a-zA-Z0-9-]{2,}\.){0,}[_a-zA-Z0-9-]{3,}(\.[_a-zA-Z]{2,4}){1,2}$" not> keine gültige E-Mail-Adresse </bx:recordfield.Email>

Achtung: matches funktioniert nicht oder nicht korrekt wenn RegEx-Sonderzeichen wie Klammern, „+“ „?“, „*“ im Request stehen Mit equals funktioniert es dann:

<selected>
  <option value="bx:recorddata.id/>"<bx:recordfield.Kategoriename equals="request:param"> selected</bx:recordfield.Kategoriename>><bx:recordfield.Kategoriename/></option>
</selected>

Innerhalb einer Schleife: wenn übergebener Wert des Parameters param mit dem Kategorienamen übereinstimmt, wird dieser DS vorausgewählt.

<bx:recordfield.Email contains="batix.com">class="intern"</bx:recordfield.Email>

Jedem Link, der den String "batix.com" enthält, wird die Klasse "intern" zugewiesen (um ihn z.B. auf www.batix.com von externen Links zu unterscheiden)

mehrzeiliger Text

<bx:recordfield.{field} [encode="(quoted-printable | javascript | csv | plain | csvfield)"] [maxwords="{n}"] [maxchars="{n}" [ellipsis]] />
csv
encode | type Der Text wird (falls gewünscht umgewandelt) ausgegeben.** Standard: htmlencode quoted-printable:** das Format in einer Email, siehe entsprechenden Wikipedia-Eintrag javascript: Den Zeichen "\n \r \t " ' " wird ein Backslash vorangestellt. csv: alle Zeilenumbrüche durch Leerzeichen ersetzt und sonstige Steuerzeichen entfernt. plain: unformatierter Text csvfield: (ab v2.5.9) der Text wird mit " umgeben und allen " im Text wird ein zusätzliches " vorangestellt url: gibt es für dieses Tag nicht, man kann bx:tools.urlencode drumrum machen htmltext: zeigt plain-Feld in Verwaltung aber macht
s im Frontend rein
maxwords nur eine bestimmte Anzahl an Wörtern ausgeben
maxchars nur bestimmte Anzahl Buchstaben ausgeben
ellipsis ohne Parameter: fügt "..." an den text an, wenn dieser abgeschnitten wurde.
ellipsis=" usw." (mit Parameterwert) fügt usw. an den Text an oder halt irgendwas anderes sinnvolles.

Beispiele

<bx:recordfield.Titel/>
<bx:recordfield.Text maxwords="20" ellipsis />
<a href="detail.htm?beitragsid=<bx:recorddata.id/>">mehr</a>

Anteasern in einer Liste: es sollen max. 20 Wörter ausgegeben werden, dann wird ein ... gesetzt.

Datum/Zeit

<bx:recordfield.{field} [locale="{lang}"] [pattern="{format}"] [year="{mod}"] [month="{mod}"] [day="{mod}"] [hour="{mod}"] [minute="{mod}"] [second="{mod}"] [type="holiday"]/>
locale Sprachformatierung (z.B. "de" oder "en_US")
locale sollte immer angegeben werden, da sonst die Standardeinstellung vom Server genutzt wird, die sich aber nach Updates oder Umzügen ändern kann.
pattern Formatierung des Datums (Standard für Datum / Datum+Zeit / Zeit ist "EEEEEE, d. MMMMMM yyyy" / "dd.MM.yyyy HH:mm" / "HH:mm")
year month day minute second Datum direkt setzen oder das aktuelle Datum manipulieren folgende Angaben bei {mod}: n: das entsprechende Feld wird auf den Wert n gesetzt +n: das entsprechende Feld wird um den Wert n erhöht -n: das entsprechende Feld wird um den Wert n verringert Achtung: Monate laufen von 0-11
type="holiday" prüft, ob der Tag auf einen Feiertag fällt und schreibt statt des Datums die Feiertagsbezeichnung hin (z. B. Silvester)(ab V2.6.0)(Thüringer Feiertage)

Beispiele

<bx:recordfield.Datumsfeld day="15" month="+1" /> 

zeigt anstatt des gespeicherten Datums den 15. des folgenden Monats an.

Abfrage

<bx:recordfield.{field} if="( past | future | empty | today)" [not] > Inhalt </bx:recordfield.{field}>

Mittels dieser Variante wird Inhalt nur ausgegeben wenn das Datum im Datensatz (inklusive eventueller Modifikationen) in der Vergangenheit liegt (past), in der Zukunft liegt (future) oder leer ist (empty). not kehrt die Bedingung um.

Beispiele

<bx:clipboard.cut name="aktJahr"><bx:tools.datum pattern="yyyy"/></bx:clipboard.cut>
<bx:recordfield.Geburtsdatum year="clipboard:aktJahr" if="today"> Herzlichen Glückwunsch zum Geburtstag! </bx:recordfield.Geburtsdatum >

Das Feld Geburtsdatum wird mit dem heutigen Datum verglichen. Da das Jahr ja nicht stimmt, wird es auf das aktuelle Jahr gesetzt und kann nun verglichen werden.

Datumsmanipulation

<bx:recordfield.{field} weekday="{angabe}"/>

mo", "di", "mi", "do", "fr", "sa", "so" oder "mon", "tue", "wed", "thu", "fri", "sat", "sun" wechselt auf den entsprechenden Wochentag, der Woche in dem das Calendar-Objekt ist. vorangestelltes Plus- oder Minuszeichen wechslet zum folgenden bzw. vorigen entsprechenden Wochentag. Wenn calendar bereits auf dem gleichen Wochentag steht, wird nichts geändert. Dieser Fall wird mit doppelten plus/minus anders behandelt. Dann wird nämlich +/-7 Tage gerechnet.

Vom gespeicherten Wert aus können folgende Werte ermittelt werden:

weekday Do = der Donnerstag dieser Woche (egal ob schon vergangen oder nicht) +Do = der nächste Donnerstag (heute, falls heute Donnerstag) -Do = der vorige Donnerstag (heute, falls heute Donnerstag) ++Do bzw --Do = der nächste/vorige Donnerstag (nie heute)

Zahl/Preis

Formatierte Ausgabe

<bx:recordfield.{field} [locale="{lang}"] [pattern="{format}"] [gs="{c}"] [ds="{c}"] />
<bx:recordfield.{field} isempty [not]> Inhalt </bx:recordfield.{field}>
locale Sprachformatierung (z.B. "de" oder "en_US")
pattern Formatierung festlegen, (Standard bei Zahl: "0.#####", bei Preis: "0.00", bei Preis mit Tausenderpunkt: "#,##0.00")
gs Tausender-Trennzeichen festlegen
ds Dezimal-Trennzeichen festlegen
isempty Abfrage, ob das Feld leer ist

Abfrage des Betrages

<bx:recordfield.{field} equals="{n}" [not]> Inhalt </bx:recordfield.{field}>
<bx:recordfield.{field} equals="{n}" [true="{text}"] [false="{text}"] />

(Ausgabe von Quelltext abhängig vom Zahlenwert)

equals Vergleich des Feldinhalts mit einem Wert. Ausgabe bei Übereinstimmung
true, false eingetragener Text wird bei Übereinstimmung bzw. Nicht-Übereinstimmung ausgegeben.
<bx:recordfield.{field} {gt | gte | lt | lte}="{n}"> Inhalt </bx:recordfield.{field}>

Zahl mit einem Wert vergleichen. Ausgabe bei Übereinstimmung. Ab Version 2.5.7 kann anstatt der festen Vergleichszahl für  {n} auch "request:{Parametername}", "attribute:{Attributname}" oder "clipboard:{Name}" verwendet werden.

gt
gte
lt
lte
größer größer gleich kleiner kleiner gleich

Alternativwert

<bx:recordfield.Preis alt="0" pattern="0.00"/>
<bx:recordfield.Anzahl alt="-1" lte="0">Anzahl fehlt oder ist 0</bx:recordfield.Anzahl>

Ab Version 2.5.8 kann der Parameter alt verwendet werden um einen Alternativwert zu verwenden, falls keine Zahl gespeichert ist (auch keine 0).

<bx:recordfield.Preis alttext="gratis" pattern="0.00"/>

Ab Version 2.5.8 kann der Parameter alttext verwendet werden um einen Alternativtext anzuzeigen, falls keine Zahl gespeichert ist (auch keine 0).

Dies kann z. B. auch für Intranet-Eingabeseiten verwendet werden, um zu markieren wo Zahlenwerte leer sind.

Wahrheitswert

<bx:recordfield.{field}> Inhalt </bx:recordfield.{field}>				<!-- Ausgabe, wenn Feld im Container angehakt ist -->
<bx:recordfield.{field} not> Inhalt </bx:recordfield.{field}>			<!-- Ausgabe, wenn Feld im Container NICHT angehakt ist -->
<bx:recordfield.{field} empty> Inhalt </bx:recordfield.{field}>         <!-- Ausgabe, wenn Feld im Container "nicht gewählt" ist -->
<bx:recordfield.{field} not empty> Inhalt </bx:recordfield.{field}>     <!-- Ausgabe, wenn Feld nicht "nicht gewählt", also entweder ja oder nein ist -->

Zusätzlich zu den beiden Statussen "j" und "n" also true und false, gibt es noch den Status "empty". Diesen Status hat das Feld, wenn es noch nie ausgewählt wurde (im Backend wurde beim Speichern des DS keine Feld mit dem entsprechenden Namen übergeben) oder wenn im Container direkt dieser Status ausgewählt wurde (siehe Bild "Datenansicht").

Ob dieser Status "nicht gewählt" erlaubt ist, kann in der Containerdefinition festgelegt werden. Dort kann auch ein Wert den entsprechenden Statussen zugewiesen werden (Felder "angezeigter Text...".

Definitionsansicht: image2015-7-21 12:54:54.png Datenansicht: image2015-7-21 12:51:38.png
not Ausgabe, wenn das Feld nicht angehakt wurde (ohne: Ausgabe, wenn das Feld angehakt wurde)
veraltet für
not
: invert und else
empty Ausgabe, wenn Status "nicht gewählt" zutriffe (Erklärung siehe Text oben)

Beispiele

<bx:recordfield.Infomaterial_gewuenscht empty>
  <input type="radio" name="Infomaterial_gewuenscht" value="j"> Infomaterial gewünscht
  <input type="radio" name="Infomaterial_gewuenscht" value="n"> kein Infomaterial gewünscht
</bx:recordfield.Infomaterial_gewuenscht>

<bx:recordfield.Infomaterial_gewuenscht not empty>
  Du hast dich bereits entschieden.
</bx:recordfield.Infomaterial_gewuenscht>

Das Feld "Infomaterial_gewuenscht" kann nur einmal ausgewählt werden und dann nie wieder.

<bx:recordfield.Häkchenfeld show="( real | config )" />	  <!-- Ausgabe der in der Verwaltung gespeicherten Einstellungen -->
<bx:recordfield.{field} show="config" [true="{text}"] [false="{text}"] [empty="{text}"] />  <!-- direkt im Tag angegebene Werte überschreiben die Einstellung -->

Eine Ausgabe entspechend des gespeicherten Statuses erfolgt.

true Text, der ausgegeben wird, wenn das Feld angehakt wurde
false Text, der ausgegeben wird, wenn das Feld nicht angehakt wurde
empty Text, der ausgegeben wird, wenn das Feld den Status "nicht ausgewählt" hat (Erklärung siehe oben)
show ab V 2.6.2 real: gibt den wirklich gespeicherten Wert (z.B. "j", "n", "1", "0") aus config: gibt den in der Verwaltung konfigurierten Wert aus (Standard: "wahr", "falsch")

Bisher gab es noch keine Option um zu sagen „nicht angehakt oder leer“ bzw. „angehakt oder leer“.

<bx:recordfield.{häkchenfeld} [not empty] alt="{true|false}">...</bx:recordfield.{häkchenfeld}>
<bx:rf> <bx:rf not> <bx:rf empty> <bx:rf not empty> <bx:rf not alt=".."> <bx:rf alt="..">
angehakt angezeigt angezeigt angezeigt
nicht angehakt angezeigt angezeigt angezeigt
leer angezeigt angezeigt (wenn alt="false") angezeigt (wenn alt="true")
einen der drei Werte abfragen Gegenteil(die beiden anderen Möglichkeiten)
<bx:recordfield.häkchen>
zeigt Block an, wenn das Feld angehakt ist
<bx:recordfield.häkchen not alt="false">
zeigt Block an, wenn das Feld nicht angehakt oder leer ist
<bx:recordfield.häkchen not>
zeigt Block an, wenn das Feld als nicht angehakt gespeichert ist
<bx:recordfield.häkchen alt="true">
zeigt Block an, wenn das Feld angehakt oder leer ist
<bx:recordfield.häkchen empty> zeigt Block an, wenn das Feld leer ist <bx:recordfield.häkchen not empty> zeigt Block an, wenn das Feld als angehakt oder nicht angehakt gespeichert ist

Beispiele

...
Infomaterial gewünscht? <bx:recordfield.Infomaterial_gewuenscht true="ja" false="nein" empty="noch nicht entschieden" />
...
xml
<div id='status' style='background-color:<bx:recordfield.aktiviert true="green" false="red"/>;'>...</div>

Bild

<bx:recordfield.{field} [width="{n}"] [height="{n}"] [nogifshrink] [cover]/>

Es wird das Bild (also ein Tag) ausgegeben, ggf. verkleinert, wenn gewünscht.

width Angabe der max. Breite (abhängig von der Höhe)
height Angabe der max. Höhe (abhängig von der Breite)
nogifshrink keine Verkleinerung von GIF-Dateien
cover (ab V 2.6.3, ansonsten bei 2.6.2 reinkopieren)
Bild wird nur soweit verkleinert, daß es das angegebene Element ganz ausfüllt (siehe Beispiel 2)
cover="crop" Originalbild wird abgeschnitten und auch so gespeichert

Beispiele

Beispiel 1

<div style="width:150px;height:150px;border:1px solid black;">
  <img src="<bx:recordfield.Bild width="150" height="150" type="path"/>" alt="">
</div>

Bild wird in den genannten Dimensionen ausgegeben. Es wird entweder auf die Breite oder Höhe verkleinert.

Beispiel 2

css:
.qimg{
  width:150px;
  height:150px;
  overflow:hidden;
  border:1px solid black;
  background-position:center;
  }
______________________

<div class="qimg" style="background-image:url('<bx:recordfield.Bild width="150" height="150" cover type="path"/>');">
  <img src="" alt="">
</div>

Bild wird deckend in den genannten Dimensionen ausgegeben. Es wird entweder in der Breite (bei Querformt) oder in der Höhe (bei Hochformat) beschnitten.

Unterschied: siehe Bild, halbtransparente Bildteile werden durch css abgeschnitten

beispiel-cover.jpg

Bild-Daten ausgeben

<bx:recordfield.{field} type="(path | url | title | alt | author | empty | id | inline)" [not] />
type statt des eigentlichen Bildes kann folgendes ausgegeben werden: path: relativer Pfad url: komplette URL title, name: Titel des Bildes (Metadaten, Eingabe unter "Grafiken") originalname: Originaldateiname vom Upload licence: Lizenzangabe description: Beschreibung des Bildes alt: Alternativtext des Bildes (Metadaten, Eingabe unter "Grafiken") author: Autor des Bildes (Metadaten, Eingabe unter "Grafiken") empty: Abfrage, ob Feld leer ist (ab v 2.6.2) id: ID in der Bildergalerie (ab v 2.6.2) inline: erzeugt img-Tag mit Binärdaten in src (ab 2.6.1), sinnvoll bei Newsletter, da steht das Bild direkt in der Seite, also nicht als Link oder Anhang base64data: Tagerweiterung für vcf (Outlook-Visitenkarte, siehe Beispiel 2) mit Foto ab v2.6.6
not in Verbindung mit empty, kehrt die Abfrage um

Beispiele

<bx:recordfield.Bild type="empty" not>
  <div style="background-image:url('<bx:recordfield.Bild type="path"/>');" title="<bx:recordfield.Bild type="path"/>"> Inhalt </div>
</bx:recordfield.Bild>

Anzeige als Hintergrundbild, aber nur, wenn auch ein Bild vorhanden ist.

<bx:record.Visitenkarte pool="Ansprechpartner" id="request:editID">
BEGIN:VCARD
VERSION:2.1
N:<bx:recordfield.Name/>;<bx:if><bx:recordfield.Titel/> </bx:if><bx:recordfield.Vorname/>;;;
FN:<bx:if><bx:recordfield.Titel/> </bx:if><bx:recordfield.Vorname/> <bx:recordfield.Name/>
<bx:if>PHOTO;<bx:recordfield.Bild type="base64data" pattern="TYPE=$type;ENCODING=BASE64:\n$data\n" width="200" height="200"/></bx:if>
ORG:<bx:recordfield.Unternehmen><bx:recordfield.Titel/></bx:recordfield.Unternehmen>;
<bx:if>TITLE: <bx:recordfield.Taetigkeit/></bx:if>
NOTE;ENCODING=QUOTED-PRINTABLE: <bx:recordfield.Beschreibung type="plain"/>
contact=0D=0A
TEL;WORK;VOICE:<bx:recordfield.Telefon/>
<bx:if>TEL;HOME;VOICE:</bx:if>
<bx:if>TEL;CELL;VOICE:<bx:recordfield.Mobil/></bx:if>
<bx:if>TEL;WORK;FAX:<bx:recordfield.Fax/></bx:if>
ADR;WORK:;;<bx:recordfield.Straße/>;<bx:recordfield.Ort/>;<bx:recordfield.PLZ/>;;
LABEL;WORK;ENCODING=QUOTED-PRINTABLE:<bx:recordfield.Straße/>=0D=0A<bx:recordfield.Ort/>, <bx:recordfield.PLZ/> =0D=0A
<bx:if>URL:<WWLINK TYPE="GENERIC" VALUE="<bx:recordfield.Internet/>"><bx:recordfield.Internet/></WWLINK></bx:if>
EMAIL;PREF;INTERNET:<bx:recordfield.Email/>
REV:
END:VCARD
</bx:record.Visitenkarte>

Erzeugung einer Visitenkarte für Outlook

Bild-Größenangaben ausgeben

<bx:recordfield.{field} type="(origwidth | origheight | calcwidth | calcheight)" />

Hier werden nur die Größen als Zahl ausgegeben (z.B.: für Javascript-Popups um die Größe zu übergeben).

origwidth Ausgabe der Originalbreite
origheight Ausgabe der Originalhöhe
calcwidth Ausgabe der (berechneten) Endbreite
calcheight Ausgabe der (berechneten) Endhöhe

Dokument

<bx:recordfield.{field} [type="(link | path | url | id | name | size | description | meta)"] [name="{meta}"] [disposition="attachment|inline|none"]/> 
<bx:recordfield.{field} [type="link"]> Inhalt </bx:recordfield.{field}>

Falls type nicht angegeben wurde, wird der Standardwert link verwendet.

type link: erzeugt einen klickbaren Link auf das Dokument (falls Inhalt angegeben, wird dieser als Linktext verwendet) path: gibt den relativen Pfad url: gibt die komplette URL aus id: gibt die ID aus name: gibt den Namen aus size: gibt die Dateigröße aus, description: gibt die Beschreibung aus meta: Metadatenabfrage, Name des Meta-Feldes wird mit name übergeben (siehe unten) empty: (ab V 2.6.2) Abfrage, ob Feld leer ist
name (nur in Verbindung mit type="meta") Name der Meta-Eigenschaft
unit (nur in Verbindung mit type="size") auto: wählt automatisch die entsprechende Einheit, je nach Größe der Datei b: Angabe in Byte kb: Angabe in Kilobyte mb: Angabe in Megabyte
pattern (nur in Verbindung mit
type="size")
Formatierung der Zahl (Standardwert ist "#,##0")
locale (nur in Verbindung mit
type="size")
Sprachen-Formatierung der Zahl (standardmäßig "de_DE")
disposition siehe Beispiele

Beispiele

<bx:recordfield.Dokument disposition="inline"/>

Ausgabe: http://domain/files/{Batix-ID}/{Dateiname} setzt content-disposition:inline; filename=“{Dateiname}“, wird als Standard genommen, wenn nichts angegeben wird

<bx:recordfield.Dokument disposition="attachment"/>

Ausgabe:http://domain/files/download/{Batix-ID}/{Dateiname} bewirkt bei PDFs einen Zwangsdownload anstatt eine Anzeige im Browser-Plugin, dasselbe auch durch http://domain/files/{Batix-ID}/{Dateiname}?dl=true

<bx:recordfield.Dokument disposition="none"/>

Ausgabe: http://domain/files/media/{Batix-ID}/{Dateiname} bewirkt bei MP4-Videos, die in Apple-Mobilgeräten abgespielt werden sollen, daß das funktioniert, weil der Header nicht geschrieben wird (scheint nur Apple-Geräte zu betreffen)

Pixelkoordinaten

<bx:recordfield.{field} type="(x | y) [multiply="{n}"] [add="{n}"] [alt="{n}"] />
type Je nach
type
wird entweder die x- oder die y-Koordinate ausgegeben
multiply Angabe zum Multiplizieren des Koordinatenwertes (bei Kartenvergrößerund bzw. -verkleinerung)
add Wert, der zum Koordinatenwerte dazuaddiert werden kann
alt Alternativwert, der ausgegeben wird, wenn keine Zahl festgelegt ist

Einfachverknüpfung

<bx:recordfield.{field} [chkuser] [show="active|inactive|all"] <not> > Inhalt </bx:recordfield.<field>>
<bx:recordfield.{field} type="id" />
<bx:recordfield.{field}> />
<bx:recordfield.{field} type="if" value="{ID}" <not>> Inhalt </bx:recordfield.<field>>

Innerhalb des Tags kann wiederum mittels bx:recordfield auf die Elemente der Verknüpfung zugegriffen werden. Falls kein Vergleich passt, wird der Inhalt nicht ausgegeben. Falls kein Inhalt angegeben ist, wird der Titel des Datensatz-Feldes ausgegeben.

chkuser ID des Datensatzes mit der User-ID des aktuell eingeloggten Users bzw. mit den IDs seiner Gruppen verglichen.
type="id" gibt die ID des Datensatzes aus
type="if" (ab V 2.5.8) Inhalt des Tags wird nur dann angezeigt, wenn die ID des verknüpften Datensatzes mit der in value angegebenen übereinstimmt
value zu prüfenden ID. Mehrere zu prüfende IDs können durch Leerzeichen oder Kommas getrennt werden. #null: "nichts verknüpft" wird abgefragt #all: hebt alle Bedingungen auf, zeigt alles an (siehe Beispiel)
not kehrt die Bedingung um
show active: nur aktive DS (Standard) inactive: nur inaktive DS all: aktive und inaktive DS werden angezeigt

Beispiele

Beispiel für den Einsatz von nofilter

<bx:clipboard.cut>#all</bx:clipboard.cut>
 <bx:irgendeineBedingung><bx:clipboard.cut>eine Kategorieid</bx:clipboard.cut></bx:irgendeineBedingung>
 <bx:recordfield.Einzelkategorie type="if" value="clipboard:default">...</bx:recordfield.Einzelkategorie>

Clipboard wird mit #all initialisiert Clipboard wird mit einer ID gefüllt oder auch nicht wenn nicht gefüllt, greift das #all und hebt alle Bedingungen auf (ID = gibt aus, wenn es diese ID ist, #null = gibt aus, wenn nichts verknüpft ist) und gibt bei jedem DS aus

Mehrfachverknüpfung

<bx:recordfield.{field} [forceindex="<n>" | indexparam="<param>"] [max="<n>"] [idfield="<param>"] [force = {single | list}] [orderby="<field>"] [desc] [chkuser] [type="quantity"] [show="{active | inactive | all}"]>
 Inhalt 
</bx:recordfield.{field}>

<bx:recordfield.{field} zusätzliche Parameter [boundary="<text>"] [type="ids"] />

Hier stellt sich bx:recordfield als Schleife dar, welche für jeden Unter-Datensatz durchlaufen wird.

forceindex Stelle, an der die Ausgabe beginnen soll
indexparam Parametername, wo die Stelle, an der die Ausgabe beginnen soll, steht
max maximale Anzahl der auszugebenden Datensätze (z.B. max="5")
idfield Parametername, der die ID des Datensatzes enthält (Standard ist der Name des Feldes)
force Ausgabemodus (single oder list) kann erzwungen werden
orderby Feldangabe, nach der die Ausgabe sortiert sein soll (Datum, Name etc.)
desc dreht die Sortierrichtung um
chkuser DS-ID und ID seiner zugeordneten Gruppen wird mit der ID des eingeloggten Users verglichen, dh:
Wenn im DS eine Gruppe zugeordnet ist, dann wird der Inhalt ausgegeben
type quantity: Anzahl der verknüpften Datensätze anzuzeigen
boundary Trennzeichen, wenn die Titel aller Elemente ausgegeben werden (Standard ","), sollen nur die IDs ausgegeen werden, muß
type="ids"
angegeben werden (Tag ohne Inhalt)
show auch inaktive anzeigen lassen ab v2.6.6

Erweiterung für neue Container (v2.5.8) Werte für type:

<bx:recordfield.{field} type="[ ids | titel | quantity ]" [boundary="{text}"]/>

<bx:recordfield.{field} type="[ if-any | if-none | if-all ]" value="{Liste von IDs}"> ... </bx:recordfield.{field}>

<bx:recordfield.{field} type="[ if-empty | computebody | chkuser ]" [not] [nosv]> Inhalt </bx:recordfield.{field}>
type= ids gibt die verknüpften ID's mit Leerzeichen getrennt aus
titel gibt zur Zeit den Titel aus z. B. "2 verknüpfte Datensätze" (Standard wenn type nicht angegeben und geschlossenes Tag)
quantity gibt die Datensatzanzahl aus. "0" wenn keine Datensätze verknüpft
if-any gibt den Inhalt aus, wenn ein verknüpfter Datensatz die angegebene ID hat
if-none gibt den Inhalt nur aus, wenn keiner der verknüpften Datensätze die angegebene ID hat
if-all gibt den Inhalt aus, wenn alle angegebenen IDs im Datensatz verknüpft sind
if-empty gibt den Inhalt aus wenn kein Datensatz verknüpft ist
not: wenn mindestens 1 Datensatz verknüpft ist
computebody gibt eine Schleife für jeden verknüpften Datensatz aus (Standard, wenn type nicht angegeben und offenes Tag)
Die Parameter von oben sind noch gültig (force, idfield, max, indexparame, orderby nofilter)
chkuser wenn das Feld eine BC-Verknüpfung ist, wird geprüft, ob es mit dem eingeloggten Benutzer/Gruppe übereinstimmt (wie bei if-empty)
boundary damit kann man den Trenner angeben, z.B. boundary=","  Standard ist Leerzeichen
nosv wenn Admin, der ja in allen Gruppen drin ist, eingeloogt, wird er keiner Gruppe zugewiesen

Untercontainer

<bx:recordfield.{field} [forceindex="{n}" | indexparam="{param}"] [max="{n}"] [idfield="{param}"] [force="{single | list}"] [orderby="{field}"] [desc] [type="empty | quantity"] [show="active|inactive|all"] [not]> Inhalt </bx:recordfield.<field>>

<bx:recordfield.{field} [filterfield="{field}" [filtertype="{n}"] filtervalue="{text}" [filterrequired="{true|false}"] [nofilter]> Inhalt </bx:recordfield.<field>>

Dieser Typ ist der Mehrfachverknüpfung ähnlich. Für jeden Datensatz wird der Inhalt des Tags angezeigt. Ab v2.5.? gibt es die Möglichkeit einen Filter zu definieren, nach dem die Unterdatensätze gefiltert werden

forceindex Stelle, an der die Ausgabe beginnen soll
indexparam Parametername, wo die Stelle, an der die Ausgabe beginnen soll, steht
max maximale Anzahl der auszugebenden Datensätze (z.B. max="5")
idfield Parametername, der die ID des Datensatzes enthält (Standard ist der Name des Feldes)
force Ausgabemodus (single oder list) kann erzwungen werden
orderby Feldangabe, nach der die Ausgabe sortiert sein soll (Datum, Name etc.)
Sortierung nach Anlegereihenfolge: Angabe des Feldes, das die Parent-ID enthält
desc dreht die Sortierrichtung um
nofilter Filtereigenschaften werden nicht vom übergeordneten Container übernommen (siehe Beispiel unten)
filterfield gibt den Namen des Feldes im Untercontainer an, das durchsucht werden soll
filtertype Vergleichstyp (siehe
Filter
, standardmäßig auf 8 gestellt)
filtervalue Static-Wert oder
Parameter-Werte
filterrequired required-Flag für das Filter-Objektsetzen (standardmäßig false)
type
not
empty: Abfrage, ob der UK leer ist.
not
kehrt die Abfrage um
quantity: gibt die Anzahl aus
show active: nur aktive DS (Standard) inactive: nur inaktive DS all: aktive und inaktive DS werden angezeigt

Beispiele

Beispiel für eine Filterung des Untercontainers

<bx:recordfield.Sub filterfield="Text" filtertype="1" filtervalue="request:suche">
  <bx:recordfield.Text />
</bx:recordfield.Sub>

Beispiel für den Einsatz von nofilter

<bx:containerfilter.Kuecheninhalt pool="Kuecheninhalt">
  ...
  <bx:recordfield.Lebensmittel>
    ..
  </bx:recordfield.Lebensmittel>
  ..
</bx:containerfilter.Kuecheninhalt>

Filter für den Container "Kücheninhalt" (alle DS, die im UK "Lebensmittel" das Wort "brot" im Feld "Titel" enthalten).):

<filter-object>
  <field>Lebensmittel/Titel</field>
  <type>1</type>
  <static-value>brot</static-value>
</filter-object>

Verhalten, wenn nofilter nicht gesetzt ist:

Bei Ausgabe des Recordfield "Lebensmittel" werden nur die DS, die im Titel "brot" enthalten, ausgegeben, da der Filter vom Containerfilter übernommen wurde. nofilter verhindert das und alle DS werden ausgegeben.

Veraltete Tags

Die folgenden Befehle sind veraltet und werden durch bx:recorddata ersetzt.

<bx:recordfield.parentid />		           <!-- Gibt die ID des übergeordneten Objekes zurück. -->
<bx:recordfield.recordid />                  <!-- Gibt die ID des Feldes aus. -->
<bx:recordfield.rootid />                    <!-- Die ID des zugehörigen Hauptcontainers wird ausgegeben. -->
<bx:recordfield.previous object="<name>" />  <!-- veraltet: stattdessen bx:recorddata.previouslist benutzen -->
<bx:recordfield.next object="<name>" />      <!-- veraltet: stattdessen bx:recorddata.nextlist -->

Verweise auf diese Seite:

(8 Verweise)

Batix-Tags Referenz

bx:relativelink

Unterpunkt des aktuellen Hauptmenüpunktes

 Falls der gesuchte Pfad nicht existiert, wird in der ersten Form nichts ausgegeben. In der zweiten Form wird der Taginhalt ausgegeben, dies allerdings nur, wenn ifempty auf "showbody" gesetzt ist (was der Standard ist). Wenn ifempty="hide" angegeben wurde, wird bei Nichtfinden des Pfades auch nichts angezeigt. Um einen klickbaren Link zu erzeugen, muss das Tag einen Inhalt besitzen, dieser wird dann als Linktext übernommen.

pattern {pfad} gibt hier einen Menüpfad, ab dem aktuellen Haupmenüpunkt an
href Optional kann eine Zieldatei mittels
href
angegeben werden, die an den Pfad angehängt wird.
ifempty showbody: Taginhalt wird ausgegeben (Standard)
hide: bei Nichtfinden wird auch nichts angezeigt

Hauptmenüpunkt wechseln

Um den Hauptmenüpunkt zu wechseln, die tieferliegende Navigation aber intakt zu lassen, wird diese Variante verwendet (z.B. um zwischen Sprachen zu wechseln). Es wird nur der Hauptmenüpunkt des aktuellen Navigationspfades durch <menü> ersetzt und geprüft, ob der Zielpfad existiert. Falls dieser nicht gefunden wird, erfolgt die Ausgabe des Tag-Inhalts (falls vorhanden). Über href kann eine Zieldatei spezifiziert werden, die an den Pfad angehängt wird. Wenn der Zielpfad schließlich existiert und der Tag-Inhalt angegeben wurde, wird dieser als Linktext für einen klickbaren Link verwendet.

<pfad> wird bei dieser Variante von der Startseite aus gesehen angegeben (siehe Beispiel). Falls der Pfad nicht gefunden werden kann, wird ein Fehler ausgegeben. Auch hier kann eine Zieldatei über href und optionaler Linktext als Tag-Inhalt angegeben werden.

Beispiele

Code:

Demo: <bx:relativelink pattern="?/demo"/><br/>
Eintragen: <bx:relativelink href="eintragen.htm" pattern="?/demo">
  Eintragen!</bx:relativelink><br/>
Deutsch: <bx:relativelink pattern="de/*"/><br/>
Englisch: <bx:relativelink pattern="en/*"/><br/>
<br/>
Fehler 1: <bx:relativelink pattern="?/nichtvorhanden">
  Nicht vorhanden!</bx:relativelink><br/>
Fehler 2: <bx:relativelink pattern="fr/*">
  Sprache unvollständig!</bx:relativelink><br/>
<br/>
<bx:relativelink pattern="en/demo"/>

Administration:

Webseite:

Batix-Tags Referenz

bx:scanner

Die Ausgabe des Tags <span style="color: rgb(0,51,102);">scanner</span> ist abhängig vom User-Agent, der die Seite aufruft. Wenn der User-Agent mit "Batix Crawler/" beginnt, werden die vom Tag umschlossenen Bereiche ggf. nicht in die Seite geschrieben und damit auch nicht in den Suchindex aufgenommen. Wenn man "?crawler=batix" an die URL einer CM-Seite anhängt, wird die Seite angezeigt, wie sie der Batix-Crawler verarbeiten würde.

scanner.skip

<bx:scanner.skip> Inhalt </bx:scanner.skip>

Bereiche, die so markiert sind, werden nicht in den Suchindex aufgenommem. Links in diesen Bereichen wird die Suchmaschine folgen. Dieses Tag schreibt einen kleinen HTML-Kommentar, der vom Batix-Crawler dann berücksichtigt wird. Wenn ein anderer User-Agent die Seite aufruft, werden diese Bereiche angezeigt.

scanner.hide

<bx:scanner.hide> Inhalt </bx:scanner.hide>

Diese Bereiche werden komplett vor dem Crawler verborgen. Daher wird er auch Links in diesen Bereichen nicht folgen.

Text für Description in Seite sammeln

<bx:scanner.description> Inhalt </bx:scanner.description>

Diese Funktion markiert Bereiche, die als Meta-Description im HTML-Kopf angezeigt werden sollen.

Batix-Tags Referenz

bx:schleife

Das Tag schleife ersetzt das frühere bx:loop. Es können nun mehrere Schleifen in einer Ebene oder geschaltet benutzt werden. Der Inhalt dieses Tags kann beliebig mit anderen Tags versehen werden, z.B. bx:text oder bx:bild. Um innerhalb der Schleife zu navigieren, benutzt man die Eigenschaften von bx:loop.

Will man auf einer Seite nur eine Iteration vornehmen, dann kann man auch das [bx:tools.for](/books/cms-handbuch-entwickler/page/bx-tools) - Tag nehmen.

Listausgabe

<bx:schleife.{bez} [orderby="{feldname}"] [richtung="desc" | desc] [list="{feldname}"] [showmax="{n}" | single [random] | all] [indexparam="{param}"]>
  Inhalt 
</bx:schleife.{bez}>
bez frei wählbarer Titel der Schleife
dient auch zum Unterscheiden von mehreren Schleifen einer Seite in der Datenbank
dieser Titel ist auch der erwartete Request-Parametername bei Aufruf als Detailseite
orderby Feldname innerhalb der Schleife, nach dem die Liste sortiert werden soll
richtung oder nur "desc" dreht die Sortierrichtung um
list Feld innerhalb der Schleife (z.B. Name), das in der Verwaltung als Datensatz-Titel angezeigt wird
Wenn man innerhalb der Schleife mit bx:record einen DS aussuchen kann, dann kann auch der Bezeichner des bx:record genommen werden. (siehe 3. Beispiel)
showmax Angabe der maximale Anzahl an Elementen
indexparam Um mehrere blätterbare Listen zu ermöglichen, legen Sie für jede Liste einen eigenen Request-Parameter mittels "indexparam" an.
single | all single: Detailseitenmodus - wenn keine ID übergeben wurde, wird nichts angezeigt all: Listenmodus, auch wenn eine ID angegeben ist single random: ein Random-Element wird angezeigt

Beispiele

Listenseite

<bx:schleife.Cats list="Name">
  <bx:loop.count add="1"/> - <a href="detail.htm?Cats=<bx:loop.id/>"><bx:text.Name/></a><br>
</bx:schleife.Cats>

Detailseite

<bx:schleife.Cats>
  <h1><bx:text.Name/></h1>
  <bx:textarea.Beschreibung/>
  <bx:bild.Bild/>
</bx:schleife.Cats>

Die Detailseite.

Record

<bx:schleife.Ansprechpartner list="Mitarbeiter">
  <bx:record.Mitarbeiter pool="Mitarbeiter><bx:recordfield.Vorname/> <bx:recordfield.Name/></bx:record.Mitarbeiter>
</bx:schleife.Cats>

Es wird das angezeigt, was bei der Containerdefinition definiert wurde.

Batix-Tags Referenz

bx:search

**Achtung!**

Dieses Tag ist deprecated (missbilligt), es wird nicht mehr weiterentwickelt oder in zukünftigen Versionen nicht mehr unterstützt. Bitte stattdessen bx:websearch benutzen.

<bx:search.category...
<bx:search.list...
<bx:search.name...
<bx:search.titel...
<bx:search.link...
<bx:search.topname...
<bx:search.parentname...
<bx:search.empty...
Batix-Tags Referenz

bx:secureform

Das Tag bx:secureform wird benutzt, um Formulare gegen Manipulationen abzusichern. Es ist verfügbar ab Version 2.6.5.

[Unter diesem Link](/books/cms-handbuch-entwickler/page/manipulationsgeschuetzte-formulare-mit-secureform) gibt es eine ausführliche Anleitung, wie dieses Tag mit dem [zugehörigen Action](/books/cms-handbuch-entwickler/page/sicheres-formular-ueberpruefen) zu benutzen ist.

secureform

<bx:secureform> ... </bx:secureform>

Das Tag wird um eine <form> geschachtelt und definiert somit einen Gültigkeitsbereich für die inneren Tags (s.u.).

Beispiele

<bx:secureform>
  <form action="save.act">
    ...
  </form>
</bx:secureform>

secureform.field

<bx:secureform.field name="{parametername}" [cut]> ... </bx:secureform.field>
<bx:secureform.field name="{parametername}" hidden-when-empty [cut]> ... </bx:secureform.field>

Dieses innere Tag wird um die einzelnen Werte von <input>s oder Ähnlichem geschachtelt. Es merkt sich den Name und Wert des Parameters, um später über alle gesammelten Parameter den Hash zu bilden.

Der Wert wird auch wieder vom Tag ausgegeben, es funktioniert also wie [bx:clipboard.copy](/books/cms-handbuch-entwickler/page/bx-clipboard). Falls der Wert nicht ausgegeben werden soll, kann cut angegeben werden (funktioniert dann wie [bx:clipboard.cut](/books/cms-handbuch-entwickler/page/bx-clipboard)).

Falls im Inhalt andere Tags benutzt werden, muss darauf geachtet werden, dass diese **kein** HTML- oder sonstiges Encoding vornehmen (d.h. es muss ggf. `type="plain"` oder `encode="plain"` angegeben werden)! Das `secureform.field` Tag macht automatisch ein HTML-Encoding, falls es nicht von `tools.htmlencode` umschlossen ist.

Der Parameter hidden-when-empty muss angegeben werden, falls leere Werte dieses Parameters vom Browser nicht mitgesendet werden. Das würde sonst die Hashbildung verfälschen, denn das Tag beachtet den Parameter und merkt sich den leeren Wert, allerdings bekommt das Action den Parameter nicht übergeben und zieht ihn entsprechend nicht zur Hashbildung heran. Ist hidden-when-empty also angegeben und der Taginhalt leer, dann fließt dieser Parameter nicht mit in die Hashberechnung ein.

Als Wert (Tag-Inhalt) darf kein User-Input verwendet werden, die dieser ja nicht vom Server festgelegt wird.

Im Normalfall darf also z.B. kein bx:pagedata.request innerhalb von bx:secureform.field stehen.

parametername entspricht dem Name des Parameters, der vom Browser später mitgeschickt wird
ist meistens gleich dem name-Attribut eines <input>s

Beispiele

<!-- statischer Wert -->
<input type="hidden" name="gruppe" value="<bx:secureform.field name="gruppe">12345ABC</bx:secureform.field>">
 
<!-- dynamischer Wert -->
<input type="hidden" name="kid" value="<bx:secureform.field name="kid"><bx:recordfield.Kunde type="id" /></bx:secureform.field>">
 
<!-- Wert, bei dem das HTML-Encoding abgeschaltet werden muss -->
<input type="hidden" name="fester_titel" value="<bx:secureform.field name="fester_titel"><bx:text.Titel_aus_Verwaltung type="plain" /></bx:secureform.field>">
 
<!-- Feld, dass z.B. bei <bx:containerfilter dummy> wegfallen kann und somit hidden-when-empty benutzt werden muss -->
<bx:if><input type="hidden" name="editid" value="<bx:secureform.field name="editid" hidden-when-empty><bx:recorddata.id /></bx:secureform.field>"></bx:if>

secureform.values

<bx:secureform.values name="{parametername}" [cut]>...</bx:secureform.values>

In dieser Form wird ein erlaubter Wert eines Parameters gesammelt (siehe Mehrere erlaubte Werte). Es verhält sich wie bx:secureform.field (cut, HTML-Encoding). Bitte die Hinweise weiter oben auch hier beachten!

parametername entspricht dem Name des Parameters, der vom Browser später mitgeschickt wird

Die gesammelten, erlaubten Werte müssen dann für jedes Feld ausgegeben werden. Dies geschieht in folgender Form:

<bx:secureform.values name="{parametername}" />                        <!-- hidden Feld wird erzeugt -->
<bx:secureform.values name="{parametername}" param [encode="..."] />   <!-- nur Parametername ausgeben -->
<bx:secureform.values name="{parametername}" values [encode="..."] />  <!-- nur gesammelte Werte ausgeben -->

Die erste Variante (nur ein geschlossenes Tag mit name Parameter) erzeugt ein input type="hidden" mit passenden name und value Attributen.

Falls man selbst einen Link zusammenbaut, kann param bzw. values benutzt werden, um entweder den Name des speziellen Parameters bzw. dessen Wert auszugeben. Je nach Fall muss die Rückgabe entsprechend encoded werden, z.B. encode="javascript" oder encode="url".

Falls keine Werte für den Parameter gesammelt wurden, geben alle drei Varianten nichts aus.

secureform.hash

<bx:secureform.hash />        <!-- hidden Feld wird erzeugt -->
<bx:secureform.hash name />   <!-- nur Hash-Parametername ausgeben -->
<bx:secureform.hash value />  <!-- nur Hash-Wert ausgeben -->

Dieses innere Tag durchläuft alle gesammelten Parameter-Werte-Paare und bildet mit anderen, geheimen Faktoren einen Hashwert. Ohne Parameter wird ein <input type="hidden"> mit passenden name und value Attributen in die Seite geschrieben.

Möchte man nur Name oder Wert haben, ist dies auch möglich (um diese z.B. in Scripts zu verwenden).

Nach `` oder `` darf kein weiteres `` oder `` folgen. Alle Tags müssen außerdem innerhalb von `` stehen.

secureform.check

<bx:secureform.check securelist="{parameterliste}" [url="{url}"] [forward] />

Hiermit können in einem Template die abgesicherten Parameter geprüft werden. Die Parameter ähneln die des Actions.

parameterliste Dies ist eine komma-getrennte Liste der Parameternamen, welche zur Hashbildung herangezogen werden.
Tauchen hier Parameternamen auf, die nicht im Request sind, so werden diese Parameter nicht zur Hashbildung benutzt.
Hier können auch Parameter stehen, die nie an die Seite übergeben werden dürfen - da diese im Frontend nicht mitgehasht werden und höchstens durch Manipulation im Request landen, schlägt die Prüfung fehl und die Seite bricht ab.
Zusätzlich zu dieser manuellen Liste gibt es eine im System verankerte Liste, welche einige Standardparameter enthält, die immer geschützt sein müssen (z.B.: recordid, listid).
url Falls die Prüfung fehlschlägt, wird zu dieser URL weitergeleitet. Ist zusätzlich forward angegeben, wird statt dem Redirect ein Forward gemacht (URL bleibt im Browser stehen).
Ist hier nichts eingetragen und die Prüfung schlägt fehlt, wird die Abarbeitung der Seite abgebrochen und der generierte Quelltext wird nicht an den Client ausgeliefert.
Manche Tags führen schon Aktionen aus, bevor <bx:secureform.check> die Parameter prüft, diese sind aber meistens unkritisch.

Alle Parameter in securelist müssen, falls vorhanden, abgesichert sein. Das heißt ihr Wert muss entweder direkt in den Hash eingeflossen sein, oder einen der erlaubten Werten entsprechen (und diese Liste muss dann in den Hash eingeflossen sein).

Dieses Tag sollte in der ersten Zeile des Quelltextes stehen, um sicherzustellen, dass die Abarbeitung der restlichen Seite so früh wie möglich abgebrochen wird.

Erlaubte Werte

Falls ein spezieller Parameter für mehrere erlaubte Werte mitgeschickt wurde, wird zusätzlich geprüft, ob der originale Parameter einem dieser Werte entspricht.

Verweise auf diese Seite:

(4 Verweise)

Batix-Tags Referenz

bx:sessiondata

Das Tag sessiondata setzt, liest und vergleicht Werte von Session-Variablen.

Auslesen eine Attributes, das mit dem Action geschrieben wurde

<bx:sessiondata[.{mapname}] name="{key}" />

Ein in die Session geschriebener Wert wird abgerufen. Dies gilt für Werte, die über das Action SaveInSessionAction in der Session geschrieben wurden. Falls <mapname> nicht spezifiziert ist, wird der Standardwert "default" verwendet. Es sind nur Strings möglich. Ab Version 2.6.0 kann man im Filter auch direkt auf den Wert zugreifen, wenn kein Map-Name angegeben wurde. Ein Umspeichern auf der Seite entfällt.

{mapname} Name der Map
key gesuchter Eintrag

sessiondata.id

<bx:sessiondata.id [force="no-create"]/>

Gibt die Session-ID aus *( ab Version 2.5.8 ) Wenn es noch keine Session gibt, dann wird eine erstellt und dann ausgegben, außer man gibt "no-create" an (ab V 2.6.9) *

sessiondata.attribute

<bx:sessiondata attribute="<key>" />
 <bx:sessiondata.attribute name="<key>" encode="typ"/>
 <bx:sessiondata.attribute name="<key>" [not] > Inhalt </bx:sessiondata.attribute>

 <bx:sessiondata.attribute name="<key>" value="<value>" [not] > Inhalt </bx:sessiondata.attribute>

*(ab V 2.5.6 ) *Ein Wert aus der Session wird über dessen key abgerufen. Werte vom Typ String werden hier unterstützt. Zusätzlich sind als Werte auch Objekte des Typs BatixModul möglich, hier wird der Titel des Moduls zurückgegeben. Falls das Object kein String oder BatixModul ist, wird der Wert von toString() zurückgegeben.

attribute Name des Attributs
name Name des Attributs
value Wert zum Vergleich mit dem Wert im Attribute
not kehrt die Bedigung um
encode Hiermit kann der ausgegebene Text für verschiedene Formate kodiert werden:
- html - javascript - sql (zur Verwendung in SQL für Strings) - sql-like (zur Verwendung in SQL mit LIKE) - sql-rlike (zur Verwendung in SQL mit RLIKE und REGEXP) - url - xml

sessiondata.setattribute

<bx:sessiondata.setattribute name="<key>" [cut] > Tag-Body </bx:sessiondata.setattribute>

Erzeugt ein Session-Attribut mit dem angegebenen Namen und speichert als Wert den ausgewerteten Body des Tags. Bei leerem Body wird das Attribut gelöscht. (ab V 2.5.8 )

name Name des Attributs
cut bewirkt, daß der Body nicht auf der Seite angezeigt wird

sessiondata.removeattribute

<bx:sessiondata.removeattribute name="<key>" />

Ein Wert aus der Session wird gelöscht. Ab der Stelle dieses Aufrufs in der Seite ist der Wert nicht mehr verfügbar. *(ab V 2.5.8 ) *

sessiondata.invalidationtime

<bx:sessiondata.invalidationtime pattern="HH:mm"/>

Gibt die Uhrzeit aus zu der die Session inaktiv wird, falls keine weiteren Requests erfolgen. (ab V 2.5.8 )

pattern Datumsmuster
Batix-Tags Referenz

bx:sitemap

**Erweitertes Tag** Das Tag `sitemap` ist eine Erweiterung von **[bx:navigation](/books/cms-handbuch-entwickler/page/bx-navigation)**. Alles was in **[bx:navigation](/books/cms-handbuch-entwickler/page/bx-navigation)** möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in **[bx:navigation](/books/cms-handbuch-entwickler/page/bx-navigation)**.

Allgemeine Syntax

<bx:sitemap.{level} [normal | protected] [showprotected] [showinactive] [path="{pfad}"]  > Inhalt </bx:sitemap.<level>>

Da die Sitemap eine komplett aufgeklappte Navigation darstellt, ist der Parameter open weggefallen.

normal/protected nur nicht-geschützte Menüpunkte anzeigen / nur geschützte (Intranet-)Menüpunkte anzeigen
showprotected geschütze Elemente auch dann einblenden, wenn der Betrachter keinen Zugriff darauf hat
showinactive inaktive Elemente anzeigen
path Pfad zum Menüpunkt, von welchem die Unterpunkte angezeigt werden sollen (nur wenn
<level>
> 0 und kein
<bx:sitemap.0>
-Tag außen herum steht)

sitemap.text

<bx:sitemap.text/>

Gibt die Beschreibung des Punktes aus. .

Batix-Tags Referenz

bx:statistik

Dies ist ein Tag, das statistische Angaben von Userzugriffen auf Navigationspunkte ausgeben kann. Funktioniert nur mit langen URLs (also mit /www/projektname/.....)

statistik.visitors

<bx:statistik.visitors start="{date}" ende="{date}" />

Die Anzahl an unterschiedlichen Session-IDs, die den aktuellen Navigationspunkt im angegebenen Zeitraum aufriefen. Die Auswertung erfolgt nur für den aktuellen Menüpunkt.

veraltet: <bx:statistik.anzahl ... />

start Startdatum, pattern: dd.MM.yyyy, kann durch ein Formularfeld übergeben werden
ende Endedatum, pattern: dd.MM.yyyy, kann durch ein Formularfeld übergeben werden

statistik.totalvisitors

<bx:statistik.totalvisitors start="{date}" ende="{date}" />

Die Anzahl an unterschiedlichen Session-IDs, die das Web im angegebenen Zeitraum aufriefen. Die Auswertung erfolgt für das gesamte Projekt.

statistik.hits

<bx:statistik.hits start="{date}" ende="{date}" />

Die Anzahl an Seitenaufrufen des aktuellen Menüpunktes im angegebenen Zeitraum. Die Auswertung erfolgt nur für den aktuellen Menüpunkt.

statistik.totalhits

<bx:statistik.totalhits start="{date}" ende="{date}" />

Die Anzahl an Seitenaufrufen des gesamtem Webs im angegebenen Zeitraum. Die Auswertung erfolgt für das gesamte Projekt. statistik.pagelist

<bx:statistik.pagelist start="{date}" ende="{date}"> Inhalt </bx:statistik.pagelist>

Eine Schleife durch die unterschiedlichen URLs, die zu diesem Punkt gespeichert sind. In diesem Tag können .visitors, .hits, .url und .name als Inhalt verwendet werden. Es werden alle aufgerufenen URLs zum aktuellen Menüpunkt durchlaufen.

statistik.initialdate

<bx:statistik.initialdate [ pattern="{format}" ] />

Schreibt das Datum / die Zeit des ersten (ältesten) Eintrags für das Web in die Seite. Falls pattern nicht angegeben wurde, wird der Standard-Wert "dd.MM.yyyy HH:mm:ss" verwendet.

statistik.terminaldate

<bx:statistik.terminaldat [ pattern="{format}" ] />

Schreibt das Datum / die Zeit des letzen (neuesten) Eintrags für das Web in die Seite. Falls pattern nicht angegeben wurde, wird der Standard-Wert "dd.MM.yyyy HH:mm:ss" verwendet.

statistik.url

<bx:statistik.url/>

Diese Funktion erfordert eine umgebende .pagelist. Es wird die URL des aktuellen Schleifenelements ausgegeben.

statistik.name

<bx:statisik.name/>

Diese Funktion erfordert eine umgebende .pagelist.

Beispiele

<form action="./" method="post">
  Zeitraum:<br>
  von <input type="text" name="von" value="<bx:if><bx:pagedata.request name="von"/><bx:if.else>01.<bx:tools.datum pattern="MM.yyyy"/></bx:if.else></bx:if>">
  bis <input type="text name="bis" value="<bx:if><bx:pagedata.request name="bis"/><bx:if.else><bx:tools.datum pattern="dd.MM.yyyy"/></bx:if.else></bx:if>">
  <input type="submit" value="anzeigen">
  <br>Beginn der Erfassung <bx:statistik.initialdate pattern="dd.MM.yyyy"/>
</form>

...

<table>
    <tr>
      <th>&nbsp;</th>
      <th>Seitenaufrufe</th>
      <th>Besucher</th>
    </tr>
    <bx:sitemap.0 showinactive>
      <tr>
        <td><a href="/www/<bx:pagedata.webdir/>/<bx:sitemap.path/>/"><bx:sitemap.name/></a></td>
        <td><bx:statistik.hits start="request:von" ende="request:bis"/></td>
        <td><bx:statistik.anzahl start="request:von" ende="request:bis"/></td>
      </tr>
  </bx:sitemap.0>
</table>

Beispiel einer einfachen Statistik

Batix-Tags Referenz

bx:submenu

Das Tag submenu erzeugt eine Liste der Unterpunkte des aktuellen Menüpunktes. Kann geschachtelt werden (siehe Beispiel ganz unten). Innerhalt der Schleife kann bx:navdata benutzt werden.

submenu.list

<bx:submenu.list [all]> Inhalt </bx:submenu.list>

Innerhalb des Tags kann auf die Inhalte des Unterpunktes (bx:text..., bx:bild... usw) zugegriffen werden. Es können darin die nachfolgenden Tags verwendet werden.

all um auch nicht aktivierte Menupünkte anzuzeigen

submenu.name

<bx:submenu.name />

Der Name des Menüpunktes wird ausgegeben.

<bx:submenu.link> Inhalt </bx:submenu.link>

submenu.description

<bx:submenu.description [maxwords="{n}"] />

Dieses Tag gibt die Beschreibung des Menüpunktes aus,

maxwords optional auf {n} Wörter begrenzt

submenu.path

<bx:submenu.path />

Ausgabe des relativen Pfades zum Unterpunkt (auch bei mehreren Schachtelungsebenen). Der virtuelle Pfad wird ohne "/www/webname/" und ohne "/" am Ende ausgegeben.

submenu.target

<bx:submenu.target alt="_self" />

Das Target aus dem Menüpunkt wird ausgegeben.

submenu.meta

<bx:submenu.meta name="Meta-Key" />
<bx:submenu.meta name="Meta-Key" [not] > ... </bx:submenu.meta>

Metadaten aus dem Navigationspunkt ausgeben oder abhängig vom Vorhandensein einen Block ausgeben. Es kann auch bx:navdata (siehe Batix Docs) benutzt werden.

submenu.cols

<bx:submenu.cols num="{n}" equals="{n}">...</bx:submenu.cols>

Zeigt abhängig von einer Spaltennummer einer Menüpunktliste Daten an.

Beispiele

<bx:submenu.cols num="3" equals="3">style="margin-right:0;"</bx:submenu.cols>

Nur Spalte drei soll kein Rechts-Margin haben

<bx:submenu.cols num="3" equals="2" true="Spalte zwei" false="nicht Spalte zwei"/>

Wenn Spalte 2: zeige anderen Text als Spalte 1 und 3

<bx:submenu.cols num="3" 1="links" 2="mitte" 3="rechts"/>
<bx:submenu.cols num="3" col1="links" col2="mitte" col3="rechts"/>

Je nach Spalte anderer Text

submenu.index

<bx:submenu.index [add="Startwert"]/>

Ausgabe einer laufenden Nummer des Schleifendurchlaufs. (Beginnend bei 1) Mit <bx:submenu.index add="0"/> beginnt die Schleife ab 0 (z. B. für Javascript-Arrays)

submenu.redirected

<bx:submenu.redirected> ... </bx:submenu.redirected>
<bx:submenu.redirected not> ... </bx:submenu.redirected>

Abfrage, ob der Punkt weitergeleitet ist

Beispiele

<bx:submenu.redirected><a href="<bx:submenu.redirecturl/>"><bx:navlink><bx:bild.Bild/></bx:navlink></a></bx:submenu.redirected> (extern)
<bx:submenu.redirected not><bx:submenu.link><bx:submenu.name/></bx:submenu.link></bx:submenu.redirected> (intern)

Zugriff auf Inhalte eines Untermenü-Punkts, wenn Weiterleitung im Unterpunkt

submenu.redirecturl

<bx:redirecturl />

Rückgabe der Redirect-URL

Schachtelung und Geschwister

Beispiel

<bx:submenu.list>
  <bx:submenu.name />
  <bx:Submenu.list>
    <bx:Submenu.name />
  </bx:Submenu.list>
</bx:submenu.list>

Es werden die zwei Ebenen unter dem jeweiligen Menüpunkt ausgegeben. Zur Unterscheidung der Schleifen muß die Schreibweise bissl kreativ angepaßt werden (Groß- und Kleinschreibung).

<bx:clipboard.cut name="navid"><bx:pagedata.parentnavid/></bx:clipboard.cut>

<bx:navlink navid="clipboard:navid">
  <bx:submenu.list>
    <button class="btn btn-default" onclick="location.href='<bx:submenu.path/>'"><bx:submenu.name/></button>
  </bx:submenu.list>
</bx:navlink>  

Geschwisternavigationspunkte ausgeben

Batix-Tags Referenz

bx:submenulist

**Achtung!**

Dieses Tag ist deprecated (missbilligt), es wird nicht mehr weiterentwickelt oder in zukünftigen Versionen nicht mehr unterstützt. Bitte stattdessen bx:submenu benutzen.

Dieses Tag stellt Untermenüpunkte des aktuellen Menüpunktes mittels einer Schleife dar.

<bx:submenulist [all]> Inhalt </bx:submenulist>

Um auch inaktive Punkte anzuzeigen, muss all angegeben werden. Folgende Tags können im Inhalt verwendet werden:

submenuname

<bx:submenuname />

Gibt den Name des Menüpunktes aus.

submenudir

<bx:submenudir />

Gibt den virtuellen Verzeichnisnamen des Menüpunktes aus.

Verweise auf diese Seite:

Keine Verweise gefunden.

Batix-Tags Referenz

bx:systemdata

Mithilfe des Tags systemdata lassen sich Systemvariablen ausgeben. Systemvariablen werden in der Verwaltung unter dem Punkt "Systemeinstellungen" angelegt und verwaltet. Sie können pro Projekt angepaßt werden.

systemdata.attribute

<bx:systemdata.attribute name="<attrib>" />
<bx:systemdata.attribute name="<attrib>" [not]> Inhalt </bx:systemdata.attribute>
<bx:systemdata.attribute name="<attrib>" value="<Test-Value>" [not]> Inhalt </bx:systemdata.attribute>

globales System-Attribut auswerten Die erste Form schreibt den Wert des Attributes (falls vorhanden) in die Seite, die Zweite den Tag-Inhalt (not verwendbar), falls das Attribut definiert/nicht definiert wurde*, *die Dritte schreibt den Inhalt nur bei Übereinstimung des Wertes.

name Name des Requestattributs
value zu prüfender Wert
* (seit v2.5.9)*
not kehrt die Bedingung um

systemdata.variable

<bx:systemdata.variable name="<key>" />
<bx:systemdata.variable name="<key>" [not]> Inhalt </bx:systemdata.variable>
<bx:systemdata.variable name="<key>" value="<Test-Value>" [not]> Inhalt </bx:systemdata.variable>

Projektvariablen auswerten. Wird keine gefunden, wird die globale genommen. Rest siehe oben.

weitere Verwendungen

Auf die Variablen kann auch mit dem Präfix "system:" in bx-Tag-Parametern zugegriffen werden z. B.:

<bx:containerloop pool="system:newslistid">

wenn in jedem Projekt eine Variable namens newslistid definiert wird, die eine passende Container-ID enthält

oder:

<bx:recordfield.Datum pattern="system:pattern">

wenn im deutschen Projekt ein deutsches Datumsmuster und im englischen Projekt ein englisches Muster eingetragen wird

seit v2.6:

in java-includes können die Variablen so aufgerufen werden:

<%@taglib prefix="batix" uri="/batix"%>
<batix:taginfo>
<%
String wert = variables.getVariable("test");
%>
</batix:taginfo>

in Jsp-Action geht der Aufruf so:

<%@page import="com.batix.modul.SystemVariables"%>
<%@page import="com.batix.action.JspAction"%><%
JspAction action = JspAction.getInstance(request);
SystemVariables variables = SystemVariables.getInstance(action);
String wert = variables.getVariable("test");
%>
Batix-Tags Referenz

bx:tablechoice

Dieses Tag ist eine Erweiterung von bx:recordchoice. Alles was in bx:recordchoice möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in bx:recordchoice.

Batix-Tags Referenz

bx:tabledata

Dieses Tag ist eine Erweiterung von bx:recorddata. Alles was in bx:recorddata möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in bx:recorddata.

Batix-Tags Referenz

bx:tablefield

Dieses Tag ist eine Erweiterung von bx:recordfield. Alles was in bx:recordfield möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in bx:recordfield.

Batix-Tags Referenz

bx:tablefilter

Dieses Tag ist eine Erweiterung von bx:containerfilter. Alles was in bx:containerfilter möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in bx:containerfilter.

Batix-Tags Referenz

bx:tablekat

Dieses Tag ist eine Erweiterung von bx:containerkat. Alles was in bx:containerkat möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in bx:containerkat.

Batix-Tags Referenz

bx:tableloop

Dieses Tag ist eine Erweiterung von bx:containerloop. Alles was in bx:containerloop möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in bx:containerloop.

Batix-Tags Referenz

bx:tablerecord

Dieses Tag ist eine Erweiterung von bx:record. Alles was in bx:record möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in bx:record.

Batix-Tags Referenz

bx:tablesqlfilter

Das Tag tablesqlfilter filtert einen Container über eine SQL-Anweisung, die in den Tag-Einstellungen der Administraton angegeben ist.

<bx:tablesqlfilter.{titel} pool="{name | id }" [where="{sql}"]> Inhalt </bx:tablesqlfilter.{titel}>

Innerhalb der Bedingung (in der Administration) können Platzhalter für Request-Parameter verwendet werden. So wird z.B. "[[param]]" durch den Wert des Parameters "param" ersetzt, bevor die Bedingung ausgewertet wird.

Wenn weder in der Administration, noch im Parameter where eine Bedingung angegeben ist, werden alle Datensätze angezeigt.

containername | id ID des zu filternden Containers
where Standard-Bedingung, falls in der Administration nichts eingetragen ist
Batix-Tags Referenz

bx:text

Mittels des Tags text kann für Redakteure eine Eingabemöglichkeit in Form eines einzeiligen Textfeldes geschaffen werden.

Die einzelnen Funktionen können kombiniert werden.

Dieses Tag kann sich in der Verwaltung darstellen.

Textfeld anzeigen

<bx:text.{titel} [comment="{kommentar}"] [admin-mode="config" admin-title="{alternativer Titel}"]/>
comment Kommentar, der beim Tag z.B. als Hinweis mit ausgegeben wird
admin-mode Erzwingt, daß das Tag bei den Tageinstellungen (anstatt bei Dateneingabe) angezeigt wird.
admin-title In Verwaltung wird ein anderer Titel ausgeben als der beim Tag angegebene.

Für `{titel}` und `{kommentar}` siehe die allgemeinen Hinweise zu [Redakteurs-Tags](/books/cms-handbuch-entwickler/page/redakteurs-tags).

Länge begrenzen

<bx:text.{titel} [size="{breite}"] [maxlength="{maxlänge}"] />

Das Eingabefeld ist hiermit {breite} Zeichen breit bzw. können dann nur {maxlänge} Zeichen in das Feld eingetragen werden.

size kann nicht auf kleiner als 2 gesetzt werden (wird dann auf 63 gesetzt), der Maximalwert beträgt 63. Der Standardwert ist 63.

maxlength kann nicht auf kleiner als 2 gesetzt werden (wird dann auf 255 gesetzt), der Maximalwert beträgt 255. Der Standardwert ist 255.

Ausgabe maskieren

<bx:text.{titel} [encode="(html | plain | url | javascript | entitymask | xml)"] />

Standardmäßig wird ausgegebener Text HTML-kodiert (html ist also Standard für encode), außer der MIME-Type der Frontend-Seite beginnt mit "text/plain" (dann ist plain Standard).

Wenn etwas anderes benötigt wird - z.B. falls Text in JavaScript Code eingebunden ist - kann dies über encode gesteuert werden. Bei plain wird der Text unverändert ausgegeben.

Für Details zu den anderen Formaten, einfach den Links in der nachstehenden Tabelle folgen:

html HtmlEncode
url UrlEncode
mit Projekt-Zeichensatz
javascript Non-Strict
ScriptEncode
entitymask HtmlMask
xml XmlEncode

Ausgabe maskieren (veraltet)

** Deprecated - Veraltetes Feature** Die hier aufgeführten Informationen beziehen sich auf eine veraltete Funktion, die nicht mehr weiterentwickelt wird und ggf. in zukünftigen Versionen nicht mehr unterstützt wird. Diese Funktion sollte deshalb nicht mehr benutzt werden.

<bx:text.{titel} [urlencode | inscript | htmlmask | unmodified] />

Falls encode nicht angegeben ist, kann die Maskierung kann auch mittels Flags gesteuert werden. Dabei gelten foldende Zuordnungen zwischen den Flags hier und encode oben:

Flag encode
urlencode url
inscript javascript
htmlmask entitymask
unmodified plain
Batix-Tags Referenz

bx:textarea

Das Tag textarea stellt in der Verwaltung ein Eingabefeld für einen beliebigen, mehrzeiligen Text zur Verfügung.

<bx:textarea.{bezeichner} [cols="<n>"] [rows="<n>"] [ small | medium | large | xlarge ] [comment="<text>"] />
<bx:textarea.{bezeichner} [maxchars="<n>" | maxwords="<n>"] [type="plain"] [encode="htmltext"] [wrap="<wrap>"] />
<bx:textarea.{bezeichner} [imgloop="<schleife>"] [imgname="<text>"] [href="<text>"] [width="<n>"] [height="<n>"] />

Auf der Webseite wird der Text unformatiert dargestellt.

cols Breitenangabe
rows Höhenangabe (Zeilen)
small
medium
lage
xlarge
| Vorlage | cols | rows | | --- | --- | --- | | small | 21 | 5 | | medium | 42 | 8 | | large | 63 | 20 | | xlarge | 63 | 35 |
Vorlage cols
small 21
medium 42
large 63
xlarge 63
comment in der Verwaltung kann zusätzlicher Text angezeigt werden, z.B. für Erklärungen.
maxchars nur angegebene Zeichenanzahl vom Text ausgeben z.B. für Anmoderationen
gibt ganze Worte, so weit wie möglich, aus
maxwords nur angegebene Wortanzahl vom Text ausgeben z.B. für Anmoderationen
type="plain" erweiterter Editor für dieses Textfeld wird in der Verwaltung deaktiviert
erweiterbar mit
encode="htmltext"
encode="htmltext" zeigt plain-Feld in Verwaltung aber macht
s im Frontend rein
wrap="wrap" Art des Zeilenumbruchs des Textfeldes in der Verwaltung,
Standardwert ist hier virtual. (siehe auch
SELFHTML Dokumentation
)

Beispiele

Code:

<bx:textarea.Seitentext large comment="Dieser Text steht direkt unter der Überschrift."/>

Ansicht in der Verwaltung (Formatierungen werden über den zweiten Balken oben vorgenommen):

image2015-4-10 8:17:45.png

.......

image2015-4-10 8:15:26.png

Ansicht auf der Seite:

image2015-4-10 8:32:55.png

Bilder mittels Platzhalter einfügen

Über den Button "Bild einfügen" in der Toolbar können Sie Platzhalter für Grafiken einfügen. Es besteht dann die Möglichkeit diese Platzhalter durch Bilder zu ersetzen, die in einer Schleife festgelegt sind.

Legen Sie dazu im Quelltext der Seite ein Bx:schleife Tag an, welches ein Bx:bild Tag enthält. Damit die Schleife an sich nicht auf der Webseite ausgegeben wird, setzen Sie den Parameter showmax der Schleife auf 0. Zusätzlich muss im Textfeld der Paramater imgloop spezifiziert werden. imgname beschreibt den Titel des Bx:bild Tags in der Schleife. Jetzt können Sie die Seite im Projektmenü bearbeiten und in der Schleife die gewünschten Bilder einfügen. Die Platzhalter im Text werden dann der Reihe nach durch die Bilder der Schleife ersetzt.

Um eine einheitliche Größe der Bilder festzulegen kann width und/oder height angegeben werden. Falls eine Verlinkung stattfinden soll muss der Parameter href gesetzt werden.

Deutlich wird das Ganze an einem Beispiel.

Beispiele

Code:

<bx:schleife.bilder showmax="0">
  <bx:bild.DemoBild/>
</bx:schleife.bilder>
<bx:textarea.demotextarea medium imgloop="bilder" imgname="DemoBild" width="200" height="100" />

In der Administration:

image2015-4-10 8:31:40.png

Auf der Seite:

image2015-4-10 8:32:15.png

Bilder verlinken

Durch Hinzufügen von href="bilder.htm" zum <bx:textarea>, weglassen von <bx:schleife.bilder showmax="0"> und stattdessen Erstellung eines Detail-Templates wie "bilder.htm" im nächsten Beispiel, werden die einzelnen Bilder im Text auf die jeweilige Detailseite verlinkt.

Beispiele

In diesem zweiten Beispiel ist das Bild auf eine Detailseite mit Großansicht verlinkt. In diesem Fall fällt die Definition der Schleife in der Hauptseite weg.

Die Darstellung des Bildes in der Hauptseite kann durch Textbausteine flexibler definiert werden. Hierzu wird in <bx:textarea> Parametern namens left, center und/oder right der Name eines Textbaustein-Templates zugewiesen. In diesen Templates wird nur der Ersatz-Code für den Platzhalter im Eingabefeld geschrieben. Im Beispiel-Textbaustein "Bild-links" wird nur das Bild mit umgebenden div-Tag angezeigt. Im Beispiel "Bild-rechts" wird zusätzlich eine Bildunterschrift angegeben

Code in Hauptseite "index.htm"

<bx:textarea.demotextarea medium imgloop="bilder" left="Bild-links" right="Bild-rechts" />

Code in Bilder-Detailseite "bilder.htm"

...
<bx:schleife.bilder>
  <h1><bx:text.DemoBildName/></h1>
  <bx:bild.DemoBild width="640" height="480"/>
  <bx:textarea.BildBeschreibung medium/>
</bx:schleife.bilder>
...
<bx:loop.showprevious schleife="Bilder">vorheriges Bild</bx:loop.showprevious> |
<a href="index.htm">zurück zum Artikel</a> | 
<bx:loop.shownext schleife="Bilder">nächstes Bild</bx:loop.shownext>
...

Textbaustein "Bild-links"

<div style="float:left;padding:2px">
  <a href="bilder.htm?bilder=<bx:loop.id/>"><bx:bild.DemoBild width="200" height="200"/></a>
</div>

Textbaustein "Bild-rechts"

<div style="float:right;padding:2px">
  <a href="bilder.htm?bilder=<bx:loop.id/>"><bx:bild.DemoBild width="150" height="300"/></a><br>
  <a href="bilder.htm?bilder=<bx:loop.id/>"><small><bx:text.DemoBildName/></small></a>
</div>
Batix-Tags Referenz

bx:titel

**Erweitertes Tag** Das Tag `titel` ist eine Erweiterung von **[bx:text](/books/cms-handbuch-entwickler/page/bx-text)**. Alles was in **[bx:text](/books/cms-handbuch-entwickler/page/bx-text)** möglich ist, ist auch hier möglich (evtl. Änderungen sind weiter unten angegeben). Neue Funktionen, die auf dieser Seite angegeben sind, können nur in diesem Tag verwendet werden, nicht in **[bx:text](/books/cms-handbuch-entwickler/page/bx-text)**.

Die einzige Änderung besteht darin, dass der Titel des Tags "loopTitel" ist und das Eingabefeld in der Administration eine Größe von 40 Zeichen hat.

<bx:titel/>
Batix-Tags Referenz

bx:tools

Das Tag tools vereint kleine Hilfen, um häufig auftretende Aufgaben zu vereinfachen.

Hilfsmittel für Requestparameter

tools.request

<bx:tools.request name="{param}" />
<bx:tools.request name="{param}" [value="{text}"] [not]> Inhalt </bx:tools.request>

Es wird ein Request-Parameter ausgegeben oder dieser ausgewertet.

Die erste Form gibt den Inhalt von <param> aus, falls vorhanden. In der zweiten Form wird der Tag-Inhalt nur ausgegeben, wenn der Request-Parameter existiert, oder, falls zusätzlich "value" angegeben ist, einen bestimmten Wert enthält. Die Bedingung ist mit not umkehrbar. Eine vergleichbare Funktion beinhaltet bx:pagedata.

tools.listrequest

<bx:tools.listrequest [include="{filter}" | exclude="{filter}"] />

Alle Parameter aus dem Request werden als Formularfelder vom Typ "hidden" in die Seite geschrieben. Falls nur bestimmte Request-Parameter ausgegeben (include) oder bestimmte Parameter ausgeschlossen (exclude) werden sollen, können diese als Komma-getrennte Liste angegeben werden (z.B.: include="artikelID,kundenID").

tools.querystring

<bx:tools.querystring [include="{filter}" | exclude="{filter}"] />

Diese Funktion wandelt alle Request-Parameter in einen QueryString um. Falls nur bestimmte Request-Parameter umgewandelt (include) oder bestimmte Parameter ausgeschlossen (exclude) werden sollen, können diese als Komma-getrennte Liste angegeben werden (z.B.: exclude="counter,index").

Kodierung (Encodings)

tools.htmlencode

<bx:tools.htmlencode> Inhalt </bx:tools.htmlencode>

Der Tag-Inhalt wird HTML-kodiert. Wenn man nur < > & " encoden möchte, muß man <bx:tools.xmlencode> nehmen. Es werden folgende Ersetzungen vorgenommen:

Originalwert ausgegebener Wert
< &lt;
> &gt;
" &quot;
& &amp;
' &#039;
äöüÄÖÜß§€,
deutsche Anführungszeichen unten und oben
und langen Bindestrich
alles ab
ASCII-Code
128
zu "&#[code];"

tools.urlencode

<bx:tools.urlencode [charset="{set}"]> Inhalt </bx:tools.urlencode>

Es wird eine URL-Kodierung des Tag-Inhalts vorgenommen. Mit dem Parameter charset kann eine andere Zeichenkodierung angegeben werden (Standard ist "iso-8859-1"). Es wird java.net.URLEncoder benutzt.

tools.urlpathencode

<bx:tools.urlpathencode [charset="{set}"]> Inhalt </bx:tools.urlencode>

Zum Kodieren von Pfadbestandteilen (z. B. Dateiname). Führt ein URL-Encoding des Tag-Bodys aus. Mit dem Parameter 'charset' kann ein anderes Encoding angegeben werden (Standard=iso-8859-1). Zum encoden wird URLEncoder.encode(String, String) verwendet.

tools.entityencode

<bx:tools.entityencode> Inhalt </bx:tools.entityencode>

Es werden alle Zeichen mit einem ASCII-Code > 127 (0x80) in die Form &#nnn; gebracht, wobei nnn für den ASCII-Code in dezimaler Schreibweise steht. Ab v2.5.9 werden auch eventuelle Steuerzeichen (0x00-0x1F) entfernt.

tools.xmlencode

<bx:tools.xmlencode> Inhalt </bx:tools.xmlencode>

Dieses Tag führt zunächst ein .htmlencode aus und lässt das Ergebnis nochmals durch .entityencode laufen. * Ab v2.5.9 werden auch eventuelle Steuerzeichen (0x00-0x1F) entfernt.*

tools.removectrlchars

<![CDATA[<bx:tools.removectrlchars> Inhalt mit seltsamen Zeichen </bx:tools.removectrlchars>]]>

Dieses Tag entfernt eventuelle Steuerzeichen (0x00-0x1F, außer Tab und Zeilenumbruch). Das Ergebnis kann dann innerhalb eines CDATA-Blocks verwendet werden (ab Version 2.5.9).

tools.html2plain

<bx:tools.html2plain> Inhalt </bx:tools.html2plain>

Der Inhalt wird zunächst durch .htmlencode umgewandelt, danach werden folgende Ersetzungen vorgenommen:

Originalwert ausgegebener Wert Originalwert ausgegebener Wert
\r nichts \n Leerzeichen
<br> \r\n <br /> \r\n
<BR> \r\n <p> \r\n\r\n
<sonstige Tags> nichts &nbsp; Leerzeichen
&uuml; ü &Uuml; Ü
&auml; ä &Auml; Ä
&ouml; ö &Ouml; Ö
&szlig; ß &quot; " (gerade Anführungsz. oben)
&lt; < &gt; >
&amp; & &bdquo; " (dopp. Anführungsz. unten)
&ldquo; " (dopp. Anführungsz.oben) &#150; - (Breite n)
&hellip; ... &ndash; - (Breite n)
&euro; &acute; ´
&rsquo; ' &sect; §

Zuletzt wird noch eventueller Whitespace am Anfang und Ende des Textes entfernt.

tools.plain2html

<bx:tools.plain2html> Inhalt </bx:tools.plain2html>

Wandelt den plain-Text im body in HTML-Code um, indem er HTML encoded wird und bei jeden Zeilenumbruch ein
oder
gesetzt wird

Wirkungsweise

<bx:tools.plain2html>Erste Zeile Zweite Zeile Dritte Zeile Vierte Zeile Fünfte Zeile</bx:tools.plain2html>

Wird zu

«Erste Zeile<br> Zweite Zeile<br> Dritte Zeile<br> Vierte Zeile<br> F&uuml;nfte Zeile»

tools.csvfield

<bx:tools.csvfield> Inhalt </bx:tools.csvfield>

Der Text wird mit " umgeben und allen " im Text wird ein zusätzliches " vorangestellt. (ab v2.5.9)

tools.scriptencode

<bx:tools.scriptencode> Inhalt </bx:tools.scriptencode>

Diese Funktion dient zum Encoden eines Textes, damit dieser direkt als String in JavaScript verwendet werden kann. (ab v2.5.9)

Originalwert ausgegebener Wert
\n \\n
\r \\r
" \"
' \'
\t \\t

Zusätzlich wird jeder Backslash (), der nicht zum Escapen verwendet wird (also nicht vor folgenden Zeichen steht: n r t " ') verdoppelt.

tools.scripteventencode

<bx:tools.scripteventencode > Inhalt </bx:tools.scripteventencode >

Hier wird ein String so encoded, dass er direkt als Event-Code für ein HTML-Element festgelegt werden kann. (ab v2.5.9)

Originalwert ausgegebener Wert
\n \\n
\r \\r
& &amp;
" &quot;
' \'
\t \\t
\ \\

tools.umlautencode

<bx:tools.umlautencode > Inhalt </bx:tools.umlautencode >

Deutsche Umlaute werden hier in die Schreibweise mit normalen Buchstaben überführt. (ab v2.5.9)

Originalwert ausgegebener Wert
ß ss
Ä Ae
ä ae
Ö Oe
ö oe
Ü Ue
ü ue

tools.mysqlencode

<bx:tools.mysqlencode>Gasthaus 'Zur Tanne'</bx:tools.mysqlencode>

Escaped einige Zeichen, die für SQL-Injections verwendet werden könnten. (ab v2.5.9) Beispiel im Quellcode: wird in Gasthaus \'Zur Tanne\' umgewandelt

tools.mysqlencodeall

... WHERE KEYWORDS LIKE '%<bx:tools.mysqlencodeall><bx:pagedata.request name="suche"></bx:tools.mysqlencodeall>%' ...

Escaped einige Zeichen, die für SQL-Injections verwendet werden könnten (auch % und _). (ab v2.5.9) Dies ist zur Verwendung in einem SQL-LIKE-Befehl gedacht (siehe Quellcode) Das %-Zeichen ist im LIKE ein Platzhalter für beliebig viele Zeichen. Ohne diesen Befehl würde z. B. im LIKE-Ausdruck WHERE Feld LIKE '100%' alles gefunden werden, das mit "100" beginnt.

Sonstige Tools

tools.lastmodified

<bx:tools.lastmodified [pattern="{format}"] />

Gibt Datum/Zeit der letzten Änderung des aktuellen Menüpunktes aus (Meta-Wert "dataPublished" oder "contentPublished"). Das Format der Ausgabe lässt sich über pattern steuern (Standard ist "dd.MM.yyyy HH:mm").

tools.positiontracker

<bx:tools.positiontracker [boundary="{text}"] [showall] [startlevel="{n}"] />

Für Breadcrumb. Es wird ein Position-Tracker in die Seite geschrieben. Die übergeordneten Menüpunkte werden jeweils mit einer entsprechenden Anzahl von "../" verlinkt.

boundary Text zwischen den einzelnen Ausgaben (Standard-Wert ist " >> ")
showall auch inaktive
Hauptmenüpunkte
werden ausgegeben
startlevel Angabe, wenn in einem anderen Level gestartet werden soll (Hauptmenü = Level 0)

Beispiele

<bx:tools.positiontracker boundary=" | " startlevel="1"/>

Ausgabe der Menüpunkte ab der 2. Ebene, Trenner ist ein Pipe-Zeichen zwischen zwei Leerzeiche.

tools.datum

<bx:tools.datum [show="{month-begin | month-end}" |
                [year="{mod}"] [month|month1="{mod}"] [day="{mod}"] [hour="{mod}"] [minute="{mod}"] [second="{mod}"]]
                [locale="{lang}"] [pattern="{format}"] />

Dieses Tag kann benutzt werden, um das aktuelle oder ein bestimmtes Datum auszugeben. Das Datum kann auch manipuliert werden (siehe bei bx:recordfield) Achtung: Monate laufen von 0-11

show month-begin: 1. des aktuellen Monats (0.00.00) month-end: letzter des aktuellen Monats (23.59.59)
ohne Angabe von show: jetzt
year
month
day
hour
minute
second
mit diesen Parametern kann ein Datum manipuliert werden n: das entsprechende Feld wird auf den Wert n gesetzt +n: das entsprechende Feld wird um den Wert n erhöht -n: das entsprechende Feld wird um den Wert n verringert
locale Sprachformatierung (z.B. "de" oder "en_US")
locale sollte immer angegeben werden, da sonst die Standardeinstellung vom Server genutzt wird, die sich aber nach Updates oder Umzügen ändern kann.
month1 wie bei month, aber beginnt nicht bei 0 sondern bei 1, d.h. bei month1="1" wird Januar und nicht Februar ausgegeben
pattern legt die
Formatierung des Datums
fest (Standard ist "dd.MM.yyyy")

Beispiele

<bx:tools.datum/>									<-- "heute", z.B. 08.06.2014 -->
<bx:tools.datum pattern="d. MMM yy HH:mm:ss"/>		<-- "jetzt" wird ausgegeben, z.B. 3. Feb 12 13:42:55 -->
<bx:tools.datum show="month-end" pattern="dd"/>		<-- Tag des Monatsende vom aktuellen Monat, z.B. beim Aufruf im Februar: 28 -->
<bx:tools.datum lang="en_US"/>						<-- Ausgabe von "heute" im US-Format, z.B. 2001-07-04 -->
xml
<bx:tools.datum month="+1" day="1"/> 							<-- nächster Monats-Erster -->
<bx:tools.datum month=+1 day=1 hour=-24"/>						<-- Monatsletzter   --> 
<bx:tools.datum day="+7"/>										<-- in einer Woche -->
<bx:tools.datum day="-1" hour="12" minute="0" second="0"/>		<-- gestern Mittag -->
<bx:tools.datum year="-1" month="11" day="31"/>					<-- Silvester letztes Jahr -->

tools.timeframe

<bx:tools.timeframe after="{zeit}" before="{zeit}" week="{bits}" [not] [now={...}]> Inhalt </bx:tools.timeframe>

Zeigt den Inhalt an, wenn die aktuelle Serverzeit in einem bestimmten Rahmen liegt. Wenn before kleiner als after ist, wird der Uhrzeitbereich außerhalb der Angaben verwendet (ab v2.6.8. - vorher wäre es nie ausgeführt worden, weil keine Uhrzeit vor 7 und nach 20 Uhr sein kann)

after wird im 24h-Format angegeben (HH:mm)
before wird im 24h-Format angegeben (HH:mm)
week Angabe als eine sogenannte Bitmaske, d.h. jede Stelle steht für einen Tag.
So steht z.B. "1111100" für
nur werktags
oder "1010100" für
montags, mittwochs, freitags
.
not zur Umkehrung der Uhrzeitangaben. Es beeinflußt nur die Uhrzeit und nicht den Parameter '
week
'
now Mit dem Parameter now kann man eine andere Uhrzeit testen, ohne bis zu dieser Uhrzeit warten zu müssen. (siehe Beispiel 3)

Beispiele

Beispiel 1

<bx:tools.timeframe after="06:00" before="18:00" week="1000000">Wir haben geöffnet.</bx:tools.timeframe>

Inhalt wird nur Montags von 6.00 bis 18.00 Uhr angezeigt.

Beispiel 2

<bx:tools.timeframe before="6:00" after="18:00">Wir haben geschlossen.</bx:tools.timeframe>

entspricht: <bx:tools.timeframe not before="18:00" after="6:00">

Beispiel 3

<bx:tools.timeframe after="22:00" now="7.3.2018 22:01">Bettruhe!!!</bx:tools.timeframe>

tools.for / tools.forchar

<bx:tools.for start="{n}" end="{n}" [inkrement="{n}"]> Inhalt </bx:tools.for>	<!-- für Zahlen -->
<bx:tools.forchar start="{zeichen}" end="{n}"> Inhalt </bx:tools.forchar>		<!-- für Buchstaben -->

Dieses Tag führt den Inhalt einer Schleife mehrfach aus und ersetzt jedesmal einen Platzhalter durch eine laufende Nummer. Im Inhalt des Tags können dann "{i}" und "{ii}" verwendet werden (ii = vorangestellte 0, wenn kleiner als 10)

start Startet bei angegebener Zahl
bzw. angegebenem Zeichen (z.B.
a
)
end Endet bei angegebener Zahl bzw. angegebenem Zeichen (z.B. z)
inkrement der Wert, um den erhöht werden soll (Standard: 1)
falls
start
>
end
ist, muss hier eine negative Zahl eingetragen werden!

Beispiele

<bx:clipboard.cut name="anzTage"><bx:tools.datum show="month-end" pattern="dd"/></bx:clipboard.cut>
<select>
  <bx:tools.for start="1" end="clipboard:anzTage">
    <option value="{ii}">{i}</option>
  </bx:tools.for>
</select>

Die Tage des aktuellen Monats (Anzahl wurde vorher mit bx:tools.datum ermittelt und in einem Clipboard zwischengespeichert) werden in einem Drop-Down ausgegeben (value mit vorangestellter 0, wenn unter 10)

Ergebnisse finden beginnend mit:<br>
|
<bx:tools.forchar start="A" end="Z">
  <a href="suche.act?init={i}">{i}</a>|
</bx:tools.forchar>

tools.for-split

<bx:tools.for-split source="[Daten]" regex="[Trenner]" clipboard="[key]" attribute="[key]" placeholder="[Platzhalter]"> Auswertung mit [Platzhalter] </bx:tools.for-split>

Dieses Tag führt den Inhalt einer Schleife mehrfach aus und ersetzt jedesmal einen Platzhalter durch eine laufende Nummer. Im Inhalt des Tags können dann "{i}" und "{ii}" verwendet werden (ii = vorangestellte 0, wenn kleiner als 10)

source Quelle
regex Angabe des Trenners, z.B. Komma, Leerzeichen oder Semikolon
clipboard Wert kann wird im Clipboard gespeichert
attribute Wert kann wird im Request-Attribute gespeichert
placeholder Es kann ein anderer Platzhalter definiert werden, ansonsten lautet der Platzhalter {i}

Beispiele

<bx:tools.for-split source="Hallo Welt" regex=" "> :{i}: </bx:tools.for-split>

ergibt " :Hallo: :Welt: "

<bx:clipboard.cut name="idliste">AAA,BBB,CCC</bx:clipboard.cut>
<bx:tools.for-split source="clipboard:idliste" regex="," clipboard="einzelneID">
<bx:record id="clipboard:einzelneID">
 ... <bx:recordfield...> ... 
</bx:record>
</bx:tools.for-split>

tools.random

<bx:tools.random/>												<-- zufälliger double-Wert zwischen 0 und 1, ca. 15 Nachkommastellen -->
<bx:tools.random max="{zahl}"/>									<-- zufälliger int-Wert zwischen 0 und {zahl} -->
<bx:tools.random chance="{zahl}"> [Inhalt] </bx:tools.random>	<-- zeigt den Inhalt mit der Wahrscheinlichkeit von {zahl} Prozent an (1≤{zahl}≤99) -->

Dieser Befehl zeigt eine Zufallszahl an bzw. zeigt einen Inhalt mit einer bestimmten Wahrscheinlichkeit an.

tools.randstring

<bx:tools.randstring [length={len}] [lower] [upper] [num] [alphanum] [extra] [extra2] [all] />

Dieser Befehl erzeugt einen zufälligen String aus bestimmten Charakter-Klassen. Dies ist z.B. für Passwortgenerierung nützlich.

Es muss mindestens eine Charakter-Klasse angegeben werden.

length Länge des zu erzeugenden Strings (Standard 12 Zeichen)
lower Kleinbuchstaben a-z
upper Großbuchstaben A-Z
num Ziffern 0-9
alphanum lower + upper + num
extra ! ? - _ ( ) + * \ / | $ ~ # @
extra2 < > { } [ ] " § % & ' ^ ° ; . : =
all alphanum + extra + extra2

Beispiele

<bx:tools.randstring length=10 alphanum/>

Es wird ein Paßwort mit 10 Zeichen erzeugt, das Groß- und Kleinbuchstaben sowie Zahl enthält.

tools.uuid

<bx:tools.uuid />

Hiermit wird eine zufällige UUID (Typ 4) erzeugt (z.B. f3910a2f-63cf-433b-8117-1ac0d22bb4f5).

tools.id

<bx:tools.id />

Dieses Tag erzeugt eine neue Batix-ID und gibt diese aus (z.B. 12E241E47CB).

Fehlersuche (Debugging)

tools.showrequest

<bx:tools.showrequest/>

Erzeugt eine Debug-Ausgabe des Request-Typs sowie sämtlicher Parameter, die im Request enthalten sind.

tools.duration

<bx:tools.duration save="{name}"/>
<bx:tools.duration show="{name"/>

Erzeugt eine Debug-Ausgabe der Bearbeitungszeit einer im Aufbau befindlichen Seite.

save Anfang der Zeitmarke wird gesetzt
Durch die Benennung sind mehrere Zeitmarken möglich
show verstrichene Zeit seit save wird angezeigt (in Sekunden mit 3 Nachkommastellen) Weitere show-Tags liefern fortlaufende Messungen.

Beispiele

<html>
  <head></head>
  <body>
    ... Quelltext ...
    <bx:tools.duration save="dauer1"/>
    ... komplizierte SQL ...
    Verarbeitungsdauer SQL1: <bx:tools.duration show="dauer1"/>
    <bx:tools.duration save="dauer2"/>
    ... zu vergleichende SQL ...
    Verarbeitungsdauer SQL2: <bx:tools.duration show="dauer2"/>
    ... Quelltext ...
  </body>
</html>

Für beide SQL-Aufrufe wird die Ausführungszeit gemessen und ausgegeben - ein direkter Vergleich ist möglich.

tools.log

<bx:tools.log level="{stufe}" [copy]>zu loggender Text</bx:tools.log>

Schreibt den Inhalt in die Logdatei, anstatt in die Seite.

level Logstufe
error
,
warn
,
info
oder
debug
Standard:
info
copy Text soll auch auf der Seite angezeigt werden

Beispiele

<bx:tools.duration save="dauer"/>
... aufwändige Filterungen ...
<bx:tools.log>Verarbeitungsdauer: <bx:tools.duration show="dauer"/></bx:tools.log>

Die Zeit, die die "aufwändige Filterung" braucht, wird in die Log-Datei geschrieben

Zeichenketten-Funktionen

tools.replacetext

Ersetzen-Modus
<bx:tools.replacetext regex="<ausdruck>" replacement="<text>"> Inhalt </bx:tools.replacetext>

Es wird nach bestimmten Ausdrücken im Tag-Inhalt gesucht und diese werden durch den gewünschten Text ersetzt. Es wird die Java-Methode String.replaceAll verwendet, dadurch ergeben sich vielfältige Möglichkeiten.

regex regulärer Ausdruck, nach dem im Text gesucht werden soll
replacement Ersetzungs-Text

Beispiele

<bx:tools.replacetext regex="World" replacement="Batix">Hello, World!</bx:tools.replacetext>

Hier wird aus "Hello, World!" der Text "Hello, Batix!"

<bx:tools.replacetext regex="(.+?),(.+?),(.+?)" replacement="Wert 2=$2; Wert 1=$1; Wert 3=$3">
  Alice,123,ABC
</bx:tools.replacetext>

Umwandeln von CSV-Daten: Das Ergebnis wäre hier der Text "Wert 2=123; Wert 1=Alice; Wert 3=ABC".

<bx:clipboard.cut name="temp"><a href="$1">$1<a></bx:clipboard.cut>
<bx:tools.replacetext regex="(http://[^\ ]+)" replacement="clipboard:temp">
  Einen Text mit http://einer.url/zu/einem Text mit einem Link machen.
</bx:tools.replacetext>

Um in einen Text mit einer URL einen Link um die URL einzufügen: Das bx:clipboard wird benötigt, weil im replacement-Parameter die Zeichen ", < und > nicht verwendet werden können. ab v2.5.9

*Allgemeine Hilfe und Beispiele zu regulären Ausdrücken gibt es u.a. auf http://www.regular-expressions.info (englisch). *

Schleifen-Modus
<bx:tools.replacetext regex="<ausdruck>" source="<quelle>">
  Inhalt
</bx:tools.replacetext>

Durch die Angabe von source schaltet das Tag in den Schleifen-Modus. Hierbei wird der Tag-Inhalt für jeden Match ausgeführt. Ausgaben, die im Tag-Inhalt erfolgen werden ignoriert (stattdessen kann ein Clipboard geschrieben werden, um den Match zu modifizieren). Es werden Informationen (Match-Index, Match-Gruppen) über Clipboards bereitgestellt, der gematchte Text kann so auch ersetzt / verändert werden.

Folgende Clipboards werden pro Durchlauf gesetzt:

Clipboard-Name Beschreibung
replacetext_match Der komplette gematchte String.
In dieses Clipboard kann im Tag-Inhalt auch geschrieben werden, die gematchte Textstelle wird nach jedem Durchlauf mit dem Inhalt dieses Clipboards ersetzt.
replacetext_index Laufende Nummerierung der Matches, beginnend bei Null.
Im ersten Durchlauf steht also "0" im Clipboard, danach "1", usw..
replacetext_group_<n> <n> ist eine Zahl
Für jede Gruppe des Regexes (mit runden Klammern umschlossen) werden die gematchten Textstellen pro Durchlauf in nummerierte Clipboards gepackt, wobei - wie bei Regex üblich - replacetext_group_0 noch mal den kompletten Match enthält, replacetext_group_1 die erste Gruppe, replacetext_group_2 die zweite usw..

Man kann sich den Tag-Inhalt wie eine Funktion vorstellen, die pro Match aufgerufen wird: Parameter werden über die Clipboards übergeben, der Rückgabewert läuft auch über ein Clipboard (replacetext_match).

Beispiele

Batix Quelltext:

<bx:clipboard.cut name="zutaten" trim>
300#g#Mehl
5##Eier
150#ml#Milch
</bx:clipboard.cut>
<bx:tools.replacetext regex="(\d+)#([^#]+)?#(.*)" source="clipboard:zutaten">
  1 = Anzahl
  2 = Einheit
  3 = Zutat
  <bx:clipboard.cut name="replacetext_match">
    Zutat <bx:clipboard.paste name="replacetext_index" />:
    <bx:clipboard.paste name="replacetext_group_3" />
    (<bx:clipboard.paste name="replacetext_group_1" />
    <bx:clipboard.paste name="replacetext_group_2" />)
    <br>
  </bx:clipboard.cut>
</bx:tools.replacetext>

Ausgabe:

Zutat 0: Mehl (300 g)
Zutat 1: Eier (5 )
Zutat 2: Milch (150 ml)

Erkärung:

replacetext_match 300#g#Mehl
replacetext_index 0
replacetext_group_0 300#g#Mehl
replacetext_group_1 300
replacetext_group_2 g
replacetext_group_3 Mehl

tools.uppercase

<bx:tools.uppercase> bring mich gross raus </bx:tools.uppercase>

Wandelt alle Buchstaben im Body in Großbuchstaben um und gibt diese aus.

tools.lowercase

<bx:tools.lowercase> jetzt werd ich ganz klein </bx:tools.lowercase>

Wandelt alle Buchstaben im Body in Kleinbuchstaben um und gibt diese aus.

tools.substring

<bx:tools.substring maxlength="{Zahl}" [startindex="{Zahl}"] [fillbefore="{ein Zeichen}" | fillafter="{ein Zeichen}"]>

Schneidet aus dem übergebenen Tagbody den durch Indexpositionen angegebenen Bereich heraus und gibt nur diesen zurück.

maxlength muß mindestens 1 sein
startindex Stelle, ab wann der Substring herausgelöst werden soll (startet mit 0)
Standard: 0 (bei Fehlen des Parameters)
fillbefore
fillafter
optionales Füllzeichen (keine Entity)
wenn Text kürzer ist als bei
maxlength
angegeben, wird er mit dem angegeben Zeichen aufgefüllt

Beispiele

<bx:tools.substring maxlength="5" startindex="6">Hello World</bx:tools.substring> 

Gibt "World" aus

<bx:tools.substring maxlength="5" fillbefore="0">7318</bx:tools.substring>

 gibt "07318" aus (wenn z. B. PLZ als Zahl gespeichert ist und demzufolge nur 4 Ziffern hat)

bx:tools.trim

<bx:tools.trim [lines] [spaces] [single-line]> Inhalt </bx:tools.trim>

Entfernt alle Whitespace-Zeichen (Zeilenumbrüche, Leerzeichen, Tabulator) am Anfang  und Ende des inneren Bereiches

lines reduziert mehrfache Zeilen zu einem Einzelnen (siehe Beispiel)
spaces  reduziert mehrfache Leerzeichen zu einem einzelnen
single-line entfernt alle Zeilenumbrüche und schreibt alles leerzeichengetrennt in eine Zeile

Beispiele

<bx:tools.trim lines>   Hallo

 

 

          Welt

                         </bx:tools.trim>

reduziert mehrfache Zeilenumbrüche zu einem Einzelnen würde also nur „Hallo“ und darunter „Welt“ schreiben

tools.absoluteurl

<bx:tools.absoluteurl> Pfadangabe </bx:tools.absoluteurl>

Erzeugt aus dem relativen URL-Pfad im Tag-Body eine absolute URL und schreibt sie anstelle des Tags in die Seite.

Beispiele

<bx:tools.absoluteurl>../test.htm</bx:tools.absoluteurl>

Im Beispiel würde das Tag in der Seite durch eine URL "http[s]://{hostname}/www/{pfad}/test.htm" ersetzt werden, die auf die Seite test.htm im übergeordneten Menüpunkt verweist.

tools.rooturl

<bx:tools.rooturl> Pfadangabe </bx:tools.rooturl>

Erzeugt aus dem relativen URL-Pfad im Tag-Body eine absolute URL und schreibt einen absoluten Pfad beginnend mit "/" anstelle des Tags in die Seite.

Beispiele

<bx:tools.rooturl> ../test.htm</bx:tools.rooturl>

Im diesem Beispiel würde das Tag in der Seite durch eine URL "/www/{pfad}/test.htm" ersetzt werden, die auf die Seite test.htm im übergeordneten Menüpunkt verweist.

Batix-Tags Referenz

bx:userdata

Das Tag userdata gibt seinen Inhalt abhängig vom Status des angemeldeten Benutzers aus (z.B. für Intranetbereiche).

userdata.in/userdata.login

<bx:userdata.in> Inhalt </bx:userdata.in>
<bx:userdata.login> Inhalt </bx:userdata.login>

Inhalt wird nur ausgeführt, wenn der User eingeloggt ist.

userdata.out/userdata.logout

<bx:userdata.out> Inhalt </bx:userdata.out>
<bx:userdata.logout> Inhalt </bx:userdata.logout>

Inhalt wird nur ausgeführt, wenn der User ausgeloggt ist.

userdata.id

<bx:userdata.id />

Die ID des Benutzers wird zurückgegeben.

userdata.name

<bx:userdata.name />

Der vollständige Name (Anrede + Vorname + Nachname) wird ausgegeben.

userdata.email

<bx:userdata.email />

Die Email-Adresse des Users wird ausgegeben.

userdata.isintrauser

<bx:userdata.isintrauser [not]> Inhalt </bx:userdata.isintrauser>

Der Inhalt wird ausgeführt, wenn der Benutzer ein bzw. kein Intranetuser ist. Er wird nicht ausgeführt, wenn der Benutzer nicht eingeloggt ist oder einen höheren Status als Intranetuser besitzt. not kehrt die Funktionalität um, d.h. nur Intranetusern wird der Inhalt vorenthalten.

userdata.ismember

<bx:userdata.ismember groupid="{ID}" [nosv] [not]> Inhalt </bx:userdata.ismember>

Dieses Tag prüft, ob der Benutzer einer bestimmten Gruppe angehört. Supervisoren werden automatisch als gruppenzugehörig erkannt. Falls kein Benutzer angemeldet ist, wird "nicht angemeldet" angezeigt.

groupid einzelne Gruppen-ID oder eine Liste von IDs, getrennt durch Komma
nosv Supervisoren werden nicht als gruppenzugehörig erkannt
not kehrt Bedingungen um.

userdata.issupervisor

<bx:userdata.issupervisor [not]> Inhalt </bx:userdata.issupervisor>

Wird ausgeführt wenn User ein Supervisor ist bzw. wenn er kein Supervisor ist. Es wird nie ausgeführt, wenn kein User eingeloggt ist. (ab v2.5.8)

userdata.isbatix

<bx:userdata.isbatix [not]> Inhalt </bx:userdata.isbatix>

Block wird ausgeführt, wenn User ein Batix-Wartungszugang ist bzw. wenn nicht. Es wird nie ausgeführt, wenn kein User eingeloggt ist.

userdata.issystemadmin

<bx:userdata.issystemadmin [not]> Inhalt </bx:userdata.issystemadmin>

Block wird ausgeführt, wenn User ein System-Supervior ist bzw. wenn nicht. Es wird nie ausgeführt, wenn kein User eingeloggt ist.

userdata.username

<bx:userdata.username/>

Gibt den Username des angemeldeten Benutzers zurück.

userdata.meta

<bx:userdata.meta name="{metaname}" />															<!-- Wert der Metaeigenschaft wird ausgegeben (falls vorhanden) -->
<bx:userdata.meta name="{metaname}" [value="{wert}"] [not]> Inhalt </bx:userdata.meta>			<!-- Bedingung: Inhalt wird getestet -->

Dieser Befehl gibt Metadaten des angemeldeten Benutzers aus oder zeigt Inhalte abhängig von Metadatenwerten an. Falls der Benutzer nicht angemeldet ist, zeigt das Tag nichts an.

name Name der Metaeigenschaft
ohne value: Ob Metaeigenschaft überhaupt vorhanden ist
value Vergleichswert der Megaeigenschaft. Bei Übereinstimmung wird Inhalt ausgewertet
ohne value: Ob Metaeigenschaft überhaupt vorhanden ist
not kehrt die Bedingung um
Batix-Tags Referenz

bx:userrecord

Das Tag userrecord erzeugt eine Schleife aus den Datensätzen einer Liste, in denen ein Wert der ID des angemeldeten Users entspricht. Ist kein Benutzer angemeldet, macht dieses Tag nichts.

Vergleich mit einem Feld im Container

<bx:userrecord pool="{id}" field="{feld}" [dummy]> Inhalt </bx:userrecord>
<bx:userrecord pool="{id}" field="{feld}" [type="id"] [seperator="{,}{;"][dummy] />

Hier wird der Inhalt des Datensatz-Feldes <feld> mit der UserID verglichen - aber ACHTUNG! keine BC-Verknüpfung sondern ein Textfeld, wo die ID drin steht. Falls kein Inhalt angegeben wurde, wird der Titel des Datensatzes ausgegeben.

Ab V 2.7.0: Das Feld "field" kann auch eine BC-Verknüpfung sein.

pool ID des Containers
field BC-Verknüpfungs-Feld (das die ID des eingeloggten Users enthalten kann)
dummy falls kein User angemeldet ist oder kein passender Datensatz gefunden wurde,
wird ein Dummy-Datensatz angezeigt
type="id" Ausgabe der DS-IDs
seperator="," Trenner zwischen den IDs (siehe Beispiel)

Beispiele

<bx:userrecord pool="Merkliste" field="BC" type="id" separator="," orderby="Nachname" desc />

Alle dem User zugeordneten Datensatz-IDs aus Merkliste mit Komma getrennt in die Seite schreiben

<bx:userrecord pool="Mitarbeiter" field="BC" type="id" />

Vom erstbesten (und hoffentlich einzigen) Datensatz aus Mitarbeiter, dem der eingeloggte User zugeordnet ist, die Datensatz-ID in die Seite schreiben

(mit zusätzlichen orderby kann man auch den ersten im Alphabet oder mit desc den Neuesten nehmen)

Vergleich mit einer Metaangabe im Datensatz

<bx:userrecord pool="{id}" name="{meta}" [dummy]> Inhalt </bx:userrecord>
<bx:userrecord pool="{id}" name="{meta}" [dummy] />

Falls kein Inhalt angegeben wurde, wird der Titel des Datensatzes ausgegeben.

pool ID des Containers
name erhält hier den Name eines Meta-Wertes der Datensätze,
dessen Inhalt wird dann mit der UserID verglichen.
dummy falls kein User angemeldet ist oder kein passender Datensatz gefunden wurde,
wird ein Dummy-Datensatz angezeigt

Beispiele

Eingeloggt als: <bx:userrecord pool="Mitarbeiter" name="mitarbeiterID"><bx:recordfield.Vorname/> <bx:recordfield.Name/></bx:userrecord>

Im Datensatz des Containers "Mitarbeiter" gibt es eine Meta-Angabe namens "mitarbeiterID", in der die Datensatzid des Users steht.

Datensatzid als Metaangabe beim User gespeichert

<bx:userrecord pool="..." meta="..." [dummy]>...</bx:userrecord>

Der Container-Datensatz, dessen ID im Meta-Wert 'meta' des Users steht oder nichts falls dort keine ID steht.

Beispiele

Eingeloggt als: <bx:userrecord pool="Mitarbeiter" meta="mitarbeiterID"><bx:recordfield.Vorname/> <bx:recordfield.Name/></bx:userrecord>

Beim User gibt es eine Meta-Angabe namens "mitarbeiterID", in der die Datensatzid des zugehörigen Datensatzes im Container "Mitarbeiter" steht.

Batix-Tags Referenz

bx:validation

Das Tag validation kann Fehlermeldungen einer Containervalidation auswerten und so die Anzeige von Fehlertexten möglich machen. Es ist verfügbar ab Version 2.5.8

validation.error

<bx:validation.error field="{feldname}" data="{validationsfeldname}" [code="{n}"]> ... </bx:validation.error>

Dieser Befehl zeigt den Body des Tags an, wenn das angegebene Feld im Validations-Fehlerfeld aufgelistet ist.

field: Name des zu prüfenden Feldes

data: Feldname im Container, wo die Validierung als xml gespeichert ist

code: zu prüfender Fehlercode. Es gibt folgende Fehlertypen:

validation.haserror

<bx:validation.haserror data="{validationsfeldname}" [not]> ... </bx:validation.haserror>

Zeigt den Body an, wenn im Validationsfeld Fehler gelistet sind. Bei Verwendung von not wird der Body angezeigt, wenn keine Fehler gelistet sind.

validation.errorcount

<bx:validation.errorcount data="{validationsfeldname}" />

Gibt die Anzahl der Validationsfehler aus.

Batix-Tags Referenz

bx:websearch

Dieses Tag ermöglicht die Darstellung von Suchergebnissen der Webseite. Die Suche ist über die Funktionen des Jakarta Lucene Projektes realisiert worden. Das Web muss vorher indiziert worden sein. Zum Ausklammern von Bereichen aus der Suche verwendet man bx:scanner

Eingabefeld

<bx:websearch.input />

Es wird ein Text-Inputfeld erzeugt, welches in Suchformularen verwendet werden kann. Falls schon eine Suche stattgefunden hat, enthält das Feld den Suchtext.

Hauptschleife

<bx:websearch [max="{n}"] [maxparam="{paramname}"] [indexparam="index"]> Inhalt </bx:websearch>

Dieses Tag bildet die Hauptschleife um die Suchergebnisse. Zur Verwendung im Inhalt stehen die nun folgenden Tags bereit.

Bisher mußte der Blätterparameter „index“ heißen. Und bei den Containerfiltern (Teasern) in der Seite mußte man indexparam auf etwas anderes setzen. Nun kann der Parametername selbst definiert werden. <bx:websearch.previous|next|firstshown|lastshown> lesen den neuen Parameter von der <bx:websearch>-Schleife und verlinken jetzt mit diesen Namen.

max maximale Anzahl an Ausgaben
maxparam Request-Parameter, der den Zahlenwert für den Überlauf enthält
* (ab Version 2.5.9)*
indexparam Name des Blätterparameters

websearch.title

<bx:websearch.title/>

gibt den Titel der Seite (<title> HTML-Tag) oder, falls dieser nicht existiert, "<ohne Titel>" aus

websearch.rank

<bx:websearch.rank/>

Rangfolge des Ergebnisses, beginnend mit 1

websearch.score

<bx:websearch.score/>

die Wertung des Suchergebnisses als Gleitkommazahl

websearch.relevanz

<bx:websearch.relevanz/>

eine Wertung des Ergebnisses als Ganzzahl mit Prozentzeichen

websearch.stars

<bx:websearch.stars [max="<n>"]> Inhalt </bx:websearch.stars>

Symbole als Relevanzanzeige ausgeben

max maximale Anzahl an Symbolen (Standard: 5)
Der Inhalt bestimmt das Symbol, er kann z.B. ein
bx:bild
-Tag enthalten
<bx:websearch.link> Inhalt </bx:websearch.link>
<bx:websearch.link />

verlinkt den Inhalt mit der Fundstelle. Als geschlossenes Tag wird die URL verlinkt (ab Version 2.5.9)

websearch.url

<bx:websearch.url/>

gibt die URL der Fundstelle an. ab Version 2.5.8

websearch.path

<bx:websearch.path/>

gibt den Pfad zur Fundstelle an. Es handelt sich um die URL, deren Hostname abgeschnitten wurde. ab Version 2.5.9

websearch.description

<bx:websearch.description/>

die Beschreibung des Dokuments (HTML <meta> Wert "description")

websearch.navname

<bx:websearch.navname/>

der Name des entsprechenden Navigationspunktes

websearch.navid

<bx:websearch.navid/>

die ID des entsprechenden Navigationspunktes

websearch.previous

<bx:websearch.previous [hide] [url="{link}"] />
<bx:websearch.previous [hide] [url="{link}"]> Linktext </bx:websearch.previous>

(steht außerhalb der Schleife) einen Link zur vorigen Ergebnisseite generieren

hide es wird nichts ausgegeben wird, wenn es keine nächste Seite gibt
url Ziel-Dateiname festlegen (Standard ist die aktuelle Seite)
Linktext Ein Linktext kann als Tag-Inhalt angegeben werden (Standard: "weiter >>").

websearch.next

<bx:websearch.next [hide] [url="{link}"] />
<bx:websearch.next [hide] [url="{link}"]> Linktext </bx:websearch.next>

(steht außerhalb der Schleife) einen Link zur nächsten Ergebnisseite generieren Parameter: siehe unter websearch.previous

websearch.totalhits

<bx:websearch.totalhits/>

(steht außerhalb der Schleife) Gesamtzahl der Ergebnisse

websearch.firstshown

<bx:websearch.firstshown/>

(steht außerhalb der Schleife) Nummer des ersten Ergebnisses auf der Seite

websearch.lastshown

<bx:websearch.lastshown/>

(steht außerhalb der Schleife) Nummer des letzten Ergebnisses auf der Seite

websearch.query

<bx:websearch.query encode="typ"/>

(steht außerhalb der Schleife) der Begriff/Text, nach dem gesucht wurde

encode Hiermit kann der ausgegebene Text für verschiedene Formate kodiert werden:
- html - javascript - sql (zur Verwendung in SQL für Strings) - sql-like (zur Verwendung in SQL mit LIKE) - sql-rlike (zur Verwendung in SQL mit RLIKE und REGEXP) - url - xml

websearch.if

<bx:websearch.if [not] [empty | scrollable | morethan="<n>" | lessthan="<n>"] > Inhalt </bx:websearch.if>

(steht außerhalb der Schleife) zeigt Inhalt nur unter bestimmten Bedingungen an. Nur, wenn Suche bereits stattgefunden hat: (Falls keiner der vier Parameter angegeben wurde, erfolgt die Ausgabe nur, wenn bereits eine Suche erfolgt ist (oder auch nich, bei not). )

empty es wurden keine Suchergebnisse gefunden
darf auch innerhalb der Schleife verwendet werden. Um das Gegenteil abzufragen, wird
not
verwendet.
scrollable es sind mehr Seiten vorhanden (Anzahl Ergebnisse >
max
)
morethan
lessthan
es wurden mehr als
<n>
Ergebnisse gefunden
es wurden weniger als
<n>
Ergebnisse gefunden

Eingabefeld

<bx:websearch.input />

Es wird ein Text-Inputfeld erzeugt, welches in Suchformularen verwendet werden kann. Falls schon eine Suche stattgefunden hat, enthält das Feld den Suchtext.

Beispiele

<bx:tag.feature param="value" />

Weitere Beispiele unter Snippets/Websuche.

Batix-Tags Referenz

bx:xml

Ab Version 2.6.8

Mit dem Tag bx:xml können XML Strukturen ausgelesen und einfach durchgegangen werden. Um schnell in tief verschachtelte Objekte zu gelangen, kann GPath genutzt werden.

XML laden

<bx:xml data="[1, 2, 3]">...</bx:xml>
<bx:xml data="clipboard:xml_data">...</bx:xml>
<bx:xml url="http://server/..." [encoding="utf-8"]>...</bx:xml>

Das XML-Dokument kann entweder direkt als Text übergeben werden (wobei der Umweg über ein Clipboard oder Attribut möglich ist), es kann aber auch eine URL angegeben werden, von der die Daten geladen werden (encoding gibt dabei an, mit welchem Zeichensatz die Daten eingelesen werden, Standard ist utf-8).

Im URL-Modus sendet das XML-Tag nicht das Session-Cookie mit, da meist externe URLs aufgerufen werden und die SESSIONID nicht ausversehen preisgegeben werden soll.

Falls die Daten von einem internen, geschützten Menüpunkt geladen werden (auf den der aktuell eingeloggte Benutzer Zugriff hat), kann <a href="http://docs.batix.info/display/DEVS/bx:jspinclude" target="_blank">bx:jspinclude</a> verwendet werden - dieses schickt das Session-Cookie mit:

<bx:clipboard.cut name="xml_data"><bx:jspinclude>/intern/api.xml</bx:jspinclude></bx:clipboard.cut>
<bx:xmln data="clipboard:xml_data">
  ...
</bx:xml>
```</p>

Ist in den XML-Daten ein Objekt kodiert, kann dieses mit geschachtelten xml-Tags durchgegangen werden; ein Array über gleichnamige Tags kann simuliert werden.

Eine fortgeschrittenere Möglichkeit des Daten-Ladens, kann über das Attribut `application` realisiert werden. Hier gibt man den Name eines Application-Attributes an, in dem eine `Node` oder `NodeList` gespeichert ist. Dieses wird dann vom Tag benutzt und es entfällt das String-Parsen. Dies ist nützlich bei Caches, die man global in der Application vorhalten kann, und die sich nicht oft ändern. Ein entsprechendes Objekt kann z.B. mittels Groovys `XmlParser` erzeugt werden.

## XML durchgehen

Die XML-Struktur kann einfach via Tags durchgegangen werden:

```xml
<bx:xml data="..."> <!-- Root-Tag -->
  <bx:xml.Kunde> <!-- Sub-Tag -->
    Der Kunde heißt: <bx:xml.Vorname /> <bx:xml.Nachname />
    <bx:xml field="address_home">
      Er wohnt in: <bx:xml.Ort />
    </bx:xml>
  </bx:xml.Kunde>
</bx:xml>

Tag-Attribute können via @ angesprochen werden:

<!-- XML-Daten -->
...<age underage="false">18</age>...
 
<!-- Attribut age abfragen -->
...
<bx:xml.age@underage bool>Zutritt verboten!</bx:xml.age@underage>
...

Es ist jeweils die Angabe von [encode=...](/books/cms-handbuch-entwickler/page/encodings-uebersicht) möglich, um z.B. Ausgaben für URLs oder CSV zu encoden.

Das auszugebende Feld kann entweder im Tag-Titel (nach bx:xml., also im Beispiel "Kunde") oder im Parameter field="" (oben z.B. "address_home") angegeben werden. Die Angabe via field ist nötig, falls der Feldname Sonderzeichen / Leerzeichen enthält.

Wird versucht auf ein Feld zuzugreifen, das nicht existiert, wird nichts ausgegeben. Es kann alternativ via dummy ein Alternativwert (als komplettes XML-Tag) angegeben werden, der stattdessen genommen wird.

<bx:clipboard.cut name="xmldummy">
  <object>
    <some></some>
    <item></item>
  </object>
</bx:clipboard.cut>
<bx:xml.missingObject dummy="clipboard:xmldummy">
  <bx:xml.some />
</bx:xml.missingObject>

Da XML-Tags (sowohl Root-Tags als auch Sub-Tags) mehrfach verschachtelt sein können und man manchmal Sachen von Über-Über-...-Elementen ausgeben will, kann man via Tag-Titel oder name die Tags benennen und via base diese referenzieren (der Parameter name hat beim Suchen des passenden Parent-Tags Vorrang vor dem Tag-Titel). Das entspricht der Funktionalität von baseloop bei Containern. Mittels base="$" kann das Root-Tag referenziert werden (das Tag, bei dem die Daten geladen wurden). Die Angabe von base kann immer zusätzlich zu allen anderen Parametern erfolgen (z.B. können base und path gleichzeitig benutzt werden).

<bx:xml data="..."> <!-- Root-Tag -->
  <bx:xml.Sub>
    <bx:xml.SubSub name="Kunde">
      <bx:xml.SubSubSub>
        <bx:xml.Feld base="Sub">
          <!-- selber Kontext, als wenn man direkt innerhalb von <bx:xml.Sub> wäre -->
        </bx:xml.Feld>
        <bx:xml.Feld base="Kunde">
          <!-- selber Kontext, als wenn man direkt innerhalb von <bx:xml.SubSub> wäre -->
        </bx:xml.Feld>
        <bx:xml.Feld base="$">
          <!-- selber Kontext, als wenn man direkt innerhalb des Root-Tags wäre -->
        </bx:xml.Feld>
      </bx:xml.SubSubSub>
    </bx:xml.SubSub>
  </bx:xml.Sub>
</bx:xml>

Je nach Datentyp muss ein entsprechender Parameter im bx:xml-Tag übergeben werden, da XML an sich keine Datentypen kennt (Schemas werden nicht unterstützt):

Null

Der Inhalt wird ausgeführt (oder nicht bei not), falls im XML das gesuchte Feld nicht vorhanden ist. Es wird hier auch der Spezialtyp nil einer XML-Schema-Instanz beachtet.

<! -- Feld in XML nicht enhalten oder als nil mit korrektem Namespace markiert -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <mynull xsi:nil="true" />
</root>
 
<bx:xml.Feld null>Feld war nicht vorhanden oder nil</bx:xml.Feld>
<bx:xml.Feld null not>Feld war vorhanden und nicht nil</bx:xml.Feld>

Boolean

Boolesche Werte können ähnlich wie Häkchenfelder im Container abgefragt werden. Eine kurze Version (geschlossenes Tag) mit truefalse steht auch zur Verfügung.

<bx:xml.Condition bool [not]>
  ...
</bx:xml.Condition>
 
<bx:xml.Condition bool [true=""] [false=""] />

Um dem booleschen Wert true zu entsprechende, muss der Feldwert einer der folgenden Strings sein:

Number

Zahlen (mit und ohne Dezimalstellen) können via num angesprochen werden. Das Tag erwartet als Dezimaltrenner einen Punkt. Die Angabe von comma bewirkt, dass vorher ein Komma im Feldwert durch einen Punkt ersetzt wird.

ausgeben / formatieren

Zahlen können formatiert ausgegeben werden. Ist kein pattern angegeben, werden Ganzzahlen ohne und Kommazahlen mit Nachkommastellen ausgegeben. Der Tausender- und Dezimal-Trenner kann mittels gs bzw. ds spezifiziert werden. Der Rundungsmodus ist standardmäßig HALF_UP (normales kaufmännisches Runden) und kann via rounding geändert werden (siehe Java-Docs für mögliche Werte). ).

<bx:xml.Zahl num [comma] [pattern=""] [locale=""] [gs=""] [ds=""] [rounding=""] />

 locale sollte immer angegeben werden, da sonst die Standardeinstellung vom Server genutzt wird, die sich aber nach Updates oder Umzügen ändern kann.

vergleichen

Folgende Vergleiche sind möglich:

Parameter ausgeführter Vergleich
equals ==
gt >
gte >=
lt <
lte <=

Das Ergebnis kann jeweils mit not umgekehrt werden. Für alle Vergleiche ist auch eine verkürzte Variante mit truefalse möglich (hier wird der jeweilige Wert von true oder false ausgegeben).

<bx:xml.Zahl num [comma] [equals=""] [gt=""] [gte=""] [lt=""] [lte=""] [not]>
</bx:xml.Zahl>
 
<bx:xml.Zahl num [comma] [equals=""] ... [true=""] [false=""] />

Date

Über den Tag-Parameter date wird der vorhande String-Wert im Feld als Datum interpretiert.

Eingabeformat

Ist lediglich date ohne weiteren Wert im Tag angegeben, werden einige Standard-Patterns unterstützt:

<bx:xml.mydate date />

Es wird folgende Liste in dieser Reihenfolge durchprobiert:

Alternativ kann ein eigenes Pattern angegeben werden:

<bx:xml.mydate date="dd/MM/yyyy" />

Es muss nicht der gesamte String matchen. Möchte man z.B. aus dem Wert "20.08.2018 um 08:50" nur das Datum ziehen, genügt das Pattern dd.MM.yyyy.

Ausgabeformat

Standardmäßig wird das geparste Datum anhand des Patterns dd.MM.yyyy HH:mm:ss ausgegeben. Es kann auch ein eigenes Pattern angegeben werden:

<bx:xml.mydate date pattern="dd.MM. HH:mm" />

Werden z.B. Tages- oder Monatsnamen ausgegeben, wird über locale die gewünschte Sprache eingestellt:

<bx:xml.mydate date pattern="EEEE, d. MMMM" locale="de" />

Datum/Zeit modifizieren

Durch die Angabe von verschiedenen Parametern können alle Teile des Ausgangsdatums angepasst werden. Es kann eine Zahl angegeben werden, um den entsprechenden Wert absolut zu setzen. Dabei kann dieser Zahl ein Plus (+) oder Minus (-) vorangestellt werden, um die Modifikation stattdessen relativ durchzuführen. Die möglichen Parameter sind (werden auch in dieser Reihenfolge angewandt):

Etwaige Überschreitungen (z.B. +15 Monate) werden entsprechend weiter gezählt (also +1 Jahr und 3 Monate).

Beispiel (Tag auf den 15. Februar setzen, zwei Stunden dazu zählen, zehn Jahre abziehen):

<bx:xml.mydate date day="15" month="2" hour="+2" year="-10" />

Mögliche Werte beim Wochentag sind dabei folgende Werte (keine Zahlen erlaubt):

Es wird auf den entsprechenden Wochentag in der gleichen Woche gewechselt. Auch hier gibt es die Möglichkeit ein Plus oder Minus voranzustellen, dann wird entsprechend auf den Tag in der nächsten bzw. vorherigen Woche gewechselt.

Trifft der angegebene Wochentag bereits auf das Ausgangsdatum zu, wird das Datum nicht geändert. Dieses Verhalten kann durch Angabe eines doppelten Plus (++) oder Minus (--) überschrieben werden (es wird dann auch gewechselt, falls der Wochentag schon zutrifft).

Zeitliche Abfrage

Eine weitere Funktion ist die Abfrage, ob das Ausgangsdatum (bzw. das modifizierte Datum) vor oder nach dem jetzigen Zeitpunkt (Zeit auf dem Server) bzw. heute liegt. Der Unterschied ist, dass beim Vergleich mit heute die Uhrzeit nicht beachtet wird, sondern nur der Datumsteil.

Die folgenden Abfragen sind möglich:

Das Tag kann dabei entweder offen (optional noch mit not) oder geschlossen mit den true und/oder false Parametern genutzt werden. Beispiele:

<bx:xml.mydate date before-now>in der Vergangenheit</bx:xml.mydate>
<bx:xml.mydate date after-now not>auch in der Vergangenheit oder genau jetzt</bx:xml.mydate>
 
<bx:xml.mydate date before-today true="vor heute" />
<bx:xml.mydate date after-today false="vor heute oder heute" />
 
<bx:xml.mydate date today true="am heutigen Tag" false="nicht heute" />

String

ausgeben

Im einfachsten Fall wird der String ausgegeben und ggf. automatisch encoded (siehe Encodings für andere Encoding-Möglichkeiten).

<bx:xml.Text />

vergleichen

Strings können auch verglichen werden. Die Angabe von ignoreCase bewirkt, dass Groß-/Kleinschreibung nicht beachtet wird, not kehrt das Ergebnis um.

Parameter Vergleich
matches Vergleich via RegEx (regulärem Ausdruck),
String muss diesem komplett entsprechen
equals Gleichheit
contains der String muss den Wert das Parameters beinhalten

Auch hier ist eine verkürzte Variante mit true und false möglich.

<bx:xml.Text [matches=""] [equals=""] [contains=""] [ignoreCase] [not]>
</bx:xml.Text>
 
<bx:xml.Text [matches=""] [equals=""] [contains=""] [ignoreCase] [true=""] [false=""] />

BatixRecord

Steht in den XML-Daten im Feld eine Batix-ID, so kann hier auch ein Container angebunden werden. Das Tag verhält sich dann wie bx:record, es können innerhalb die normalen Container-Tags wie bx:recordfield oder bx:recorddata benutzt werden. Auch der Zugriff von außerhalb des Tags mit z.B. bx:recorddata.nav ist möglich.

Der Datensatz wird anhand des Feldes ID rausgesucht. Es kann aber auch via linkfield auf ein anderes Feld im Datensatz verwiesen werden (Text oder Einzelverknüpfung), hierbei wird der erste gefundene Datensatz genommen.

Wird kein Datensatz mit entsprechender ID (oder Wert im Feld) gefunden, wird nichts ausgegeben. Die Angabe von dummy bewirkt, dass stattdessen ein leerer Datensatz vorgehalten wird (der Tag-Inhalt wird ausgeführt, innere bx:recordfield-Tags etc. geben aber nichts aus, wie bei [bx:record](/books/cms-handbuch-entwickler/page/bx-record)).

<bx:xml.IDFeld pool="Container" [linkfield=""] [dummy]>
  <bx:recordfield... />
  <bx:recorddata.if... />
</bx:xml.IDFeld >
 
<bx:recorddata.nav object="IDFeld">
  <bx:recorddata.total />
</bx:recorddata.nav>

Array

Gleichnamige XML-Tags können mittels array in einer Schleife durchlaufen werden.

Ein Array funktioniert analog zu z.B. bx:containerfilter, für jedes Element wird der Tag-Inhalt einmal ausgeführt. Das Start-Element kann dabei mittels index (0-basiert) und die maximale Anzahl Durchläufe via max geregelt werden.

Um das aktuelle Element im Durchlauf auszugeben wird einfach <bx:xml /> verwendet. Je nach Datentyp (in Arrays können auch verschiedene Datentypen vorhanden sein) können hier die entsprechenden Parameter und deren Funktionen verwendet werden (z.B. formatierte Ausgabe bei Zahlen).

<!-- XML Teil -->
<Liste>10</Liste>
<Liste>20</Liste>
<Liste>30</Liste>

<!-- durchgehen -->
<bx:xml.Liste array [index="20"] [max="10"]>
  <bx:xml />
</bx:xml.Liste>

Es können die meißten Funktionen von [bx:recorddata](/books/cms-handbuch-entwickler/page/bx-recorddata) verwendet werden:

<bx:xml.Liste array>
  ...
</bx:xml.Liste>
<bx:recorddata.nav object="Liste">
  Gesamt: <bx:recorddata.total/><br>
  <bx:recorddata.navlist max="5">
    ...

Ferner gibt es noch folgende Hilfsmethoden:

<bx:xml.Liste array>
  <bx:xml {first|last} [not]>...</bx:xml> <!-- Inhalt nur ausführen, wenn es das erste oder letzte Element ist -->
  <bx:xml {first|last} [true=...] [false=...] /> <!-- dito, nur verkürzte true/false Schreibweise -->
  <bx:xml index [add="5"] /> <!-- aktuellen Durchlauf-Index ausgeben, ggf. etwas dazu addieren -->
  <bx:xml total /> <!-- Gesamtanzahl der Elemente ausgeben -->
  <bx:xml empty [not]>...</bx:xml> <!-- ausführen, falls das Array leer ist -->
  <bx:xml empty [true=...] [false=...] /> <!-- dito, nur mit true/false -->
  <bx:xml cols=...> <!-- funktioniert wie bx:recorddata.cols -->
</bx:xml.Liste>

Für mehr Informationen zu cols siehe die entsprechende Passage bei bx:recorddata.

Datensätze

Befinden sich im Array Strings, welche Batix-IDs sind, kann mittels pool eine Schleife über Datensätze (wie z.B. bx:containerfilter) aufgemacht werden. Falls die ID in einem anderen Feld steht, kann dies wieder via linkfield referenziert werden. Innerhalb des Xml-Tags sind alle normalen Datensatz-Tags verfügbar. dummy verhält sich im Falle eines leeren Arrays wie ein leerer Datensatz (ansonsten wird der Inhalt nicht ausgeführt).

Falls im Array (zusätzlich) nicht-Strings sind, wird im Log eine Warnung ausgegeben.

<bx:xml.Kunden array pool="Shop_Kunden" [linkfield=""] [dummy]>
  <bx:recordfield... />
  <bx:recorddata.if... />
</bx:xml.Kunden>

Object

Um in ein XML-Objekt tiefer einzusteigen, wird das Xml-Tag (analog zu bx:recordfield bei Verknüpfungen) geschachtelt.

<bx:xml data="...">
  <bx:xml.Kunde>
    <bx:xml.Name />
  </bx:xml.Kunde>
</bx:xml>

Namespaces

Namespaces werden ebenfalls grundlegend unterstützt (es kann nach dem Namespace-Präfix gesucht werden, der Namespace-Identifier (meist eine URI) wird ignoriert). Hierbei muss für den Feldname allerdings field benutzt werden, da der Doppelpunkt sonst Probleme macht:

<!-- XML Teil -->
<nstest>Namespace 0</nstest>
<ns1:nstest>Namespace 1</ns1:nstest>
<ns2:nstest>Namespace 2</ns2:nstest>

ohne: <bx:xml field="nstest" />
1: <bx:xml field="ns1:nstest" />
2: <bx:xml field="ns2:nstest" />
alle: <bx:xmL field="*:nstest" array>...</bx:xmL> <!-- Elemente ohne expliziten Namespace sind nicht enthalten -->

GPath

Mittels GPath-Expressions können relativ einfach verschachtelte Strukturen angesprochen werden. Das erspart lästiges Verschachteln von Xml-Tags.

Operator Bedeutung
* children
** depth-first

Beispiele:

<bx:xml path="mystring" />
<bx:xml path="mystring@name" />
<bx:xml path="mystring.@name" />
<bx:xml path="myobj.name" />
<bx:xml path="myobj.age@underage" />
<bx:xml path="myobj.age.@underage" />
<bx:xml path="**.@title" />
<bx:Xml path="**.@title" array>[<bx:xml />]</bx:Xml>
<bx:Xml path="*.@title" array>[<bx:xml />]</bx:Xml>
<bx:Xml path="myobj.*" array>[<bx:xml />]</bx:Xml>

Actions

Alle Action-Bausteine (39 Seiten).

Actions

Actions – Übersicht

Aktionen realisieren im Zusammenwirken mit Dokumentvorlagen an bestimmten Menüpunkten erforderliche Funktionalitäten - z.B. das Speichern von Formulardaten, das Versenden von Emails, das Anmelden bei einem Newsletter u.v.m.

actions1.jpg

Übersicht

Kategorie Actions
Speicherung Bild hochladen
Containerdaten aus Email importieren
Dokument hochladen
Formulardaten validieren
Container Container kopieren
Container-Filteraction
Containerdaten speichern
Containerdatensatz löschen
Containerinhalt validieren
Validierungsergebnis ausgeben
Benutzer und Zugang Benutzergruppe anlegen
Intranet Login
Intranet Logout
Intranet-User anlegen/ändern
Passwort des angemeldeten Users ändern
Versenden von E-Mails CMS-Seite versenden
Formular als Mail versenden
Ausführung von Code Batix Quelltext ausführen
JSP-Baustein ausführen
Sonstiges Captcha Abfrage
Excel-Action
Sicheres Formular überprüfen (SecureformAction)
Suche im Web
Vorhandene Bedingung abfragen
Weiterleitung
Wert in Session speichern
XHTML 2 PDF
Veraltet Newsletter – Abo abmelden
Newsletter – Abo ändern
Newsletter – Abonnentenlogin
Newsletter aktivieren
Newsletter – Newsletter abonnieren
Newsletter – Passwort vergessen (1)
Newsletter – Passwort vergessen (2)
Shop – Bestellung versenden
Shop – Hinzufügen zu Warenkorb
Shop – Löschen im Warenkorb
Shop – Zusatzgebühr zum Warenkorb

Abgesehen von oben angeführten Actionbausteinen können spezielle individuelle Aktionen unter Voraussetzung entsprechender Kenntnisse problemlos angelegt werden.

Aktionsliste

Wenn Sie den Eintrag Ressourcen->Aktionen anklicken, erhalten Sie etwa folgende Seite im Arbeitsbereich:

image2015-5-28 9:32:45.png

Es werden Ihnen alle momentanen Aktionen mit folgenden Informationen angezeigt:

Details der Aktion

Klicken Sie auf den Titel einer Aktion, um deren Bausteine einzusehen und allgemeine Einstellungen zur Aktion vorzunehmen.

image2015-5-28 9:30:5.png

Hier können Sie:

Neuen Aktionsbaustein anhängen

Um eine neue Aktion anzulegen, klicken Sie - wenn Sie sich in der Übersichtsseite aller Aktionen befinden - auf den Button image2017-1-11 9:24:13.png/image2017-1-11 7:48:54.pngin der Symbolleiste. Hier müssen Sie noch die Felder ausfüllen und die Aktion abspeichern (image2017-1-11 9:23:40.png/image2017-1-11 7:49:23.png). Anschließend werden Sie aufgefordert, einen neuen Aktionsbaustein hinzuzufügen. Klicken Sie auf diese Zeile und Sie sehen folgenden Assistenten:

image2015-5-28 9:25:4.png

Klicken Sie auf den Auswahlbutton neben der gewünschten Aktion und anschließend zum Speichern auf image2017-1-11 9:23:40.png/image2017-1-11 7:49:23.png.

Details des Aktionsbausteins

Hier können Sie:

Actions

Batix Quelltext ausführen

Führt Batix Quelltext aus

Werte können mit bx:pagedata.setscriptattribute an den nächsten Action-Baustein übergeben werden.

<bx:pagedata.setscriptattribute name="<name>"> Inhalt </bx:pagedata.setscriptattribute>

Ausgabe im Log: <bx:tools.log>...</bx:tools.log>

Actions

Benutzergruppe anlegen

Dieses Action erzeugt eine neue Benutzergruppe.

Parameter

groupname Feld mit Gruppennamen
Parametername des Feldes, in dem der Benutzergruppenname steht (nur angeben, wenn Anlegen einer Gruppe)
field-id Parametername des Gruppen-ID-Feldes
Feldname mit dem die Benutzergruppen-ID übergeben wird (nur angeben, wenn Änderung einer Gruppe)
activate Gruppe aktiv schalten, Standard: ja
attribute-groupid Name für neue Gruppen-ID
Attributname, in dem die ID der neuen Gruppe gespeichert werden soll
Actions

Bild hochladen

Diese Aktion verschiebt eine hochgeladene Datei in die Dateiverwaltung. Dabei ist es wichtig, dass im Upload-Formular enctype="multipart/form-data" gesetzt ist.

Parameter

fileparam gibt den Request-Parameter an, der die hochgeladene Datei enthält
folderid falls das Bild in einen bestimmten Ordner der Bildergallerie gespeichert werden soll, kann hier die ID des Ordners angegeben werden
folderparam eine Alternativmöglichkeit um das Bild in einen bestimmten Ordner zu speichern, die ID wird aus dem hier angegebenen Request-Parameter ausgelesen (Standard-Parametername ist "folderid")
folderpath die dritte Möglichkeit zur Angabe des Ordners, hier wird der Name des Ordners angegeben
targetweb um das Bild in ein anderes Projekt/Web zu speichern, hier die ID des Webs angeben
titel mit diesem Parameter kann der Titel des Bildes festgelegt werden
titelparam um den Titel aus einem Request-Parameter auszulesen, hier den Parametername angeben
autor hiermit kann der Autor des Bildes direkt festgelegt werden
autorparam der Autor kann alternativ auch über einen Parameter angegeben werden

Bemerkungen

Bei Werten, die durch verschiedene Parameter festgelegt werden können, gilt folgende Reihenfolge der Überprüfung (es wird dabei abgebrochen, sobald ein Wert gefunden wurde):

In den Metadaten des Bildes werden unter "uploader" und "author" der eingeloggte Benutzer (falls er eingeloggt ist) sowie unter "uploaderIP" die IP des Uploaders eingetragen.

Multi-Upload (ab V 2.6.3)

Mehrere Bilder werden gleichzeitig mit HTML5 über ein Multiupload hochgeladen und in einem verknüpften Container gespeichert. Achtung! Da die Bilder im Hintergrund gespeichert werden, muß es schon einen Eltern-Datensatz geben, d.h., der Upload-Actionbaustein kommt nach dem Speicher-Actionbaustein.

url weiterleitende URL (z. B. zu einem Save-Action)

Beispiel

Detailseite

<form action="send.act" method="post" enctype="multipart/form-data">
  ...
  <input name="Bilder" type="file" multiple>
  <input type="submit">
</form>

Formular bauen, file-input-Feld muß den Parameter multiple haben

Action bauen: der Upload-Actionbaustein kommt nach dem Speicher-Actionbaustein

Angaben beim Upload-Actionbaustein:

Actions

Captcha Abfrage

Diese Aktion prüft, ob der zum CAPTCHA-Bild eingegebene Text korrekt ist. Dazu muß auf der Seite ein Bild mit dem Namen SimpleCaptcha.jpg, das die visuelle Ausgabe enthält, und ein Input-Feld mit name="captcha" eingebunden sein.

Parameter

requestField der Requestparameter, der die Antwort enthält (standardmäßig "j_captcha_response")
successpage die Seite, auf die weitergeleitet wird, wenn die Antwort richtig ist
failpage die URL, die bei falscher Antwort aufgerufen wird
appendRequest gibt an, ob der aktuelle Request an die Folgeseite weitergegeben wird

Ein verfremdetes Bild mit einer Zeichenfolge wird ausgegeben und muß in ein Eingabefeld geschrieben werden.

Quelltext dazu:

<div>
  <img src="/SimpleCaptcha.jpg<bx:pagedata.sessionurl/>" alt="Captcha-Bild">
  <bx:pagedata.request name="fehler" value="1">Die eingegebene Zeichenfolge war nicht korrekt.</bx:pagedata.request>
  <input type="text" name="captcha" value="">
</div>

Die Felder werden anlog des erstellten HTML-Designs ausgefüllt.

Achtung: Wenn das Captcha in einem IFrame verwendet wird, muß beim Bild und bei der Form <bx:pagedata.sessionurl/> angehängt werden.

Beispiel: <form action="save.htm<bx:pagedata.sessenurl/>">...</form>

Actions

CMS-Seite versenden

Eine normale Seite im Projekt wird gelesen und dann als HTML-Email versendet.

Da diese Aktion auf Formular als Mail versenden aufbaut, sind alle dort angegebenen Parameter auch hier verwendbar, mit den unten aufgeführten Änderungen bzw. Neuerungen.

Parameter

mailFrom Die Email-Adresse, unter der die Mail versandt wird. Falls beim Versenden ein Fehler auftritt oder auf diese Mail geantwortet wird, geht bei dieser Adresse eine Email ein. Bei Kontakt könnte hier auch email angegeben werden, dann kann auf diese Mail direkt geantwortet werden (nicht mehr verwenden). Besser ist jedoch Reply-To (Beschreibung ganz unten) zu verwenden.
mailFromName Der im Email-Programm angezeigte Absendername (auch möglich z.B. [[Name]] [[Vorname]])
mailTo Der Empfänger der Email
subject Der Betreff der Mail
file Der virtuelle Dateiname des zu versendenden HTML-Designs
appendRequest gibt an, ob der Request, welcher der Aktion übergeben wurde, an die URL der CMS-Seite angehängt werden soll (wenn diese z.B. eine ID enthält)

Datei anhängen

Um Email-Anhänge zu erzeugen kann an einer beliebigen Stellen des Email-Templates der Platzhalter für den Anhang hinzugefügt werden.

Die Syntax ist folgende:

<![ATTACHMENT[Dokument-ID]]>

oder

<![ATTACHMENT[Anhang-Dateiname|URL für Anhangsdaten]]>

Um die Anhänge zu parsen muß im Action bei weitere Eigenschaften eine Einstellung eingetragen werden.

parse-attachments=true

Beispiel

<![ATTACHMENT[<bx:pagedata.request name="pdf" />]]>

wenn die Dokument-ID mit dem Request-Parameter "pdf" übergeben wird

<![ATTACHMENT[export_<bx:tools.datum/>.css|exporttemplate.txt]]>

wenn die Ausgabe des Templates namens exporttemplate.txt aus dem selben Navigationspunkt als Anhang mit aktuellen Datum im Namen sesendet werden soll.

<bx:containerfilter.Sammlung pool="..." max="10">
 <![ATTACHMENT[<bx:recordfield.Dokument type="id"/>]]>
</bx:containerfilter.Sammlung>

Hängt alls gefilterten Dokumente des Containers an die Mail an.

Reply-To

Ein Reply-To Header kann im Freieingabe-Feld gesetzt werden (ganz unten: Freigabe weiterer Eigenschaften):

reply-to=[[Kontakt_Mail]] 
Actions

Container-Filteraction

Mit diesem Action kann man einen Container nach bestimmten Filter-Kriterien durchsuchen und darauf reagieren.

Parameter

list die ID der Datenliste (Container), die gefiltert werden soll (Pflichtfeld)
xml die Definition des Filters (Pflichtfeld)
url die für jeden gefundenen Datensatz aufgerufene URL. Das kann ein weiteres Action sein, z.B. ein Speicheraction. (Pflichtfeld)
Kann auch frei gelassen werden, wenn der Filter nur auf Erfolg oder Mißerfolg prüfen soll, z.B. ob eine bestimmte E-Mail schon vorhanden ist oder nicht.
Test-Modus (für Entwicklung gedacht) Im Testmodus werden keine URLs ausgeführt, die Actionausführung wird nach dem Action abgebrochen und stattdessen eine Infoseite angezeigt, auf der aufgelistet wird, welche Urls ausgeführt würden.
emptyresulturl eine URL die nur dann ausgeführt wird, wenn keine URL im Filter ausgeführt wurde. Die Ausführung erfolgt im Hintergrund, z.B. wenn eine bestimmte Email noch nicht angelegt ist, dann kann sie damit angelegt werden und die Action-Abfolge wird nicht unterbrochen.
successurl wenn ausgefüllt und mindestens eine URL ausgeführt wurde, wird die Ausführung nach diesen Action abgebrochen und an die angegebene Seite weitergeleitet.
failurl wenn ausgefüllt und keine URLs ausgeführt wurden, wird die Ausführung nach diesen Action abgebrochen und an die angegebene Seite weitergeleitet.
request-method falls der Request mittels POST geschickt werden soll, muss dieser Parameter den Wert POST enthalten

spezielle Platzhalter bei successurl und failurl

(ab v2.6) bei "weiteren Eigenschaften" können Parameter definiert werden, die statistische Werte in Actionattribute mit den dort definierten Namen schreiben:

record-counter-param=filterdurchläufe Anzahl der DS, die durch die Filterung gekommen sind
processed-counter-param=versuche Anzahl der URL-Aufrufe, es fallen evt. DS weg z.B. durch bx:if
success-counter-param=erfolge Anzahl der erfolgreichen URL-Aufrufe
error-counter-param=fehler Anzahl der nicht erfolgreichen URL-Aufrufe, aufgerufene Seite/Action bringt Fehler

In anschließenden Actions kann auf die Werte über den angegebenen Name in eckigen Klammer zugegriffen werden (z.B. auswertung.htm?anzahl=[[anzAufruf]]&fehler=[[anzFehler]] )

diese Werte kann man dann z. B. im Success-URL-Feld benutzen:

erfolg.htm?report=[[versuche]]+Datensaetze+verarbeitet,+davon+[[fehler]]+mit+Fehlern

oder z. B. auch in einem folgenden Weiterleitungsaction oder Saveaction

Bemerkungen

In der URL können Batix-Tags benutzt werden, z.B. bx:pagedata um der Aktion übergebene Parameter weiterzuleiten oder bx:recordfield bzw. bx:recorddata um Informationen zum aktuellen Datensatz zu übergeben.

Die Parameter der URL müssen selbst URL-Encoded werden. Dazu kann man <bx:tools.urlencode>Text</bx:tools.urlencode> benutzen.

Im URL-Feld können beliebig Zeilenumbrüche und Leerzeichen gesetzt werden, um den Code entwicklerfreundlich zu formatieren. In der ausgeführten URL werden diese Zeichen vorher entfernt. Leerzeichen, die in Parametern übergeben werden sollen, müssen vorher kodiert werden.

Actions

Container kopieren

Diese Aktion kopiert Daten aus einem Container in einen anderen. Felder mit gleichen Namen und Typ werden automatisch übernommen. Für weitere Felder kann über eine Konfiguration eine Zuordnung geschaffen werden. Über solch eine Konfigurationseinstellung können auch mehrere Felder in ein Feld hineinkopiert werden.

Funktionen:

Parameter

source-listid gibt die ID der Quell-Liste an
target-listid dies ist die ID der Ziel-Liste
idfield der Name des Request-Parameters, der die ID des zu kopierenden Datensatzes enthält
config die Kopierzuordnung in XML

Auf die ID des erzeugen Kopie-DS kann man in einem weiteren Actionbaustein über das Action-Attribute copyrecord zugreifen.

Weitere Eigenschaften: include-child-lists=true (es werden die Untercontainer mit kopiert - wie in der Verwaltung - ab V2.6.6) attribute-recordid=copyrecord (es kann statt copyrecord für die ID des neuen DS ein anderer Name definiert werden)

XML-Syntax

Die Syntax der Kopierzuordnung folgt diesem Muster:

<rules>
  <field name="Titel" source="Name"/>
  <field name="Datum"><![CDATA[<bx:recordfield.Datum_Beginn pattern="dd.MM.yyyy"/><bx:if> - <bx:recordfield.Datum_Ende pattern="dd.MM.yyyy"/></bx:if>]]></field>
  <field name="Alter"><![CDATA[<bx:pagedata.request name="neuesAlter"/>]]></field>
  <field name="Kategorie/Titel" source="Titel"/>
</rules>
name Feldname des Zielfelds
source Feldname des Quellfelds
<![CDATA[...]]> zu speichernder Inhalt als Tag-Inhalt
es können auch Tags wie bx:recordfield verwendet werden
Feld/Unterfeld Unterelemente einer Einzelverknüpfung ansprechen

Beispiele

Die XML Datei hat folgendes Format:

Beispiel Titel

<rules>
  <field name="Datum" source="Datum_Beginn"/>
  <field name="Flat_Ausgabe"><![CDATA[
Beschreibung:
<bx:recordfield.Beschreibung type="plain"/>
Bemerkungen:
<bx:recordfield.Bemerkungen type="plain"/>
]]></field>
  <field name="Kategorie" source="Kategorie/Titel"/>
  <field name="Zeitstempel" source=""/>
</rules>

Das Haupt-Tag heißt <rules>. Dazwischen dürfen beliebig viele <field>-Einträge stehen, die das Pflicht-Attribut name haben müssen, das den Feldnamen des Zielcontainers enthält.

Bei geschlossenen <field/>-Tag muß in einem Parameter source der Name des Feldes im Quellcontainer angegeben werden. Mit "/" kann auch ein Feld hinter einer Einzelverknüpfung aufgerufen werden.

Wenn ein Feld aus dem Quellcontainer nicht übernommen werden soll, kann bei name der Feldname und source="" angegeben werden. (Hier im Beispiel würde nicht der Inhalt des Timestamp-Feldes des Quellcontainers kopiert werden und so ein aktueller Timestamp im Zielcontainer erstellt werden)

Wenn <field> geöffnet wird, können Batix-Tags benutzt werden, um den Inhalt von Textfeldern im Zieldatensatz aus mehreren Feldern des Quelldatensatzes zusammenzusetzen. An <bx>-Tags können nur einige verwendet werden, z. B. bx:pagedata um der Aktion übergebene Parameter weiterzuleiten oder bx:recordfield bzw. bx:recorddata um Informationen zum aktuellen Datensatz zu übergeben. Der Inhalt sollte in einem CDATA-Block eingeschlossen sein, wenn er XML-Sonderzeichen (z. B. "<", "&") enthalten könnte.

Actions

Containerdaten aus Email importieren

Diese Aktion speichert Container- und Untercontainerdatensätze. Die nötigen Daten werden von einem Mail-Server abgerufen.

singlemode wenn gewählt wird mit jedem Aufruf der Aktion nur eine Mail gelesen, ansonsten alle
pop3server der Server, von dem die Mails geholt werden
username der Benutzername zur Anmeldung am Server
password das Passwort zum Benutzername
delmail sollen gelesene Mails gelöscht werden?
listid ID des Containers, in den die Daten gespeichert werden sollen
recordidfield Name des Tags, der die ID eines vorhandenen Datensatzes enthält (Standard ist "recordid")
dokumentContainerId ID des Containers, in den die der Mail angehängten Dateien gespeichert werden sollen
dokumentFolder ein Request-Parameter, der angibt, in welches Verzeichnis der Dateiverwaltung, die in der Mail angehängten Dateien gespeichert werden sollen, kann auch als Eigenschaft der Aktion festgelegt werden mittels documentFolder
documentField Name des Feldes im Dokument-Container, dem die Datei zugewiesen werden soll
nextpage auf diese Seite wird nach Fertigstellung weitergeleitet, diese URL kann auch im Request-Parameter backfile stehen
active gespeicherten Datensatz aktivieren?
timestamp gibt ein Feld an, in dem der Bearbeitungszeitpunkt des Imports im Container festgehalten werden kann

weitere Eigenschaften:

appendrecordid falls gesetzt, gibt diese Eigenschaft den Parameter an, über den der Folgeseite die ID des gespeicherten Datensatzes mitgeteilt wird
targetweb um die Daten in ein anderes Web zu speichern, hier die ID des Webs angeben
Actions

Containerdaten speichern

iese Aktion speichert einen Containerdatensatz, dessen Felder im Request übergeben wurden.

Funktionen:

Parameter

nextpage auf diese Seite wird nach Fertigstellung weitergeleitet, diese URL kann auch im Request-Parameter backfile stehen
active soll der erzeugte Datensatz aktiviert werden?
appendrecordid der Name eines zusätzlichen Parameters, welcher der Folgeseite übergeben wird und die ID des erzeugten Datensatzes enthält
listid ID der Liste, in die der neue Datensatz gespeichert wird
recordidfield der Name des Parameters, der die ID des zu überschreibenden Datensatzes enthält
timestamp der Name eines Datum-Feldes, in dem der Zeitpunkt der Erstellung festgehalten wird
createnew gibt an, ob ein neuer Datensatz erstellt werden darf (nur wenn keine recordid übergeben wurde)

weitere Eigenschaften:

update-active=j
update-active=n
Datensatz aktivieren oder deaktivieren
es ist auch möglich den Wert via Platzhalter zu übergeben:
update-active=[[paramName]]
ein leerer oder nicht vorhandener Parameter führt zur Deaktivierung
log-meta=false speichert keine MetaDaten (erstellt bzw. letzte Änderung)

Bemerkungen

Durch bestimmte Name und Verwendung der Request-Parameter kann der Ablauf dieser Aktion beeinflusst und angepasst werden.

Möchte man einen Datensatz aktivieren bzw. deaktivieren, so ist der Request-Parameter "activ" mit dem Wert "j" bzw."n" zu übergeben.

einfaches Feld speichern

Hier entspricht der Name des Parameters dem Feldname. Veraltet: Bei Verknüpfungen werden "Name.LINKLIST" und "Name.LINKRECORD" verwendet.

Mehrfachverknüpfung

Um bei einer Mehrfachverknüpfung einzelne DS hinzufügen oder löschen zu können, wir Name.MODE angegeben (set, add oder delete).

Beispiel

Aus Hobby-Liste entfernen:
  <form action="save.act" method="post">
    <input type="hidden" name="Hobbies.MODE" value="delete">
    <bx:recordfield.Hobbies>
      <input type="checkbox" name="Hobbies" value="<bx:recorddata.id/>"> <bx:recordfield.Titel/>
    <bx:recordfield.Hobbies>
  </form>

Weitere Hobbies hinzufügen:
  <form action="save.act" method="post">
    <input type="hidden" name="Hobbies.MODE" value="add">
    <bx:containerfilter.Hobbies pool="Hobbies" force="list" orderby="Titel">
      <input type="checkbox" name="Hobbies" value="<bx:recorddata.id/>"> <bx:recordfield.Titel/>
    </bx:containerfilter.Hobbies>  
  </form>

Checkbox: Wert "unchecked" speichern

Um den Zustand einer Checkbox in einem Wahrheitswert zu speichern, erstellt man ein hidden-Field für den nein-Wert, das den Name der Checkbox.CHECKBOX hat. Beispiel: <input type="checkbox" name="agb" value="j"><input type="hidden" name="agb.CHECKBOX" value="n">

Radiobox: Wert "null" in einem Wahrheits-Feld speichern

Um den Zustand null - also nicht ja und nicht nein - zu speichern, gibt man als Wert "#null" an. Beispiel: <input type="checkbox" name="feldname" value="#null">

in Untercontainer speichern

Es kann "Untercontainerfeld/Feld" verwendet werden, um Felder in einem Untercontainer anzusprechen. Ein bestimmter Untercontainer kann über seine ID angesprochen werden: "Untercontainerfeld.UNTERCONTAINERID/Feld". Es können auch mehrere DS auf einen Rutsch in Untercontaienr gespeichert werden: "Untercontainerfeld.new-n/Feld"

Beispiele

Beispiel Titel

<bx:containerfilter.Firmen pool="Firmen">
  <bx:recordfield.Telefonnummern>
    <input type="text" name="Telefonnummern.<bx:recorddata.id/>/Nummer" value="<bx:recordfield.Nummer/>">
  </bx:recordfield.Telefonnummern>
</bx:containerfilter.Firmen>

Untercontainer "Telefonnummern" im Container "Firmen", speichern von Änderungen in einem Rutsch

mehrere Datensätze speichern

Um mehrere Datensätze zu ändern kann "DATENSATZID/Feld" benutzt werden.

mehrere Datensätze erstellen

Weiterhin können mit einer Aktion mehrere Datensätze angelegt werden, die Parameter müssen dann wie folgt benannt werden: "new-n/Feld", wobei "n" durch eine Zahl ersetzt wird (also z.B. "new-1/Titel" und "new-2/Titel").

Verknüpftes Bilder in einem Bild-Field wieder löschen

Beispiele

Beispiel Titel

<form>
  <input type="file" name="bild" value="">
  <input type="checkbox" name="bild.archivid" value="">
</form>

Feld wird mit dem Checkbox-Inhalt überschrieben.

Actions

Containerdatensatz löschen

Es wird ein bestimmter Datensatz mitsamt allen Feldern und Untercontainern gelöscht.

Parameter

table die ID der Liste, aus der ein Datensatz gelöscht werden soll
nextpage auf diese Seite wird nach Fertigstellung weitergeleitet, diese URL kann auch im Request-Parameter backfile stehen
ID-Field der Request-Parameter, der die ID des zu löschenden Datensatzes enthält (Standard ist "recordid")
Actions

Containerinhalt validieren

Diese Aktion liest einen Datensatz aus einem Container und validiert ihn anhand von Kriterien.

Funktionen:

Parameter

idfield der Request-Parameter, der die ID des Datensatzes enthält
list die Liste, aus welcher der Datensatz entnommen wird (Container-ID oder Containername)
config die Validierungsregeln
alternativ auch Dateiname, wo die Regeln drin stehen

XML-Syntax der Validierungsregeln

<model>
	<bind nodeset="Name" index="alias" required="true()" match="..." constraint="..." type="xsd:anyURI"/>
	<bind nodeset="Feld1" required="Feld2 = 'Wert'"/>
	<bind nodeset="Location" .../>
</model>

Es kann auch ein Pfad angegeben werden, wo dann die Regeln hinterlegt sind (für mehr Flexibilität, da kann man die Regeln im Container speichern oder so)

nodeset gibt das Feld im Container an, welches validiert werden soll
index ist ein Bezeichner für diesen Test (beliebiger Text)
required required="true()" - Feld muß gefüllt sein

required="Feld2 = 'Wert'" - Feld muß in Abhängigkeit eines anderen Feldwertes gefüllt sein. Wichtig sind die Leerzeichen vor und nach dem = . Allerdings keine Leerzeichen vor und nach Feldname bzw. Wertangabe.
match kann einen regulären Ausdruck enthalten (für einzeilige und mehrzeilige Textfelder)
constraint kann eine Bedingung angegeben werden, die der Feldinhalt erfüllen muß (z.B. ". > 18:00", zur Zeit "< >" für Datumsangaben, "< > =" für Zahlen und "=" für einzeiligen Text)
type gibt den xsd-Typnamen an (zur Zeit noch nicht unterstützt)

Beispiele

Feld muß gefüllt sein

...
<bind nodeset="Zaehlernummer" required="true()"/>
...

Die Zählernummer (z.B. eines Stromanschlusses) muß immer angegeben werden (im Container muß im entsprechenden Textfeld etwas stehen).

Feld muß in Abhängigkeit eines anderen Feldwertes gefüllt sein

...
<bind nodeset="Zaehlernummer" required="Neuanschluß = false"/>
...

Die Zählernummer muß angegeben werden, wenn im Formular das Häkchen bei "Neuanschluß" nicht gesetzt wurde (im Container angelegtes Häckchenfeld darf nicht angehakt sein).

Feld muß in Abhängigkeit eines anderen Feldwertes gefüllt sein

...
<bind nodeset="Zaehlernummer" required="Neuanschluß = 'nein'"/>
...

Gleiches Beispiel wie oben, nur daß das Feld "Neuanschluß" ein Textfeld ist und das Wort "nein" drin steht.

E-Mail-Validierung

...
<bind nodeset="Email" index="2" match="^[_a-zA-Z0-9-](\.{0,1}[_a-zA-Z0-9-])*@([_a-zA-Z0-9-]{2,}\.){0,}[_a-zA-Z0-9-]{3,}(\.[_a-zA-Z]{2,4}){1,2}$"/>
...

Der im Feld "Email" gespeicherte Wert muß dem angegebenen Regex ensprechen (dieser Regex ist nur einer von vielen).

Datum prüfen

...
<bind nodeset="Geburtsdatum" index="2" constraint="Geburtsdatum < #today"/>
...

Das Geburtsdatum muß vor heute liegen.

constraint

Mit constraint werden Gültigkeitsbedingungen des Feldinhalts angegeben. Diese sind je nach Typ des Feldes unterschiedlich. Der Wert im Parameter constraint muß folgende Form haben:

<bind nodeset="..." constraint="{Containerfeld} {Operator} {Vergleichswert}" />

Wichtig sind die Leerzeichen, die die 3 Werte trennen.

Hier ist die Liste der unterstützten Bedingungen, geordnet nach Feldtyp:

Textfelder (einzeilig, mehrzeilig)

{Vergleichswert}: Gültig sind:

{Operator}:

Datumsfelder

{Vergleichswert}

{Operator}

Zahlenfelder

{Vergleichswert}

{Operator}

Häkchenfelder (Wahrheitswert)

{Vergleichswert}

{Operator}

Verknüpfungen, Untercontainer

werden in Version 2.5.8 noch nicht unterstützt

Actions

Dokument hochladen

Diese Aktion verschiebt ein hochgeladenes Dokument in die Dateiverwaltung. Dabei ist es wichtig, dass im Upload-Formular enctype="multipart/form-data" gesetzt ist.

Funktionen:

fileparam gibt den Request-Parameter an, der die hochgeladene Datei enthält
folderid falls das Dokument in einen bestimmten Ordner der Dokumentenverwaltung gespeichert werden soll, kann hier die ID des Ordners angegeben werden
folderparam eine Alternativmöglichkeit um das Dokument in einen bestimmten Ordner zu speichern, die ID wird aus dem hier angegebenen Request-Parameter ausgelesen (Standard-Parametername ist "folderid")
folderpath die dritte Möglichkeit zur Angabe des Ordners, hier wird der Name des Ordners angegeben
targetweb um das Dokument in ein anderes Projekt/Web zu speichern, hier die ID des Webs angeben
info mit diesem Parameter kann die Beschreibung des Dokumentes festgelegt werden
infoparam um die Beschreibung aus einem Request-Parameter auszulesen, hier den Parametername angeben

Bemerkungen

Bei Werten, die durch verschiedene Parameter festgelegt werden können, gilt folgende Reihenfolge der Überprüfung (es wird dabei abgebrochen, sobald ein Wert gefunden wurde):

In den Metadaten des Dokumentes werden unter "uploader" und "author" der eingeloggte Benutzer (falls er eingeloggt ist) sowie unter "uploaderIP" die IP des Uploaders eingetragen.

Multiupload

funktioniert wie beim Bilderupload.

.

Actions

Excel-Action

Erzeugt eine Excel-Datei, die gleich geöffnet oder als Download angeboten werden kann.

Parameter

createnew Sheets anlegen, falls diese noch nicht existieren? (Standard = nein)
Wird keine Vorlage verwendet, muß "ja" gewählt sein.
downloadname Dateiname der erzeugten Datei (nicht ausfüllen, um Datei nicht zum Download anzubieten)
dokumentname Dateiname für die Dokumentenverwaltung (nicht ausfüllen um die erzeugte Datei nicht abzuspeichern)
ACHTUNG! "ordnerid" muß mit angegebenw werden.
ordnerid ID des Ordners in der Dokumentenverwaltung, in der die fertige Datei abgelegt werden soll
Muß mit angegeben werden, wenn in der Dokumentenverwaltung gespeichert werden soll.
xml XML Daten direkt eingeben (wenn leer wird xmlfile genommen)
Parameter mit [[[...]]] angeben
xmlfile Dateiname der Seite, welche die XML Daten liefert
templateid Server-Dateiname der Excel-Datei in der Dokumentenverwaltung, die als Vorlage dienen soll (wegen Styling oder Formeln).
Leer lassen um neue Datei zu erzeugen, die dann allerdings nicht gestylt werden kann.
overwrite Soll eine evtl. vorhande Datei überschrieben werden (Standard: nein) - wird nicht mehr genutzt
beschreibung Beschreibung für die gespeicherte Datei in der Dokumentenverwaltung (nur für neu erstellte Dateien)
forcehttp Soll in jedem Fall http anstatt https zum template laden benutzt werden? (Standard: nein)

Aufbau der XML-Datei

<?xml version="1.0" encoding="utf-8" ?>
<data>
  <style name="fettkursiv" bold="true" italic="true"/>
  <style name="comic" font="Comic Sans MS" size="14" color="red"/>

  <sheet name="Sheet-Name" [widthA="20" widthB="10" widthC="40"]>

    <insert row="0" col="0" style="fettkursiv">Zeile0 Spalte0</insert>
    <insert row="0" col="1">Zeile0 Spalte1</insert>
    <insert row="0" col="2">Zeile0 Spalte2</insert>
    
    <insert row="1" col="0">Zeile1 Spalte0</insert>
    <insert row="1" col="1">Zeile1 Spalte1</insert>
    <insert row="1" col="2">Zeile1 Spalte2</insert>

  </sheet>
</data>

ODER

<?xml version="1.0" encoding="utf-8" ?>
<data>
  <sheet idx="0">

    <insert adress="A1">Zeile0 Spalte0</insert>
    <insert adress="B1">Zeile0 Spalte1</insert>
    <insert adress="C1">Zeile0 Spalte2</insert>
    
    <insert adress="A2">Zeile1 Spalte0</insert>
    <insert adress="B2">Zeile1 Spalte1</insert>
    <insert adress="C2">Zeile1 Spalte2</insert>

  </sheet>
</data>
bold true/false (oder weglassen)
italic true/false (oder weglassen)
color siehe hier, nur Farbnamen
excelfarben.png
widthA, widthB ... Spaltenbreite nach Spaltenname
Actions

Formular als Mail versenden

Die Daten aus dem Request werden in ein Email-Design mit Platzhaltern eingefügt. Dann wird es als Email versendet.

Funktionen:

Parameter

nextpage auf diese Seite wird nach Fertigstellung weitergeleitet
mailFrom die Email-Adresse, unter der die Mail versandt wird
mailFromName der im Email-Programm angezeigte Absendername
mailTo der Empfänger der Email
subject der Betreff der Mail
sendHTMLFormat wenn gewählt, wird die Email als HTML-Mail versandt
cc Email-Adressen für CC (durch Semikolon trennen)
bcc Email-Adressen für BCC (durch Semikolon trennen)

Bemerkungen

Platzhalter der Form "[[param]]" können in Adressen und Betreff verwendet werden. Diese werden dann durch die entsprechenden Request-Parameter oder Aktions-Attribute ersetzt. Ebenfalls kann im Betreff "{format}" verwendet werden, das aktuelle Datum wird dann gemäß "format" formatiert (bei fehlerhafter Angabe wird "dd.MM.yyyy" verwendet). .

Actions

Formulardaten validieren

Mit dieser Aktion ist es möglich, Formulardaten auf korrekte Syntax zu überpüfen.

failpage die seite, auf die weitergeleitet wird, wenn die Validierung fehlschlägt
validate:param für jeden Parameter, der validiert werden soll, muss es einen solchen Eintrag geben (param ist dabei durch den Name des zu überprüfenden Parameters zu ersetzen)
der Wert stellt den regulären Ausdruck dar, mit dessen Hilfe der Parameter überprüft wird

Bemerkungen

Um Email-Adressen zu validieren kann als Parameter-Wert statt dem regulären Ausdruck einfach "email" geschrieben werden, es wird dann ein Ausdruck benutzt, der auf die meisten gängigen Adressen passt. Ein erweiterter regulärer Ausdruck für Email-Adressen ist z.B. dieser (Quelle: http://www.regular-expressions.info/email.html): [A-Za-z0-9!#$%&'*+/=?^_{|}~-]+(?:.[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])? Um also wirklich sicher zu gehen, empfiehlt sich die Verwendung dieses Ausdrucks beim Überprüfen von Email-Adressen.

Innerhalb des regulären Ausdrucks können Platzhalter der Form [:param:] stehen, diese werden dann durch den Wert des Action-Parameters "param" ersetzt.

Beispiel für ein simples Formular mit den dazugehörigen Erweiterungen für die Validation

<form name="" method="" action="">
  <input type="hidden" name="validate:Vorname" value=".+">
  <input type="text" name="Vorname" value="">
  <input type="hidden" name="validate:Name" value=".+">
  <input type="text" name="Name" value="">
  <input type="hidden" name="validate:Strasse" value=".+">
  <input type="text" name="Strasse" value="">
  <input type="submit" value="senden">
</form>

Die Werte in den Value-Parametern der Hiddenfields sind reguläre Ausdrücke

Actions

Intranet Login

Um einen User im Intranetbereich zu authentifizieren wird diese Aktion benutzt.

Funktionen:

Parameter

successpage gibt die URL an, auf die bei Erfolg weitergeleitet wird, kann auch im Request übergeben werden (hat dann Vorrang)
failpage auf diese URL wird bei Misserfolg weitergeleitet, kann auch als Request-Parameter übergeben werden (hat dann Vorrang)
block-counter wenn ausgefüllt: Anzahl der erlaubten Fehlversuche bis zur Sperrung des Benutzers
block-timeout Zeit in Minuten nach der Fehlversuche neu gezählt werden (Standard=60)
minimale Sessionlänge (min-session-timeout) Angabe in Minuten. Die evtl. beim Benutzer eingestellte Sessionlänge wird für diese Session überschrieben
maximale Sessionlänge Angabe in Minuten. Die evtl. beim Benutzer eingestellte Sessionlänge wird für diese Session überschrieben

Freigabe weitere Eigenschaften

username wird im Request übergeben, alternative Namen sind: j_username, user, name, login
passwort wird im Request übergeben, alternative Namen sind: password, j_password, pass
Actions

Intranet Logout

Diese Aktion invalidiert die Session und loggt damit den Benutzer aus.

Parameter

nextpage auf diese Seite wird anschließend weitergeleitet
Actions

Intranet-User anlegen/ändern

Mit dem Action kann man einen Intranet-User anlegen und Angaben ändern (z.B. bei Paßwort vergessen). Meist in Verbindung mit einem Anmeldeformular kann man die im Formular eingegebenen und validierten Daten zum Anlegen des Users nutzen. field-user wäre z.B. Email und field-password wäre eines der beiden Paßwörter. Das Action gibt die ID des Users zurück (attribute-userid), die dann anschließend im Container gespeichert werden muß. Zusätzlich kann man noch die ID einer Benutzergruppe angeben, der der User zugeordnet sein soll. Mit dologin legt man schließlich fest, ob der User nach Abschluß der Anmeldung eingeloggt sein soll oder nicht.

Parameter

field-user Parametername des Benutzerfeldes
Feldname mit dem der Benutzername übergeben wird (nur wenn neuer Benutzer)
field-id Parametername des Benutzer-ID-Feldes
Feldname mit dem die Benutzer-ID übergeben wird (nur wenn Änderung eines Benutzers)
field-password Parametername des Passwortfeldes
Feldname mit dem das Passwort übergeben wird
activate Benutzer aktiv schalten, Standard: ja
attribute-userid Name für neue Benutzer-ID
Attributname, in dem die ID des neuen Benutzers gespeichert werden soll
groups zuzuordnende Gruppen, Liste von Gruppen-IDs
dologin Benutzer sofort anmelden, (Standard nein) Ansonsten wird der aktuelle Benutzer ausgeloggt

Freigabe weiterer Eigenschaften:

anrede=...

name=...

vorname=...

email=...

anschrift=...

telefon=...

fax=...

bemerkung=...

Löschen

Mit dem Action-Parameter (unter Freieingabe) delete (auf "true" setzen) kann der Benutzer auch gelöscht werden.

Actions

JSP-Baustein ausführen

Ein JSP-Baustein wird ausgeführt.

Parameter

jsp-id der auszuführende Baustein (ist aus einer Liste auswählbar)
quiet wenn "true" werden keine keine Fehler angezeigt
Actions

Newsletter – Abo abmelden

Kurzbeschreibung

Funktionen:

Parameter

entfernt URL zur Folgeseite, wenn der Newsletter erfolgreich abgemeldet wurde
nichtvorhanden die Folgeseite, falls für die angegebene Email-Adresse kein Newsletter vorhanden ist
falsch Weiterleitung, falls das Passwort falsch ist

Request-Parameter

email die Email-Adresse
aboid die ID des Abos
passwort das Passwort zur Email-Adresse

Bemerkungen

Es werden entweder die Request-Parameter email und aboid oder email und passwort benötigt.

Actions

Newsletter – Abo ändern

Einstellungen des Newsletterabo werden geändert.

Parameter

nextpage die Folgeseite

Request-Parameter

id access rubrik email htmlmail passwort1 passwort2

Actions

Newsletter – Abonnentenlogin

Authentifizierung um Newsletterabo zu ändern.

Parameter

login Folgeseite, wenn Login OK war
error Folgeseite, wenn der Login fehlgeschlagen ist

Request-Parameter

email die Email-Adresse
password das Passwort
Actions

Newsletter aktivieren

Ein abonnierter Newsletter wird freigeschalten.

Parameter

successpage die Seite, die nach erfolgreicher Freischaltung angezeigt wird
failpage die angezeigte Seite, falls das Abo nicht aktiviert werden konnte
requestparam der Request-Parameter der die Aktivierungs-ID enthält (Standard: "id"), alternativ kann im Request auch email und aboid übergeben werden

Es kann eine Mail verschickt werden mit dem Optin-Link, mit dem der NL aktiviert werden kann.

Beispiele

Sie haben sich bei unserem Newsletter angemeldet. Bitte bestätigen Sie Ihre Email-Adresse, indem Sie auf unten stehenden Link klicken.:

https://www.testseite.de/optin.act?nlid=[[activateid]]

Actions

Newsletter – Newsletter abonnieren

Jemand wird zur Newsletter-Kundenliste hinzugefügt und erhält eine Email mit seinen Zugangsdaten.

Parameter

abonniert URL der Folgeseite bei erfolgreicher Anmeldung
schonvorhanden URL der Fehlerseite, wenn der Newsletter bereits abonniert wird
setactive Abonnent ohne Prüfung sofort aktivieren?
subject Betreff der Bestätigungsmail
mailFrom die Email-Adresse des Absenders (wird bei Fehlermeldungen und beim Antworten auf Bestätigungsemail benutzt)
mailFromName der in der Mail angezeigte Absendername

Request-Parameter

email die Email-Adresse
rubrik (optional) mehrmals angeben, um die Rubriken zu spezifizieren (Standard: alle)
passwort1
passwort2
(optional) Passwort und -Bestätigung (Standard: zufall)
htmlmail (optional) Newsletter im HTML-Format senden ('j' oder 'n', Standard: 'n')
firma, ansprech, strasse, ort (optional) Abonenntendaten
frage, antwort (optional) geheime Frage und Antwort
Actions

Newsletter – Passwort vergessen (1)

Diese Aktion verlangt eine Eingabe der Email-Adresse um die geheime Antwort eingeben zu können.

Parameter

question-page Seite zur geheimen Frage (Standard: "./frage.htm")
unknown-page Seite, wenn die Email-Adresse nicht in der Datenbank ist (Standard: "./")
unsupported-page Seite, falls keine Frage festgelegt wurde (Standard: "./")
email (Request-Parameter) die Email-Adresse
Actions

Newsletter – Passwort vergessen (2)

Nach Eingabe der geheimen Antwort wird eine Email mit dem Passwort versandt.

Parameter

ok-page Ziel URL, wenn die Antwort richtig war
fail-page Ziel URL wenn Antwort auf die Frage falsch war
mailFrom Email-Adresse, unter der die Mail versandt wird
mailFromName im Email-Programm angezeigter Absendername
subject Betreff
sendHTMLFormat Email im HTML-Format senden?

Request-Parameter

aboid die Abo-ID
antwort die Antwort auf die geheime Frage
Actions

Passwort des angemeldeten Users ändern

Das Passwort des gerade angemeldeten Users kann mittels dieser Aktion geändert werden.

Parameter

oldpassword-field Feld für altes Passwort
Optional. Falls ausgefüllt, muss das alte Passwort in diesem Request-Paramater übergeben werden. Diese Eigenschaft muss ggf. über die weiteren Eigenschaften angegeben werden.
password1-field Feld für Passwort
Request-Feldname, der Passwortfeld enthält.
password2-field Feld für Passwortwiederholung
Request-Feldname, die Passwortwiederholung enthält.
failpage Fehlerseite
Fehlerseite falls Passwort leer, zu kurz oder ungleich der Wiederholung

Bemerkungen

Die beiden übergebenen Eingaben müssen übereinstimmen und das Passwort muss mindestens 3 Zeichen lang sein.

Actions

Shop – Bestellung versenden

Diese Aktion versendet den Warenkorb per Email.

Parameter

name der Name des Warenkorbes (falls mehrere getrennte Warenkörbe verwaltet werden sollen)
mailFrom die Email-Adresse des Absenders
mailFromName der anzuzeigende Absender-Name im Email-Programm
subject der Betreff
mailTo Empfänger-Adresse
ccMailField der Request-Parameter, der die Adresse für die Bestätigungsmail enthält
ccSubject der Betreff für die Bestätigungsmail
art-titel Name des Feldes, was die Artikelbezeichnung enthält
art-preis Name des Feldes, was den Preis enthält
art-nummer Name des Feldes, was die Artikelnummer enthält
backfile URL zur Bestätigungsseite (standardmäßig "../")
currency das Währungssymbol
clearbasket Warenkorb leeren?
extraChargeField Feldname für den Betrag eines zusätzlichen, produktabhängigen Postens
extraChargeName der Name des zusätzlichen Postens (Standard ist der Wert von extraChargeField)

Bemerkungen

Weiterhin können Parameter der Form "addCharge1Field" und "addCharge1Name" verwendet werden ("1" kann dabei jeweils erhöht werden, also "addCharge2Field, addCharge2Name, addCharge3Field, addCharge3Name, ..."). Diese zusätzlichen Posten werden der Summe hinzugefügt.

Actions

Shop – Hinzufügen zu Warenkorb

Durch diese Aktion wird ein neues Element in den Warenkorb aufgenommen.

Parameter

name Name des Warenkorbes (falls mehrere getrennte Warenkörbe verwaltet werden sollen), standardmäßig der Wert des Request-Parameters "basket"
basketlink die URL der Folgeseite, hier kann "[[url]]" verwendet werden, die Folgeseite steht dann im Request-Parameter "url"
extraParameterPrefix eine Markierung für zusätzlich Parameter, die dem Warenkorb übergeben werden (alle Parameter, die mit diesem Wert anfangen werden übergeben)

Request-Parameter

basket der Name des Warenkorbes
artikelid die Artikel-ID
type nur für CM-Seiten-Shop-Modus
url die Folgeseite
anzahl Bestellmenge
index nur für Updatemodus
Actions

Shop – Löschen im Warenkorb

Diese Aktion löscht einen Artikel aus dem Warenkorb oder leert den Warenkorb komplett.

Parameter

name der Name des Warenkorbes
nextpage die Folgeseite
clear löscht den gesamten Warenkorb (zu verwenden nach Versendung der Bestellung)
remove (Request-Parameter) enthält die zu löschenden Posten (falls als erster Posten "all" übergeben wird, werden alle Einträge gelöscht)
Actions

Shop – Zusatzgebühr zum Warenkorb

Eine Zusatzgebühr (z. B. Nachnahme, Lieferkosten, Versicherung) wird in den Warenkorb gelegt oder entfernt.

Parameter

basketname der Name des Warenkorbes
group der Name des Postens (kann auch im Request übergeben werden, als "name" oder "group")
value / element (Request-Parameter) enthält den Wert des Postens, falls hier nichts steht wird der Posten entfernt
Actions

Sicheres Formular überprüfen (SecureformAction)

Das SecureForm-Action wird benutzt, um Formulare gegen Manipulationen abzusichern. Es ist verfügbar ab Version 2.6.5.

Parameter

securelist Dies ist eine komma-getrennte Liste der Parameternamen, welche zur Hashbildung herangezogen werden.
Tauchen hier Parameternamen auf, die nicht im Request sind, so werden diese Parameter nicht zur Hashbildung benutzt.
Hier können auch Parameter stehen, die nie an das Action übergeben werden dürfen - da diese im Frontend nicht mitgehasht werden und höchstens durch Manipulation im Request landen, schlägt die Prüfung fehl und das Action bricht ab.
Zusätzlich zu dieser manuellen Liste gibt es eine im System verankerte Liste, welche einige Standardparameter enthält, die immer geschützt sein müssen (z.B.: recordid, listid).
failurl Falls die Prüfung fehlschlägt, wird zu dieser URL weitergeleitet.
Ist hier nichts eingetragen und die Prüfung schlägt fehlt, wird das Action mit einer Fehlermeldung abgebrochen.

Alle Parameter in securelist müssen, falls vorhanden, abgesichert sein. Das heißt ihr Wert muss entweder direkt in den Hash eingeflossen sein, oder einen der erlaubten Werten entsprechen (und diese Liste muss dann in den Hash eingeflossen sein).

Erlaubte Werte

Falls ein spezieller Parameter für mehrere erlaubte Werte mitgeschickt wurde, wird zusätzlich geprüft, ob der originale Parameter einen dieser Werte entspricht.

Actionklasse: com.batix.action.SecureformAction

Actions

Suche im Web

Es wird eine Suche in vorher indizierten Seiten des Webs ausgeührt. Das Suchergebnis wird in der Benutzersitzung gespeichert und kann danach auf der Ergebnisseite wieder ausgelesen werden.

Diese Suchergebnisse können dann mittels bx:websearch in eine HTML-Seite eingefügt werden.

Parameter

searchparam Request-Parameter der den Suchbegriff enthält (Standard ist "search")
resultpage die Seite, auf die danach weitergeleitet wird
useAccessFilter sollen Menüpunkte, auf die der Benutzer kein Zugriff hat herausgefiltert werden?
useNavFilter aktiviert die Parameter includeNav, excludeNav sowie searchroot
includePattern ein regulärer Ausdruck, der angibt, was in die Suche eingeschlossen wird
excludePattern ein regulärer Ausdruck, der angibt, was aus der Suche ausgeschlossen wird
includeNav Liste von Navigations-ID's von in die Suche eingeschlossenen Pfaden
excludeNav Liste von Navigations-ID's von aus der Suche ausgeschlossenen Pfaden
searchroot gesamtes Web durchsuchen? (wenn nicht speziell angegeben)

Bemerkung

Sobald useAccessFilter verwendet wird, werden alle anderen Parameter zur Einschränkung (wie z.B. useNavFilter, include... oder exclude...) nicht mehr beachtet.

Actions

Validierungsergebnis ausgeben

Diese Aktion wertet das Ergebnis einer Container-Validierung aus. Es kann ein Report in ein Textfeld des Datensatzes geschrieben werden, ein Häkchen im Containerdatensatz geschalten werden oder das Action abgebrochen und auf eine andere URL weitergeleitet werden.

Parameter

reportfield das Feld, in dem das Validierungsergebnis gespeichert werden soll
format das Format, in dem das Validierungsergebnis geschrieben werden soll ("xml" oder "properties")
resultfield das Häkchenfeld in dem der Validierungsstatus gespeichert werden soll (angehakt bedeutet "Validation nicht bestanden")
fail-url hierhin wird weitergeleitet, wenn die Validierung fehlgeschlagen ist
success-url hierhin wird weitergeleitet, wenn die Validierung erfolgreich war
list zu validierende Datenliste, falls mehrere Container gleichzeitig validiert werden

Bemerkung

Es muss vorher eine Validierung stattgefunden haben.

Sobald eine URL aufgerufen wird (fail-url oder success-url) wird die weitere Aktionsverarbeitung abgebrochen. In der URL-Angabe können auch Platzhalter der Form "[[param]]" verwendet werden, diese werden dann durch den jeweiligen Wert des Request-Parameters "param" ersetzt.

Actions

Vorhandene Bedingung abfragen

Dies ist eine Aktion, die einen Abbruch der Aktionsverarbeitung bewirkt, wenn ein Requestparameter ungleich einem bestimmten Wert ist.

Parameter

requestField der Requestparameter, dessen Wert abgefragt werden soll
compareValue der Wert, den der Requestparameter haben muss, um die Bedingung zu erfüllen
es können auch Spezailwerte verwendet werden:

#null - Feld ist nicht im Request enthalten
#empty - Feld ist leer im Request
#nodata - Feld ist nicht im Request oder ist leer

Ferner ist es möglich, reguläre Ausdrücke der Form ^regex hier$ zu verwenden.
Auch kann man zwei Request-Werte vergleichen, indem man bei compareValue den zweiten Parameter in zwei eckige Klammern stellt.
conditionTrue zu dieser URL wird weitergeleitet, wenn die Bedingung erfüllt wird
conditionFalse falls die Überprüfung fehlschlägt, wird hierhin weitergeleitet

Die URLs können Platzhalter der Form [[Parametername]] sowie die speziellen Platzhalter {querystring} und {request} enthalten. Ebenfalls kann den speziellen Platzhaltern "?" oder "&" vorangestellt werden (z.B. {&request}), diese Zeichen werden dann mit ausgegeben, falls der Platzhalter zu einem Wert aufgelöst werden kann.

Klassenname

com.batix.action.ConditionAction

Actions

Weiterleitung

Diese Aktion leitet an eine andere Seite weiter.

Funktionen:

Parameter

destination die Ziel-URL
appendQueryString gibt den Query-String des aktuellen Requests an die Ziel-URL weiter

Bemerkungen

In der URL können Platzhalter der Form "[[param]]" verwendet werden, diese werden dann durch die Werte der entsprechenden Request-Parameter ersetzt. Weiterhin gibt es zwei spezielle Platzhalter:

[[session-id]] die Session-ID
[[newrecordid]] ID eines Datensatzes, der durch eine vorherige Speicher-Aktion angelegt wurde

ACHTUNG!

Nach Update von einer V2.6.6 auf eine aktuelle Version wichtig:

Stilistischer Aufbau: /index.htm ->Liste /detail.htm ->Detailseite /save.act ->Speichern-Aktion

Bei Formular absenden an save.act haben Weiterleitungen die bisher mit "?query=foo" den Browser bisher wegen einem Tomcat "Bugfeature" auf "./?query=foo" weitergeleitet. Das ist eigentlich falsch und inzwischen gefixt. Nun wird aber der Browser bei *Verwendung" des Bugs als Endlosschleife immer wieder auf das Save-Action geleitet: "./save.act?query=foo". Daher muss in den aktuellen Versionen für eine Weiterleitung auf die Index-Seite des Menüpunktes "./?query=foo" verwendet werden, da sonst korrekterweise auf die Adresse geleitet wird, die der Browser auch zuletzt angefragt hat. Fehlerbild wären also seltsame leere Actionaufrufe aus dem Frontend und Benutzer, die melden, dass ihr Browser nach Formular-Absenden keine sinnvolle Seite mehr darstellt und stattdessen was von "Zu viele Weiterleitungen" berichtet.

Actions

Wert in Session speichern

Alle Request-Parameter mit dem angegebenen Präfix werden in eine Hashmap in der Session geschrieben. Der Name des Session-Parameters ist "com.batix.sessionlist:mapname".

Parameter

mapname Name der Hashmap (Standard: "default")
fieldname Name des Parameters
fieldnamePrefix alternativ: Präfix der zu speichernden Parameter
savename (ggf. über Freieingabe setzen)
Name des Session-Attributes, in dem der Wert aus dem Request gespeichert werden soll

Wird savename nicht angegeben, wird als Name des Session-Attributes der Wert aus fieldname verwendet.

Actions

XHTML 2 PDF

Liest URLs aus einem Container,einem Request-Parameter oder mit Vorgabe im Action und erstellt daraus PDF-Dateien. Vollständige und strikte Unterstützung von CSS 2.1 sowie einigen Erweiterungen von CSS 3.0. (siehe [1])

Funktionen:

Parameter

Dokumentverwaltung in Dokumentverwaltung speichern (Standard = nein)
Wenn hier nein angegeben wird, dann wird das PDF-Dokument direkt zum Browser gestreamt
Verzeichnis-Id
Eingabe bei weitere Eigenschaften:
folderparam=parametername
folderpath=/pfad/
targetweb=Projekt-ID
ID des Zielordners in des Dokumentenverwaltung
Wenn bei Dokumentverwaltung ein ja gewählt ist, kann man in Attribut Verzeichnis-Id die ID eines Ordners der Dokumentenverwaltung angeben oder alternativ diese ID in einem Request-Parameter namens 'Verzeichnis-Id' oder in einem Request-Parameter dessen Name in Attribut folderparam eingetragen ist. Der Ordner kann auch über dessen Namen angegeben werden in Attribut folderpath. Zusätzlich kann man im Attribut targetweb ein anderes Projekt des selben Mandanten angeben.
Dokumentname Dateiname des erzeugten PDF
Wenn bei Dokumentverwaltung der Standard nein gewählt ist, kann hier der vorgeschlagene Dateiname angegeben werden (Platzhalter sind erlaubt). bei einem ja wird dies als Originaldateiname verwendet
Dateifeldname Name des Feldes, in dem die Verknüpfung in nächsten Action gespeichert werden soll
nur wenn bei Dokumentverwaltung = ja gewählt ist: Hier kann ein Action-Parameter für Folgeactions definiert werden, z. B. um das Dokument zu einem Containerdatensatz zuzuweisen.
URL Pfad zur Seite
Im Hintergrund wird die URL aufgerufen und dann das zurückgelieferte HTML in eine PDF-Datei gerendert.
Request-Name Name des Requestparameters der eine URL enthält
Ein Parameter mit diesen Namen muß im Request, der dieses Action aufruft, mit übertragen werden. Er muß eine URL enthalten und diese URL wird aufgerufen und dann das zurückgelieferte HTML in eine PDF-Datei gerendert. (Wird ignoriert wenn bei URL etwas angegeben ist)
Container-Id Container in welchem die URLs gespeichert sind
Bei Angabe der ID eines Containers (pool) wird in diesen Container in allen Datensätzen bzw. diesen, die den Kriterien in Container-Filter entsprechen, nach dem Feld Container-Feld geschaut. Dieses Feld enthält die URL zum Quellcode für das PDF und von allen gefilterten Datensätzen werden diese Quellcodes zusammenkopiert und als ein großes PDF gerendert
Container-Feld Containerfeld welches die komplette URL enthält
Containerfilter Filterkriterien des Containers im XML-Format
(z.B. Session-ID prüfen)
Eingabe bei weitere Eigenschaften:
info=irgendeine Info
infoparam=parametername
Dateiname des erzeugten PDF
Hier kann eine Dokumentbeschreibung für den Eintrag in der Dokumentverwaltung eingetragen werden. Entweder ein fester Wert in Attribut info oder der Name eines anderen Request-Parameters im Attribut infoparam

Quelldatenmodi:

Ausgabemodi:

Tips

Seitennummern rechts unten:

@page {
  @bottom-right {
    content: "Seite " counter(page);
    font-family: Arial, Helvetica, Sans-Serif;
    font-size: 12pt;
  }
}

Seitengröße:

814 x 1134 Pixel (Größe für Hintergrundbilder, die die gesamte Seite ausfüllen sollen)

PDF und Schriften

Beispiel für CSS-Style zur Einbettung von Schriften in ein PDF-Dokument:

@font-face{
	font-family:Source Sans Pro Light;
	src:url(/static/<bx:pagedata.webdir/>/assets/fonts/SourceSansPro-Light.ttf) format("truetype");
	font-style:normal;
	font-weight:400;
	-fs-pdf-font-embed: embed;
	-fs-pdf-font-encoding: Identity-H;
}

Der Schriftname bei font-family muss identisch sein mit der Bezeichnung in der TrueType-Font-Datei. Als Windows-User findest du die korrekte Bezeichnung mit Doppelklick auf die ttf-Datei.

image2020-9-17_15-3-23.png

Ressourcen & Plugins

Container, Mediendatenbank, Vorlagen, Plugin Newsletter, Zeitsteuerung.

Ressourcen & Plugins

Container

In Containern können Daten (Artikeldaten, Kontaktdaten, Vorgangsdaten usw.) gespeichert und auf den Webseiten vollständig oder teilweise ausgewertet, kombiniert und ausgegeben werden. Sie bilden damit ein mächtiges, weil vielseitig verwendbares, unabhängiges Instrument zur Verwaltung und Abbildung beliebiger Daten über Projekte und Mandaten hinaus.

cont1.jpg

Erklärung anhand eines Beispiels

Sie möchten auf der Website Ihres Unternehmens eine Ansprechpartner-Seite einrichten. Die Daten dazu liefert Ihnen eine Excel-Liste:

image2015-5-29 11:25:0.png

Also legen Sie einen Container an, um diese Daten ins System zu bekommen. Zusätzlich wollen Sie diese noch anreichern mit einem Bild und den Aufgabenbereichen. Die Eingabe dazu erfolgt gleich im Container.

image2015-5-29 12:55:36.png

Nach dem Import Ihrer Excel-Liste haben Sie die Daten nun im CMS.

image2015-5-29 12:43:34.png

Dann brauchen Sie auch noch ein Template, um diese Daten mittels Tags in eine Website zu bekommen. Für dieses Beispiel brauchen Sie die Tags bx:containerfilter und bx:recordfield.

...
    <div id="content">
      <h1>Ansprechpartner</h1>
      <bx:textarea.Seitentext large comment="Dieser Text steht direkt unter der Überschrift."/>
      <bx:containerfilter.Abteilung pool="Abteilungen" orderby="Titel">
        <h3 class="streifen"><bx:recordfield.Titel/></h3>
        <br>
        <bx:containerfilter pool="Ansprechpartner" name="Abteilung" type="8" value="special:PARENTCONTAINER" orderby="Familienname">
          <div class="ansprechpartner">
            <img src="<bx:recordfield.Bild width="60" height="150" type="path"/>">
            <strong><bx:recordfield.Vorname/> <bx:recordfield.Familienname/></strong><br>
            Tel.: <bx:recordfield.Telefon/>
            <div class="floatclear"></div>
          </div>
        </bx:containerfilter>
        <br>
      </bx:containerfilter.Abteilung>
    </div> 
...

Das Ergebnis sieht dann - je nach CSS-Styles - ungefährt so aus:

image2015-5-29 12:34:59.png

Grundlagen

Um Container zu verwenden, muss zwischen Daten und Darstellung unterschieden werden. Zum einen müssen die Daten erfasst und strukturiert werden, zum anderen müssen verschiedene Darstellungsformen vorbereitet und später den Daten zugeordnet werden.

Die Inhalte werden definiert

Unter Definition im Menüpunkt Container werden eben diese definiert und verwaltet und es werden jedem angelegten Containertyp verschiedene Templates (=Gestaltungsvorlagen) zugeordnet. Das ist die Aufgabe des Administrators. Er legt fest, welche Container mit welchen Daten einem Redakteur zur Verfügung gestellt werden und welche vom Designer erstellten Vorlagen zur Darstellung der Informationen vom Redakteur verwendet werden dürfen.

Bei der Containerdefinition wird festgelegt, wieviele Datensätze der Container enthalten soll und welcher Art sie sind. Containerdefinitionen sind also Templates (Vorlagen) für Daten.

Beispiel: Zur Definiton des Containers Ansprechpartner speichern wir die einzeiligen Textfelder Titel, Vorname, Name, Telefonnummer, das mehrzeilige Textfeld Tätigkeitsbeschreibung und das Feld Foto vom Typ Bild. Zu unserer Containerdefinition Ansprechpartner gehören also sechs Datensätze.

Bei der Containerverwaltung werden Gruppen von Containerdefinitionen angelegt. In diesen Gruppen können dann die einzelnen Container bearbeitet werden.

Beispiel: Wir haben zwei Abteilungen, Einkauf und Verkauf. Jede dieser beiden Abteilungen verfügt über mehrere (beliebig viele) Ansprechpartner. Wir legen zwei Gruppen (Einkauf und Verkauf) an und weisen diesen Gruppen zu, aus welchen Containerdefinitionen ihre zu editierenden Datensätze stammen sollen. Hier handelt es sich um die oben angelegte Containerdefinition Ansprechpartner.

Die Inhalte werden erstellt: Container editieren

Im Navigationsbereich auf der linken Seite sollten jetzt bei Verwaltung zwei Einträge vorhanden sein: Einkauf und Verkauf. Wir haben jetzt nichts anderes gemacht, als zwei Kategorien anzulegen, in denen künftig beliebig viele Einträge (Container, Ansprechpartner) editiert und verwaltet werden können. Die Container in beiden Kategorien können dabei mit Daten entsprechend der Containerdefinition (Vorlage) gefüllt werden.

In unserem Beispiel bedeutet dies, dass jeder dieser Container über maximal sechs Felder verfügt. Wir können nun beliebig viele Ansprechpartner in den beiden Kategorien anlegen.

Die Darstellung

Wir haben nun alle Daten der Ansprechpartner eingegeben. Nun möchten wir, dass eine jeweils andere Auswahl der Ansprechpartner auf verschiedenen Bereichen der Webseite erscheint. Die Zusammenstellung dieser einzeln existierenden Ansprechpartner geschieht im jeweiligen Menüpunkt, also der Administration derjenigen Seite, auf welcher die Informationen erscheinen sollen. Nun könnte der Redakteur damit beginnen, die einzelnen Container auf der Seite Ansprechpartner Einkauf zusammenzustellen. Das kann er aber im Moment noch nicht. Er hat zwar die Daten an sich schon zur Verfügung, weiß aber noch nicht, wie diese dargestellt werden sollen - er hat zwar ein Datentemplate (Containerdefinition), aber noch kein Designtemplate (Darstellungsvorlage). Das ist Aufgabe des Designers.

Innerhalb des Punktes Dokumentvorlagen bei Vorlagen im Bereich Ressourcen gibt es mehrere Kategorien: Komplettseiten, Designtemplates, Textbausteine und Sonstiges. Uns interessieren an dieser Stelle nur die ersten beiden Punkte:

Komplettseiten

Komplettseiten sind Vorlagen für komplette Webseiten - also inklusive Navigation, Platzhaltern, mehrfach verwendeten Grafiken, Modulen usw. Jedem Menüpunkt in einem Projekt wird eine solche Vorlage zugewiesen. Um nun Container abbilden zu können - von denen wir immer noch nicht wissen, wie sie konkret aussehen - muss der Designer nichts anderes tun, als in einer bestimmten Stelle des Quelltextes einer Komplettseite einen Platzhalter für Container einzufügen.

Beispiel: In unserem Projekt weist jede Seite dasselbe Schema auf: Links die Navigation, oben eine editierbare Grafik, darunter die Überschrift der Seite und darunter der spezifische Seiteninhalt. Der Designer entwickelt also einen Quelltext, der in der linken Tabellenzelle einen Platzhalter für die dynamisch auszulesende Navigation beinhaltet, oben mittels bx:Tag einen Platzhalter für ein Bild und darunter ebenfalls mittels bx:Tag einen Platzhalter für die Headline bereithält. Darunter würden gewöhnlich weitere Platzhalter für Schleifen, Texte, Bilder, Dokumente usw. folgen. Hier in der Quelltextvorlage für eine Komplettseite zur Darstellung von Containern ist das anders: Hier erscheint lediglich ein bx:Tag, der Platz für die Darstellung von Containern schafft - welche das auch sind und wie sie auch aussehen mögen. Der Vorteil liegt auf der Hand: Möchte der Designer zwar nichts an der Darstellung der Container, wohl aber etwas am "Drumherum" ändern (z.B. ein weiteres Textfeld unter der Headline), muss er nur noch eine Designvorlage ändern. Jedenfalls dann, wenn es sich um Menüpunkte handelt, die irgendwie auf Container zugreifen. Der Designer legt eine solche Seite an und nennt sie zum Beispiel Containerseite.

Designtemplates

Designtemplates sind nichts anderes als Code-Schnipsel. Hier benötigen wir keinen kompletten Quelltext, sondern nur die Informationen, die wir für die Darstellung der Container entsprechend ihrer Definition benötigen. Hier bei den Designtemplates wird nun das Aussehen der Container bestimmt - und zwar in beliebig vielen Formen und Formaten.

Beispiel: Wir möchten in den Menüpunkten Einkauf und Verkauf alle Ansprechpartner mit allen (also sechs) Datensätzen darstellen. In einem anderen Bereich der Webseite - zum Beispiel bei den FAQ - möchten wir den Text einfügen "Weitere Antworten finden Sie bei...", gefolgt vom Namen und der Telefonnummer des entsprechenden Ansprechpartners. Der Designer legt nun zwei Designtemplates an: Ansprechpartner_komplett umfasst einfach in einer Tabelle alle Datensätze des Ansprechpartners untereinander. Ansprechpartner_kurz umfasst lediglich vier Datensätze: Text ("Weitere Antworten finden Sie bei..."), Vorname, Name und Telefonnummer. Darüber hinaus ist der Name im ersten Designtemplate rot, im zweiten blau.

Ergebnis

Jetzt haben wir neben den Containern (Ansprechpartnern), die in verschiedene Kategorien unterteilt sind nun auch mehrere (genauer: zwei) Möglichkeiten, diese Container darzustellen: entweder komplett oder nur mit Name, Vorname und Telefonnummer. Der Designer hat seine Arbeit getan. Damit der Redakteur aber auch die verschiedenen Darstellungsformen nutzen kann, muss noch einmal der Administrator in Aktion treten.

Im Bereich Formatzuweisung in Container bei Ressourcen werden den vorhandenen Containerdefinitionen die vom Designer erstellten Designtemplates zugewiesen. Nun sind Datenvorlagen (Containerdefinition) mit beliebig vielen passenden Darstellungsvorlagen (Designtemplates) verknüpft und können vom Redakteur benutzt werden.

Inhalte und Darstellung werden zusammengeführt: Die Arbeit am Menüpunkt

Der Redakteur legt im Bereich Redaktion einen neuen Menüpunkt an. Nachdem er alle erforderlichen Eingaben getätigt hat, wird er darauf hingewiesen, dass er für diesen Menüpunkt noch keinen Quelltext (= Vorlage für eine Komplettseite) benutzt. Jetzt wählt der Redakteur die oben angelegte Vorlage Containerseite. Nun kann er den Menüpunkt (z.B. Ansprechpartner Einkauf) mit Inhalten füllen. Nachdem er die Überschrift eingegeben und ein Bild hochgeladen hat kann er nun darunter beliebig viele Container einfügen - natürlich prinzipiell auch andere als die bereits angelegten. In diesem Menüpunkt fügt er schrittweise alle Ansprechpartner ein, die zum Bereich Einkauf gehören. Bei jedem einzelnen Ansprechpartner wird er vom Programm gefragt, wie dieser Ansprechpartner dargestellt werden soll (es gibt zwei Möglichkeiten: komplett und verkürzt). Er entscheidet sich für die komplette Variante und verfährt anschließend analog im Bereich Ansprechpartner Verkauf.

Ergebnis: Der Webauftritt verfügt nun über zwei Menüpunkte mit allen verfügbaren Daten der jeweiligen Ansprechpartner.

Container in anderen Menüpunkten verwenden

Wir haben oben davon gesprochen, einen Menüpunkt FAQ zu erstellen, in welchem verschiedene Fragen und Antworten erscheinen. Sollte zu einem Fragekomplex noch Klärungsbedarf bestehen, sollen ein Text sowie kurze Daten des kompetenten Ansprechpartners erscheinen. Die intelligenteste Lösung besteht darin, dass weitere Container definiert werden. Hier sind das beliebig viele FAQ (bestehend aus den zwei mehrzeiligen Textfeldern Frage bzw. Antwort). Auch hier gibt es natürlich ein entsprechendes Designtemplate. Der Redakteur hat nun im neu anzulegenden Menüpunkt nichts anderes zu tun, als diesem wiederum die Vorlage Containerseite zuzuweisen und die Inhalte zu integrieren.

Nur bedient er sich hier aus zwei Containern. Nachdem er beispielsweise die ersten fünf FAQ eingefügt hat, wählt er beim sechsten Eintrag einen Container aus der Kategorie "Ansprechpartner". Bei der Frage, wie dieser Container dargestellt werden soll, wählt er diesmal die kurze Variante. Mit den übrigen FAQ verfährt er genauso und weist den Themenkomplexen abschließend den entsprechenden Ansprechpartner zu. Sollte an einer Stelle eine weitere FAQ eingefügt werden, verschiebt der Redakteur den Eintrag im Administrationsbereich einfach an die entsprechende Stelle.

Nun kann der Redakteur diese Seite mit Aktionen verbinden: Versenden der Inhalte als eMail, Weiterempfehlen, Ausdrucken usw.

Konsequenzen

  1. Wenn sich zum Beispiel bei einem Ansprechpartner die Telefonnummer ändert, muss der Eintrag nur einmal geändert werden.
  2. Sollen zum Beispiel die FAQ auf einer anderen Webseite dieses Clients in einer völlig anderen Form benutzt werden, müssen maximal nur zwei Dateien geändert werden: die entsprechende Komplettseite und das spezielle Designtemplate.
  3. Soll diese Seite ausgedruckt werden, ist eine auf einen Drucker angepasste Ausgabe erforderlich. Auch hier muss nur eine neue Komplettseite (z.B. Druckdesign) angelegt werden. Im Administrationsbereich wird dieser neue Quelltext dem Menüpunkt zusätzlich zugewiesen. Nun hat diese Seite ein zweites - an einen Drucker angepasstes - Erscheinungsbild.
  4. Die Daten müssen in einem völlig anderen Medium (z.B. PDA oder Belichtungsvorlage für Druck) dargestellt werden. Hier müssen nur entsprechende Designs mit speziellen Merkmalen angelegt und in weiteren Menüpunkten (z.B. Client->Webseite->PDA-Variante) mit den Containern verknüpft werden.
  5. Alle Änderungen in einem Containerdatensatz wirken sich unmittelbar auf alle verschiedenen Ausgabemöglichkeiten (Druck, PDA usw.) aus.

Definition und Verwaltung

Definition/Anlegen eines Containers

Über den Knopf wird ein neuer Container angelegt.

image2015-5-29 12:59:54.png

Container in Administration sichtbar Der Container taucht in der linken Navigationleiste unter "Container" auf.
Container globar freigeben Wenn angehakt, können Sie auch von anderen Mandanten aus auf diesen Container zugreifen, ansonsten ist er nur innerhalb eines Mandanten für alle Projekte nutzbar.
Titel/Alias Name des Containers, muß innerhalb eines Systems eindeutig sein
optionale Containerbezeichnung
kurze Beschreibung ebensolche
Tabellenname wird automatisch generiert anhand des Titels, füllt sich nach der Speicherung, kann aber überschrieben werden
Kategorie Bei vielen Containern empfiehlt es sich, diese in Kategorien einzuteilen. Die Namen können frei vergeben werden.

Nachdem Sie diese Felder ausgefüllt haben, bitte speichern mit image2017-1-11 9:23:40.png/image2017-1-11 7:48:54.png

image2015-5-29 13:29:8.png

Containerfeld mit "neues Containerfeld anhängen" werden die benötigten Felder angelegt
Anzeigemuster Anzeige in der Verwaltung, Pattern: %Feldname%
Sortierfeld voreingestellte Sortierung in der Verwaltung. Standard: Reihenfolge der Erstellung (also nach ID)

Anlegen der Felder

image2015-5-29 13:33:26.png

Feldposition auswählbare Sortierreihenfolge
Feldname
optionale Feldbezeichnung
Feldbeschreibung ebensolche
Feldtyp Datentyp des Feldes, z.B. Text, Zahl o.ä.
Eigenschaften
SQL ausführen

Folgende Feldtypen stehen zur Verfügung:

einzeiliger Text
mehrzeiliger Text
HTML-Editor Feld
Bildverknüpfung
Dateiverknüpfung
Datum
Datum + Uhrzeit
Uhrzeit oder Zeitraum
Ganzzahl
Dezimalzahl
Preis (2 Nachkommastellen)
Wahrheitswert (Binär)
Pixelkoordinaten in Bild Bei Vorlage einer entsprechenden Anwendung werden Koordinaten aus einer angeklickten Grafik in diese Textfelder geladen
Einzelverknüpfung Bei einem Untercontainer legen Sie fest, dass dessen Definition in ihrer neuen Definition als Unterschleife verwandt wird. Bei einem Container Ansprechpartner könnten Sie so z.B. beliebig viele Adressen (definiert in einem Container Adressen) zuordnen. Diese Adressen werden dann in der Redaktion im entsprechenden Container - und nur in diesem - angelegt.
Mehrfachverknüpfung Bei einer Einfachverknüpfung legen Sie fest, dass sie einen Datensatz aus einem anderen Container benutzen möchten. Die Pflege der Daten erfolgt im Gegensatz zum Untercontainer im verknüpften Container. Beispiel: Im Container Ansprechpartner gibt es eine Einzelverknüpfung zum Container Abteilung. So können Sie jedem Ansprechpartner genau eine Abteilung zuordnen (und bei der Ausgabe auf Webseiten nach diesem Kriterium filtern).
Liste aus Untertabelle Manchmal machen sich Mehrfachverknüpfungen notwendig. Die Pflege der Daten erfolgt im Gegensatz zum Untercontainer im verknüpften Container. Beispiel: Sie haben einen Container Fachgebiete, dem Sie mehrere Sachgebiete zuordnen möchten. Dann wählen Sie diese Option.
Ressourcen & Plugins

Mediendatenbank

Die Mediendatenbank umfasst alle Grafiken und Dokumente, die in den Projekten eines Mandanten dynamisch zugewiesen werden können. Das bedeutet, dass diese Grafiken oder Dokumente in allen Bereichen (einzelne Menüpunkte, Containerdatensätze) angewählt und entsprechend der genutzten Vorlage (Dokumentvorlage, Containerdefinition) genutzt werden können.

Die Mediendatenbank umfasst folgende zwei Bereiche:

Grafiken

Galerieansicht

bisheriges Design:

bildergalerie1.png

neues Design:

bildergaleri_neu.png

Neues Bild hochladen

Hier erhalten Sie folgende Informationen und haben folgende Möglichkeiten:

Listenansicht

bisheriges Design:

image2015-5-28 13:9:9.png

neues Design:

image2017-1-11 13:56:13.png

In der blätterbaren Listenansicht erhalten Sie überblicksweise folgende Informationen zu den einzelnen Grafiken:

Detailansicht

bisheriges Design:

image2015-5-28 13:9:32.png

neues Design:

image2017-1-11 13:57:17.png

Eine andere Darstellung der Galerie finden Sie in der Detailansicht. Hier finden Sie ebenfalls zu jeder Grafik Links zu den Metadaten und der Vorschau in Originalgröße. Darüber hinaus erfahren Sie, wie oft die Grafik im Projekt verwendet wird und erhalten mit einem Klick auf die Zahl eine verlinkte Liste der einzelnen Verwendungen. Mit dem Link "bearbeiten" gelangen Sie zur Bearbeitungsseite für die Grafik. In der Toolbox haben Sie in dieser Ansicht die Möglichkeit, die Kategorien zu bearbeiten.

Bearbeitenseite

bisheriges Design:

image2015-5-28 13:12:11.png

neues Design:

image2017-1-11 13:59:3.png

Auf dieser Seite können Sie weitere Informationen zur Grafik hinterlegen

Titel Vergeben Sie hier einen Titel für die Grafik zur Verwendung im System und ordnen Sie die Grafik einer vorhandenen Kategorie zu. Kategorie Wählen Sie hier eine Kategorie für die Grafik. Beschreibung Tragen Sie hier nähere Beschreibungen für die Grafik ein. Von besonderer Bedeutung für externe Suchmaschinen (z.B. Google) sind die beiden nächsten Einträge: Autor und alternativer Text. Insbesondere der letzte Eintrag ist wichtig für die Erfüllung der Anforderungen an barrierefreies Webdesign. Datei austauschen Mit dem Punkt "Datei austauschen" können Sie die vorhandene Grafik durch eine andere Grafik von einem lokalen Datenträger ersetzen. Achtung: Damit tauschen Sie die Grafik auch auf allen verwendeten Menüpunkten oder in anderen Verwendungszwecken, denen die ursprüngliche Grafik zugewiesen war.

Kategorien

bisheriges Design:

image2015-5-28 13:13:25.png

neues Design:

image2017-1-11 14:1:29.png

Alle Grafiken lassen sich in beliebig viele Kategorien (auf einer Ebene) sortieren. In einzelnen Ansichtsmodis haben Sie über die Toolbox die Möglichkeit, die Kategorien zu bearbeiten.

zuweisen
Bilder in den Kategorien zuweisen (s. u.)

bearbeiten
Dabei wechseln Sie auf eine Seite, in der Sie den Titel der Kategorie ändern und über den Button Speichern in der Symbolleiste speichern können. Alternativ können Sie hier auch mit dem Button Neuer Datensatz in der Symbolleiste eine neue Kategorie anlegen oder über den Button diesen Datensatz löschen in der Symbolleiste die gewählte Kategorie entfernen. Die der gelöschten Kategorie zugewiesenen Grafiken werden dann der Kategorie "ohne Kategorie" zugewiesen.

Bilder in den Kategorien zuweisen

bisheriges Design:

image2015-5-28 13:16:12.png

neues Design:

image2017-1-11 14:2:35.png

Hier sehen Sie alle Grafiken der gewählten Kategorie. Klappen Sie das Menü der gewünschten Grafiken auf und wählen Sie die Kategorie, in der die Grafik gespeichert werden soll. Nachdem Sie alle Zuweisungen getätigt haben, klicken Sie auf "update". Den Grafiken werden nun die neuen Kategorien zugewiesen.

Massenupload

Durch dieses Modul können mehrere Bilder gleichzeitig zur Bildergalerie hinzugefügt werden.

Im ersten Schritt wird eine zip-Datei, welche die Bilder enthält, hochgeladen. Im zweiten Schritt können die Bilder ausgewählt werden, die verwendet werden sollen. Im dritten Schritt werden die Bilder entpackt und der Bildergalerie hinzugefügt.

Dokumente

Hier können Sie Dokumente (PDF, Word, JPG, o.a.) zentral speichern und dann auf Seiten oder im Container verknüpfen. Somit braucht eine Datei nur einmal gespeichert werden, kann aber an mehreren unterschiedlichen Stellen eingebunden werden.

medien2.jpg

Listenansicht

image2015-5-29 9:14:55.png

Hier können Sie nach verschiedenen Projekten und Mime-Typen filtern und zwischen Ordnern wechseln sowie diese anlegen bzw. bearbeiten (s.u.). Fahren Sie mit der Maus über die Zeile, in der das gewünschte Dokument steht. Die Hintergrundfarbe ändert sich und Sie können klicken, um auf die Bearbeitungsseite des Dokumentes zu gelangen (s.u.). Zu jedem Dokument finden Sie folgende Informationen: Originalname der Datei, Dateigröße, Erstellungsdatum (= Datum des Uploades in das CMS), Dokumententyp und Anzahl der Verwendungen im Projekt. Anmerkung: Sollten sich die Dokumente auf einem anderen Server befinden, ist der Hintergrund in einem Rot-Ton gehalten und einige Informationen sind nicht verfügbar.

Ordner bearbeiten

image2015-5-29 9:23:11.png

Mit einem Klick auf "bearbeiten" in der Ordneransicht der Übersichtsseite gelangen Sie auf die Bearbeitungsseite des Ordners. Hier verfügen Sie über folgende Möglichkeiten:

aktiviert Aktivieren Sie den Ordner, damit er in der Datenbank genutzt werden kann.
Name Vergeben Sie einen aussagekräftigen Namen für den Ordner.
virtueller Verzeichnisname Das CMS verwendet intern spezielle Bezeichnungen, die Sie bitte hier eintragen. Halten Sie sich dabei unbedingt an die aufgeführten Konventionen, verwenden Sie also nur Kleinbuchstaben und keine Leer- oder Sonderzeichen.
im Ordner Hier können Sie festlegen, wo der Ordner in der Ordnerhierarchie platziert werden soll. Klicken Sie auf die Auswahlbox und Sie können in der vollständigen Liste den gewünschten übergeordneten Ordner auswählen.

Dokument bearbeiten

image2015-5-29 9:25:46.png

Hier finden Sie z.B. Informationen wie Dateiname, Upload-Datum, Verwendungen und Links. Beim Download vorgeschlagener Dateiname und Beschreibung helfen, wenn Sie das Dokument veröffentlichen wollen. Es ist auch möglich die Datei in einen neuen Ordner zu verschieben oder sie komplett auszutauschen (wählen Sie dazu die neue Datei mittels "Durchsuchen" von einem lokalen Datenträger aus und Betätigen Sie den Button ButtonSpeichern.pngSpeichern).

Tip

Es ist ratsam, bei PDF-Dokumenten immer einen aussagekräftigen Titel einzutragen, damit bei der Suche dieser angezeigt werden kann und der Crawler beim Indizieren der Seiten keinen Fehler bringt.

Ressourcen & Plugins

Plugin Newsletter

Dieses Plugin ist zwar schon etwas älter, wird allerdings noch in vielen Projekten eingesetzt.

Bedienungsanleitung für Redakteure

Die Redakteure können Artikel, Rubriken und Abonnenten selbst anlegen und pflegen, aber das NL-Design ist doch etwas anspruchsvoller.

Bisherige Methode mit Platzhaltern (wurde bei "HTML-Quellcode" eingefügt, siehe Bild unten)

Quellcode vom Hauptteil

<tr>
  <td width="200"><!-- PICTURE --></td>
  <td>
    <strong><!-- TITEL --></strong><br>
    <!-- TEXT --><br>
    <br>
    <!-- LINK -->
  </td>
</tr>
<tr>
  <td colspan="2"><hr class="dotted"></td>
</tr>

HTML-Quellcode

<html>
  <head>
      <style type="text/css">
          body{font-family:sans-serif;font-size:10pt;}
          hr{height:0;border-top:1px solid black;border-bottom:0;}
          hr.dotted{border-top:1px dotted black;}
        </style>
    </head>
  <body>
    <table width="700" align="center" style="background-color:#dedede;">
          <tr><td colspan="2"><img src="http://demo.batix.de/pic/164CB94635F.jpg?size=140x100" border="0"> NEWSLETTER</td></tr>
          <tr><td colspan="2"><hr><!-- HEAD --></td></tr>
          <tr><td colspan="2"><!-- ANKER --><hr class="dotted"></td></tr>
          <!-- MAIN -->
          <tr><td colspan="2"><!-- BOTTOM --></td></tr>
          <tr><td colspan="2"><hr><a href="http://demo.batix.de/www/wiki_web/nl_abmelden.htm?aboid=<!-- ABOID -->">vom Newsletter abmelden</a></td></tr>
        </table>
  </body>
</html>

Platzhalter für den Hauptteil, also der Teil, der den Artikel repräsentiert und sich wiederholt.

Platzhalter Feldname bei "Artikel bearbeiten"
Titel
Datum
Beitrag

(rechtsbündig) erstes Bild
(linksbündig)

(rechtsbündig) zweites Bild
(rechtsbündig)
Nummer des Artikels, zum Bau einer Sprungmarke
baut aus den Feldern "Link-Text" und "Link" einen Link zusammen
"Bildunterschrift / 2.Titel" - kann für genau diese Zwecke verwendet werden

Platzhalter für den Seiten-Quellcode (der Teil für die Artikel wird gesondert behandelt)

Platzhalter Feldname
Kopftext (bei "Versand"/"Kopftext" oder beim Design)
an dieser Stelle wird der Quelltext des Hauptteils eingefügt, der separat definiert wird (siehe oben)
Impressumstext (bei "Versand"/"Kopftext" oder beim Design)
Liste der Artikel ohne Link
generiert eine Liste der Artikel aus den Titeln, Sprungmarke wird an den Titel im Artikel gepappt
in Verbindung mit Email zum Abmelden (Weiterleitung auf Abmelde-Action, Übergabe der Werte aboid und email
siehe oben
um Rubriken zu ändern, beim Klick drauf kommt man auf die Website und ist gleich angemeldet und kann die Rubriken ändern.

Dort kann jetzt auch ein Pfad zu einem HTML-Design mit Tags angegeben werden:

nl.png

Neue Methode mit Tags

Anstelle der Platzhalter kann auch ein Design angegeben werden, in dem Tags anstelle der Platzhalter eingesetzt werden können.

<!-- eigentliche Schleife über die Artikel -->
  <bx:newsletterdesign.articles> ... <bx:newsletterdesign.articles>  

<!-- einzelnen Elemente eines Newsletterartikels (Tabelle NLARTIKEL) -->
  <bx:newsletterdesign.datum [pattern="dd.MM.yyyy"] [locale="de"]/>
  <bx:newsletterdesign.titel/>
  <bx:newsletterdesign.subtitel/>
  <bx:newsletterdesign.text/>
  <bx:newsletterdesign.link/>
  <bx:newsletterdesign.picture width="..." height="..." [html-Attribute für img-Tag]/>
  <bx:newsletterdesign.picture2 width="..." height="..." [html-Attribute für img-Tag]/>

<!-- Befehle zu Schleifenverwaltung -->
  <bx:newsletterdesign.index/>
  <bx:newsletterdesign.first [not]> ... </bx:newsletterdesign.first>
  <bx:newsletterdesign.last [not]> ... </bx:newsletterdesign.last>

<!--  -->
  <bx:newsletterdesign.aes />
  <bx:newsletterdesign.aboid />
  <bx:newsletterdesign.email />

<!-- zusätzliche Befehle zum Ausgeben des Kopf und Fußtextes des Newsletterdesigns (Tabelle NLDESIGN) -->
  <bx:newsletterdesign.headfield/>
  <bx:newsletterdesign.bottomfield/>

<!-- Abonnenten-Angaben -->
  <bx:newsletterdesign.user field="{Feldname}" /> <!-- mögliche Werte für das Feld: "ansprech", "firma", "email", "id" -->

<!-- wäre auch noch möglich: -->
<bx:newsletterdesign.usermember rubrik="150ABCDEF987" not> User nicht in RubrikX </bx:newsletterdesign.usermember>
<bx:newsletterdesign.articles>

</bx:newsletterdesign.articles>

Die folgenden Platzhalter sind zusätzlich im Emailtext (der Optin-Email) verfügbar:

<LIST> eine mehrzeilige Liste der gebuchten Rubriken mit Anstrich davor
<PASSWORD> das Passwort (mittlerweile unüblich und meist nicht mehr vergeben)
[[aboid]] Die Datensatz-ID der Abonnenten (für das Abo-aktivieren-Action)
[[activateid]] ein verschlüsselt aussehender Wert für das Abo-aktivieren-Action (enthält Email-Adresse und aboid)

Test-Beispiel

Beispiel Titel

<html>
    <head>
        <style type="text/css">
        .kopf { border:1px solid darkred; background-color:mistyrose; padding:5px }
        .fuss { border:1px solid forestgreen; background-color:lightgreen; padding:5px }
        .mitte { border:1px solid silver; background-color:whitesmoke; padding:5px }
        .artikel { border:1px solid navy; background-color:lightblue; padding:5px }
        </style>
    </head>
    <body>
        <div class="kopf"><bx:newsletterdesign.headfield/></div>

        <div class="mitte">
            <ul>
                <bx:newsletterdesign.articles>
                    <li>#<bx:newsletterdesign.index/>: <a href="#anker<bx:newsletterdesign.index/>"><bx:newsletterdesign.titel/></a></li>
                </bx:newsletterdesign.articles>
            </ul>
            <bx:newsletterdesign.articles>
                <bx:newsletterdesign.first>[[begin-liste[<br></bx:newsletterdesign.first>
                <div class="artikel">
                    <bx:newsletterdesign.picture width="200" height="200" style="float:right"/>
                    <bx:newsletterdesign.picture2 width="50" height="50" style="float:left"/>
                    <a name="anker<bx:newsletterdesign.index/>">#</a>
                    <i>D="<bx:newsletterdesign.datum pattern="d. MMMMMM yyyy" locale="de"/>"</i><br>
                    <b>T="<bx:newsletterdesign.titel/>"</b><br>
                    <br>
                    <bx:newsletterdesign.text/>
                    <br><br>Bildtitel={<bx:newsletterdesign.subtitel/>}
                    <br>URL=[<bx:newsletterdesign.link/>]
                </div>
                <bx:newsletterdesign.last not><hr style="clear:both"></bx:newsletterdesign.last>
                <bx:newsletterdesign.last><br>]ende-liste]]</bx:newsletterdesign.last>
            </bx:newsletterdesign.articles>
        </div>

        <div class="fuss"><bx:newsletterdesign.bottomfield/></div>
    </body>
</html>

Test-Design mit allen Befehlen.

Ressourcen & Plugins

Ressourcen/Plugins

Im Bereich Ressourcen finden Sie alle Daten, Vorlagen, Aktionen und andere Ressourcen, die Sie für Ihr Projekt benötigen. Dieser Bereich ist in folgende Teilbereiche gegliedert:

Mediendatenbank
Die zweigeteilte Mediendatenbank beinhaltet, in frei einteilbarer Kategorisierung, alle dynamisch verwendeten Grafiken und Dokumente eines Mandanten.

Container
Hier definieren Sie Container, erstellen Container auf Grundlage der angelegten Definitionen für die Verwendung in einem oder mehreren Projekten und weisen diesen nach Bedarf bestimmte Formate (Designvorlagen) zu.

Vorlagen
Hier speichern und bearbeiten Sie Vorlagenressourcen (statische Elemente eines Projektes), Dokumentvorlagen (z.B. HTML-Templates oder Textbausteine) und Stilvorlagen (z.B. CSS-Dateien).

Aktionen
Hier definieren und bearbeiten Sie Aktionen, die für Abläufe im Projekt von Bedeutung sind (z.B. Emailversand, Speichern von Datensätzen, Weiterleitungen ...).

Zeitsteuerung
Nur für Administratoren - Hier definieren Sie zeitgesteuerte, projektspezifische Aktionen (z.B. regelmäßige Indizierung für die interne Suchmaschine oder automatisches Archivieren abgelaufener Meldungen).

Ressourcen & Plugins

Vorlagen

Unter Vorlagen werden alle Daten (Grafiken, Dateien, Scripte u.a.) verstanden, die nicht dynamisch in Bestandteile des CMS integriert werden, sondern vielmehr die Grundlage für Gestaltung und Funktionalität z.B. einer Webseite bilden. Dazu gehören:

Dokumentvorlagen

Dokumentvorlagen sind im Prinzip das Herzstück des CMS. Sie bilden die Grundlage für die Gestaltung eines Webauftrittes und seiner Menüpunkte. An diesen führen sie dynamische Inhalte (Texte, Bilder, Dateien) mit festen Bestandteilen (Vorlagenressourcen) und Inhalten von Containern zusammen. Sie greifen auf Stilvorlagen zurück und realisieren somit ein CI-gerechtes Erscheinungsbild. Im Zusammenwirken mit den Aktionen an einem Menüpunkt bewirken Sie außerdem die Realisierung erforderlicher Funktionalitäten. Darüber hinaus realisieren sie ebenfalls die Bearbeitungsmöglichkeiten im Arbeitsbereich der Administration - ist z.B. auf der Webseite das Erscheinen eines Bildes und eines Textes gewünscht, werden im Administrationsbereich entsprechende Eingabemöglichkeiten geschaffen.

ressource3.jpg

Übersichtsseite

image2015-5-28 10:50:50.png

Dokumentvorlagen sind in folgende Typen unterteilt:

Komplettseiten vollständige (HTML-)Seiten für den Gebrauch vor allem in Menüpunkten
Designtemplates Dokumentvorlagen für die Ausgabegestaltung von Containerinhalten (Formatzuweisung)
Textbausteine "Codeschnippsel" zur Verwendung in Komplettseiten
Beispiel: Es gibt einen Textbaustein Navigation, welcher in allen Komplettseiten verwendet, aber nur hier einmalig angelegt und gepflegt wird. Machen sich Änderungen notwendig, muss nur an dieser einen Stelle eingegriffen werden.
Tipp: Überlegen Sie beim Aufbau der einzelnen Seiten Ihres Projektes genau, welche Inhalte (z.B. Banner oben, Navigation, Links, Impressum unten usw.) auf allen Seiten identisch sind. Diese Bestandteile sind geborene Kandidaten für Textbausteine.
JSP-Bausteine
Groovy
Plugins
sonstige ein weiterer Typ zur Ablage von Dokumentvorlagen

Bearbeitungsseite

Hier speichern Sie den Quelltext (z.B. HTML-Template) der Dokumentvorlage und nehmen weitere Einstellungen vor. Diese sind im einzelnen:

Auch hier können Sie über die entsprechenden Buttons in der Symbolleiste eine neue Dokumentvorlage erstellen bzw. die vorhandene löschen.

Achtung: Das Löschen der Dokumentvorlage hat zur Folge, dass Menüpunkte, die diese Dokumentvorlage verwenden, in der Administration redaktionell nicht mehr bearbeitet werden können und im Webauftritt Fehlermeldungen verursachen.

Volltextsuche in Dokumentvorlagen

Ab Version 2.4 ist es möglich, eine Volltextsuche über alle Dokumentvorlagen durchzuführen. Dabei werden diese nach der eingegebenen Zeichenkette durchsucht. Das Eingabefeld steht in der Toolbox zur Verfügung. Die passenden Dokumentvorlagen werden daraufhin unter dem Eingabefeld verlinkt aufgelistet.

Statische Ressourcen

Der Punkt "statische Ressource" ersetzt den Punkt Vorlagenressourcen. Wie im Explorer können hier Ordner angelegt werden.

zweifache F-Tastenbelegung, Umschaltung mit "Strg"-Taste (Fokus muß auf dieser Seite sein)

ressourcen2.jpg

Stilvorlagen

Stilvorlagen realisieren den Ausgabestil von Dokumentvorlagen. Für Webseiten bedeutet dies, dass eine CSS-Datei (Stilvorlage) einem HTML-Template (Dokumentvorlage) mitteilt, welche Formatierungen für Schriften, Grafiken, Eingabefelder usw. verwendet werden sollen.

ressourcen4.jpg

Übersichtsseite

image2015-5-28 11:8:42.png

Sie sehen eine Listenform aller vorhanden Stilvorlagen, die den einzelnen Dokumentvorlagen zugeordnet werden können. An Informationen werden Ihnen die Bezeichnung der Stilvorlage, deren Größe in Bytes und der Status angezeigt. Inaktive Stilvorlagen können nicht verwendet werden. Die entsprechenden Einstellungen nehmen Sie auf der Bearbeitungsseite vor, die Sie durch einen Klick auf die Bezeichnung der gewünschten Stilvorlage erreichen.

Bearbeitungsseite

image2015-5-28 11:9:14.png

Auf der Bearbeitungsseite können Sie folgende Einstellungen vornehmen:

Vorlagenressourcen

Vorlagenressourcen sind Dateien, die direkt aus Dokumentvorlagen angesprochen und nicht einem Menüpunkt dynamisch zugewiesen werden. Daher werden diese Vorlagenressourcen auch als "statisch" bezeichnet.

Zur Speicherung der statischen Quellen sollte "Vorlagenressourcen" nicht mehr verwendet werden, sondern stattdessen "statische Ressourcen" .

ressourcen1.jpg

image2015-5-28 10:27:20.png

Wählen Sie eine Datei von Ihrem lokalen Datenträger und speichern Sie diese in den Vorlagenressourcen durch Betätigung des Buttons "upload". Welche Dateitypen das CMS verwenden kann, entnehmen Sie bitte der Liste. Es besteht weiterhin die Möglichkeit, alle Dateien in den Vorlagenressourcen als ZIP-Datei zu exportieren. Klicken Sie auf den entsprechenden Link und Sie werden nach Abschluss des Komprimierungsvorganges zum Speichern der generierten Datei aufgefordert. In der unteren Liste werden Ihnen alle vorhandenen Dateien mit Originalname, Erstelldatum (= Datum des Uploads in das CMS) und Dateigröße präsentiert. Mit einem Klick auf "bearbeiten" können Sie verschiedene Details der Datei editieren:

Mit einem Klick auf ButtonLöschen.pngDatensatz löschen können Sie die gerade ausgewählte Datei aus dem System entfernen. Vorsicht: Verwenden Sie diese Datei (z.B. in einer Dokumentvorlage) führt das Entfernen der Datei zu Fehlern auf der Webseite!

Ressourcen & Plugins

Zeitsteuerung

Mit der Zeitsteuerung kann man bestimmte Abläufe zeitlich steuern. Bisher wurde ein einfacher Timer benutzt, mit dem Start- und Endzeit und die Intervalle einstellen konnte. Ab Version 2.6.1. ist ein neuer Timer eingebunden, mit dem dann auch solche Zeiten wie z.B. "jeden Freitag um neun Uhr" oder "jeden Wochentag um 9.30 Uhr" oder sogar "alle 5 Minuten zwischen 9.00 und 10.00 Uhr an jedem Montag, Mittwoch und Freitag im Januar" möglich sind.

in alten Versionen

TimerTaskKlassen:

veraltet: (nicht mehr benutzen)
com.batix.timer.ContainerDeActivatorTask (aktiviert/deeaktiviert alte Containerdatensätze wenn Datum herangekommen ist)
com.batix.timer.ContainerRemoveTask (löscht alte Containerdatensätze wenn Datum herangekommen ist)
com.batix.timer.DetailDeactivatorTask (bx:schleife deaktiviert einzelne Schleifen-Datensätze)
com.batix.timer.NavDeActivatorTask ( aktiviert/deeaktiviert Navigationspunkte zu bestimmten Zeitpunkt)
com.batix.timer.NewsArchiver (altes Newssmodul; verschiebt alte News ins Archiv)

aktuelle Timerklassen:

com.batix.timer.ContainerImportTimer (aktualisiert einen neuen Container mit Daten von einem anderen System)

Steuerparameter:
container-id=125DA0FBA30 - Container intern
extern-id=10EA47412E6 - Container extern
extern-host=https://www.externer-server.de - Hostname des externen Systems
img-kat=125A1311768 - Bildergaleriekategorie für importierte Bilder
doc-kat=125A2CE1376 - Bildergalerieordner für importierte Dokumente
flag=html - Editorfelder mit importieren


com.batix.timer.UserReactivation (aktiviert gesperrte User, wenn sie 3x falsches Passwort eingegeben hatten)

com.batix.timer.VisitorStatTimer (verkürzt Userstatistik)

Steuerparameter:
days-to-keep=60


com.batix.timer.URLConnectionTimer (ruft URL auf (für gewöhnlich ein Action))

Steuerparameter:
url=http://www.dein-web.de/aktionen/testaktion.act - ruft ein Aktion auf
max-redirects=30 - Anzahl der Redirekts (optional)


com.batix.search.CrawlerTask (Keywords: Web indizieren, Indizierung, Crawler)

Steuerparameter:
sleeptime=500
report-to=Email-Adresse (liefert einen Report über die Seiten, die beim indizieren 404 zurückgeliefert haben, an die angegebenen E-Mail-Adresse, ab 2.6.1 RC15)
report-from=Absender-Adresse (wenn report-from fehlt, wird noreply@batix.info verwendet)

Um auch Actions zu indizieren (z.B. Weiterleitungen usw. - wenn man sicher ist, daß nix gelöscht wird) kann man im Action in die Metadaten accept-crawler=true eintragen.

ab Version 2.6.1 - Cron Trigger

Cron Trigger sind oft besser geeignet als SimpleTrigger, wenn man zu wiederkehrenden Zeiten Jobs starten will, im Gegensatz zu exakt angegebenen Zeitintervallen beim Simple Trigger. Mit dem Cron Trigger kann man Startzeiten festlegen wie z.B. "jeden Freitag um neun Uhr" oder "jeden Wochentag um 9.30 Uhr" oder sogar "alle 5 Minuten zwischen 9.00 und 10.00 Uhr an jedem Montag, Mittwoch und Freitag im Januar". Der Cron Trigger hat aber auch analog dem Simple Trigger eine Startzeit und Endzeit, die den Einsatz des Triggers steuert.

Mode

Ausführlich: Zeiträume können über bestimmte Felder ausgewählt werden Expert: Zeiträume können mit Cron-Expressions im Feld "Cron-Trigger" angegeben werden

Stunde

Innerhalb welcher Stunde(n)?

jede - innerhalb jeder Stunde Zahl auswählen - innerhalb der ausgewählten Stunde, z.B. 0 angegeben, dann von 0 .00 bis 0.59 zyklisch - alle 2,4,... Stunden starten (für je eine Stunde) Eingabe - spezielle Angaben mit Cron-Expressions Werte: '*' - gleichbedeutend mit Auswahl 'jede' 0 1 2 ... 23 - gleichbedeutend mit Zahl auswählen ',' - mehrere Stunden angeben z.B. '3,7,10': innerhalb der Stunde 3, 7 und 10 '-' - Zeitraum definieren, z.B. '10-20' bedeutet: ab Stunde 10 bis einschließlich Stunde 20 '/' - Inkremente (bei zyklischem Start) festlegen, z.B. 0/2 bedeutet: Start mit Stunde 0 alle 2 Stunden (gleichbedeutend mit Auwahl zyklisch und Angabe einer Zahl) oder 3/3 bedeutet: Start mit Stunde 3 alle 3 Stunden

Minute

Zu welcher Minute innerhalb der Stunde(n) bzw. Alle wieviele Minuten innerhalb der Stunde(n)?

jede - startet jede Minute innerhalb der Stunde Zahl auswählen - z.B. Start zur Minute 15 innerhalb der Stunde zyklisch - alle 2, 5,... Minuten starten Eingabe - spezielle Angaben mit Cron-Expressions Werte: '*' - gleichbedeutend mit Auswahl 'jede' 0 1 2 3 .. 59 - gleichbedeutend mit Auswahl einer Zahl '/' - Inkremente (bei zyklischem Start) festlegen, z.B. 0/10 bedeutet: Start mit bei Minute 0 alle 10 Minuten (gleichbedeutend mit Auwahl zyklisch und Angabe einer Zahl) oder 30/2 bedeutet: Start mit Minute 30 alle 2 Minuten ',' - mehrere Werte angeben '2,20,45': Start zur Minute 2, 20 und 45 '-' - Zeitraum definieren, z.B. "10-20" bedeutet: ab Minute 10 bis Minute 20 jede Minute

Tag

Innerhalb welchen Tages im Monat?

jeden - innerhalb jeden Tages im Monat Zahl auswählen - innerhalb des ausgewählter Tages im Monat Eingabe - spezielle Angaben mit Cron-Expressions Werte: '*' - gleichbedeutend mit Auswahl 'jeden' 1 2 3 4 ... 31 - gleichbedeutend mit 'Zahl auswählen' ',' - mehrere Tage angeben, z.B. '13,14,19': innerhalb des 13., 14. und 19. Tages im Monat '-' - Zeitraum angeben, z.B. '5-10': innerhalb des 5. bis einschließlich 10. Tages im Monat /' - Inkremente (bei zyklischem Start) festlegen, z.B. 1/4 bedeutet: (Start mit Tag 1) alle 4 Tage oder 3/3 bedeutet: Start mit Tag 3 alle 3 Tage 'L' - letzter Tag im Monat, egal ob 28. 30. oder 31. Tag, z.B. 'L-2': vor-vorletzer Tag im Monat 'W' - der nächste Wochentag zum angegebenen Tag im Monat, z.B. '13W': wenn der 13. ein Samstag ist, wird der Freitag genommen, wenn er ein Sonntag ist, dann der Montag '?' - kein spezieller Wert (als Art Platzhalter)

Monat

Innerhalb welchen Monats?

jeden - jeden Monat Zahl auswählen - in welchem Monat aktiv? Eingabe - spezielle Angaben mit Cron-Expressions Werte: '*' - gleichbedeutend mit Auswahl 'jeden' 1 2 3 ... 12 oder JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC (gleichbedeutend mit der Auswahl einer Zahl) ',' - Angabe mehrerer Werte, mit Komma getrennt, "FEB,OCT" bedeutet: innerhalb der Monate Februar und Oktober

Wochentag

Innerhalb welchen Wochentages?

jeden - Timer startet täglich Mo-Fr - Timer startet innerhalb dieses Tages Eingabe - spezielle Angaben mit Cron-Expressions Werte: '*' - gleichbedeutend mit Auswahl 'jeden' 1 2 3 ... 7 oder SUN, MON, TUE, WED, THU, FRI SAT - gleichbedeutend mit 'Zahl auswählen' (1=Sonntag) ',' - mehrere Wochentag angeben, z.B. 'MON,FRI': innerhalb Montags und Freitags '-' - Zeitraum angeben, z.B. 'MON-FRI' bedeutet 'wochentags' 'L' - alleinige Angabe: letzter Tag, also Sonnabend. In Verbindung mit einer Wochentagszahl: letzter x-Tag im Monat, z.B. '6L': letzter Freitag im Monat '?' - kein spezieller Wert (als Art Platzhalter) '/' - Inkremente (bei zyklischem Start) festlegen, z.B. 1/2 bedeutet: alle zwei (Wochen)Tage mit Start am Sonntag '#' - der wievielte Wochentag im Monat, z.B. '2#1': der erste Montag im Monat (auch so schreibbar: 'MON#1')

Jahr

Innerhalb welchen Jahres?

jedes - in jedem Jahr Eingabe - es können individuelle Jahre angegeben werden

Wechselwirkungen:

zwischen Wochentag und Tag

z.B. Wochentag "Mo" und Tag "4": jeden Montag, der ein 4. des Monats ist (bei Monat muß dann "jeder" eingestellt sein)

zwischen Monat und Tag

z.B. Monat "jeden" und Tag "31": an jedem 31. d. Monats, also nur in Monaten, die 31 Tage haben (Tag: "jeder")

zwischen Monat, Tag und Wochentag

z.B. Monat "9", Wochentag "Fr" und Tag "13": wenn der September eine Freitag, den 13. hat, dann startet der Timer, ansonsten nicht

Das ganze kann noch mit Jahr gekoppelt werden, ist aber m.E. nicht sinnvoll

Aktion

Auswahl eines Timer-Actions (siehe oben unter "Aktuelle Timerklassen")

Steuerparameter

siehe oben unter "aktuelle Timerklassen" unter jeweiliger Klasse

Cron-Expressions

Cron-Expressions werden verwendet, um eine Instanz eines Cron-Triggers zu configurieren. Cron-Expressions sind Strings die aus 7 Einzelwerten bestehen, die die individuellen Einzelheiten des Ablaufplans beschreiben. Die Einzelwerten werden mit Leerzeichen getrennt und repräsentieren:

0 0 5 * * ? *
┬ ┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │ │ └── Jahr (optional) 
│ │ │ │ │ └──── Wochentag (1-7) (Sonntag=1)
│ │ │ │ └────── Monat (1-12)
│ │ │ └──────── Tag (1-31)
│ │ └────────── Stunde (0-23)
│ └──────────── Minute (0-59)
└────────────── Sekunde (0-59, meist 0)

Die zu verwendenden Werte stehen oben unter dem jeweiligen Feld (Tag, Monat usw.).

Beispiele: "0 0 12 ? * WED" - startet jeden Mittwoch um 12.00 Uhr "0 0/5 * * * ?" - startet alle 5 Minuten (beginnend mit Minute 0) "0 30 10-13 ? * WED,FRI" - startet um 10:30, 11:30, 12:30, and 13:30, jeden Mittwoch und Freitag "0 0/30 8-9 5,20 * ?" - startet halb zwischen 8 und 10 Uhr am 5. und 20. jeden Monats. Start also um 8.00, 8.30, 9.00 und 9.30, aber nicht um 10:00 Uhr Manche Startzeiten sind aber auch zu komplex, um sie in nur einem Ausdruck abhandeln zu können, z.B. alle 5 Minuten zwischen 9.00 und 10.00 Uhr und alle 20 Minuten zwischen 1.00 und 10.00 Uhr. Das kann man nur mit zwei Timern abhandeln.

Snippets & Rezepte

Fertige Code-Bausteine für häufige Aufgaben.

Snippets & Rezepte

Action-Parameter anlegen

Es kann sein, daß man innerhalb eines Actions Parameter benötigt, die im Request nicht übergeben wurden. Hierzu kann man den Action-Baustein "Batix Quelltext ausführen" im Zusammenhang mit dem Tag "bx:pagedata.setscriptattribute" benutzen. Hierzu ein paar Beispiele:

Umwidmen eines Request-Parameters

<bx:pagedata.setscriptattribute name="Email"><bx:pagedata.request name="Imehl"/></bx:pagedata.setscriptattribute>

Bestandteil einer Botfalle

Quelltext der Seite

<bx:containerfilter.Mitarbeiter pool="Mitarbeiter" idfield="mid" force="single">
  <bx:pagedata.setscriptattribute name="Email"><bx:recordfield.Email/></bx:pagedata.setscriptattribute>
</bx:containerfilter.Mitarbeiter>

Wenn man im nachfolgenden Action die Email braucht, diese aber nicht übergeben wurde (z.B. für Email-Versand-Action)

<bx:pagedata.setscriptattribute name="weiterleitung">
  <bx:pagedata.request name="abgeschlossen" value="j">/test/naechsteSeite.htm</bx:pagedata.request>
  <bx:pagedata.request name="abgeschlossen" value="n">/test/gleicheSeite.htm</bx:pagedata.request>
</bx:pagedata.setscriptattribute>

Im anschließenden Weiterleitungsaction kann der Parameter mit [[abgeschlossen]] eingesetzt werden.

Snippets & Rezepte

Blättern (Pagination)

Einfaches Listenblättern

sieht so aus:

liste.PNG

Die Leiste oben und unten kann in Bausteine ausgegliedert werden. Dann kann Sie für jede Liste im Web genutzt werden. Voraussetzung: die Liste heißt dann immer "Liste", also <bx:containerfilter.Liste pool="...">

HTML in der Seite

<bx:include modul="blaetternOben"/>

<bx:containerfilter.Liste pool="Witze" orderby="Titel" max="5">
  <div class="listitem"<bx:recorddata.if last> style="margin-bottom:0;"</bx:recorddata.if>>
    <a href="detail.htm?rezeptid=<bx:recorddata.id/>"><bx:recordfield.Titel/></a>
  </div>
</bx:containerfilter.Liste>

<bx:include modul="blaetternUnten"/>

ausgelagertes Include "blaetternOben"

<div class="blaetternoben">
  <bx:recorddata.nav object="Liste">
    <bx:recorddata.startindex/> - <bx:recorddata.endindex/> von <bx:recorddata.total/> Einträgen
  </bx:recorddata.nav>
</div>

ausgelagertes Include "blaetternUnten"

<div class="blaetternunten">
  <bx:recorddata.nav object="Liste">
    <bx:if><bx:recorddata.previouslist><< zurück</bx:recorddata.previouslist><bx:if.else><span style="color:#8f8f8f;"><< zurück</span></bx:if.else></bx:if>
    &nbsp;&nbsp;|&nbsp;<strong>Seite:</strong>&nbsp;
    <bx:recorddata.navlink move="-5"/>
    <bx:recorddata.navlist max="5" boundary="&nbsp;·&nbsp;"/>
    <bx:recorddata.navlink move="5"/>
    &nbsp;|&nbsp;&nbsp;
    <bx:if><bx:recorddata.nextlist>weiter >></bx:recorddata.nextlist><bx:if.else><span style="color:#8f8f8f;">weiter >></span></bx:if.else></bx:if>
  </bx:recorddata.nav>
</div>

wenn nichts zum Blättern da ist, nicht anzeigen

<bx:tabledata.nav object="Aktuelles">
  <bx:iF type="any">
    <div class="blaetternunten">
      <bx:iF.ignore>
        <bx:if><bx:tabledata.previouslist><< zurück</bx:tabledata.previouslist><bx:if.else><span style="color:#8f8f8f;"><< zurück</span></bx:if.else></bx:if>
      </bx:iF.ignore>
      &nbsp;&nbsp;|&nbsp;<strong>Seite:</strong>&nbsp;
      <bx:tabledata.navlink move="-5"/>
      <bx:tabledata.navlist max="5" boundary="&nbsp;·&nbsp;"/>
      <bx:tabledata.navlink move="5"/>
      &nbsp;|&nbsp;&nbsp;
      <bx:iF.ignore>
        <bx:if><bx:tabledata.nextlist>weiter >></bx:tabledata.nextlist><bx:if.else><span style="color:#8f8f8f;">weiter >></span></bx:if.else></bx:if>
      </bx:iF.ignore>
    </div>
  </bx:iF>
</bx:tabledata.nav>

zugehöriges CSS

.blaetternunten,.blaetternoben{
  background-color:#999999;
  text-align:center;
  padding:5px;
  color:#ffffff;
  }

Etwas ausführlicheres Stylen

sieht so aus:

liste1.PNG

Code

<bx:recorddata.nav object="Liste">
  <div id="blaetterbox">
    <div id="blaetterelements">
      <span id="blaettern-left">
       <bx:if><bx:recorddata.previouslist>« zurück</bx:recorddata.previouslist><bx:if.else><span style="color:#B2B2B2;">« zurück</span></bx:if.else></bx:if>
      </span>
      <span id="blaettern-middle">
        <bx:recorddata.navlist max="5" boundary="">
          <bx:recorddata.navlistcurrent><span><bx:recorddata.navlistpage/></span></bx:recorddata.navlistcurrent>
          <bx:recorddata.navlistcurrent not><a href="?index=<bx:recorddata.navlistindex/>"><bx:recorddata.navlistpage/></a></bx:recorddata.navlistcurrent>
        </bx:recorddata.navlist>
      </span>
      <span id="blaettern-right">
        <bx:if><bx:recorddata.nextlist>weiter »</bx:recorddata.nextlist><bx:if.else><span style="color:#B2B2B2;">weiter »</span></bx:if.else></bx:if>
      </span>
    </div>
  </div>
</bx:recorddata.nav>

zugehöriges CSS

#blaetterbox {
  width:100%;
  height:28px;
  background-color:#b2b2b2;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  }
#blaetterbox #blaetterelements {
  width:365px; margin:auto;
  font-size:10pt;
  font-weight:bold;
  padding-top:6px;
  text-align:center;
  }
#blaetterbox #blaetterelements #blaettern-middle{#
  padding:0 20px;
  }
#blaetterbox #blaetterelements #blaettern-left a, #blaetterbox #blaetterelements #blaettern-right a{
  text-decoration:none;
  color:#605639;
  filter: dropshadow(color=#949494, offx=-1, offy=-1);
  }
#blaetterbox #blaetterelements #blaettern-left span, #blaetterbox #blaetterelements #blaettern-right span{
  text-decoration:none;
  color:#ffffff;
  text-shadow: -1px -1px 0px #949494;
  filter: dropshadow(color=#949494, offx=-1, offy=-1);
  }
#blaetterbox #blaetterelements #blaettern-middle span{
  text-decoration:none;
  letter-spacing:5px;
  color:#ffffff;
  background-color:#968659;
  padding:6px 1px 5px 7px;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  }
#blaetterbox #blaetterelements #blaettern-middle a{
  text-decoration:none;
  letter-spacing:5px;
  color:#605639;
  padding:6px 1px 7px 7px;
  }

Springe-zu-Funktion

Ergänzung mit:

Code

<br><br>springe zu: 
<select name="change" size="1" style="width:50px;" onchange="">
  <bx:recorddata.navlist object="MeineSuchergebnisliste" max="0">
    <option value="<bx:recorddata.navlistpath encoding="html" />"><bx:recorddata.navlistpage/></option> 
  </bx:recorddata.navlist>
</select>

sieht dann so aus:

fff.png

Dieser Quelltext-Schnipsel kann beliebig außerhalb des recorddata.nav-Blocks in das HTML-Template eingebunden werden (auf Wunsch auch innerhalb, kein Ding) und baut eine SELECT-Box in den HTML-Quellcode ein inkl. aller verfügbaren Seitenergebnisse und dem entsprechenden Blätter-Parameter.

Hinweis:
Man muss abschließend nur noch die SELECT-Box via JavaScript animieren etwas zu tun, wenn eine Auswahl getroffen wurde (Parameter versteckt setzen+Form abschicken oder URL-Aufruf …)

Zusätzlich kann eine kleine Abfrage um die Select-Box gebaut werden, dass diese bspw. nur angezeigt wird, wenn es mehr als 5 Seiten zu blättern gibt. Somit bleibt die Webseite schön clean und wenn es wirklich mehrere Suchseiten gibt die auch nicht mehr über die bisherige Darstellung sinnvoll angezeigt werden, dann ist die Springe-zu-Funktion hilfreich. Bei 2 Seiten ist diese neue Erweiterung nicht so hilfreich wie bei 15 Suchergebnisseiten.

Bootstrap4-Pagination

<bx:recorddata.empty object="{listenname}" not>
  <bx:recorddata.nav object="Telefonate" indexparam="{parametername_index}">
    <nav aria-label="Page navigation" class="mt-4">
      <ul class="pagination">
        <li class="page-item"><a class="page-link" href="./?parametername_index=0<bx:if>&searchvalue=<bx:pagedata.request name="searchvalue"/></bx:if>" title="zur ersten Seite"><i class="fa fa-fast-backward" aria-hidden="true"></i> zur Seite 1</a></li>

        <bx:recorddata.previouslist type="if"><li class="page-item"><a class="page-link" href="./?parametername_index=<bx:Recorddata.previouslist type="index"/><bx:if>&searchvalue=<bx:pagedata.request name="searchvalue"/></bx:if>" title="eine Seite zurück"><i class="fa fa-backward" aria-hidden="true"></i></a></li></bx:recorddata.previouslist>
      
        <bx:recorddata.navlist max="5">
          <bx:recorddata.navlistcurrent not>
            <li class="page-item"><a class="page-link" href="./?parametername_index=<bx:recorddata.navlistindex/><bx:if>&searchvalue=<bx:pagedata.request name="searchvalue"/></bx:if>" title="Zur Seite <bx:recorddata.navlistpage/>"><bx:recorddata.navlistpage/></a></li>
          </bx:recorddata.navlistcurrent>
          <bx:recorddata.navlistcurrent>
            <li class="page-item active"><a class="page-link" href="#"><bx:recorddata.navlistpage/> <span class="sr-only">(current)</span></a></li>
          </bx:recorddata.navlistcurrent>
        </bx:recorddata.navlist>
      
        <bx:recorddata.nextlist type="if"><li class="page-item"><a class="page-link" href="./?parametername_index=<bx:Recorddata.nextlist type="index"/><bx:if>&searchvalue=<bx:pagedata.request name="searchvalue"/></bx:if>" title="eine Seite vor"><i class="fa fa-forward" aria-hidden="true"></i></a></li></bx:recorddata.nextlist>
    
        <li class="page-item"><a class="page-link" href="./?parametername_index=<bx:recorddata.lastlist type="index"/><bx:if>&searchvalue=<bx:pagedata.request name="searchvalue"/></bx:if>" title="zur letzten Seite">zur Seite <bx:recorddata.totalpages/> <i class="fa fa-fast-forward" aria-hidden="true"></i></a></li>
      </ul>
    </nav>
  </bx:recorddata.nav>
</bx:recorddata.empty>
Snippets & Rezepte

CSS-Menü

Beispielcode für ein einfaches Menü

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Batix Testmenü mit CSS</title>
<link rel="stylesheet" href="batix-css-menue.css" type="text/css">
</head>
<body>
 
<div class="BX_cssmenue">
  <ul>
    <bx:sitemap.0>
     <li><!--[if IE]><!--><a<bx:sitemap.if hasChilds> class="submenue"</bx:sitemap.if> href="/www/<bx:pagedata.webdir/>/<bx:navigation.path/>/" target="<bx:navigation.target default="_self"/>" title="<bx:navigation.meta name="meta"/>"><!--<![endif]--><bx:sitemap.name/>
      <!--[if gt IE 6]><!--></a><!--<![endif]--><!--[if lte IE 6]><table><tr><td><![endif]-->
        <bx:sitemap.if hasChilds><ul></bx:sitemap.if>
          <bx:sitemap.1>
           <li class="<bx:sitemap.if first>firstitem</bx:sitemap.if><bx:sitemap.if last>lastitem</bx:sitemap.if>"><a<bx:sitemap.if hasChilds> class="submenue"</bx:sitemap.if> href="/www/<bx:pagedata.webdir/>/<bx:navigation.path/>/" target="<bx:navigation.target default="_self"/>" title="<bx:navigation.meta name="meta"/>"><bx:sitemap.name/>
            <!--[if gt IE 6]><!--></a><!--<![endif]--><!--[if lte IE 6]><table><tr><td><![endif]-->
              <bx:sitemap.if hasCHilds><ul></bx:sitemap.if>
                <bx:sitemap.2>
                 <li class="<bx:sitemap.if first>firstitem</bx:sitemap.if><bx:sitemap.if last>lastitem</bx:sitemap.if>"><a<bx:sitemap.if hasChilds> class="submenue"/</bx:sitemap.if> href="/www/<bx:pagedata.webdir/>/<bx:navigation.path/>/" target="<bx:navigation.target default="_self"/>" title="<bx:navigation.meta name="meta"/>"><bx:sitemap.name/></a></li>
                </bx:sitemap.2>
              <bx:sitemap.if hasCHilds></ul></bx:sitemap.if>
            <!--[if lte IE 6]></td></tr></table></a><![endif]-->
           </li>
          </bx:sitemap.1>
        <bx:sitemap.if hasChilds></ul></bx:sitemap.if>
      <!--[if lte IE 6]></td></tr></table></a><![endif]-->
     </li>
   </bx:sitemap.0>
  </ul>
</div>
 
</body>
</html>

Beispiel für die dazugehörige css-Datei

 .BX_cssmenue {
  width:600px;
  height:25px;
  border:1px solid #98b1c4;
  background:#bdcedc;
  z-index:100;
  position:relative;
}
.BX_cssmenue ul {
  float:left;
  list-style-type:none;
  position:relative;
  margin:0;
  padding:0;
}
.BX_cssmenue li {
  float:left;
}
.BX_cssmenue li:hover,.BX_cssmenue li a:hover {
  position:relative;
}
.BX_cssmenue a {
  display:block;
  float:left;
  height:25px;
  white-space:nowrap;
  padding:0 10px 0 10px;
  line-height:25px;
  font-size:12px;
  font-weight:bold;
  font-family:Arial,Helvetica,sans-serif;
  text-align:center;
  color:#293d6b;
  text-decoration:none;
}
.BX_cssmenue li:hover a,.BX_cssmenue a:hover {
  background:#98b1c4;
}
.BX_cssmenue a.submenue {
  background:url(/static/dev/css-menu/top-sub.gif) no-repeat center right;
  padding:0 20px 0 10px;
}
.BX_cssmenue li:hover a.submenue,.BX_cssmenue a.submenue:hover {
  background:#98b1c4 url(/static/dev/css-menu/top-sub.gif) no-repeat center right;
}
.BX_cssmenue ul ul {
  position:absolute;left:-5000px;
  top:-5000px;
  width:202px;
  height:auto;
  border:none;
  background:#bdcedc;
}
.BX_cssmenue table {
  margin-top:-1px;
  border-collapse:collapse;
}
.BX_cssmenue ul :hover ul {
  left:0px;
  top:25px;
}
.BX_cssmenue li li {
  width:200px;
  border:1px solid #98b1c4;
  border-width:0 1px;
  padding:0
}
.BX_cssmenue li li.firstitem {
  border-top:1px solid #98b1c4;
}
.BX_cssmenue li li.lastitem {
  border-bottom:1px solid #98b1c4;
}
.BX_cssmenue ul ul a,.BX_cssmenue ul :hover ul a,.BX_cssmenue ul :hover ul :hover ul a {
  float:none;
  margin:0;
  width:180px;
  height:auto;
  white-space:normal;
  padding:4px 10px 5px 10px;
  font:bold 12px Arial,Helvetica,sans-serif;
  text-decoration:none;
  text-align:left;
  color:#293d6b;
  background:none;
}
.BX_cssmenue ul ul :hover a,.BX_cssmenue ul ul a:hover,.BX_cssmenue ul ul :hover ul :hover a,.BX_cssmenue ul ul :hover ul a:hover {
  background:#98b1c4;
}
.BX_cssmenue ul ul a.submenue,.BX_cssmenue ul :hover ul a.submenue {
  width:180px;
  padding:4px 10px 5px 10px;
  background:url(/static/dev/css-menu/sub-sub.gif) no-repeat center right;
}
.BX_cssmenue ul ul :hover a.submenue,.BX_cssmenue ul ul a.submenue:hover  {
  background:#98b1c4 url(/static/dev/css-menu/sub-sub.gif) no-repeat center right;
}
.BX_cssmenue ul :hover ul ul {
  position:absolute;
  left:-5000px;
  top:-5000px;
}
.BX_cssmenue ul :hover ul :hover ul {
  left:190px;
  top:-1px;
}
.BX_cssmenue br {
  clear:both;
  height:0;
  font-size: 1px;
  line-height: 0px;
 }
Snippets & Rezepte

CSV-Import in Container

Die Daten einer zuvor hochgeladene CSV-Datei werden in einen Container gespeichert. Es ist auch möglich, eine ZIP-Datei mit verschiedenen CSV-Dateien hochzuladen.

Datei
Feldname der zuvor hochgeladenen Datei
ID_ZielContainer
Angabe der ID, wenn der Name nicht anderweitig ermittelt werden kann (z.B. durch Dateiname oder 1. Zeile in der Datei)
ZielContainer_aus_Datei
noch nicht benutzt
ZielContainer_aus_Dateiname
wenn angehakt, dann wird als Zielcontainer der Name der Datei genommen.
ZielContainer_in_Zeile
Angabe der Zeile, in der der Name des Zielcontainers steht (im Beispiel unten wäre das die 1)
Feldnamen_in_Zeile
Zeilennummer der Zeile, in der die Feldname stehen (im Beispiel unten wäre das die 2)
Trennzeichen
Trennzeichen, mit der die Dateifelder getrennt sind (z.B. , )
Daten_ab_Zeile
Nummer der Zeile, ab der die Daten beginnen (im Beispiel unten wäre das die 3)
Feldnamenliste
Wenn in der Importdatei keine Feldnamen enthalten sind, dann können diese hier angegeben werden.
Namens-Umwandlung
Zeilenweise Liste: CSV-Feldname=Feldname im Container oder Dateiname=ZielContainerID

Beispielaufbau einer CSV-Datei:

Kontakt
Name,Vorname,Abteilung,Telefon,Email
Mustermann,Paul,Datensicherheit,03671/223344,test@batix.com
Wurst,Hans,Marketing,090/345678,hawu@dotcom.com
...

Snippets & Rezepte

Eingeloggt bleiben

Variante 1 - über Sessiongültigkeit

Im Login-Action trägt man im Baustein "Login" im Feld "minimale Sessionlänge" ein, wie lange die Session haltbar ist (in Minuten, 1 Monat = 43200 Minuten).

Danach legt man einen Groovy-Baustein an, wo geprüft wird, ob das Häkchen "eingeloggt bleiben" gesetzt ist. Wenn ja, wird ein Cookie "JSESSIONID" geschrieben, der dann im Browser mit der gleichen Haltbarkeit wie im vorherigen Login-Baustein gespeichert wird (in Sekunden, 1 Monat = 2592000 Sekunden).

import javax.servlet.http.Cookie;

if (action.getParameter("remember") == "j") {
  Cookie c = new Cookie("JSESSIONID", session.id)
  c.maxAge = 2592000 // Sekunden
  c.path ="/"
  action.originalResponse.addCookie(c)
}

Allerding liegen dann viele offene Sessions auf dem Server rum - ist dann wohl eher für kleinere Projekte interessant.

Snippets & Rezepte

Formularversand mit Ajax

Dieses Beispiel veranschaulicht die Möglichkeit Formulardaten mittels jQuery per Ajax versenden. Voraussetzung hierfür ist das Einbinden des jQuery-Frameworks und des speziellen Scriptes jquery.form.js

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Beispieldokument</title>
 
<script type="text/javascript" src="jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="jquery.form.js"></script>
<script type="text/javascript">
  // warten bis die DOM-Struktur geladen ist 
  $(document).ready(function() {
    var options = { 
      target:        '#div_suchergebnisse'   // Element in das die Serverantwort geschrieben wird
      //beforeSubmit:  showRequest,  // optionale Funktion vor dem Absenden des Formulares 
      //success:       showResponse  // optionale Funktion nach dem Absenden des Formulares 
    };
    // Anbindung des betreffenden Formulares, dass per Ajax versendet werden soll (mehrere möglich) 
    $('#testform').ajaxForm(options) 
  });
</script>
 
</head>
<body>
 
  <form name="testform" id="testform" method="post" action="zieladresse.htm">
    <input type="hidden" name="field1"  id="field1" value="">
    <input type="text" name="field2"  id="field2" value=""><br>
    <input type="text" name="field3"  id="field3" value="">
    <input type="submit" value="absenden">
  </form>
 
  <div id="div_suchergebnisse">
    Hier landet das Ergebnis der Suche
  </div>
 
</body>
</html>

Es sind noch wesentlich mehr Optionen für diese Funktion verfügbar.
Mehr Informationen und Script-Download unter http://jquery.malsup.com/form/#getting-started

Snippets & Rezepte

Google-Sitemap Datei erzeugen

Diese Beispiel realisiert folgende Funktionen:

Folgende Tags wurde verwendet:

Quellcode

Dieser Code wird als Designtemplate gespeichert und im Startseiten-Menüpunkt z.B. als sitemap.xml eingebunden. Es ist wichtig, dass diese Datei im obersten Verzeichnis des Projektes liegt, da immer nur URLs unterhalb des Pfades dieser Datei indiziert werden.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<bx:sitemap.1>
	<url>
		<loc>http://<bx:pagedata.hostname/>/www/<bx:pagedata.webdir/>/<bx:sitemap.path/>/</loc>
		<lastmod><bx:tools.lastmodified pattern="yyyy-MM-dd" />T<bx:tools.lastmodified pattern="hh:mm:ss" />+00:00</lastmod>
		<changefreq>weekly</changefreq>
		<priority>1</priority>
	</url>
<bx:sitemap.2>
	<url>
		<loc>http://<bx:pagedata.hostname/>/www/<bx:pagedata.webdir/>/<bx:sitemap.path/>/</loc>
		<lastmod><bx:tools.lastmodified pattern="yyyy-MM-dd" />T<bx:tools.lastmodified pattern="hh:mm:ss" />+00:00</lastmod>
		<changefreq>weekly</changefreq>
		<priority>0.75</priority>
	</url>
<bx:sitemap.3>
	<url>
		<loc>http://<bx:pagedata.hostname/>/www/<bx:pagedata.webdir/>/<bx:sitemap.path/>/</loc>
		<lastmod><bx:tools.lastmodified pattern="yyyy-MM-dd" />T<bx:tools.lastmodified pattern="hh:mm:ss" />+00:00</lastmod>
		<changefreq>weekly</changefreq>
		<priority>0.5</priority>
	</url>
<bx:sitemap.4>
	<url>
		<loc>http://<bx:pagedata.hostname/>/www/<bx:pagedata.webdir/>/<bx:sitemap.path/>/</loc>
		<lastmod><bx:tools.datum pattern="yyyy-MM-dd" day="-3"/></lastmod>
		<changefreq>weekly</changefreq>
		<priority>0.25</priority>
	</url>
<bx:sitemap.5>
	<url>
		<loc>http://<bx:pagedata.hostname/>/www/<bx:pagedata.webdir/>/<bx:sitemap.path/>/</loc>
		<lastmod><bx:tools.datum pattern="yyyy-MM-dd" day="-3"/></lastmod>
		<changefreq>weekly</changefreq>
		<priority>0.20</priority>
	</url>
</bx:sitemap.5>
</bx:sitemap.4>
</bx:sitemap.3>
</bx:sitemap.2>
</bx:sitemap.1>
</urlset>

Es werden alle Menüpunkte bis zu einer Tiefe von 5 Ordnern ausgegeben. priority ist lediglich eine relative, projekt-interne Angabe und wird von Suchmaschinen genutzt, um bestimmte Links bei einer Auswahl von mehreren Links im Projekt zu priorisieren, diese Angabe hat keine Auswirkung auf das Ranking in der Suchmaschine.

Bei lastmod wurden 2 verschiedene Implementierungen genutzt. Mittels bx:tools.lastmodified wird allerdings nur das Bearbeitungsdatum des Hauptmenüpunktes zurückgegeben (nicht das der einzelnen Menüpunkte), bx:tools.datum dagegen liefert immer "Heute - 3 Tage". Welche Möglichkeit genutzt wird, kann nicht verallgemeinert werden (optimal wäre das Bearbeitungsdatum des jeweiligen Menüpunktes).

Snippets & Rezepte

HTML-Mails für MS-Outlook

E-Mails im HTML-Format benötigen ein sehr spezielles Design, um in Outlook korrekt angezeigt zu werden. Es gibt eine ganze Reihe HTML- und CSS-Elemente, die nicht erlaubt sind (z.B. Div's, Hintergrundbilder, Positionierungen etc.).

Eine komplette Liste aller erlaubten/nicht erlaubten Elemente und Parameter finden Sie unter http://msdn.microsoft.com/en-us/library/aa338201.aspx.

Die große Kunst beim HTML-Mail-Design besteht darin, dass die Mails nicht nur in allen Browsern, sondern auch in allen E-Mail-Clients aussehen müssen. Während fast alle Mail-Clients und Webmailer keine Probleme mit der Darstellung haben, kommt Outlook mit modernem HTML-Design überhaupt nicht zurecht und verlangt nach Quellcode, wie er in den frühen 90er Jahren zu finden war. Mail-Designs müssen für Outlook wieder umständlich mit Tabellen, zerschnippelten Bildern und Platzhalter-GIF's erzeugt werden.

Wer hierfür Beispiele braucht, sollte die Newsletter von ALTEC Solartechnik oder Waldbad Brunn abonnieren.

Snippets & Rezepte

Kalender bauen

Benutzt werden die beiden Tags bx:calendarloop und bx:calenderfield

<table class="calendar1">
    <tr class="head">
      <td colspan="7">
        <div class="month">
          <span><a href="./?<bx:calendarfield.month link="prev" object="Kalender"/>" title="einen Monat zurück">&laquo;</a></span>
          <span><bx:calendarfield.month object="Kalender"/></span>
          <span><a href="./?<bx:calendarfield.month link="next" object="Kalender"/>" title="einen Monat vor" >&raquo;</a></span>
        </div>
        <div class="year">
          <span><a href="./?<bx:calendarfield.year link="prev" object="Kalender"/>" title="ein Jahr zurück">&laquo;</a></span>
          <span><bx:calendarfield.year object="Kalender"/></span>
          <span><a href="./?<bx:calendarfield.year link="next" object="Kalender"/>" title="ein Jahr vor">&raquo;</a></span>
        </div>
        <div style="clear:both;"></div>
      </td>
    </tr>
    <tr class="daynames">
      <td>Mo</td>
      <td>Di</td>
      <td>Mi</td>
      <td>Do</td>
      <td>Fr</td>
      <td class="we">Sa</td>
      <td class="we">So</td>
    </tr>
  <bx:calendarloop.Kalender activedayrequest="filter" pool="12549B83FF8" datestart="Startdatum" dateend="Endedatum">
    <bx:calendarfield.if firstweekday><tr class="days"></bx:calendarfield.if>
      <td class="
      <bx:calendarfield.if currentmonth="false">othermonth</bx:calendarfield.if>
      <bx:calendarfield.if weekend>we</bx:calendarfield.if>
      <bx:calendarfield.if mark>marked</bx:calendarfield.if>
      <bx:calendarfield.if today>today</bx:calendarfield.if>">
        <a href="./?filter=<bx:calendarfield.day pattern="dd."/><bx:calendarfield.month pattern="MM."/><bx:calendarfield.year pattern="yyyy"/>"><bx:calendarfield.day pattern="d"/></a>
      </td>
    <bx:calendarfield.if lastweekday></tr></bx:calendarfield.if>
  </bx:calendarloop.Kalender>
  <tr class="footer">
    <td colspan="7">
      <a href="">Heute</a>
    </td>
  </tr>
</table>

zugehöriges CSS

table.calendar1 a{color:#555555;}
table.calendar1 td{width:20px;height:20px;text-align:center;}
table.calendar1 .head td{background-color:#FFB689;}
table.calendar1 .head .month{float:left;padding-left:5px;}
table.calendar1 .head .year{float:right;padding-right:5px;}
table.calendar1 .daynames td{background-color:#aaaaaa;}
table.calendar1 .daynames .we{color:#962420;font-weight:bold;}
table.calendar1 .days td{background-color:#cccccc;}
table.calendar1 .days td.marked{background-color:#FBD9CA;}
table.calendar1 .days td.today{outline:1px solid red;}
table.calendar1 .days td.active{outline:1px solid green;}
table.calendar1 .days td.othermonth{background-color:#eeeeee;}
table.calendar1 .days td.othermonth a{color:#ffffff !important;}
table.calendar1 .days td.we a{color:#962420;font-weight:bold;}
table.calendar1 .footer td{background-color:#FFB689;}
Snippets & Rezepte

Locale bei Date-Pattern hinzufügen

  1. Projekt auswählen
  2. bei Dokumentvorlagen rechts unter Tools auf Quelltext ersetzen klicken
  3. in das erste Textfeld (Suchbegriff) eintragen:
    pattern="([^"]*(?:MMM|E)[^"]*)"(?! locale)
  4. in das zweite Textfeld (Ersetzen durch) eintragen:
    pattern="$1" locale="de"
  5. Haken regulärer Ausdruck setzen
  6. auf Vorschau klicken und prüfen, ob alles passt
  7. auf jetzt ersetzen klicken
  8. ggf. Schritte 6 und 7 wiederholen, falls viele Quelltexte betroffen sind
Snippets & Rezepte

Manipulationsgeschützte Formulare mit Secureform

Vom System generierte Werte in Formularen sind leicht veränderbar. Falls in den Aktionen keine Überprüfungen dieser Werte vorhanden sind, entstehen schnell Sicherheitslecks. Parameter können dann beliebig manipuliert werden und die Aktionsbausteine verrichten unbedarft ihren Dienst mit gefälschten Daten. So können z.B. IDs ausgetauscht werden und somit fremde Datensätze überschrieben werden.

Damit nicht in jeder Aktion selbst eine Überprüfung in JSP oder Groovy geschrieben werden muss, gibt es das Tag bx:secureform und die Aktion Sicheres Formular überprüfen (SecureformAction). Im Zusammenspiel stellen diese beiden Komponenten sicher, dass ausgewählte Parameter nicht manipuliert werden können.

Dieser Artikel bietet eine detaillierte Erklärung der Funktion und Vorgehensweise. Es sollten zusätzlich die Seiten des Tags und der Aktion durchgelesen werden.

Parameter sammeln

Im Formular

Im ersten Schritt werden die zu sichernden Formularelemente gesammelt. Das sind jene Parameter, die später an das Action geschickt werden. Es müssen nicht alle Parameter abgesichert werden, nur jene die im Action als zu sichern angegeben wurden.

Zunächst wird um das gesamte Formular ein <bx:secureform> Tag gesetzt. Dies definiert einen Bereich, in dem Parameter gesammelt werden. Dadurch können auf einer Seite mehrere solche Bereiche definiert werden, falls es mehrere Formulare gibt.

Bereich definieren

<bx:secureform>
  <form action="...">
  </form>
</bx:secureform>

Danach werden die zu schützenden Parameterwerte gesammelt. In den meisten Fällen wird der value eines <input type="hidden"> einfach mit <bx:secureform.field> umschlossen.

Parameter sammeln

<bx:secureform>
  <form action="...">
    <input type="hidden" name="Besitzer" value="<bx:secureform.field name="Besitzer"><bx:userdata.id /></bx:secureform.field>">
  </form>
</bx:secureform>

Falls ein Parameter im Formular geschützt wird, muss er auf jeden Fall auch in den Aktionseinstellungen angegeben werden (s.u.) - da die Prüfung im Baustein sonst fehlschlägt.

Parameter, die nicht mitgesendet werden, falls sie keinen Wert haben, dürfen nicht mit zur Hashbildung herangezogen werden. Das sind z.B. Datensatz-ID Felder, die nur bei fehlerhaften Validierungen gefüllt werden, damit beim erneuten Absenden des Formulars kein neuer Datensatz erzeugt wird. Meist kommt dabei <bx:containerfilter dummy> oder <bx:record dummy> zum Einsatz. Der Parameter hidden-when-empty bewirkt, dass ein Feld mit leerem Wert von <bx:secureform.field> ignoriert wird.

hidden-when-empty

 <bx:secureform>
  <form action="...">
    <bx:if><input type="hidden" name="kid" value="<bx:secureform.field name="kid" hidden-when-empty><bx:recorddata.id /></bx:secureform.field>"></bx:if>
    <input type="hidden" name="Besitzer" value="<bx:secureform.field name="Besitzer"><bx:userdata.id /></bx:secureform.field>">
  </form>
</bx:secureform>

Zum Schluss wird der Hash generiert und in das Formular geschrieben. Die einfachste Methode ist vom System direkt ein <input type="hidden"> generieren zu lassen.

Hash ausgeben

<bx:secureform>
  <form action="...">
    <bx:if><input type="hidden" name="kid" value="<bx:secureform.field name="kid" hidden-when-empty><bx:recorddata.id /></bx:secureform.field>"></bx:if>
    <input type="hidden" name="Besitzer" value="<bx:secureform.field name="Besitzer"><bx:userdata.id /></bx:secureform.field>">
    <bx:secureform.hash />
  </form>
</bx:secureform>

Dies erzeugt ein verstecktes Formularfeld mit passendem Name und Wert. Alternativ kann der Name oder Wert auch einzeln ausgegeben werden, siehe dazu die Tag Doku.

Das Tag kann auch benutzt werden, um einen Link / Button abzusichern:

<bx:secureform>
  <a href="delete.act?kid=<bx:secureform.field name="kid"><bx:recorddata.id /></bx:secureform.field>&<bx:secureform.hash name />=<bx:secureform.hash value />">löschen</a>
</bx:secureform> 

Hier werden die Parameter name und value von bx:securefom.hash benutzt, denn beide Werte sind dynamisch.

Falls URL-Parameter mit z.B. bx:if umschlossen sind, muss auch wieder hidden-when-empty benutzt werden (s.o.).

Erlaubte Werte festlegen

Falls ein Parameter mehrere, bestimmte Werte annehmen darf, ist dies mit bx:secureform.values abbildbar. In diesem Fall wird nicht das Feld mit dem Wert gehasht (da es vom Nutzer ja geändert werden kann), sondern ein zweites Feld eingefügt. Es enthält die erlaubten Werte und wird anstelle des veränderlichen Feldes mitgehasht.

So kann sich der Inhalt des Feldes (z.B. ein <select>) ändern, es wird aber trotzdem eine abgesicherte Information über die erlaubten Werte mitgeschickt.

Der Parametername wird normal in die Aktion eingetragen, diese unterscheidet aber, ob ein Info-Parameter mit den erlaubten Werten übergeben wurde oder nur der Normale und zieht dann den entsprechenden Parameter zur Hashbildung heran.

Im Formular

mehrere erlaubte Werte (Formular)

<select name="Anrede">
  <option value="<bx:secureform.values name="Anrede">m</bx:secureform.values>">Herr</option>
  <option value="<bx:secureform.values name="Anrede">w</bx:secureform.values>">Frau</option>
</select>
<bx:secureform.values name="Anrede" />

Das Tag in der geschlossenen Variante erzeugt automatisch ein <input type="hidden"> mit passenden name und value Attributen.

mehrere erlaubte Werte (Link)

var url = "save.act?";
// ...andere (ggf. abgesicherte) Parameter, wie z.B. ID...
url += "&Anrede=" + encodeURIComponent($("[name=Anrede]").val());
url += "&<bx:secureform.values name="Anrede" param encode="javascript" />=<bx:secureform.values name="Anrede" values encode="javascript" />"

Aktion absichern

Um eine Aktion abzusichern, wird ein neuer Sicheres Formular überprüfen (SecureformAction) Baustein eingefügt. Dieser muss an erster Stelle stehen, damit bei Manipulation die Aktion direkt abgebrochen wird und nachgelagerte Bausteine nicht ausgeführt werden.

In der Liste der abzusichernden Request-Parameter werden all die Parameter aufgezählt, die (falls übergeben) abgesichert sein müssen - d.h. diese Parameter werden zur Hashbildung im Baustein herangezogen. Das bedingt natürlich, dass diese Parameter auch im Formular eingesammelt wurden. Umgedreht gilt dasselbe: Parameter, die im Formular gesammelt wurden, müssen auch im Aktionsbaustein gelistet sein.

Im unteren Feld kann eine URL für den Fehlerfall spezifiziert werden. Hierhin wird weitergeleitet, sobald die Prüfung fehlschlägt. Wurde keine URL angegeben und die Prüfung schlägt fehl, so wird die gesamte Aktion mit einer Fehlermeldung abgebrochen.

image2016-4-24 21:56:43.png

Steht ein Parameter in der Liste, wurde aber nicht übergeben, so wird er vom Baustein nicht zu Hashbildung herangezogen.

Die Liste kann auch für Parameter verwendet werden, die der Aktion niemals übergeben werden dürfen (falls z.B. andere Bausteine schlecht darauf reagieren).

Da diese nicht im Formular gesammelt werden und somit nicht in den Hash einfließen, wird vom Formular ein anderer Hash erzeugt, als von der Aktion (da diese den Parameter mit in die Berechnung integriert, da er in der Liste steht).

Seite absichern

Analog zum Absichern einer Aktion existiert die Möglichkeit ein Template abzusichern. Dies kann z.B. verwendet werden, um bestimmte Parameter einer Listen- oder Detail-Seite abzusichern ("Kontakttyp darf nur Kunde sein" oder "Gruppe muss 123ABC oder 456DEF sein").

Hierfür gibt es das Tag <bx:secureform.check>, welches ganz oben in der Seite eingebaut wird und die Abarbeitung der Seite abbricht, sobald etwas manipuliert wurde. Optional kann auch eine URL angegeben werden, auf die weitergeleitet wird.

einfache Prüfung in Template

<bx:secureform.check securelist="Kategorie" />
<!DOCTYPE html>
<html>
...

Funktionsweise

Das Verfahren beruht auf kryptografischen Hashes. Dies sind Einwegfunktionen, die einen beliebigen Input in einen Output bestimmter Länge transformieren. Diese Berechnung ist nicht umkehrbar und somit ist der Input nicht rekonstruierbar.

Es fließen verschiedene Sachen in die Berechnung des Hashes ein. Allein die Parameternamen und -werte genügen nicht, da sonst der Hash von einem Angreifer selbst gebildet werden könnte. Der Algorithmus ist im Allgemeinen bekannt oder kann rekonstruiert werden.

Daher werden zusätzlich serverseitig generierte bzw. gespeicherte Werte für die Berechnung des Hashes benutzt. Diese Werte werden dem Client nicht mitgeteilt und er kann diese auch nicht auslesen. Nur das Tag und das Action kennen diese und können damit den korrekten Hash bilden.

Alle Parameter, die im Formular zum Hashen gesammelt und im Request mitgeschickt wurden, müssen auch in den Aktioneinstellungen angegeben werden. Umgekehrt müssen aber nicht alle Parameter, die im Aktionsbaustein stehen, auch im Request vorhanden sein. Falls sie vorhanden sind, müssen sie allerdings auch abgesichert sein. Das Formular und die Aktion müssen im Grunde denselben Satz an Parametern zur Hashbildung benutzen, sonst sind die Ergebnisse verschieden.

Snippets & Rezepte

Menü mit CSS

Ein CSS-basiertes Menü, das zur Not auch ohne JavaScript funktioniert und beliebig viele Ebenen darstellen kann.

Zum Betrieb des Menüs sind nur zwei Textbausteine in den HTML-Quelltext zu integrieren.

Textbaustein 1 für den HTML-Body

<!-- #################### Beginn CSS-Menü #################### -->

<ul id="qm0" class="qmmc">
  <bx:sitemap.0>
    <li><a class="<bx:sitemap.if hasChilds>qmparent</bx:sitemap.if><bx:sitemap.IF open> qmactive</bx:sitemap.IF>" href="/www/<bx:pagedata.webdir/>/<bx:navigation.path/>/"><bx:sitemap.name/></a>
    <bx:sitemap.iF hasChilds>
      <ul>
        <bx:sitemap.1>
          <li><a<bx:sitemap.if hasChilds> class="qmparent<bx:sitemap.IF open> qmactive</bx:sitemap.IF>"</bx:sitemap.if> href="/www/<bx:pagedata.webdir/>/<bx:navigation.path/>/"><bx:sitemap.name/></a>
            <bx:sitemap.IF hasChilds>
              <ul style="width:auto;">
                <bx:sitemap.2>
                  <li><a<bx:sitemap.if hasChilds> class="qmparent"</bx:sitemap.if> href="/www/<bx:pagedata.webdir/>/<bx:navigation.path/>/"><bx:sitemap.name/></a>
                    <bx:sitemap.if hasChilds>
                      <ul>
                        <bx:sitemap.3>
                          <li><a href="/www/<bx:pagedata.webdir/>/<bx:navigation.path/>/"><bx:sitemap.name/></a></li>
                        </bx:sitemap.3>
                      </ul>
                    </bx:sitemap.if>
                  </li>
                </bx:sitemap.2>
              </ul>
            </bx:sitemap.IF>
          </li>
        </bx:sitemap.1>
      </ul>
    </bx:sitemap.iF>
    </li>
  </bx:sitemap.0>
  <li class="qmclear"> </li>
</ul>

<!-- ##################### Ende CSS-Menü ##################### -->

<!-- Create Menu Settings: (Menu ID, Is Vertical, Show Timer, Hide Timer, On Click ('all' or 'lev2'), Right to Left, Horizontal Subs, Flush Left, Flush Top) -->
<script type="text/javascript">qm_create(0,false,100,500,false,false,false,false,false);</script>

Textbaustein 2 für den HTML-Head

<!-- #################### Beginn Styles für CSS-Menü #################### -->
<style type="text/css">


/*!!!!!!!!!!! Diese Styles nicht ändern !!!!!!!!!!!!!*/
.qmmc .qmdivider{display:block;font-size:1px;border-width:0px;border-style:solid;position:relative;z-index:1;}.qmmc .qmdividery{float:left;width:0px;}.qmmc .qmtitle{display:block;cursor:default;white-space:nowrap;position:relative;z-index:1;}.qmclear {font-size:1px;height:0px;width:0px;clear:left;line-height:0px;display:block;float:none !important;}.qmmc {position:relative;zoom:1;z-index:10;}.qmmc a, .qmmc li {float:left;display:block;white-space:nowrap;position:relative;z-index:1;}.qmmc div a, .qmmc ul a, .qmmc ul li {float:none;}.qmsh div a {float:left;}.qmmc div{visibility:hidden;position:absolute;}.qmmc li {z-index:auto;}.qmmc ul {left:-10000px;position:absolute;z-index:10;}.qmmc, .qmmc ul {list-style:none;padding:0px;margin:0px;}.qmmc li a {float:none}.qmmc li:hover>ul{left:auto;}#qm0 ul {top:100%;}#qm0 ul li:hover>ul{top:0px;left:100%;}


/*!!!!!!!!! Diese Styles zur individuellen Anpassung verändern !!!!!!!!!*/

  /*"""""""" (MAIN) Container"""""""""""*/	
  #qm0	
  {	
    padding:0px;
    margin:20px 0 0 15px;
  }

  /*"""""""" (MAIN) Items"""""""""""*/	
  #qm0 a	
  {	
    padding:2px 40px 2px 10px;
    background-color:#A20002;
    color:#FFFFFF;
    font-family:Arial;
    font-size:12px;
    text-decoration:none;
    font-weight:bold;
    text-align:left;
    border-width:1px 0px 1px 2px;
    border-style:solid;
    border-color:#7C0000;
    -moz-border-top-left-radius:7px;
    border-top-left-radius:7px;
    -moz-border-top-right-radius:7px;
    border-top-right-radius:7px;
  }

  /*"""""""" (MAIN) Hover State"""""""""""*/	
  #qm0 a:hover	
  {	
    background-color:#7C0000;
    color:#FFFC85;
  }

  /*"""""""" (MAIN) Active State"""""""""""*/	
  body #qm0 .qmactive, body #qm0 .qmactive:hover	
  {	
    background-color:#7C0000;
    color:#FFFC85;
  }

  /*"""""""" (MAIN) Persistent State"""""""""""*/	
  body #qm0 .qmpersistent, body #qm0 .qmpersistent:hover	
  {	
    background-color:#7C0000;
  }

  /*"""""""" (SUB) Container"""""""""""*/	
  #qm0 div, #qm0 ul	
  {	
    background-color:#A20002;
    border-width:1px;
    border-style:solid;
    border-color:#7C0000;
  }

  /*"""""""" (SUB) Items"""""""""""*/	
  #qm0 div a, #qm0 ul a	
  {	
    padding:4px 20px 4px 15px;
    color:#FFFFFF;
    font-size:12px;
    font-weight:normal;
    text-align:left;
    border-width:0px 0px 1px;
    border-style:solid;
    border-color:#7C0000;
  }

  /*"""""""" (SUB) Hover State"""""""""""*/	
  #qm0 div a:hover, #qm0 ul a:hover	
  {	
    color:#FFFC85;
    border-color:#7C0000;
  }

  /*"""""""" (SUB) Active State"""""""""""*/	
  body #qm0 div .qmactive, body #qm0 div .qmactive:hover	
  {	
    color:#FFFC85;
  }

  /*"""""""" (SUB) Persistent State"""""""""""*/	
  body #qm0 div .qmpersistent, body #qm0 div .qmpersistent:hover	
  {	
    background-color:#7C0000;
  }


</style>

<!-- ##################### Ende Styles für CSS-Menü ##################### -->

<!-- #################### Beginn Scripts für CSS-Menü ################### -->

<!-- Core MyCSSMenu Code -->
<script type="text/javascript">/* <![CDATA[ */var qm_si,qm_li,qm_lo,qm_tt,qm_th,qm_ts,qm_la,qm_ic,qm_ib;var qp="parentNode";var qc="className";var qm_t=navigator.userAgent;var qm_o=qm_t.indexOf("Opera")+1;var qm_s=qm_t.indexOf("afari")+1;var qm_s2=qm_s&&qm_t.indexOf("ersion/2")+1;var qm_s3=qm_s&&qm_t.indexOf("ersion/3")+1;var qm_n=qm_t.indexOf("Netscape")+1;var qm_v=parseFloat(navigator.vendorSub);;function qm_create(sd,v,ts,th,oc,rl,sh,fl,ft,aux,l){var w="onmouseover";var ww=w;var e="onclick";if(oc){if(oc=="all"||(oc=="lev2"&&l>=2)){w=e;ts=0;}if(oc=="all"||oc=="main"){ww=e;th=0;}}if(!l){l=1;qm_th=th;sd=document.getElementById("qm"+sd);if(window.qm_pure)sd=qm_pure(sd);sd[w]=function(e){qm_kille(e)};document[ww]=qm_bo;if(oc=="main"){qm_ib=true;sd[e]=function(event){qm_ic=true;qm_oo(new Object(),qm_la,1);qm_kille(event)};document.onmouseover=function(){qm_la=null;clearTimeout(qm_tt);qm_tt=null;};}sd.style.zoom=1;if(sh)x2("qmsh",sd,1);if(!v)sd.ch=1;}else  if(sh)sd.ch=1;if(oc)sd.oc=oc;if(sh)sd.sh=1;if(fl)sd.fl=1;if(ft)sd.ft=1;if(rl)sd.rl=1;sd.style.zIndex=l+""+1;var lsp;var sp=sd.childNodes;for(var i=0;i<sp.length;i++){var b=sp[i];if(b.tagName=="A"){lsp=b;b[w]=qm_oo;if(w==e)b.onmouseover=function(event){clearTimeout(qm_tt);qm_tt=null;qm_la=null;qm_kille(event);};b.qmts=ts;if(l==1&&v){b.style.styleFloat="none";b.style.cssFloat="none";}}else  if(b.tagName=="DIV"){if(window.showHelp&&!window.XMLHttpRequest)sp[i].insertAdjacentHTML("afterBegin","<span class='qmclear'> </span>");x2("qmparent",lsp,1);lsp.cdiv=b;b.idiv=lsp;if(qm_n&&qm_v<8&&!b.style.width)b.style.width=b.offsetWidth+"px";new qm_create(b,null,ts,th,oc,rl,sh,fl,ft,aux,l+1);}}};/* ]]> */</script>

<!-- Add-On Core Code (Remove when not using any add-on's) -->
<style type="text/css">.qmfv{visibility:visible !important;}.qmfh{visibility:hidden !important;}</style>
<script type="text/JavaScript">var qmad = new Object();qmad.bvis="";qmad.bhide="";</script>


  <!-- Add-On Settings -->
  <script type="text/JavaScript">

    /*******  Menu 0 Add-On Settings *******/
    var a = qmad.qm0 = new Object();

    // Sub Menu Fade Animation Add On
    a.fade_in_frames = 10;
    a.fade_out_frames = 20;

    // Item Bullets (CSS - Imageless) Add On
    a.ibcss_apply_to = "parent";
    a.ibcss_main_type = "arrow";
    a.ibcss_main_direction = "down";
    a.ibcss_main_size = 5;
    a.ibcss_main_position_x = -16;
    a.ibcss_main_position_y = -5;
    a.ibcss_main_align_x = "right";
    a.ibcss_main_align_y = "middle";
    a.ibcss_sub_type = "arrow";
    a.ibcss_sub_direction = "right";
    a.ibcss_sub_size = 5;
    a.ibcss_sub_position_x = -22;
    a.ibcss_sub_align_x = "right";
    a.ibcss_sub_align_y = "middle";

    // Drop Shadow Add On
    a.shadow_offset = 3;
    a.shadow_color = "#AFAFAF";
    a.shadow_opacity = 1;

    // Keyboard Access Add On
    a.keyboard_access_active = true;

  </script>
Snippets & Rezepte

Passwort vergessen

Nach Drücken von "Paßwort vergessen" wird auf eine Seite geleitet (pwvergessen.htm), wo man die E-Mail, mit der man angemeldet ist, eingeben muß. Nach Prüfung wird ein DS im Container "Token" angelegt und eine E-Mail mit einem Link (Token und Email im Request) an die angegebene Adresse geschickt. Nach Klicken des Links öffnet sich eine Seite mit Paßwort-Eingabefeldern. Nach Prüfung der Token-Daten wird das neue PW in der Benutzerverwaltung gespeichert.

Containeraufbau:

Token - einfaches Textfeld
Erstelldatum - Datumsfeld
Email - einfaches Textfeld
BC - BC-Verknüpfung
Kontakt - Einzelverknüpfung mit Kontakt-Container

Actions anlegen:

pwvergessen.act

Beispiele

1.) Actionbaustein "Container-Daten Filteraction" - Prüfen, ob's Email im "Kontakte" gibt

list: ID des Kontakte-Containers

xml:

<filter>
<filter-object required="true">
<field>Kontakt_Email</field>
<type>4</type>
<request-value>email</request-value>
</filter-object>
<limit max="1"/>
</filter>

url:

savetoken.act?Token=<bx:tools.uuid/>&Kontakt=<bx:recorddata.id/>&BCVerknuepfung=<bx:recordfield.Kontakt_BC><bx:recorddata.id/></bx:recordfield.Kontakt_BC>&Erstelldatum=<bx:tools.urlencode><bx:tools.datum pattern="dd.MM.yyyy HH:mm"/></bx:tools.urlencode>&Email=<bx:recordfield.Kontakt_Email/>

failurl:

pwvergessen.htm?fehler=1&email=[[email]]

2.) Actionbaustein "Weiterleitung" - Weiterleitung

destination: mailverschickt.htm

savetoken.act

Beispiele

1.) Actionbaustein "Container-Daten speichern" - Neuen Token-DS anlegen

listid: ID des Token-Containers

recordidfield: tokenid

active: ja

2.) Actionbaustein "CMS-Seite versenden" - Email mit Token versenden

alle vorherigen Felder ensprechend ausfüllen

file: pwemail.htm?tokid=[[tokenid]]

checkpw.act

Beispiele

1.) Aktionsbaustein "vorhandene Bedingung abfragen" - Paßwörter da?

requestField: Passwort

compareValue: #nodata

conditionTrue: changepw.htm?fehler=1&token=[[token]]&email=[[email]]

2.) Aktionsbaustein "vorhandene Bedingung abfragen" - Paßwörter gleich?

requestField: Passwort

compareValue: [[Passwortwdhlg]]

conditionFalse: changepw.htm?fehler=2&token=[[token]]&email=[[email]]

3.) Aktionsbaustein "Container-Daten Filteraction" - prüfen, ob Token-DS gültig ist

list: ID des Token-Containers

xml:

<filter>
  <filter-object required="true">
    <field>Token</field>
    <type>4</type>
    <request-value>token</request-value>
  </filter-object>
  <filter-object required="true">
    <field>Email</field>
    <type>4</type>
    <request-value>email</request-value>
  </filter-object>
  <filter-object>
    <field>Erstelldatum</field>
    <type>4</type>
    <special-value days="-1">TODAY</special-value>
  </filter-object>
</filter>

url: changepw.act?user=<bx:recordfield.BCVerknuepfung type="id"/>&Token=&tokid=<bx:recorddata.id/>&password=[[Passwort]]

failurl: changepw.htm?fehler=3

4.) Aktionsbaustein "Weiterleitung" - Weiterleitung

destination: ok.htm

changepw.act

Beispiele

1.) Actionbaustein "Intranet-User anlegen/ändern" - geändertes PW speichern

Parametername des Benutzer-ID-Feldes: user

Parametername des Passwortfeldes: password

2.) Actionbaustein "Container-Datensatz speichern" - Container-Daten speichern

listid: ID des Token-Containers

recordidfield: tokid

Seiten bauen

pwvergessen.htm: Seite mit E-Mail-Eingabe, ruft pwvergessen.act auf, Ausgabe, wenn Email nicht gefunden

Beispiele

<form action="pwvergessen.act" method="post">
  <label for="email">Ihre E-Mail-Adresse: </label>
  <input type="text" id="email" name="email" value="<bx:pagedata.request name="email"/>">
  <bx:pagedata.request name="fehler" value="1">Bitte geben Sie Ihre E-Mail-Adresse an.</bx:pagedata.request>
  <bx:pagedata.request name="fehler" value="2">Mit dieser Email sind Sie nicht angemeldet.</bx:pagedata.request>
  <br>
  <input type="submit" value="abschicken">
</form>

mailverschickt.htm: Info-Seite, "So geht' weiter...", nachdem Email mit dem Token verschickt wurde

changepw.htm: Seite mit Feldern zur Paßwortänderung, ruft checkpw.act auf, Ausgabe, wenn Token nicht mehr gültig

Beispiele

<bx:pagedata.request name="fehler" value="3">Der Link aus der E-Mail ist nicht mehr gültig. Bitte fordern Sie einen neuen Link an.</bx:pagedata.request>
<form action="checkpw.act" method="post">
  <input type="hidden" name="token" value="<bx:pagedata.request name="token"/>">
  <input type="hidden" name="email" value="<bx:pagedata.request name="email"/>">
  <label for="Passwort">neues Paßwort:*</label>
  <input id="Passwort" type="text" name="Passwort" value=""> <bx:pagedata.request name="fehler" value="1">Bitte geben Sie Ihr Paßwort incl. Wiederholung an.</bx:pagedata.request><br>
  <label for="Passwortwdhlg" style="width:145px;">Paßwortwiederholung:*</label>
  <input id="Passwortwdhlg" type="text" name="Passwortwdhlg" value=""> <bx:pagedata.request name="fehler" value="2">Die beiden Paßwörter sind nicht gleich.</bx:pagedata.request><br>
  <input type="submit" value="speichern" style="margin-left:145px;">
</form>

ok.htm: Info-Seite, "So geht' weiter...", nachdem PW erfolgreich geändert wurde

pwemail.htm: Mail mit dem Token

Beispiele

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Paßwort vergessen</title>
</head>
<body>
<bx:containerloop.User pool="132AF649539" idfield="tokid" force="single">
<bx:recordfield.Kontakt>
Guten Tag, <bx:recordfield.Kontakt_Anrede/> <bx:if><bx:recordfield.Kontakt_Vorname/> </bx:if><bx:recordfield.Kontakt_Vorname/> <bx:recordfield.Kontakt_Name/>,
<br><br>
</bx:recordfield.Kontakt>
Sie hatten auf "Paßwort vergessen" geklickt. Wenn nicht, dann ignorieren Sie diese Mail.
<br><br>
Bitte folgenden Link anklicken - Sie können dann ein neues Paßwort vergeben. Dieser Link ist einen Tag gültig und nur einmal verwendbar.
<br>
**********************************************************************************************************************<br>
http://mrp.batix.net/www/nab/mitgliederbereich/changepw.htm?token=<bx:recordfield.Token/>&amp;email=<bx:recordfield.Email/>
**********************************************************************************************************************<br>
Bitte beachten Sie: Bei einigen Browsern und E-Mail-Programmen lässt sich der Link nicht anklicken. Sollte dies der Fall sein, kopieren Sie bitte den kompletten Link in die Adresszeile Ihres Browsers und bestätigen mit der Return-Taste.
<br><br>
Mit freundlichen Grüßen<br>
Das Notarzt-Börse-Team
</bx:containerloop.User>
</body>
</html>
Snippets & Rezepte

Records – Hilfsklasse für einfaches Filtern

Für die programmatische Erstellung einer Datensatz-Filterung gab es bisher nur die Klasse SQLGenerator, welche teilweise schwierig zu bedienen war. Nun gibt es eine einfachere Möglichkeit mit besserer Typunterstüzung: die Klasse com.batix.table.Records. In Groovy-Code gibt es einen ähnlichen Helfer (findRecords), aber auch dort sollte Records vorgezogen werden.

Diese hat z. B. den Vorteil, dass die möglichen Filter für die unterschiedlichen Feldtypen ausdefiniert sind - man bekommt sie also per Code-Completion von der IDE vorgeschlagen und muss sich keine Zahlen merken. Außerdem wurden bestimmte Filter nochmals unterteilt, um beispielsweise NULL Werte zuzulassen oder nicht.

Auch in Bezug auf Sicherheit sollte der Einsatz von Records favorisiert werden: Es können aus Versehen keine Filter definiert werden, die in manchen Fällen dazu führen, dass die Filterung ausgehebelt wird (also man alle Datensätze sieht). Das war z. B. bisher der Fall, wenn man davon ausging, dass bestimmte Requestparameter immer da sind, es dann aber durch einen Fehler oder gezielten Angriff doch nicht so war.

Verfügbar ab CMS Version 2.7.3

Beispiel

Zur schnellen Übersicht ist hier ein Beispiel, in dem viele Methoden verwendet werden.

tmd.records()
  .connection(conn) // optional
  .activeOrInactive() // default active()
  .asc("timestamp").descNullsLast("sent_at") // nach mehreren Sachen sortieren
  .index(10)
  .limit(5)
  .exclude("123ABC") // bestimmte DS-IDs includen/excluden
  .filterCheckbox("valid", "ignoreValid").checked() // mehrere Felder mit oder verknüpft, d. h. mind. eins von beiden muss angehakt sein
  .filterSingleLink("Kategorie").anyId(collectionOfStrings)
  .filterMultipleLink("docs").containsAny("123ABC", "456DEF")
  .filterInteger("age").nullOr().greaterOrEquals(18)
  .filterFloat("price").lesser(100)
  .filterString("Vorname").notNullAnd().contains("test")
  .filterString("Nachname").nullOr().startsWith("test")
  .filterDate("Geburtsdatum").onYear(2000)
  .filterDate("Geburtsdatum").onMonthDay(MonthDay.now())
  .filterTime("wann").onHour(14)
  .filterTime("wann").later(LocalTime.of(13, 37))
  .filterDocument("doc").id("123ABC")
  //.count() -> int
  //.firstOrNull() -> ContainerRecord
  .forEach(rec -> { /*...*/ });

Allgemeines

Um den Zusammenbau der Konfiguration zu starten, wird eine Instanz von TableMetadata benötigt (im Beispiel oben tmd). Dann kann einfach tmd.records() oder Records.from(tmd) aufgerufen werden.

Die Klasse ist im Builder-Style gehalten. Es können also mehrere Bedingungen hintereinander definiert werden. Die Reihenfolge ist egal, da noch nichts ausgeführt, sondern nur die Abfrage-Konfiguration erstellt wird. Es sollte auf sinnvolle Zeilenumbrüche zur besseren Lesbarkeit geachtet werden (wie im Beispiel oben).

Es muss nicht zwangsläufig alles hintereinander geschrieben werden. Man kann sich die `Records` Instanz auch auf eine Variable legen und die Methoden nur in bestimmten Fällen aufrufen, z. B. anhand von Request-Parametern.

final Records.RecordsBuilder recs = tmd.records()
  .filterCheckbox("deleted").notChecked()
  .asc("Titel")
  .limit(10);

if (reqSuche != null && reqSuche.length() > 0) {
  recs.filterString("Beschreibung").notNullAnd().contains(reqSuche);
}

int cnt = recs.count();

In Kotlin kann auch z. B. apply benutzt werden:

val cnt = tmd.records().apply {
  filterCheckbox("deleted").notChecked()

  if (!reqSuche.isNullOrEmpty()) {
    filterString("Beschreibung").notNullAnd().contains(reqSuche)
  }

  asc("Titel")
  limit(10)
}.count()

Man kann sich keinen alten Stand der Konfiguration merken, da von der `Records` Instanz, die man konfiguriert bei den einzelnen Methoden keine Kopie erzeugt wird, sondern diese direkt verändert wird.

Damit die Abfrage ausgeführt wird, ist als letztes eine der Ergebnis-Methoden aufzurufen. Diese können auch mehrfach aufgerufen werden, die Abfrage wird dann immer wieder mit den aktuellen Einstellungen neu gestartet.

Bei Methoden, die mehrere Testwerte entgegennehmen, kann auch eine Collection des entsprechenden Typs anstatt einzelner Parameter übergeben werden.

Connection

.connection(/* Connection */)
.connection(request)

Mittels .connection() kann eine Datenbank-Connection übergeben werden. Dies ist nicht unbedingt nötig, da Records ansonsten selbst eine Connection im Hintergrund aufmacht. Das kann aber bei vielen Abfragen zu Performance-Problemen führen, da immer wieder eine neue Connection aufgemacht wird. Daher sollte man sich angewöhnen, eine Connection zu übergeben. Das geht direkt mit .connection(conn) oder, falls man nur einen Request zur Hand hat, mit .connection(request).

Filtern

Eine Suche nach Feldwerten kann mit den .filter...() Methoden definiert werden. Für jeden Feldtyp gibt es eine entsprechende Methode.

Der .filter...() Methode wird dann der Name des zu filternden Feldes übergeben.

Einer `.filter...()` Methode können auch mehrere Feldnamen übergeben werden (als einzelne Parameter). Das führt zu einer ODER-Verknüpfung der Felder: Mindestens eins dieser Felder muss also die Bedingung erfüllen.
Das entspricht im XML-Filter der Angabe mehrerer `<field>` Elemente.

Beispiel

.filterString("Vorname", "Nachname").notNullAnd().contains("muster")

Alle Filtermethoden prüfen ihre Argumente auf `null` bzw. leer (z. B. bei Strings) und lehnen solche Werte mit einer Exception ab.
Das bedeutet man kann weder explizit, noch aus Versehen, einen Testwert übergeben, der nicht filtert (beispielsweise einen Leerstring beim Filtern einer "Besitzer" Verknüpfung).
Somit werden bestimmte Bugs und Angriffe zur Laufzeit verhindert. Soll ein Feld nur in manchen Fällen gefiltert werden, ist das obige Beispiel unter [Allgemeines](#bkmrk-allgemeines) anzuwenden.

Nachfolgend sind die Feldtypen mit ihren zugehörigen Filter-Methoden aufgeführt.

Text

.filterString("Feldname")...

Leer abfragen

.filterString("Feldname").empty()
.filterString("Feldname").notEmpty()

Leer erlaubt oder nicht erlaubt

.filterString("Feldname").notNullAnd()...
.filterString("Feldname").nullOr()...

Der Text-Filter teilt sich in zwei Unterbereiche, die aber im Prinzip dieselben Methoden unterstützen. Sie unterscheiden sich dadurch, dass leere Felder entweder von vornherein ausgeschlossen werden, oder alternativ, dass leere Felder auch die Bedingung erfüllen (diese Variante wird z. B. angewendet, falls es ein einschränkendes Feld gibt, das aber auch leer sein kann, was dann bedeutet, dass die Einschränkung nicht greift und demzufolge der Datensatz auch mit gelistet werden soll).

Gleichheit

.filterString("Feldname").notNullAnd().value("Testwert")
.filterString("Feldname").notNullAnd().valueAny("Testwert 1", "Testwert 2")

.filterString("Feldname").notNullAnd().notValue("Testwert")
.filterString("Feldname").notNullAnd().notValueAny("Testwert 1", "Testwert 2")

.filterString("Feldname").nullOr().value("Testwert")
.filterString("Feldname").nullOr().valueAny("Testwert 1", "Testwert 2")

.filterString("Feldname").nullOr().notValue("Testwert")
.filterString("Feldname").nullOr().notValueAny("Testwert 1", "Testwert 2")

Um den kompletten Feldinhalt zu prüfen, wird eine der value Methoden verwendet.

Da die `...Any()` Methoden intern die multiplen Testwerte in einen kommagetrennten String schreiben, ist die Verwendung eines Kommas in Testwerten für diese Methoden nicht möglich bzw. führt zu fehlerhaften Ergebnissen!

Partielle Übereinstimmung

.filterString("Feldname").notNullAnd().contains("Testwert")
.filterString("Feldname").notNullAnd().containsAny("Testwert 1", "Testwert 2")
.filterString("Feldname").notNullAnd().containsAll("Testwert 1", "Testwert 2")
.filterString("Feldname").notNullAnd().startsWith("Testwert")
.filterString("Feldname").notNullAnd().endsWith("Testwert")
.filterString("Feldname").notNullAnd().regex("Pattern")

.filterString("Feldname").notNullAnd().notContains("Testwert")
.filterString("Feldname").notNullAnd().notContainsAny("Testwert 1", "Testwert 2")
.filterString("Feldname").notNullAnd().notContainsAll("Testwert 1", "Testwert 2")
.filterString("Feldname").notNullAnd().notStartsWith("Testwert")
.filterString("Feldname").notNullAnd().notEndsWith("Testwert")
.filterString("Feldname").notNullAnd().notRegex("Pattern")

.filterString("Feldname").nullOr().contains("Testwert")
.filterString("Feldname").nullOr().containsAny("Testwert 1", "Testwert 2")
.filterString("Feldname").nullOr().containsAll("Testwert 1", "Testwert 2")
.filterString("Feldname").nullOr().startsWith("Testwert")
.filterString("Feldname").nullOr().endsWith("Testwert")
.filterString("Feldname").nullOr().regex("Pattern")

.filterString("Feldname").nullOr().notContains("Testwert")
.filterString("Feldname").nullOr().notContainsAny("Testwert 1", "Testwert 2")
.filterString("Feldname").nullOr().notContainsAll("Testwert 1", "Testwert 2")
.filterString("Feldname").nullOr().notStartsWith("Testwert")
.filterString("Feldname").nullOr().notEndsWith("Testwert")
.filterString("Feldname").nullOr().notRegex("Pattern")

Teile des Feldinhaltes können mit diesen Methoden überprüft werden.

Da die `...Any()` und `...All()` Methoden intern die multiplen Testwerte in einen kommagetrennten String schreiben, ist die Verwendung eines Kommas in Testwerten für diese Methoden nicht möglich bzw. führt zu fehlerhaften Ergebnissen!

Bild

.filterPicture("Feldname")...

Leer abfragen

.filterPicture("Feldname").empty()
.filterPicture("Feldname").notEmpty()

Ziel-Datensatz existiert

.filterPicture("Feldname").exists()
.filterPicture("Feldname").notExists()

Diese Filter überprüfen, ob es ein Bild mit der im Feld hinterlegten ID auch wirklich gibt.

ID abfragen

.filterPicture("Feldname").id("123456ABCDEF")

Datei

.filterDocument("Feldname")...

Leer abfragen

.filterDocument("Feldname").empty()
.filterDocument("Feldname").notEmpty()

ID abfragen

.filterDocument("Feldname").id("123456ABCDEF")

Datum mit oder ohne Uhrzeit

.filterDate("Feldname")...

Die Filtermethoden nehmen aus Sicherheitsgründen keinen String entgegen, da dieser evtl. nicht im vom Filter erwarteten Format ist. Es muss also eine Instanz von `Date | LocalDate | LocalDateTime` übergeben werden. Bei Feldern ohne Uhrzeit wird nur der Datumsteil des Testwertes gelesen.
Falls man nur einen String hat, muss man diesen vorher in ein `LocalDate(Time)` Objekt umwandeln. Man erstellt dazu einen Formatter mit dem passenden Pattern und parst den String zum gewünschten Objekt.

Beispiele

LocalDateTime.parse("zu parsender String", DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"))
LocalDate.parse("zu parsender String", DateTimeFormatter.ofPattern("dd.MM.yyyy"))

Leer abfragen

.filterDate("Feldname").empty()
.filterDate("Feldname").notEmpty()

(Teil)Gleichheit

.filterDate("Feldname").onDate(/* Date | LocalDate | LocalDateTime */)
.filterDate("Feldname").onDay(/* int (1-31) */)
.filterDate("Feldname").onMonth(/* int (1-12) */)
.filterDate("Feldname").onMonthDay(/* MonthDay */)
.filterDate("Feldname").onYear(/* int */)
.filterDate("Feldname").onYearMonth(/* YearMonth */)

.filterDate("Feldname").notOnDate(/* Date | LocalDate | LocalDateTime */)

Abfrage neuer / älter bzw. gleich

.filterDate("Feldname").newer(/* Date | LocalDate | LocalDateTime */) // Feld > Testwert
.filterDate("Feldname").newerEquals(/* Date | LocalDate | LocalDateTime */) // Feld >= Testwert

.filterDate("Feldname").older(/* Date | LocalDate | LocalDateTime */) // Feld < Testwert
.filterDate("Feldname").olderEquals(/* Date | LocalDate | LocalDateTime */) // Feld <= Testwert

Abfrage neuer / älter oder Leer

.filterDate("Feldname").nullOr().newerEquals(/* Date | LocalDate | LocalDateTime */)
.filterDate("Feldname").nullOr().olderEquals(/* Date | LocalDate | LocalDateTime */)

Uhrzeit

.filterTime("Feldname")...

Auch hier nehmen die Methoden - wie oben bei Datum mit oder ohne Uhrzeit - keinen String entgegen. Dieser muss zunächst in ein passendes Objekt umgewandelt werden. Bei Objekten vom Typ `Date` oder `LocalDateTime` wird nur der Uhrzeitteil gelesen.

Beispiele

LocalTime.parse("zu parsender String", DateTimeFormatter.ofPattern("HH:mm:ss"))
LocalDateTime.parse("zu parsender String", DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"))

Leer abfragen

.filterTime("Feldname").empty()
.filterTime("Feldname").notEmpty()

(Teil)Gleichheit

.filterTime("Feldname").onTime(/* Date | LocalTime | LocalDateTime */)
.filterTime("Feldname").onHour(/* int (0-23) */)
.filterTime("Feldname").onMinute(/* int (0-59) */)
.filterTime("Feldname").onSecond(/* int (0-59) */)
      
.filterTime("Feldname").notOnTime(/* Date | LocalTime | LocalDateTime */)

Abfrage neuer / älter bzw. gleich

.filterTime("Feldname").later(/* Date | LocalTime | LocalDateTime */) // Feld > Testwert
.filterTime("Feldname").laterEquals(/* Date | LocalTime | LocalDateTime */) // Feld >= Testwert

.filterTime("Feldname").earlier(/* Date | LocalTime | LocalDateTime */) // Feld < Testwert
.filterTime("Feldname").earlierEquals(/* Date | LocalTime | LocalDateTime */) // Feld <= Testwert

Abfrage neuer / älter oder Leer

.filterTime("Feldname").nullOr().laterEquals(/* Date | LocalTime | LocalDateTime */)
.filterTime("Feldname").nullOr().earlierEquals(/* Date | LocalTime | LocalDateTime */)

Ganzzahl

.filterInteger("Feldname")...

Leer abfragen

.filterInteger("Feldname").empty()
.filterInteger("Feldname").notEmpty()

Gleichheit

.filterInteger("Feldname").value(/* Number */)
.filterInteger("Feldname").notValue(/* Number */)

.filterInteger("Feldname").nullOr().value(/* Number */)
.filterInteger("Feldname").nullOr().notValue(/* Number */)

Abfrage größer / kleiner

.filterInteger("Feldname").greater(/* Number */)
.filterInteger("Feldname").greaterOrEquals(/* Number */)
.filterInteger("Feldname").lesser(/* Number */)
.filterInteger("Feldname").lesserOrEquals(/* Number */)

.filterInteger("Feldname").nullOr().greater(/* Number */)
.filterInteger("Feldname").nullOr().greaterOrEquals(/* Number */)
.filterInteger("Feldname").nullOr().lesser(/* Number */)
.filterInteger("Feldname").nullOr().lesserOrEquals(/* Number */)

Dezimalzahl, Preis

.filterFloat("Feldname")...

Die Methoden sind identisch zu Ganzzahl, es muss lediglich filterFloat als Methode verwendet werden.

Alle Vergleiche auf Gleichheit bzw. Ungleichheit verwenden eine maximale Genauigkeit von 0,00001.
Das bedeutet, dass z. B. 0,000004 und 0,000005 für den Filter gleich sind.

Wahrheitswert (Checkbox)

.filterCheckbox("Feldname")...

Prüfen ob angehakt

.filterCheckbox("Feldname").checked()
.filterCheckbox("Feldname").notChecked()

Prüfen ob leer

.filterCheckbox("Feldname").empty()
.filterCheckbox("Feldname").notEmpty()

Dies ist in den meisten Fällen nicht der richtige Filter und es sollte "Prüfen ob angehakt" benutzt werden.
Hier wird nur geprüft, ob noch kein expliziter Wert im Feld steht, egal ob angehakt oder nicht angehakt.
Wurde die Checkbox also als **nicht angehakt** gespeichert, ist das Feld **nicht leer** (da "n" oder 0 drin steht).

Koordinaten

.filterCoordinate("Feldname")...

Dieser Feldtyp ist veraltet und wird nicht mehr benutzt. Er wird hier nur der Vollständigkeit halber erwähnt.

Prüfen ob leer

.filterCoordinate("Feldname").empty()
.filterCoordinate("Feldname").notEmpty()

Gleichheit der Koordinaten

.filterCoordinate("Feldname").x(/* Number */)
.filterCoordinate("Feldname").y(/* Number */)

Einzelverknüpfung

.filterSingleLink("Feldname")...

Prüfen ob leer

.filterSingleLink("Feldname").empty()
.filterSingleLink("Feldname").notEmpty()

Prüfen ob Datensatz existiert

.filterSingleLink("Feldname").exists()
.filterSingleLink("Feldname").notExists()

Es wird geprüft, ob es auch einen Datensatz mit der hinterlegten ID gibt bzw. nicht gibt.

Prüfen ob Datensatz aktiv

.filterSingleLink("Feldname").active()
.filterSingleLink("Feldname").notActive()

Es wird geprüft, ob es den Datensatz gibt. Dieser muss außerdem aktiviert bzw. deaktiviert sein.

Nach ID suchen

.filterSingleLink("Feldname").id("123456ABCDEF")
.filterSingleLink("Feldname").notId("123456ABCDEF")

.filterSingleLink("Feldname").anyId("123456ABCDEF", "ABCDEF123456")

Mehrfachverknüpfung

.filterMultipleLink("Feldname")...

Prüfen ob leer

.filterMultipleLink("Feldname").empty()
.filterMultipleLink("Feldname").notEmpty()

Nach ID suchen

.filterMultipleLink("Feldname").contains("123456ABCDEF")
.filterMultipleLink("Feldname").notContains("123456ABCDEF")

.filterMultipleLink("Feldname").containsAny("123456ABCDEF", "ABCDEF123456")
.filterMultipleLink("Feldname").containsAll("123456ABCDEF", "ABCDEF123456")

Bei containsAny reicht es, wenn eine der übergebenen IDs im Feld verknüpft ist. Für containsAll müssen alle übergebenen IDs verknüpft sein. In beiden Fällen können aber auch noch andere IDs verknüpft sein.

Untertabelle (Untercontainer)

.filterSubList("Feldname")...

Prüfen ob leer

.filterSubList("Feldname").empty()
.filterSubList("Feldname").notEmpty()

Aktiv / Inaktiv

.active()
.activeOrInactive()
.inactive()

Standardmäßig werden nur aktive Datensätze zurückgegeben. Dies lässt sich aber anpassen.

IDs inkludieren / exkludieren

.include("123456ABCDEF", "ABCDEF123456")
.exclude("123456ABCDEF", "ABCDEF123456")

Zusätzlich zu den Feldfiltern besteht die Möglichkeit nur bestimmte Datensätze anhand ihrer ID zuzulassen oder auszuschließen.

Werden Feldfilter und ID-Filter benutzt, müssen beide zutreffen. Ein mittels include angegebener Datensatz taucht also nicht zwangsläufig auf, sondern nur wenn alle anderen Bedingungen auch passen (sofern welche definiert wurden).

Paginierung

.limit(/* Integer */)
.index(/* Integer */) // 0-basiert

Die Anzahl der Ergebnisse kann mit limit begrenzt werden. Ebenso kann die Startposition mit index festgelegt werden.

Da `index` nullbasiert ist, startet man bei einer beispielhaften Seitenanzahl von zehn Ergebnissen mit dem elften Ergebnis (also Seite zwei), indem man `index(10)` angibt und nicht etwa `11` .

Sortierung

.asc("Feldname") // aufsteigend
.desc("Feldname") // absteigend
      
.ascNullsLast("Feldname")
.descNullsLast("Feldname")

Es kann nach mehreren Feldern sortiert werden. Dabei ist die Reihenfolge entscheidend. Es wird zuerst nach dem ersten angegebenen Sortierfeld sortiert, dann nach dem zweiten, usw. für alle angegebenen Sortierfelder.

Standardmäßig werden NULL Werte an den Anfang sortiert. Dies kann mit den ...NullsLast() Methoden geändert werden.

Im folgenden Beispiel wird also zunächst nach timestamp aufsteigend sortiert. Datensätze mit leerem timestamp Feld werden zuerst zurückgegeben.
Danach werden Datensätze mit gleichem Wert bei timestamp nochmals anhand sent_at absteigend sortiert. Dabei werden solche mit leerem sent_at ans Ende der Untersortierung gesetzt.

.asc("timestamp")
.descNullsLast("sent_at")

Ergebnisse laden

Es gibt verschiedene Möglichkeiten die Ergebnisse abzurufen. Wie bereits erwähnt kann dies auch mehrfach geschehen, indem man sich den Records Builder auf eine Variable legt und dessen Ergebnismethoden mehrfach aufruft.

Anzahl

.count() // int

Diese Methode gibt lediglich die Anzahl der gefundenen Datensätze zurück.

Erster Datensatz

.firstOrNull() // ContainerRecord oder null

Um nur den ersten Datensatz zu laden, kann diese Methode benutzt werden. Entspricht kein Datensatz dem Filter, wird null zurückgegeben, ansonsten ein ContainerRecord.

Datensätze durchgehen

.forEach((ContainerRecord record) -> {
  // ...
});

Hier werden die Datensätze aus der Datenbank gestreamt und dem Lambda (der Closure) einzeln übergeben. Die Methode forEach blockiert solange, bis alle Datensätze vom Lambda verarbeitet wurden.
Es werden dabei nicht zunächst alle Datensätze in den Speicher geladen, was der Performance zuträglich ist. Daher ist dies die präferierte Methode um Ergebnisse zu durchlaufen.

Stream

.stream() // Stream<ContainerRecord>

Genau wie bei forEach werden hier die Datensätze aus der Datenbank gestreamt. Man erhält allerdings direkten Zugriff auf den Stream.

Der Stream muss geschlossen werden, da sonst Leaks entstehen, da die Datenbankobjekte nicht aufgeräumt werden (weil der Stream ja nicht weiß, dass er fertig ist).
Das geschieht z. B. automatisch durch terminale Stream-Methoden oder manuell mittels `close()`.

Alle Datensätze laden

.loadAll() // ContainerRecord[]

Es wird ein Array zurückgegeben. Falls keine Elemente gefunden wurden, ist das Array leer (nicht null).

Diese Methode lädt alle gefundenen Datensätze in den Speicher, was zu Abstürzen fehlen kann. Daher sind die anderen Methoden vorzuziehen.

Snippets & Rezepte

Regelmäßiges Neuladen von DIVs

Aufbau der Hauptseite

<html>
<head>
<script type="text/javascript" src="mootools-1.2.js"></script>
<script type="text/javascript">
function registerRedirect(timeout, url, target){
  target.callUpdate = function(){
    new Request.HTML({
      url: url,
      noCache: true,
      update: target,
      onFailure: function(){
        setTimeout(target.callUpdate, 5 * 1000)
      }
    }).get();
  }
  setTimeout(target.callUpdate, timeout * 1000)
}
 
window.addEvent('domready', function() {
  registerRedirect(2, "oben.html", $("div1"))
  registerRedirect(2, "unten.html", $("div2"))
});
</script>
</head>
<body>
<div id="div1">div 1</div>
<br><hr><br>
<div id="div2">div 2</div>
</body>
</html>

Der Inhalt einer nachgeladenen Seite sieht so aus:

<script type="text/javascript">
registerRedirect(2, "oben.html", $("div1"))
</script>
... Content für oben steht hier ...
Snippets & Rezepte

Sitemap bauen

Einfaches Sitemap, kann noch verschönert werden.

Styles

.ebene0{
  font-weight:bold;
  text-decoration:underline;
  }
.ebene1{
  margin-left:30px;
  }
.ebene2{
  margin-left:60px;
  }

Quellcode

<bx:sitemap.0>
  <div class="ebene0"><a href="<bx:navigation.target default="http://" /><bx:pagedata.hostname />/www/<bx:pagedata.webdir/>/<bx:navigation.path/>"><bx:navigation.name/></a></div>
  <bx:sitemap.1>
    <div class="ebene1"><a href="<bx:navigation.target default="http://" /><bx:pagedata.hostname />/www/<bx:pagedata.webdir/>/<bx:navigation.path/>"><bx:navigation.name/></a></div>
    <bx:sitemap.2>
      <div class="ebene2"><a href="<bx:navigation.target default="http://" /><bx:pagedata.hostname />/www/<bx:pagedata.webdir/>/<bx:navigation.path/>"><bx:navigation.name/></a></div>
    </bx:sitemap.2>
  </bx:sitemap.1>
</bx:sitemap.0>
Snippets & Rezepte

Support für „not" hinzufügen

Dieses Beispiel realisiert folgende Funktionen:

Folgende Tags wurden verwendet:

Quellcode

Als Beispiel dient hier das Tag bx:pagedata.navid, welches not für seine Bedingung nicht unterstützt.

<bx:clipboard.cut name="check">
	<bx:pagedata.navid is="12345678901"><!-- --></bx:pagedata.navid>
</bx:clipboard.cut>
<bx:clipboard.cut name="content">
	Inhalt der bei allen Menüpunkten außer dem Gesuchten angezeigt wird
</bx:clipboard.cut>
<bx:if type="one">
	<bx:clipboard.paste name="check" />
	<bx:clipboard.paste name="content" />
</bx:if>

Das "check" Clipboard wird nur gefüllt, wenn ein bestimmter Menüpunkt aufgerufen wird. Dagegen wird das "content" Clipboard immer mit dem gewünschten Inhalt gefüllt. Da <bx:if> aber im Modus "one" läuft, wird der Inhalt auch nur ausgegeben, wenn sich nur im "content" Clipboard etwas befindet, d.h. wenn die NavID des aktuellen Menüpunktes nicht mit der zu überprüfenden übereinstimmt!

Snippets & Rezepte

Validation

Validation eines Container-Datensatzes

Mit einem Aktionsbaustein vom Typ ValidationAction werden die zu validierenden Felder und ihre Gültigkeitsbedingungen konfiguriert. Danach folgt ein Aktionsbaustein vom Typ ValidationResultAction der das Validationsergebnis im XML-Format in ein Feld des Containerdatensatzes schreibt.

Auf der Formularseite können durch das Tag bx:validation die fehlerhaften Eingabefelder markiert, oder ein Kommentar angezeigt werden.

Validation von übergebenen Requestparametern

Der Aktionsbaustein FormValidatorAction validiert Requestparameter gegen reguläre Ausdrücke. Die regulären Ausdrücke werden als <input type="hidden">-Felder an die Action-URL übergeben.

Validation eines einzelnen Requestparameters

Der Aktionsbaustein ConditionAction dient eigentlich zur Verzweigung des Ablaufs innerhalb einer Aktion. Ein übergebener Requestparameter wird auf einen in der Aktion festgelegen wert geprüft. Abhängig von Ergebnis kann an andere URLs weitergeleitet werden.

Snippets & Rezepte

Websuche

Voraussetzung für ein Funktionieren der Websuche ist eine Indizierung der Seiten, z.B. via Zeitsteuerung. Dies geht erst, wenn das Web fertig, also ungeschützt und unter der endgültigen Url erreichbar ist.

Suchformular

<div id="suchdiv">
  Suche:
  <form action="/www/<bx:pagedata.webdir/>/sonstiges/suche/suche.act" method="post">
    <input type="text" name="search" size="18" value="<bx:websearch.query/>"><input type="submit" value="los">
  </form>
</div>

Action:

suche.act

Typ der Aktion: Suche im Web

resultpage: Pfad zur Ausgabeseite, z.B. /suche/

Ausgabeseite

<strong>Sie suchten nach: <bx:websearch.query/></strong><br>

<div style="text-align:center;">
  <div style="float:left;"><bx:websearch.previous hide/></div>
  <div style="float:right;"><bx:websearch.next hide/></div>
  <bx:websearch.if not empty>
  Ergebnis <bx:websearch.firstshown/> bis <bx:websearch.lastshown/> von insgesamt <bx:websearch.totalhits/>
  </bx:websearch.if>&nbsp; 
</div>
<hr>
<bx:websearch.if empty>Es wurden leider keine Ergebnisse gefunden.</bx:websearch.if>
<bx:websearch.if not empty> 
  <bx:websearch max="10">
    <strong><bx:websearch.rank/>.</strong>&nbsp;<bx:websearch.link><bx:websearch.title/></bx:websearch.link>&nbsp;&nbsp;<bx:websearch.stars max="5"><img src="star.jpg">&nbsp;</bx:websearch.stars><br>
    <div style="margin-left:30px;"><bx:websearch.description/></div><br><br>
  </bx:websearch>
</bx:websearch.if> 

Encodings

Zeichenkodierungen und Escape-Funktionen.

Encodings

Encodings – Übersicht

Bestimmte Tags unterstützen Encodings (Maskierungen) um die Ausgabe in bestimmten Situationen anders aussehen zu lassen. So werden z.B. für HTML spitze Klammern durch ihre entsprechenden HTML-Entites ersetzt oder für JavaScript Steuerzeichen escaped (ein Backslash vorangestellt).

Die meisten Tags unterstützen auch eine Angabe der gewünschten Kodierung via encoding Parameter, z.B.: <bx:recordfield.Name encode="..." /> Falls explizit kein Encoding angegeben wurde, versucht das Tag automatisch passen zu encoden (z.B. HtmlEncode bei Mime-Type text/html). Die folgenden Umwandlungen können angegeben werden:

Informationen zu den einzelnen Encodings:

Auf jeder Seite steht ganz unten, welche Tags oder sonstigen Funktionen diese Umwandlung benutzen bzw. unterstützen.

Encodings

HtmlEncode

Es werden folgende Ersetzungen vorgenommen:

Originalwert ausgegebener Wert
< &lt;
> &gt;
" &quot;
' &#039;
& &amp;
Encodings

HtmlMask

Hierbei werden sämtliche Zeichen durch HTML-Entities der Form &#dd; ersetzt, wobei d für eine dezimale Ziffer steht.

Aus Hallo wird somit &#72;&#97;&#108;&#108;&#111;.

Encodings

ScriptEncode

Einige Sonderzeichen und besondere Zeichen werden durch JavaScript Escape-Sequenzen ersetzt.

Den folgenden Zeichen wird ein \ (Backslash) vorangestellt:

Strict / Non-Strict

Standardmäßig ist der Strict-Modus aktiviert, das heißt jeder Backslash wird verdoppelt.

Im Non-Strict-Modus werden Backslashes, die sich vor den oben aufgelisteten Zeichen (außer Single-Quote) befinden nicht verdoppelt (außer der Backslash steht ganz am Ende).

Encodings

UrlEncode

Es wird die Java Klasse URLEncoder benutzt. Dabei werden "unsichere" Zeichen durch ein oder mehrere Blöcke %hh ersetzt, wobei h für eine hexadezimale Ziffer steht.

Je nach verwendetem Zeichensatz können die Hexadezimalen Blöcke anders aussehen, so wird ein kleines ö z.B. mit ISO-8859-1 zu %f6, mit UTF-8 allerdings wird es zu %c3%b6.

Es gelten folgende Regeln:

Encodings

XmlEncode

Es werden folgende Ersetzungen vorgenommen:

Originalwert ausgegebener Wert
< &lt;
> &gt;
" &quot;
& &amp;
Zeichen zwischen dezimal 32 und 127
(beides inklusive)
(unverändert)
Alle restlichen Zeichen &#ddd;
d = dezimale Ziffer

je nach Plattform, auf der das CMS läuft,
können unterschiedliche Werte entstehen

Groovy

Groovy-Scripting im CMS.

Groovy

API

eine gekapselte Klasse mit statischen Methoden, die zusammengehörige Funktionalitäten enthältMyApi (bei class und logName muss noch angepasst werden.

import com.batix.Log
import com.batix.action.GroovyAction
import com.batix.modul.Customer
import com.batix.modul.SystemVariables
import com.batix.table.TableMetadata
import com.batix.tags.GroovyTag

import javax.servlet.ServletContext
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpSession
import java.sql.Connection

class MyApi {
  private static GroovyAction.GroovyContext getContext() {
    return GroovyAction.context
  }

  private static GroovyTag getIncludeTag() {
    return context.includeTag
  }

  private static GroovyAction getAction() {
    return context.action
  }

  private static ServletContext getApplication() {
    return context.application
  }

  private static HttpServletRequest getRequest() {
    return context.request
  }

  private static HttpServletResponse getResponse() {
    return context.response
  }

  private static HttpSession getSession() {
    return context.session
  }

  private static Customer getWeb() {
    return context.web
  }

  private static SystemVariables getVariables() {
    return context.variables
  }

  private static Connection getConn() {
    return action?.connection ?: includeTag?.checkConnection()
  }

  /* Logging start */
  private static def logName = "MyApi"
  //noinspection GroovyUnusedAssignment
  private static void logD(String msg, HttpServletRequest request = null) { Log.debug("[${logName}] ${msg}", request) }
  //noinspection GroovyUnusedAssignment
  private static void logI(String msg, HttpServletRequest request = null) { Log.info("[${logName}] ${msg}", request) }
  //noinspection GroovyUnusedAssignment
  private static void logN(String msg, HttpServletRequest request = null) { Log.notice("[${logName}] ${msg}", request) }
  //noinspection GroovyUnusedAssignment
  private static void logW(String msg, HttpServletRequest request = null) { Log.warn("[${logName}] ${msg}", request) }
  //noinspection GroovyUnusedAssignment
  private static void logE(String msg, Exception ex = null, HttpServletRequest request = null) { Log.error("[${logName}] ${msg}", request, ex) }
  /* Logging end */

  // Beispiel: öffentliche Konstante
  public static final def ID_STATUS_OFFEN = "15FBFE52655"

  // Beispiel: öffentliche Methode
  static Map info(String vid) { return null }
}
Groovy

Bibliothek – Übersicht

Hier werden wiederverwendbare Code-Schnipsel und Helferlein gesammelt. Diese müssen, falls nicht anders angegeben, einfach nur rauskopiert werden und im eigenen Code (am besten ganz oben) eingefügt werden.

Groovy

CMS-spezifische Helfer

Bestimmte CMS-Klassen wurden um Utilities zur einfacheren Verwendung erweitert.

Importe

Einige häufig genutzte Klassen werden automatisch importiert, z.B. java.sql.Connection, TableMetadata und BatixRecord.

Objekte

Dem Groovy-Script stehen automatisch folgende Objekte zur Verfügung:

Connection

Um einfach an eine Datenbank-Connection zu kommen, egal ob der Groovy-Baustein in einem Action oder Tag (oder sogar den Entwickler-Tools) verwendet wird, kann folgender Block verwendet werden:

Connection.with { conn ->
  // hier Code, der conn benutzt
}

Die Connection wird nach dem Block automatisch wieder geschlossen bzw. zurückgegeben.

TableMetadata holen

Eine Instanz von TableMetadata lässt sich einfach zu einem Container erzeugen, in dem Entweder der Titel, der Tabellenname oder die ID des Containers benutzt wird (es wird eine TableMetadata-Instanz zurückgegeben):

// funktioniert alles gleich
def tmdKunden = TableMetadata["Kunden"]
def tmdKunden = TableMetadata["bxc_kunden"]
def tmdKunden = TableMetadata["15525037CCA"]
 
// auch mit Punkt-Schreibweise verfügbar
def tmdKunden = TableMetadata.Kunden
def tmdKunden = TableMetadata.bxc_kunden
def tmdKunden = TableMetadata."15525037CCA" // als String, da sonst Syntax Error wegen Ziffer am Anfang

BatixRecord holen

Ein bestimmter Datensatz aus einem Container, kann durch seine ID einfach geholt werden (es wird eine BatixRecord-Instanz zurückgegeben):

def recKunde = tmdKunden["15525037CCB"]

Einen neuen Datensatz erzeugt man mit den üblichen Methoden:

def recKunde = tmdKunden.createNewRecord(conn, com.batix.util.UniqueID.createHexId(), true)

Datensatz-Felder lesen / schreiben

Hat man einen BatixRecord kann man auf einfache Art und Weise die Datensatz-Felder lesen und ändern:

// Text
String name = recKunde.Name.string
recKunde.Titel.string = "Dr."
 
// Zahl
int alter = recKunde.Alter.number // Ganzzahl-Feld
recKunde.Alter.number = 18
double rabatt = recKunde.Rabatt.number // Dezimalzahl-Feld
recKunde.Rabatt.number = 5.83
 
// Datum, Datum + Uhrzeit, Uhrzeit oder Zeitraum
Date bday = recKunde.Geburtstag.date
recKunde.lastUpdate.date = new Date()
 
// Häkchen
boolean archived = recKunde.archiviert.state
recKunde.Newsletter.state = false
 
// Einzelverknüpfung (Bild, Dokument, Datensatz)
String picId = recKunde.Foto.string
String statusId = recKunde.Status.string
recKunde.Rolle.string = "15525037CCC"
 
// Mehrfachverknüpfung
MultipleLinkField leistungen = recKunde.Leistungen
 
// Untercontainer
SubListField vertraege = recKunde.Vertraege
 
// zum Schluss Update nicht vergessen
recKunde.updateRecordInDatabase(conn)
// oder Anlegen, falls es ein neuer Datensatz war
recKunde.createRecordInDatabase(conn, false) // false = Default-Werte der Container-Felder übernehmen

Durch die angesprochenen Probleme mit Typ-Infos, kann es passieren, dass bei Datum/Zeit-Feldern der Setter uneindeutig ist, falls null übergeben wird (da es dort mehrere setDate Methoden gibt).

Falls eine Variable übergeben wird, die auch null sein kann, wird daher beim Setzen von Datum/Zeit Feldern empfohlen, die setDate Methode aufzurufen und einen expliziten Cast hinzuzufügen:

Date birthday = ...
recKunde.Geburtstag.setDate(birthday as Date)

Mehrere Datensätze filtern

Ähnlich dem XML-Filter mit bx:containerfilter können in Groovy Datensätze gefiltert werden. Der Methode werden als erster Parameter eine Liste an Kriterien (bestehend aus einer drei-Elementigen Liste pro Kriterium mit: Feld(ern), Vergleichstyp und Vergleichswert) und als zweiter Parameter eine Map von Optionen übergeben. Das Ergebnis is ein (evtl. leeres) Array aus BatixRecords.

Ab Version 2.6.8 kann bei der Kriterien-Liste jeweils ein vierter Parameter angegeben werden (true oder false), welcher dem required-Attribut in der XML entspricht. Das ist nützlich, falls man direkt Sachen aus dem Request o.ä. als Vergleichswert angibt: ["Name", 1, request.getParameter("name"), true] (in späteren Versionen führt ein leerer Vergleichswert ohne explizite required-Angabe dann zum Abbruch)

BatixRecord[] recs = tmdKunden.findRecords([
  ["Leistungen", 5, 0], // Feld darf nicht leer sein
  ["Newsletter", 4, 1], // Feld muss angehakt sein
  [["Name", "Vorname"], 1, "muster"] // mindestens eins der beiden Felder muss "muster" enthalten
], [
  orderby: "Kundennummer", // optional, Sortierungsfeld (Standard ID)
  desc: true, // optional, Sortierrichtung (Standard aufsteigend)
  index: 5, // optional, Startindex (Null-basiert)
  limit: 20, // optional, maximale Anzahl Ergebnisse
  active: true, // optional, aktive Datensätze suchen? (Standard ja)
  inactive: true // optional, inaktive Datensätze suchen? (Standard nein)
])

Die Zahlen entsprechen den Typen des normalen Filters. Es müssen nicht alle Parameter angegeben werden, ein kurzes Beispiel ist (in Groovy steht [:] für eine leere Map):

BatixRecord[] recs = tmdKunden.findRecords([
  ["archived", 4, 1] // alle archivierten Kunden finden
], [:])

Ab Version 2.7.0 können auch mehrere Sortierungs-Kriterien angegeben werden. Dabei sind folgende Formate für orderby möglich (desc wird dann ignoriert):

BatixRecord[] recs = tmdKunden.findRecords([], [
  orderby: [
    "Firma", // aufsteigend
    ["Name"], // aufsteigend
    ["Vorname", true] // absteigend
  ]
])

Einen Datensatz filtern

Ab Version 2.7.0 ist es auch möglich nur den ersten Datensatz zu laden, anstatt alle:

BatixRecord rec = tmdKunden.findRecord([
  // siehe oben
], [
  // siehe oben
])

Rückgabewert ist entweder ein BatixRecord oder null.

Batix-Quelltext ausführen

Will man schnell einen String evaluieren, der Batix-Tags enthält, kann diese Methode benutzt werden:

String code = '<bx:math>1 + 1</bx:math>'
String result = code.evaluateAsBatixSource()

Der Standard Mime-Typ ist text/html, um einen anderen zu benutzen (manche Tags machen unterschiedliche Sachen, je nach Mime-Typ der Seite) kann dieser als Parameter mitgegeben werden: evaluateAsBatixSource("text/plain").

Groovy

Groovy Syntax und Beispiele

Nebst den hier am häufigsten genutzten Elementen gibt es noch viele weitere Funktionen und Helfer, siehe dazu auch die offizielle Doku (auf die Version achten).

Syntax

Klammern um Parameter sowie das Semikolon am Ende der Zeile können weggelassen werden. Empfehlung: Klammern verwenden, Semikolon weglassen.

println "Hello, World"
println("Hello, World") // Empfehlung
println("Hello, World");

Typen müssen nicht explizit angegeben werden (def entspricht quasi Object in Java bzw. var in JavaScript). Empfehlung: Typen explizit angeben, falls die IDE sie nicht automatisch erkennt und demtentsprechend keine sinnvollen Vorschläge für Syntax-Completion macht.

def x = 11.8 // erst Zahl
println(x)

x = "Test" // dann String
println(x.toUpperCase())

Typen werden, soweit möglich automatisch umgewandelt, es müssen keine expliziten Casts verwendet werden (hier kann aber das Schlüsselwort as verwendet werden). Es erfolgt auch ein automatisches Boxing / Unboxing (int <--> Integer etc.).

def i = "5" as int
eineListe.add(12)

Der Gleichheits-Operator in Groovy (==) wird im Hintergrund zu einem .equals() Aufruf umgewandelt.

String a = "test"
String b = "te" + "st"
println(a == b) // true, in Java: a.equals(b)

Strings können von Anführungszeichen ("), Apostrophen (') oder Slashes (/) umschlossen sein. Empfehlung: Das verwenden, was im String nicht vorkommt, um nicht escapen zu müssen (Slashes, falls Anführungszeichen und Apostrophe vorkommen bzw. für Reguläre Ausdrücke).

"str" == 'str' == /str/ 

Es gibt auch Mehrzeilige Strings. Ein Backslash (\) bewirkt, dass der Zeilenumbruch vor der ersten Zeile im Code nicht mit ausgegeben wird.

println("""
Zeile 1
Zeile 2
"""
 
println("""\
einzige Zeile"""

In Strings mit Anführungszeichen (einfach oder dreifach für mehrzeilige Strings) können Code-Platzhalter verwendet werden, die durch ihren Wert ersetzt werden.

def user = "alice"
println("Hi $user")
println("aktueller Timestamp: ${new Date().time}")

Closures

Closures entsprechen in etwa den functions in JavaScript oder Lambda-Funktionen in Java 8. Es muss dabei nicht explizit return angegeben werden, der Rückgabewert des letzten Statements wird als Rückgabewert der Closure benutzt. Parameter müssen nicht typisiert werden.

// keine Parameter
def c1 = {
  "Hello"
}
c1()
 
def c2 = { name ->
  "Hello, $name!"
}
c2("World")

Methoden, die eine Closure als einzigen oder letzten Parameter akzeptieren, kann die Closure direkt übergeben werden (keine runden Klammern nötig).

"...".eachLine { line ->
  println(line.reverse())
}

Falls die Closure genau ein Parameter übergeben bekommt, so muss dieser nicht benannt werden, der Standardname ist "it".

"...".eachLine {
  println(it.reverse())
}

Spaceship-Operator

Vergleiche (compareTo) erledigt der Spaceship-Operator, das vereinfacht die Implementation eines Comparators.

println 5 <=> 10         // Java: 5.compareTo(10)
println "def" <=> "abc"  // Java: "def".compareTo("abc")
println null <=> 10      // gibt keine Exception

Beispiel: System Properties filtern

System.properties
  .findAll { it.key.startsWith("user") }
  .sort { x, y -> x.key <=> y.key }
  .each { println it }

Get / Set

Es werden automatisch JavaBeans-Accessors erzeugt bzw. angesprochen, d.h. man muss nicht getProp() oder setProp() aufrufen, sondern kann einfach prop schreiben.

// Lesen
println(obj.thing)   // entspricht obj.getThing()
println("...".empty) // entspricht "...".isEmpty()
 
// Schreiben
obj.thing = null     // entspricht obj.setThing(null)

Arrays / Lists / Maps / Ranges / Collections

Für Listen und Maps gibt es eine native Syntax.

Liste

def a = [1, 2, 3]  // eine ArrayList im Hintergrund
println(a[1])      // einfach auf Elemente zugreifen

println([].size()) // eine leere Liste

Map

def m = [language: "Groovy", version: 2.1] // eine LinkedHashMap
println m["language"]  // einfach auf Elemente zugreifen
println m.version      // einfach auf Elemente zugreifen

println([:].size())    // eine leere Map

Mit Ranges kann man einfach Zahlenbereiche generieren.

(1..10).each { println(it) }  // 1 bis 10
(1..<10).each { println(it) } // 1 bis 9
(5..-5).each { println(it) }  // absteigend

Außerdem können mittels Ranges teile von Strings und Collections extrahiert werden.

def a = [1, 2, 3, "a", "b", "c"]
println a[-2]     // b
println a[2..4]   // [3, a, b]
println a[2..1]   // [3, 2]
println a[-2..2]  // [b, a, 3]

def s = "the quick brown fox"
println s[4..9, -3..-1]   // quick fox

Um zu überprüfen, ob eine Collection ein Element enthält, kann der in Operator verwendet werden.

println(5 in [1, 5, 10]) // true

Diesen gibt es auch in der verkürzten Variante der for-Schleife.

def a = [1, 5, 10]
for (i in a) {
  println(i)
}

Groovy bringt viele Hilfsmethoden für Collections mit.

[5, 4, 8, 1, 4, 5, 2].sort().unique().reverse()   // Sortieren, Doppler entfernen, Reihenfolge invertieren
(1..10).take(3).drop(1)                           // nur die ersten 3 Elemente nehmen und davon dann das erste wegschmeißen
[4, 7, 1].min()                                   // Minimum finden
[cents: 5, dime: 2, quarter: 3].max { it.value }  // Maximum finden und dabei festlegen, was verglichen werden soll pro Element
(1..100).sum()                                    // Summe bilden
["abc", "def", "abcdef"].findAll { it.startsWith("a") }  // alle Elemente finden, die einer Bedingung entsprechen
["abc", "abcdef"].collect { it.length() } == [3, 6]      // Elemente transformieren
 
['a', 'b'] << [1, 2]    // [a, b, [1, 2]]   Element anhängen
['a', 'b'] + [1, 2]     // [a, b, 1, 2]     Listen zusammenführen
[1, 2, 3].join("~")   // 1~2~3     Elemente mittels Trenner zusammenführen
 
def a = [1, 2, 3, 4, 5]
println(a.any { it > 3 })    // true, erfüllt mindestens ein Element die Bedingung?
println(a.every { it < 5 })  // false, erfüllen alle Elemente die Bedingung?

Wenn man nicht immer prüfen will, ob ein Key in einer Map ist, bevor man ihn benutzt, kann man ein Default-Wert festlegen. Dieser wird dann unter dem Key automatisch in der Map angelegt, sobald das erste Mal auf ihn zugegriffen wird.

def map = [:].withDefault {
  new Date()
}

println map.test  // Zeit 1
sleep(2000);
println map.test  // immer noch Zeit 1
println map.test2 // Zeit 2

RegEx

Reguläre Ausdrücke haben auch eine verkürzte Syntax. Slashes werden hier nur der Lesbarkeit / Identifizierbarkeit verwendet, es sind immer noch normale Strings (nicht wie in JavaScript, wo mit Slashes direkt reguläre Ausdrücke erzeugt werden).

// Pattern erzeugen
Pattern p = ~/\d+/
println(p.matcher("123").matches())
 
// Matcher erzeugen
Matcher m = "123" =~ /\d(\d)\d/
println(m.matches())
println(m.group(1))
 
// Direkt matchen
println("123" ==~ /\d+/) // true

Null-Dereferenzierung

Um NullPointerExceptions vorzubeugen, ohne dauernd mit if auf null prüfen zu müssen, empfiehlt sich der ?. Operator. Dieser stoppt, sobald der Ausdruck vor dem Fragezeichen null ist und gibt null zurück.

class Person {
  def name
}

def p
println(p?.name?.length())  // null

p = new Person()
println(p?.name?.length())  // null

p.name = "Tester"
println(p?.name?.length())  // 6

Elvis-Operator

Default Werte können mit dem Elvis-Operator (?:) vereinfacht werden. Dies entspricht dem Ternary-If, wobei die Bedingung und der True-Teil identisch sind.

null ?: 5        // 5         -->  null ? null  :      5
false ?: "test"  // test      --> false ? false : "test"
4 ?: 8           // 4         -->     4 ?     4 :      8

Switch

Das switch Statement wurde auch erweitert.

def testSwitch(val) {
  switch (val) {
    case ~/^Switch.*Groovy$/: return 'Pattern match'
    case BigInteger: return 'Class isInstance'
    case 60..90: return 'Range contains'
    case [21, 'test', 9.12]: return 'List contains'
    case 42.056: return 'Object equals'
    case { it instanceof Integer && it < 50 }:
      return 'Closure boolean'
    default: return 'Default'
  }    
}

println testSwitch("Switch to Groovy")
println testSwitch(42G)
println testSwitch(70)
println testSwitch('test')
println testSwitch(42.056)
println testSwitch(20)
println testSwitch('default')

JSON

Mit JSON kann sehr einfach gearbeitet werden.

JSON lesen

def slurper = new groovy.json.JsonSlurper()
def json = slurper.parseText("""
{
  "name": "Mustermann",
  "ids": [5, 10, 11]
}
""")
println(json.name)   // Mustermann
println(json.ids[1]) // 10

In neueren Groovy-Versionen liefert der JsonSlurper eine LazyMap zurück, die nicht serialisiert werden kann (falls etwas in der Session gespeichert werden soll). Die Variante mit HashMap ist noch als JsonSlurperClassic verfübar.

Ein JSON-String ist auch schnell aus normalen Objekten (Strings, Lists, Maps, ...) erzeugt:

JSON schreiben

def builder = new groovy.json.JsonBuilder()
def obj = [
  name: "Mustermann",
  ids: [5, 10, 11]
]
builder(obj)
println(builder.toPrettyString()) // JSON von oben

Als Abkürzung kann die Hilfsklasse JsonOutput verwendet werden.

JsonOutput

import groovy.json.JsonOutput

def obj = [
  name: "Mustermann",
  ids: [5, 10, 11]
]
def jsonStr = JsonOutput.toJson(obj)
println(jsonStr) // alles auf einer Zeile, spart Bytes
println(JsonOutput.prettyPrint(jsonStr)) // lesbar

XML

Für XML-Input gibt es 2 Verarbeitungsmöglichkeiten: XMLParser und XMLSlurper (siehe dazu auch die Groovy Doku).

XmlParser parst das komplette XML und baut eine Struktur im RAM auf, was es erlaubt Teile der XML oft und dabei schnell abzufragen (falls dem XML-Dokument Nodes aktualisiert oder hinzugefügt werden sollen, wird auch XmlParser empfohlen):

XML lesen (mit XmlParser)

def parser = new XmlParser()
def root = parser.parseText("""
<person>
  <access read='true' write='false' />
  <data>
    <name>Mustermann</name>
  </data>
  <data>
    <name>Musterfrau</name>
  </data>
</person>
""")
println(root.access.@write[0])     // false
println(root.data[1].name.text())  // Musterfrau

XmlSlurper hingegen wertet das XML nur partiell und on-demand aus - somit wird RAM gespart, häufige Zugriffe hingegen dauern ggf. länger (dafür können Abfragen aber etwas kürzer geschrieben werden):

XML lesen (mit XmlSlurper)

def slurper = new XmlSlurper()
def root = slurper.parseText("""
<person>
  <access read='true' write='false' />
  <data>
    <name>Mustermann</name>
  </data>
  <data>
    <name>Musterfrau</name>
  </data>
</person>
""")
println(root.access.@write)     // false
println(root.data[1].name)      // Musterfrau

Um XML-Dokumente programmatisch zusammenzubauen, bietet such MarkupBuilder an:

XML schreiben

def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)

builder.person {
  access(read: true, write: false)
  data {
    name("Mustermann")
  }
  data {
    name("Musterfrau")
  }
}

println(writer.toString()) // XML von oben

Um schnell einzelne Teile einer XML zu ändern und wieder in einen String zu überführen, kann der XmlParser und die Hilfsklasse XmlUtil verwendet werden. Hier ein Beispiel, um Werte zum Validation-Feld hinzuzufügen:

XML parsen, bearbeiten, zurückschreiben

import groovy.xml.XmlUtil

// XML parsen
def rootNode = new XmlParser().parseText("""
<result size="1">
  <field name="Kontakt_Email" resultcode="1" bin="00000001" hex="0x01" />
</result>
""")

// Attribut ändern
rootNode.@size++

// Node hinzufügen (Parameter sind Name der Node sowie Attribute als Map)
rootNode.appendNode("field", [
  "name": "Kontakt_Name",
  "resultcode": "1",
  "bin": "00000001",
  "hex":"0x01"
])

// wieder XML-String erzeugen
println(XmlUtil.serialize(rootNode))
/* Ergebnis:
<?xml version="1.0" encoding="UTF-8"?><result size="2">
  <field name="Kontakt_Email" resultcode="1" bin="00000001" hex="0x01"/>
  <field name="Kontakt_Name" resultcode="1" bin="00000001" hex="0x01"/>
</result>
 */

SQL

Auch mit SQL kann einfacher gearbeitet werden.

java.sql.Connection conn = ...
def sql = new groovy.sql.Sql(conn)

def foo = "fruit"
sql.eachRow("SELECT * FROM food WHERE type=${foo}") {  // Parameter werden automatisch SQL-Encoded
  println("I like ${it.name}")                         // gibt Spalte "name" aus
}

Um ein automatisches SQL-Encoden zu gewährleisten, darf der Query-String nicht aus mehreren Strings zusammengebaut werden, sondern darf nur ein String mit Platzhaltern sein.

Überladene Methoden und Typen

Da Groovy Methoden dynamisch aufruft, zur Laufzeit aber nicht mehr die genauen Typen aus dem Quellcode kennt (wegen Type Erasure etc.), kann es vorkommen, dass mehrere Methoden gefunden werden, die zum Aufruf passen.

Das ist meistens der Fall, wenn null übergeben wird, hier weiß Groovy nur, dass es ein NullObject ist, kennt aber nicht den genauen Typ:

String str = null
println(str.getClass().simpleName) // NullObject

Beispielsweise gibt es diese zwei Methoden:

void setDate(String str) { ... }
void setDate(Date date) { ... }

Erfolgt nun in Groovy der Aufruf folgendermaßen:

// null als Literal
obj.setDate(null)
obj.date = null
 
// oder als Variable
String str = null
obj.date = str

Dann weiß Groovy nicht, welche Methode es genau aufrufen soll, das sowohl String als auch Date zu NullObject passen (null bzw. NullObject kann in beides umgewandelt werden).

Frühere Groovy-Versionen haben einfach irgendeine Methode genommen, neue Versionen werfen eine Exception. Da dies nicht rückwärts-kompatibel ist, bringen CMS-Versionen, welche neuere Groovy-Versionen enthalten, stattdessen einen Fehler im Log, funktionieren aber weiterhin mit altem Code (es wird irgendeine Methode genommen).

Falls so ein Szenario auftritt, kann man Groovy aber helfen, in dem man beim Aufruf den Typ explizit als Cast hinzufügt (es muss hier die Methode aufgerufen werden, beim Property-Setter geht die Typ-Info wieder verloren):

obj.setDate(str as String) // OK
obj.setDate((String)str)   // OK
 
// obj.date = str as String // geht nicht
// obj.date = (String)str   // geht nicht
Groovy

Groovy – Übersicht

Seit Version 2.6.2 ist es möglich die Scriptsprache Groovy im CMS zu verwenden (sowohl in Actions als auch in Templates). Zu beachten ist, dass je CMS-Version ggf. eine andere Groovy-Version eingebunden ist - dazu die .jar Datei im lib-Verzeichnis prüfen oder in Entwickler-Tools ausführen: println(GroovySystem.version).

Groovy ist eine dynamische Sprache mit vereinfachter Syntax und Funktionalitäten (ähnlich JavaScript) und vielen schon eingebauten Utilities. Außerdem wurden bestimmte Sachen des CMS erweitert, damit man sie einfach in Groovy benutzen kann (z.B. Datensätze bearbeiten).

Groovy

Logging

Es können logI("text") für INFO-Meldungen etc. verwendet werden. logE kann als zweiter Parameter zusätzlich noch eine Exception übergeben werden.

Zur besseren Übersicht im Log wird immer der Scriptname vorangestellt.

logName noch anpassen

es muss noch com.batix.Log importiert werden

Zum Kopieren (für Script)

/* Logging start */
def logName = "myScript"
//noinspection GroovyUnusedAssignment
def logD = { String msg, HttpServletRequest request = null -> Log.debug("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
def logI = { String msg, HttpServletRequest request = null -> Log.info("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
def logN = { String msg, HttpServletRequest request = null -> Log.notice("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
def logW = { String msg, HttpServletRequest request = null -> Log.warn("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
def logE = { String msg, Exception ex = null, HttpServletRequest request = null -> Log.error("[${logName}] ${msg}", request, ex) }
/* Logging end */

Zum Kopieren (für Klassen)

/* Logging start */
private static def logName = "myScript"
//noinspection GroovyUnusedAssignment
private static void logD(String msg, HttpServletRequest request = null) { Log.debug("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
private static void logI(String msg, HttpServletRequest request = null) { Log.info("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
private static void logN(String msg, HttpServletRequest request = null) { Log.notice("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
private static void logW(String msg, HttpServletRequest request = null) { Log.warn("[${logName}] ${msg}", request) }
//noinspection GroovyUnusedAssignment
private static void logE(String msg, Exception ex = null, HttpServletRequest request = null) { Log.error("[${logName}] ${msg}", request, ex) }
/* Logging end */ 

Beispiel

def user = BxUser.findInstance(request)
if (!user) {
  logE("no user found")
  return
}
 
logI("found user ${user.id}")
Groovy

Timings

Zwischendrin immer addTiming("kleine Info was gemacht wurde") aufrufen.

Es können auch einzelne Durchläufe einer Schleife gemessen werden: addTiming("Info zur Schleife", "Info zum Durchlauf"). So werden die aufeinanderfolgende Timings, bei denen der erste Parameter identisch ist, gruppiert.

Am Ende gibt getTimings() eine Zusammenfassung als String zurück. Für Schleifen wird die Gesamtdauer sowie die Anzahl der Durchläufe und die mittlere Dauer ausgegeben. Außerdem werden die Top und Flop 3 der Durchläufe (nach Dauer) angezeigt.

Zum Kopieren

/* Timings start */
def timings = []
def timingLast = new Date().time
def addTiming = { String title, String subTitle = null ->
  def duration = new Date().time - timingLast
  if (subTitle) {
    def value = [
      duration: duration,
      title: subTitle
    ]
    if (!timings || timings[-1].title != title) {
      timings << [
        title: title,
        values: []
      ]
    }
    timings[-1].values << value
    value.index = timings[-1].values.size()
  } else {
    timings << [
      duration: duration,
      title: title
    ]
  }
  timingLast = new Date().time
}
Closure<String> getTimings = {
  def res = new StringBuilder()
  res << "Timings:\n"
  def timingTotal = 0
  def emptyPrefix = " " * 27
  def maxDetails = 6
  timings.each { t ->
    if (t.values) {
      List vals = t.values.sort { a, b ->
        a.duration <=> b.duration ?:
          a.index <=> b.index
      }
      long sum = vals.sum { it.duration } as long
      double avg = sum / t.values.size()
      timingTotal += sum
      res << String.format("%8d ms (+%8d ms) %s (%dx ~%.2f ms)\n", timingTotal, sum, t.title, t.values.size(), avg)
      if (vals.size() > maxDetails) vals = [*vals[0..(maxDetails / 2 - 1)], null, *vals[-(maxDetails / 2)..-1]]
      vals.each { val ->
        res << emptyPrefix
        if (val) res << String.format("#%-4d %4dms %s\n", val.index, val.duration, val.title)
        else res << "[...]\n"
      }
    } else {
      timingTotal += t.duration
      res << String.format("%8d ms (+%8d ms) %s\n", timingTotal, t.duration, t.title)
    }
  }
  def lastDuration = new Date().time - timingLast
  timingTotal += lastDuration
  res << String.format("%8d ms total\n", timingTotal)
  return res.toString()
}
/* Timings end */

Beispiel

// do stuff
addTiming("startup")
// do more stuff
addTiming("init")
// do loop stuff 1
addTiming("fetch info", "load one...")
// do loop stuff 2
addTiming("fetch info", "load two...")
// ...
// do database stuff
addTiming("finalizing")
// do final stuff

Erzeugt dann z.B. mit logI(getTimings()) sowas:

Timings:
       1 ms (+       1 ms) startup
      94 ms (+      93 ms) init
     753 ms (+     659 ms) fetch info (7x ~94,14 ms)
                           #4      15ms load 15F53263D95
                           #5      16ms load 15F53263DA5
                           #3      17ms load 15F53263D86
                           [...]
                           #2      20ms load 15F53263D75
                           #6      78ms load 15F53263DF3
                           #1     496ms load 15F53263D61
    2598 ms (+    1845 ms) finalizing
    2605 ms total 
Groovy

Tips

Hier gibt es lose gesammelte Tricks und Kniffe.

Bessere Exceptions im Log

Um Stacktraces von unnötigem Groovy-Meta-Ballast zu befreien und so direkt lesbar zu machen, gibt es StackTraceUtils.deepSanitize. Statt die Exception direkt an Log o.ä. zu übergeben, einfach diese Methode drumherum packen und schon verschwinden unnötige Zeilen aus dem Stacktrace.

import com.batix.Log
import org.codehaus.groovy.runtime.StackTraceUtils
// ...
try {
  // ...
} catch (Exception ex) {
  Log.error("my error message", StackTraceUtils.deepSanitize(ex))
}

Session

Manchmal gibt es Probleme in Groovy, wenn es keine Session gibt, weil standardmäßig kein Sessioncookie mehr erzeugt wird. Dadurch ist die Groovy-Variable session nun manchmal leer und muß im GroovyAction mit if (!session) session = request.session gefüllt werden und in <bx:groovy> mit session = includeTag.forceSession() Das müßte auch noch irgendwo in die Hilfe eingetragen werden.

Wenn man keine Session im JSP braucht sollte man oben <%@page session="false"%> hinzufügen. Sonst wird auf der Seite, auf der das JSP eingebunden ist, ein Session-Cookie erzeugt.

Groovy

Verwendungsmöglichkeiten

Groovy-Code kann in Actions (Actionbaustein "Groovy ausführen") oder in Quelltexten (bx:groovy) eingesetzt werden. Es gibt auch die Möglichkeit in den Entwickler-Tools schnell Groovy-Code auszuführen.

Um Ausgaben zu erzeugen, kann einfach println verwendet werden:

Außerdem ist es jeweils möglich zentrale Groovy-Bausteine aus dem aktuellen Projekt einzubinden (unter Dokumentvorlagen > Groovy), um Code nachzunutzen - dies ist das gleiche Prinzip wie bei Textbausteinen.

Werkzeuge & Integrationen

Werkzeuge & Integrationen

Abgleichtool

Anleitung Abgleichtest

Ist auf dem empfangenden System auszuführen.

Zu finden unter:

Entwicklertools / Abgleichtest

Zum Anmelden die Server- und Zugangsdaten des sendenden Systems angeben.

z.B. URL: https//84-xxxxxxxxx.batix.cloud

   Benutzer : ADMIN

   Passwort: 123456789

Es werden jetzt alle Tabellen angezeigt mit Anzahl der Datensätze und Differenzen angezeigt.

z.B. Design

image2019-11-5_8-8-13.png

Mit einem Klick auf Daten werden die Details angezeigt.

Wahrscheinlich unvollständige Liste der interessanten Einträge:

Action Einzelbestandteile der Actionscripte
Actionscript Actionbausteine
Designs Alles unter Dokumentenvorlagen(Komplettseiten, Designtemplates, Textbausteine, JSP-Bausteine, Groovy, Plugins, sonstiges)
EZT Einzeiliger Text
Felder Verknüpfung EZT zu Menü
MZT Mehrzeiliger Text
NAVFILES Bestandteile der Navigationspunkte
Navigation Navigationspunkte
Styles CSS - DAtein
Tabledef Containerliste
Tablefields Containerfelderinformationen z.B. Verknüpfungen , Untercontainer usw.
ADMINGROUP Gruppen der User
IMGARCHIV Bilder für Navigation
IMGKAT Kategorien der Bildergalerie
IMG Bilderverknüpfung
LOOP BX-Schleife
LOOPELEMENT Element des LOOP
DOC Verknüpfung der Dokumente
DOCARCHIV Dokument
DOCFOLDER Baumstruktur der Dokumente

Anschließend kann es sinnvoll sein unter Entwicklertools zu klicken.

image2019-11-5_8-8-35.png

Es können jetzt die Einträge ausgewählt werden, welche auf das empfangende System übertragen werden sollen. Anschließend ganz unten auf „ausgewählte ändern" klicken und auf der Folgeseite bestätigen.

Um sich die Unterschiede der beiden Dateien anzeigen zu lassen besteht die Möglichkeit ganz link auf Details zu klicken.

Es werden dann beide Stände zum Vergleichen angezeigt.

image2019-11-5_8-9-25.png

Werkzeuge & Integrationen

VUE

Intro

Wie schon mehrfach bemerkt, ist es sehr umständlich ein dynamisches Frontend von Grund auf per Hand in HTML und JavaScript umzusetzen. Abhilfe schaffen z.B. Frameworks wie Vue (ausgesprochen wie das englische „View", manch einer nennt es auch eingedeutscht „Wü"). Diese kümmern sich um die Dynamisierung einer Ansicht anhand von Daten.

Ein ersten Projekt war die Reisekostenabrechnung im neuem CRM. Wer das noch nicht kennt, darf gern in den Feldern rumschreiben und die bunten Knöpfchen drücken (keine Angst, es wird nichts gespeichert oder gelöscht). Es wurde dabei nur der Frontend-Code angefasst (das Formular sendet immer noch an dasselbe Action) und in knapp einer Stunde war das Thema erledigt.

Dabei ist sogar eine neue Funktion (Live-Anzeige der Summe der Posten) rausgesprungen. Zu Demozwecken habe ich unten drunter noch die aktuellen Daten ausgegeben, die sich bei Änderungen live aktualisieren!

Es werden hier nicht alle Begriffe erklärt, sondern nur das, was für das Beispiel nötig ist. Wer mag kann gern Google bemühen oder den weiterführenden Links folgen. Manches ist vielleicht nicht 100% Best Practice, das würde aber sonst den Rahmen sprengen.

Installation

Vue ist fix installiert. Man muss lediglich eine .js Datei via <script> einbinden. Während der Entwicklung empfiehlt sich die Development Version, da man hier hilfreiche Warnungen und genaue Fehler erhält, sollte mal etwas schief gehen. Die Dateigröße hält sich in Grenzen:

Wer einfach mal etwas mit Vue testen will, kann z.B. hier einfach live rumprobieren: http://jsfiddle.net/filipelinhares/2eAqE/ (nach Änderungen oben auf Run drücken)

Grundlegendes

Oberste Priorität bei der Entwicklung mit Vue (und auch anderen MVC/MVVM/etc.-Frameworks) hat die Trennung von Daten (Model) und Anzeige (View).

Das bedeutet, dass alle Daten, die für den Aufbau der Anzeige nötig sind, im JavaScript als Objekte vorhanden sind, bzw. daraus berechnet werden können. In erweiterten Szenarien können Daten auch asynchron nachgeladen werden.

Ist das erledigt, definiert man die Anzeige mittels einem Template. Das erfolgt größtenteils mit normalen HTML-Tags. Hier und da können spezielle Platzhalter verwendet werden, ähnlich unseren Batix-Tags. Diese unterscheiden sich in Interpolationen und Direktiven wie z.B. Schleifen (genaue Infos dazu weiter unten).

Das Besondere an Vue ist nun, dass es die Daten nimmt und anhand derer den View zusammenbaut. Es wird also kein HTML-Code beim Server angefragt. So weit, so schnell selbst gebaut. Jetzt kommt aber der Clou! Werden nun die Daten geändert (das kann u.a. das Ändern eines Strings oder das Hinzufügen/Entfernen von Array-Elementen sein) bekommt Vue das direkt mit und passt die Anzeige entsprechend an. Es rendert also den View neu. Hierbei ist Vue auch auf Performance bedacht und rendert nur die nötigen Teile neu, die sich geändert haben. Wow! Man kann das im CRM-Beispiel ganz gut sehen, wenn man irgendwo tippt und es aktualisiert sich die Debug-Ausgabe oder die Summe.

Das ist aber noch nicht alles, denn Vue kann auch vom User gemachte Eingaben in Textfelder oder via Checkboxen etc. wieder zurück in die Daten schreiben. Vue benötigt dafür kein jQuery oder sonstige Libraries.

Model (Daten)

Im Beispiel habe ich die User-Daten der Einfachheit halber größtenteils mit Batix-Tags gefüllt. Das Objekt sieht so aus:

var fzkData = {
 date: moment().format("DD.MM.YYYY"),
  lastMonth: moment().subtract(1, 'month').format("MM.YYYY"),
  settings: {
    kennzeichen: "<bx:recordfield.FZK_Kennzeichen encode="javascript" />",
    iban: "<bx:recordfield.FZK_IBAN encode="javascript" />",
    bic: "<bx:recordfield.FZK_BIC encode="javascript" />",
    kontoinhaber: "<bx:recordfield.FZK_Kontoinhaber encode="javascript" />"
  },
  rows: []
};

Dabei ist lastMonth eine Hilfsvariable, settings und date entsprechen den Feldern im linken Bereich und rows sind die Tabellenzeilen im rechten Bereich.

Die Daten werden beim Erzeugen einer Vue-Instanz übergeben und sind dann innerhalb der Instanz sowie im Template verfügbar.

View (Anzeige)

Das komplette Template habe ich ein div mit der ID fzkApp gepackt. Ich zeige hier ein paar Ausschnitte davon. Die ganzen Bootstrap Klassen und das Beiwerk lasse ich dabei zwecks Lesbarkeit weg.

Die linke Seite sieht im Quelltext so aus

<h5>Daten</h5>
<div>
  <label for="Kennzeichen">Kennzeichen</label>
  <input type="text" name="Kennzeichen" v-model="settings.kennzeichen">
</div>
<div>
  <label for="IBAN">IBAN</label>
  <input type="text" name="IBAN" v-model="settings.iban">
</div>
<div>
<label for="BIC">BIC</label>
  <input type="text" name="BIC" v-model="settings.bic">
</div>
<div>
  <label for="Kontoinhaber">Kontoinhaber</label>
  <input type="text" name="Kontoinhaber" v-model="settings.kontoinhaber">
</div>
<div>
  <label for="Datum">Datum</label>
  <input type="text" name="Datum" v-model="date">
</div>

Der einzige Unterschied zu normalem HTML ist die v-model Direktive. Damit man diese von normalen Attributen unterscheiden kann, fangen die Direktiven übrigens mit v- (für Vue) an.

Dank v-model wird von Vue für dieses Element ein sogenanntes Two-Way-Binding zu den Daten erzeugt. Das bedeutet die folgenden Prozesse laufen automatisch ab:

Man sieht hier schön, dass der Wert von v-model dem „Pfad" in den Daten entspricht. Am Ende ist es quasi JavaScript-Code, der die gewünschte Variable holt.

Die rechte Seite sieht so aus:

<h5>Posten</h5>

<table>
  <thead>
    <tr>
      <th>Belegdatum</th>
      <th>Ausgabe (z.B. Menge + Kraftstoffart)</th>
      <th>Betrag [€]</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(row, index) in rows">
      <td><input type="text" :name="'ph_' + index + '_datum'" v-model="row.datum"></td>
      <td><input type="text" :name="'ph_' + index + '_ausgabe'" v-model="row.ausgabe"></td>
      <td><input type="text" :name="'ph_' + index + '_betrag'" v-model="row.betrag"></td>
      <td><button @click="removeRow(index)">x</button></td>
    </tr>
  </tbody>
</table>

<span>Summe: {{ sum }} €</span>

<button @click="addRow()">+</button>
<button type="submit">erstellen</button>

Hier gibt es einige neue Sachen! Zum einen wäre da v-for, was man sich wie eine for-Schleife z.B. in JavaScript vorstellen kann. Diese Direktive sorgt dafür, dass ein <tr> für jedes Element im rows-Array erzeugt wird. Hier hilft es sich die Daten gefüllt vorzustellen, nehmen wir also mal an:

"rows": [
  { // = row, index 0
    "datum": "12.10.2018",
    "ausgabe": "23,5 l Diesel",
    "betrag": "33,44"
  },
  { // = row, index 1
    "datum": "20.10.2018",
    "ausgabe": "Waschen",
    "betrag": "4,99"
  }
]

Für diesen Fall werden also bei Benutzung von <tr v-for="(row, index) in rows"> zwei <tr>s erzeugt werden. In der Direktive gibt man der Laufvariable einen Name (hier row), optional kann man auch noch den aktuellen Schleifendurchlauf bekommen (hier index). Innerhalb der Schleife kann auf Daten des aktuellen Array-Elements mittels row (der Laufvariable) zugegriffen werden, was man hier mit dem bekannten v-model sieht (v-model="row.datum"). In diesem Fall kommt v-model auch nicht mit den Array-Elementen durcheinander – Änderungen landen beim richtigen Objekt, ohne dass man extra nochmal einen Index o.ä. angeben muss.

Ein weiteres neues Konstrukt ist der Doppelpunkt. Das ist nichts weiter als eine Abkürzung für v-bind. Statt :name="..." könnte man also auch v-bind:name="..." schreiben. Im Gegensatz zu v-model erzeugt v-bind nur ein One-Way-Binding, die Anzeige wird also nur aktualisiert, falls sich die Daten ändern, nicht andersrum.

Zu beachten ist, dass der Wert von v-bind kein reiner Text, sondern JavaScript Code ist! Das ist übrigens bei fast allen Direktiven der Fall. Möchte man also einen dynamischen String zusammenbasteln, müssen z.B. Quotes und Plusse verwendet werden.

Kurz dazu, warum ich den name der Inputs so dynamisch zusammenbaue: Im Beispiel wird eine <form> an den Server geschickt und dabei müssen die Elemente natürlich sinnvoll gruppiert sein (ähnlich new-1/Feldname beim Save-Action). Man kann den name auch weglassen und später die Daten direkt irgendwo hin schicken, diese spiegeln ja den Stand im View wider. Ich habe hier wie gesagt die Backend-Logik nicht angefasst und nur das Frontend analog zum Alten gebaut.

Eine weitere Abkürzung bei @click="addRow()" ist das @, nämlich für v-on. Anstatt @click="..." könnte man also auch v-on:click="..." schreiben. Hiermit lassen sich Events binden und auch hier ist der Wert der Direktive im Prinzip wieder JavaScript-Code (man kann die runden Klammern auch weglassen). Alle Variablen, die im Scope sind, können natürlich verwendet werden – hier z.B. index, um zu übergeben, welche Zeile (also welches Array-Element) gelöscht werden soll. Wo die Methoden removeRow und addRow herkommen, sehen wir weiter unten.

Als letztes, zentrales Syntax-Element ist die Interpolation, ausgedrückt durch die geschweiften Klammern, zu nennen. Innerhalb dieser, man ahnt es vielleicht schon, wird wieder JavaScript-Code geschrieben. Im einfachsten Fall ist das nur eine Variable, die dann eben ausgegeben wird. Im Beispiel steht da sum, was keine Variable, sondern eine „Computed Property". Details dazu gibt es auch weiter unten.

Die Ausgabe der Live-Daten funktioniert ebenfalls über Interpolation und eine Computed Property:

Live-Data:<br>
<small><pre>{{ dataAsJson }}</pre></small>

Es ist vielleicht aufgefallen, dass hier nicht darauf geachtet werden muss, irgendwo htmlencode o.ä. einzubauen. Vue kümmert sich selbst darum, dass die Daten passend escaped werden und so nicht zur Sicherheitslücke werden können (zumindest was XSS angeht).

Vue-Instanz erzeugen

Das Template wird folgendermaßen mit den Daten verbunden und „reaktiv" gemacht:

new Vue({
  el: "#fzkApp",
  data: fzkData
})

Das reicht schon und man erhält seine fertige Komponente. Natürlich gibt es noch mehr Optionen, ein paar davon brauchen wir auch noch, um z.B. die Methoden und Computed Properties zu definieren.

Methoden

Im Template oben wurden ja die Funktionen addRow und removeRow aufgerufen. Diese müssen natürlich noch definiert werden. Das geschieht über die Option methods. Hier sollten Funktionen rein, die in der Komponente (entweder im Template oder in anderen Methoden) gebraucht werden und nur spezifisch für diese Komponente sind. Ich habe die zwei Methoden folgendermaßen definiert:

new Vue({
  // ...
  methods: {
    addRow: function() {
      this.rows.push({
        datum: "__." + this.lastMonth,
        ausgabe: "",
        betrag: ""
      });
    },
    removeRow: function(index) {
      this.rows.splice(index, 1);
    }
  }
})

(splice ist vielleicht nicht so bekannt: es entfernt hier einfach die angegebene Anzahl an Elementen vom übergebenen Index an)

Das this in solchen Methoden ist automatisch die Vue-Instanz. Darüber erhält man direkten Zugriff auf z.B. die Daten, Methoden und Computed Properties. Wie man sieht bearbeite ich hier auch nur die Daten, den Rest (das Rendern des entsprechenden HTMLs) übernimmt Vue!

Damit nach dem Laden der Seite direkt eine Zeile mit leeren Inputs zum Eingeben erscheint, wird addRow dann noch im created Lifecycle Hook aufgerufen, welcher feuert, sobald die Vue-Instanz angelegt wurde:

new Vue({
  // ...
  created: function() {
    this.addRow();
  }
})

Computed Properties

Computed Properties sind den Methoden ähnlich. Sie werden über die Option computed definiert. Der Unterschied zu Methoden ist, dass sie ein Ergebnis zurückliefern. Dieses kann dann im Template ausgegeben werden. Auch hier ist Vue so schlau den View zu aktualisieren, wenn sich das Ergebnis ändert. Das kann ja der Fall sein, da man in den Computed Properties irgendetwas anhand der Daten der Instanz berechnet.

Im Template oben wurden zwei Stück benutzt: dataAsJson gibt einfach die aktuellen Daten als JSON formatiert aus und sum berechnet die Summe der Tabellenzeilen. Das ist in wenigen Zeilen niedergeschrieben:

new Vue({
  // ...
  computed: {
    dataAsJson: function() {
      return JSON.stringify(this.$data, null, 2);
    },
    sum: function() {
      var s = 0;
      this.rows.forEach(function(row) {
        var amount = row.betrag ? parseFloat(row.betrag.replace(/,/, ".")) : 0;
        s += amount;
      });
      return s.toFixed(2).replace(/\./, ",");
    }
  }
});

Man sieht hier, dass auf this.$data zugegriffen wird. Das ist eine von diversen Spezial-Properties der erzeugten Vue-Instanz (die ja als this verfügbar ist). Ich hätte genauso gut auch fzkData nehmen können, da wir diese Daten im Beispiel als globales Objekt haben. Das ist aber nicht schön. Im Normalfall sollte man die Daten inline beim Instanz Erzeugen angeben, damit diese nicht aus Versehen noch von einer anderen Instanz mitbenutzt werden. Natürlich kann man auch Instanzen/Komponenten verschachteln und Daten rumreichen, das würde aber hier wieder den Rahmen sprengen. Es gibt mit Vuex auch eine State Management Library für komplexere Anwendungen, das aber nur am Rande.

Weiterführende Infos und Features

Vue bietet noch viele Features, die hier nur ganz kurz oder gar nicht erwähnt wurden. Ein paar picke ich hier extra nochmal raus. Als Dokumentation gibt ansonsten z.B. den Guide (beschreibt die Features und erklärt, wie man etwas macht) und die API Referenz (welche alle möglichen Optionen, Properties, etc. auflistet).

v-if / v-show

Mit v-if oder v-show kann man dynamisch Blöcke verstecken oder anzeigen, ähnlich unserem bx:if. So können z.B. Abschnitte in Formularen zugeschalten werden, wenn eine bestimmte Checkbox angehakt wird. Zu den Unterschieden von if und show siehe die Doku.

Beispiel (ok wäre dann z.B. ein Boolean in den Daten):

<h1 v-if="ok">Yes</h1>
<h1 v-show="ok">Hello!</h1>

v-on mit Modifiern

Beim Event-Binden kann man noch bestimmte Modifier setzen. Das reduziert Boilerplate-Code, wenn man z.B. nur an Rechtsklicks oder Enter-Tasten interessiert ist und/oder man das Event preventen will. Ein paar Beispiele aus der Doku:

<!-- prevent default -->
<button @click.prevent="doThis"></button>
<!-- prevent default without expression -->
<form @submit.prevent></form>
<!-- key modifier using keyAlias -->
<input @keyup.enter="onEnter">
<!-- the click event will be triggered at most once -->
<button @click.once="doThis"></button>

Filter

Ausgaben im Template oder mit v-bind können mittels Filtern angepasst werden. Denkbar ist z.B. eine schicke Preisformatierung mit zwei Nachkommastellen oder das Großschreiben des ersten Buchstabens einer Meldung:

{{ message | capitalize }}

Components

Man kann nachnutzbare Komponenten definieren. Ein einfacher Anwendungsfall ist z.B. ein Listenelement. Hat man z.B. eine Kontaktliste, so kann man für den einzelnen Kontakt-Eintrag eine extra Komponente definieren. Das hilft beim Organisieren von größeren Projekten und ist vergleichbar mit Textbausteinen. Jede Komponente bekommt dabei ihre eigene Vue-Instanz, das sieht man z.B. hier in einem Beispiel.

Apropos Components: Es gibt sehr viele vorgefertigte Komponenten für Vue! Das reicht von Datepickern und Kalendern bis hin zu Bootstrap-Komponenten.

Weitere Links:

https://vuejs.org/ - offizielle Website

https://entwickler.de/online/javascript/vue-js-javascript-framwork-einfuehrung-579850224.html - Einführung auf Deutsch