CMS Handbuch – Entwickler Technische Referenz und Entwicklerdokumentation für das batix® CMS Einführung & Grundlagen Konzepte, Tag-Grundlagen, Filter, Datums-Patterns, Redakteurs-Tags. 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: ... ... Eine Mehrfachverwendung von "filter-object" bewirkt eine UND-Verknüpfung dieser Objekte. Objekte Ein "filter-object" ist folgendermaßen aufgebaut: ... ... ... [ ... |... |... |... |... ] 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. feldname feldname/unterfeld 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 ... können die folgenden Abfragen eingesetzt werden. request-value Der Vergleich findet mit dem Wert eines Request-Parameters statt. Request-Parameter-Name request-attribute Der Vergleich findet mit dem Wert eines Request-Attributes statt. Request-Attribut-Name session-attribute Ein Session-Attribut wird mit dem Feld verglichen. Session-Attribut-Name static-value Der Wert zum Vergleichen wird direkt übergeben. gesuchter Wert 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). TODAY 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). NOW USERID Es wird mit der UserID des aktuellen (eingeloggten) Betrachters verglichen. USERID SESSIONID Die aktuelle SessionID wird abgeglichen. SESSIONID 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). USERGROUPS PARENTCONTAINER Es wird mit der ID des übergeordneten Containers verglichen. PARENTCONTAINER 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. 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 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. 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 feste_id Gegenteil von include: exclude (schließt diese ID(s) aus) (weitere Erläuterungen folgen noch) Beispiele Datumsvergleich Datum 11 TODAY Es werden nur Datensätze angezeigt, die maximal einen Tag alt sind. Suche Kategorie 8 kat Titel Text 1 search Archiv 4 0 Nur Datensätze, die folgenden Kriterien entsprechen werden ausgegeben: Kategorie-ID (Einzel- oder Mehrfachverknüpfung) ist die selbe wie im Request-Parameter kat Felder Titel oder Text enthalten den Suchbegriff aus dem Request-Parameter search Haken bei Archiv (Wahrheitswert) ist nicht gesetzt Parameter-Werte (Präfixe) Mit den folgenden Präfixen kann man auf verschiedene Variablen zugreifen: request :Name - der Wert wird aus dem Request-Parameter "Name" geholt attribute :Name - der Wert wird aus dem Request-Attribut "Name" geholt session :Name - der Wert wird aus dem Session-Attribut "Name" geholt clipboard :Name - der Wert wird aus dem Clipboard "Name" geholt static :Wert - es wird direkt "Wert" verwendet system :Wert - es wird auf die Systemvariable "Wert" zugegriffen Diese Präfixe können als Wert jedes Tag-Attributes verwendet werden. Nur bei bx:containerfilter : special :PARENTCONTAINER - ID des übergeordneten Datensatzes special :USERID - ID des angemeldeten Users special :SESSIONID - Sessionid wird geholt special :NOW - Vergleich mit "jetzt" special :TODAY - Vergleich mit "heute" ab 2.6.2. requests :IDs - IDs mit Leerzeichen getrennt werden aus dem Request genommen requestc :IDs - IDs mit Komma getrennt werden aus dem Request genommen 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 Ausgabe eines Zeitstempels, z.B. 13.03.2016 13:48:33 Angebote im Monat Ausgabe des Monatsnamen Redakteurs-Tags Titel Alle Unterstriche / Underscores ( _ ) im {titel} Platzhalter werden in der Verwaltung durch Leerzeichen ersetzt. Zum Beispiel wird dann aus dieses Feld in der Verwaltung: 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. und 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: 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 In {kommentar} kann ein zusätzlicher Beschreibungstext angegeben werden, der in der Verwaltung unterhalb des Titels angezeigt wird. Beispiel: Eingabefeld mit Kommentar Admin-Mode 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 wird das schon automatisch so gemacht. Jetzt lässt es sich auch per Parameter bei anderen Tags steuern. Beispiele Einige Beispiele, wo dies sinnvoll sein könnte. Admin-Titel In Verwaltung wird ein anderer Titel ausgeben als der beim Tag angegebene. Beispiele genauere Bezeichnung des "picture" im Nachhinein einen Schreibfehler zu korrigieren, wenn das Design schon oft in Gebrauch ist Diese Tags können sich in der Verwaltung darstellen: bx:bild bx:cmpageinclude bx:datum bx:dezimal bx:document bx:email bx:optional bx:text Batix-Tags Referenz Vollständige Referenz aller bx: Tags, alphabetisch. 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 {content} 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 not ,  optional 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 eingefügt, diese Art der Beschreibung sollte allerdings nur in Ausnahmefällen auftauchen. Diese Beispiele sind laut der obigen Definition valide: Lorem Ipsum Die folgenden Beispiele sind allerdings nicht valide (das Kommentar hinter jedem Beispiel beschreibt warum): bx:access Der Inhalt des Tags access wird nur ausgegeben, wenn der Intranetbenutzer Zugriff auf einen gewählten Pfad besitzt. Inhalt Inhalt > 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. . 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 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. Sollte erst ab v2.7.1 verwendet werden. Es gibt momentan keine "Tag-Einstellungen"-Ansicht in Unterschleifen. Bei 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. Kommentar zweite Zeile Kommentar:
zweite Zeile
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 Inhalt 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 "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-$:/.+ "BATIX" maximal 80 Zeichen aus: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+% "BATIX" maximal 80 Zeichen aus: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd* "BATIX" maximal 80 Zeichen (Interleaved Two of Five) "123456" Weniger als 80 Ziffern, gerade Anzahl Am besten 6, 10, 12, 14, 16, 24, oder 44 Ziffern "12345678" genau 8 Ziffern "1234567891118" genau 13 Ziffern Prüfziffer muss stimmen "12345678910" genau 11 Ziffern (ohne Prüfziffer, wird automatisch berechnet) ODER genau 12 Ziffern (mit Prüfziffer) "12345678" genau 8 Ziffern 2-Dimensionale Codes Ausgabe "http://batix.de" Parameter ecl gibt das ErrorCorrectionLevel an: L ~7% (Standard) M ~15% Q ~25% H ~30% Einschränkungen Die Länge des verschlüsselten Strings kann die Ausgabe beeinflussen. Ausgabe "http:/batix.de" (rechts mit shape=square) "Lorem ipsum dolor sit amet" (rechts mit shape=rectangle) Parameter shape none (Standard, wird automatisch je nach Inhalt gewählt) square (Quadrat erzwingen) rectangle (Rechteck erzwingen) Ausgabe "http://batix.de" Parameter ecl gibt das ErrorCorrectionLevel an (in %, (0 - 100)), 25 sollte Minimum sein. layers gibt die Anzahl der Aztec-Layer an 0 (Standard): Minimum benutzen -1, -2, -3, -4: kompakter Modus 1 - 32: selbst angeben (nicht-kompakter Modus) charset gibt den Zeichensatz an, der zur Codierung des Inhaltes verwendet werden soll. Standard ist utf-8. Ausgabe "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. auto (Standard) text byte numeric dimensions minimale und maximale Spalten- (Cols) und Zeilenanzahl (Rows) kommagetrennte Zahlen Reihenfolge: minCols,maxCols,minRows,maxRows Standard: 2,30,2,30 Fehlerabfrage 1234Es konnte leider kein Barcode erzeugt werden! Da bx:barcode im Fehlerfall nichts ausgibt, kann ein alternativer Text mittels bx:if ausgegeben werden. Beispiele Hallo Hallo 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 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 Anzeige mit Kommentar in der Verwaltung   Ausgabeart festlegen 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 " alt="" title=", Autor:" > Weitere Angaben 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 bx:browse Das Tag browse gibt benachbarte Menüpunkte (ebenenübergreifend) zum Zweck des Blätterns aus. Linktext Linktext Linktext Linktext Es wird ein Link zum entsprechenden Menüpunkt erzeugt. 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 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 Inhalt 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 ... class="othermonth" ... Abfrage der Tage, die nicht zum angezeigten Monat gehören(, um sie z.B. andersfarbig zu markieren) Siehe auch "Kalender bauen" calendarfield.day Inhalt Gibt den Tag aus. Auch als offenes Tag nutzbar, um auf die beinhalteten DS zuzugreifen z.B. 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 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 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 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 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 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 ). bx:calendarloop Das Tag calendarloop benötigt man zur Erzeugung eines Kalenders mit Container-Anbindung. Siehe auch Kalender bauen Inhalt 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 ). bx:choice Das Tag choice zeigt seinen Inhalt abhängig vom aktuellen Hauptmenüpunkt an (z.B. für mehrsprachige Templates). Inhalt 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 Inhalt 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 Inhalt Schreibt den Inhalt in das Clipboard und gibt ihn aber nicht aus. Erklärung der Parameter: siehe oben clipboard.paste 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 Löscht alle Clipboard-Einträge. Um einen einzelnen Eintrag zu Löschen kann verwendet werden. 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 Hallo Welt Ausgabe "" Am Ende wird "Hallo Welt" ausgegeben. clipboard.if Inhalt Inhalt Inhalt Inhalt 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 Hallo Welt angezeigt angezeigt angezeigt 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. 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
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. 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. Inhalt 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 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 Diese Funktion gibt die ID des Datensatzes aus. Titel Es wird der Titel des Datensatzes angezeigt. ID = Request-Parameter Inhalt Der Inhalt wird nur ausgegeben, wenn der Requestparameter die ID des aktuellen Datensatzes enthält. parametername Request-Parameter Falls "name" nicht gesetzt ist, wird der Standardwert "recordid" benutzt. 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)  Inhalt 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
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 Rolle 8 12FF89E7458 gleiches Beispiel wie oben, nur mit einer SQL: Containerfilter-Aufruf im Quelltext
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
zugehöriger Filter SELECT m.* FROM bxc_mitglieder m WHERE m.ACTIV = 'j' AND m.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 Inhalt Inhalt 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
">
- Ranking:
| 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


">zurück 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 Innerhalb der obigen Schleife gibt dieses Tag den Rang des aktuellen Suchergebnisses zurück. containersearch.relevanz Dieses Tag gibt innerhalb der Suchschleife die Relevanz des aktuellen Ergebnisses aus. bx:cookie Mit diesem Tag können Cookies gesetzt/gelesen und Vergleiche angestellt werden. (verfügbar ab Version 2.6) bx:cookie ...Inhalt... Ausgabe 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 Wert für Cookie Hiermit kann ein Cookie gesetzt werden. Der Wert kann entweder über den Tag-Inhalt oder über value übergeben werden. name Name des Cookies value Wert, der gesetzt werden soll domain für den Cookie gültige Domain Wenn nicht angegeben, wird diese vom Browser automatisch auf die aktuelle Domain gesetzt. Wird z.B. als Domain "example.org" gesetzt, ist das Cookie auch unter "sub.example.org" verfügbar. Es kann keine fremde Domain eingetragen werden. path Das selbe Prinzip wie für domain gilt für path. Wird hier "/" eingetragen (Default-Wert) ist das Cookie auch unter "/sub/" verfügbar. maxage Verfallsalter des Cookies Valide Werte:   -1 (Default-Wert, Session-Cookie = wird gelöscht, wenn Browser geschlossen wird),   0 (Cookie wird sofort gelöscht, siehe auch cookie.delete)   Angabe in Sekunden (wie lang das Cookie gültig sein soll). secure secure legt fest, dass das Cookie nur über HTTPS übertragen werden soll. cookie.copy 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 de Wenn der Cookie "sprache" noch nicht gesetzt ist, wird als Sprache deutsch gesetzt. Verweise auf diese Seite: Keine Verweise gefunden. Suchbegriffe Cookies 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. size - Feldgröße in der Administration maxlength - maximale Eingabelänge des Feldes in der Administration bx:designloop Das Tag designloop erzeugt eine Schleife von sortierbaren Designbausteinen. Früher mit Tabellen-Layout und alten Containern war das so gedacht
ist ein erweitertes bx:schleife ist ein Platzhalter für den einzufügenden Designbaustein Jetzt das neu belebte bzw. eigentlich neue Tag mit neuen Containern:
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 erweitertes bx:schleife 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. :
Beispiele Designloop, wie er beim Epona-Design eingesetzt wurde (z.B. Stadtwerke, Fröbeldekade) Beispiele One-Pager als Navigation eigentliche Schleife Keine Verweise gefunden. 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. 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 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. bx:directorylisting Mithilfe des Tags directorylisting lässt sich eine Verzeichnislistung der Dateiverwaltung darstellen. bx:directorylisting Inhalt 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 Inhalt Der Inhalt wird nur ausgegeben, wenn das aktuelle Element eine Datei ist. directorylisting.isfolder Inhalt Der Inhalt wird nur ausgegeben, wenn das aktuelle Element ein Verzeichnis ist. directorylisting.isparent Inhalt Der Inhalt wird nur ausgegeben, wenn das aktuelle Element das übergeordnete Verzeichnis ("..") ist. directorylisting.link Linktext 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 Falls das Element eine Datei ist, wird der Dateiname ausgegeben. directorylisting.filesize Falls das Element eine Datei ist, wird die Dateigröße ausgegeben. unit bestimmt die Einheit ( Byte (b), Kilobyte (k), Megabyte (m) ) directorylisting.filedate Falls das Element eine Datei ist, wird das Uploaddatum ausgegeben. pattern Ausgabeformat, Standard ist: "dd.MM.yyyy". directorylisting.titel Falls das Element eine Datei ist, wird der Dateiname ausgegeben. directorylisting.description Falls das Element eine Date ist, wird die Beschreibung ausgegeben. directorylisting.previous Linktext 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 Linktext Dieses Tag steht außerhalb der Schleife. Es erzeugt einen Link zur nächsten Seite, falls limit übeschritten wird. Standard-Linktext ist "weiter". 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. 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: Ausgabe innerhalb eines a-Tags "> | Größe: Ausgabe mit Nachkommastellen in englischer Schreibweise (Tausendertrenner ist Komma, Dezimaltrenner ist Punkt) Beispiele attachment Ausgabe: http://domain/files/{Batix-ID}/{Dateiname} setzt content-disposition:inline; filename=“{Dateiname}“, wird als Standard genommen, wenn nichts angegeben wird 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 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. bx:documentlist Das Tag documentlist listet ein virtuelles Verzeichnis der Dokumentenverwaltung. bx:documentlist Inhalt 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 Dieser Befehl gibt die ID des Eintrags aus. documentlist.link Linktext Es wird ein Link zur Datei erstellt (auch freier Linktext möglich). target Ziel-Browserfenster documentlist.filename Der Dateiname aus dem System wird ausgegeben. documenlist.filesize Die Dateigröße wird ausgegeben. unit Größeneinheit ( Byte ( b ), Kilobyte ( k ), Megabyte ( m ) ) documentlist.filedate Gibt das Uploaddatum der Datei aus. pattern Anzeigeformat (Standard: "dd.MM.yyyy") documentlist.titel Der Download-Dateiname wird geschrieben. documentlist.description Die Beschreibung der Datei wird ausgegeben. documentlist.previous Linktext 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 Linktext Dieses Tag steht außerhalb der Schleife. Es erzeugt einen Link zur vorherigen Seite, falls limit überschritten wird. Standard-Linktext ist "weiter". 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.   Schreibt einen Edit-Button in Form einer HTML-Form mit Hidden-Feldern und einem 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) link Schreibt einen Link in die Seite anstatt eines Formulars (Form in Form ist nicht erlaubt, wenn Editbutton z.B. innerhalb einer Form ist) Weitere angegebenen Attribute werden einfach in den Edit-Link übernommen. style Styleangaben für das -Feld class Klassenangabe für das -Feld form-style Styleangaben für die umgebende Form form-class Klassenangabe für die umgebende Form type="container" ** innerhalb einer Containerschleife z. B. :** --> öffnet die Verwaltung und springt zum aktuellen Datensatz des Schleifendurchlaufs field Sprungmarke zum entsprechenden Feld type="nav" **innerhalb einer Navigationsschleife z. B. : **--> öffnet die Verwaltung und springt zum Menüpunkt des Schleifendurchlaufs innerhalb einer Contentschleife ( , ): --> öffnet die Verwaltung und springt zum aktuellen Schleifenelement, auch mehrere geschachtelte Ebenen navid eine beliebige Nav-ID des Projektes Öffnet die Verwaltung und springt zum angegeben Menüpunkt function copy : Springt direkt zur Menüpunkt-kopieren-Seite sort : Springt direkt zur Untermenü-sortieren-Seite sortroot : Springt direkt zum Sortieren der Hauptebene datalist : Springt zur Container-Liste, die mit pool benannt ist (auf Anfrage) file Springt zu beliebiger Datei in Verwaltung mit „/“ am Anfang zu jsp in /verwaltung ansonsten zu virtueller Datei beim aktuellen Menüpunkt „kopieren.bx“, „sortieren.bx“ pool|baseloop (ab v 2.6.8) pool analog containerfilter, baseloop, wenn die Schleife auch auf der Seite ist - Wenn die Schleife nicht auf der Seite steht sub Name des Untercontainer-Feldes (für neuer Untercontainer-Datensatz (siehe Beispiel 2)) Beispiele `` schreibt ein ✐ als Buttontext ... Link in statischer Mail: 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: 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. bezeichner Name des Feldes in der Verwaltung size Größe des Eingabefeldes in der Verwaltung . Beispiele 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. 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 eine Ausführung des bx-Codes bewirkt werden. Im Quelltext-Containerfeld können mit z. B. Daten aus dem äußeren Datencontainer ausgegeben werden. Tag, das ein Tag zurückgibt 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 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) Dies ist gefährlich, da der Benutzer im Normalfall den Request-Parameter beliebig manipulieren und somit sämtlichen Batix-Code ausführen kann! bx:frame Das Tag frame stellt Funktionen für Framesets zur Verfügung. 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 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. 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. Falls type="url" angegeben ist, wird nur die URL zum Bild ausgegeben. bx:groovy Mittels bx:groovy kann innerhalb eines Template einfach Groovy-Code ausgeführt werden. Groovy Code ausführen ... 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 println("Hello, World") Include und Code MyLib.doStuff() Nur Include Parameter übergeben und auslesen def name = includeTag.getStringParameter("name") def age = includeTag.getIntParameter("age", 0) println("Hello, $name") if (age < 18) println("no access!") nobody

Herzlich willkommen in der Administration

// CheckRole Groovy (Auszug): def requestedRole = includeTag.getStringParameter("role") if (hasRole(requestedRole)) { println(includeTag.computeBody()) } Verweise auf diese Seite: Verwendungsmöglichkeiten Verwendungsmöglichkeiten (2 Verweise) bx:head Der Befehl head schreibt diverse Angaben zum Projekt in den Headbereich. head.style Schreibt ein in die Seite. Dies Tag wird benutzt, wenn der Stylesheet nicht am Ende des -Bereiches geschrieben werden soll, z.B. bei einer Browserweiche. head.setstatus Setzt den Status-Code der Seite (normalerweise "200") head.setheader  oder Inhalt 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 Angabe, daß die Seite nicht gecacht werden soll. head.cancelpage [optional:Daten die in den Body des Redirects geschrieben werden] 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 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 Wenn Artikel ausverkauft ist, wird von dieser Seite auf die Listenseite weitergeleitet. Wenn Artikel ausverkauft ist, wird eine Fehlerseite (ausverkauft.htm) angezeigt, aber nicht weitergeleitet. This page has moved. 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 Schreibt die Angaben vom Feld "Include im Head" beim Projekt an die angegebene Stelle, anstatt direkt vor . head.metatags Legt die Position im 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) Bx:i18n Das Tag i18n ist zur Unterscheidung von Text in unterschiedlichen Sprachen. Voraussetzungen: Die Sprachbezeichnung (z.B. DE,EN...) wird in der Session unter der Variablen I18N gespeichert. (Standard ist "de") Es gibt für jede Sprache einen Container, der so heißen muß, wie die in der I18N gespeicherten Sprachbezeichnung (z.B. DE, EN...) In diesen Containern gibt es zwei Felder, die beliebig heißen können. In dem einen wird das Schlüsselwort gespeichert, in der anderen die Übersetzung. Für die Übersetzung ist es sinnvoll, ein HTML-Editorfeld zu nehmen, denn so kann man mit kleinen Schlüsselwörtern (z.B. Begrüßung) viel Text abbilden. bx:if Das Tag if zeigt seinen Inhalt nur an, wenn eines oder mehrere innere Tags einen Inhalt besitzen. Inhalt ..................... 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
Alternativ bisher:
Ansprechpartner (mit umgebenenden ) soll ausgegeben werden, wenn mindestens ein Ansprechpartner verknüpft ist (ist die Ebene 1) if.else zu prüfende alternativer Text Der Inhalt dieses Tags wird immer dann ausgeführt, wenn die Bedingungen des übergeordneten Tests nicht zutreffen. Kurzform: entspricht: keine Angabe showalways Inhalt des else-Blocks wird immer ausgegeben* (ab *V2.6.1) siehe Beispiel Beispiele 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 zu prüfende weiterer zu prüfender Inhalt alternativer Inhalt 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 telefonisch nicht erreichbar 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 zu prüfende 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 " alt=""> 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="" 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. bx:ignore Um Bereiche eines Templates auszukommentieren kann das Tag ignore benutzt werden. nicht auszuwertender Bereich 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 in solchen Fällen vorzuziehen. 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 . 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. bx:internlink In der Administration bietet dieses Tag internlink die Auswahl eines Navigationspunktes und im Frontend zeigt es eine Verlinkung auf diesen Navigationspunkt an. Linktext shortpath relativer Pfad wird ausgegeben (www wird weggelassen) web Angabe des  Projektes, um Menüpunkte dieses anderen Projektes auszuwählen bx:javainclude Mithilfe des Tags javainclude kann eine JSP-Datei eingebunden werden, die über die Dokumentvorlagen gepflegt wird. [Text mit bx-Tags] [Text mit bx-Tags] [Text mit bx-Tags] 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 ...
neu!
... 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"%> <% Date limitDate; //auslesen eines selbst definierten Parameters vom 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()); } %> Zeige Inhalt an, wenn Datensatz neuer ist als x Tage 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 ... ... ... 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: /intern/api.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: Der Kunde heißt: Er wohnt in: 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: 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. ... { x: 5, s: "" } ... 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). 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). Feld war null oder nicht vorhanden Feld war vorhanden und nicht null Boolean Boolesche Werte können ähnlich wie Häkchenfelder im Container abgefragt werden. Eine kurze Version (geschlossenes Tag) mit  true /  false steht auch zur Verfügung. ... 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 ). 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  true /  false möglich (hier wird der jeweilige Wert von true oder false ausgegeben). 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: Es wird folgende Liste in dieser Reihenfolge durchprobiert: dd.MM.yy HH:mm:ss dd.MM.yy HH:mm dd.MM.yy HH.mm dd.MM.yy yyyy-MM-dd'T'HH:mm:ssZ (ISO 8601) Alternativ kann ein eigenes Pattern angegeben werden: 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: Werden z.B. Tages- oder Monatsnamen ausgegeben, wird über  locale die gewünschte Sprache eingestellt: 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): year month (im Bereich 1 - 12) day weekday (s.u.) hour minute second 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): Mögliche Werte beim Wochentag sind dabei folgende Werte (keine Zahlen erlaubt): mo / di / mi / do / fr / sa / so mon / tue / wed / thu / fri / sat / sun 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: before-now after-now before-today after-today today (ist am heutigen Tag) Das Tag kann dabei entweder offen (optional noch mit  not ) oder geschlossen mit den  true und/oder  false Parametern genutzt werden. Beispiele: in der Vergangenheit auch in der Vergangenheit oder genau jetzt String ausgeben Im einfachsten Fall wird der String ausgegeben und ggf. automatisch encoded (siehe Encodings für andere Encoding-Möglichkeiten). 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. 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 ). 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 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). Es können die meißten Funktionen von bx:recorddata verwendet werden: ... Gesamt:
... Ferner gibt es noch folgende Hilfsmethoden: ... ... 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. Object Um in ein JSON-Objekt tiefer einzusteigen, wird das Json-Tag (analog zu bx:recordfield bei Verknüpfungen) geschachtelt. 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 und 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). Feld '' hat den Wert '' 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: Autor: $.books[?(@.rating > 2)].author Autor: Preis: $.store.articles[?(@.price < $.maxprice)] Preis: bx:jspinclude Das Tag jspinclude veranlasst den Server eine URL aufzurufen und den zurückgegebenen Text in die Seite einzufügen. aufzurufende URL 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: ... Im Teaserbereich: /teaser/ansprechpartner.htm?amt= Es wird ein Teaser mit den Ansprechpartnern für dieses Amt im Teaserbereich aufgerufen mit der entsprechenden Amt-ID. bx:link Das Tag link schreibt einen automatisch generierten Link um seinen Inhalt. Unter anderem auch zur Verwendung im bx:loop, um auf die Detailseite zu verlinken. Detail-Link Inhalt Es wird ein relativer Link auf "detail.htm" erstellt, der die Seiten-ID als Parameter defaultLoop übergibt. class CSS-Klasse target Zielfenster im Browser Menü-Link Inhalt 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 List-Link Inhalt 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 Loop-Link Inhalt Es wird ein Link auf die angegebene URL erstellt und die ID des aktuellen Loop Elements übergeben. href aufzurufende URL Record-Link Inhalt Dieses Tag steht innerhalb von bx:record und erzeugt einen Link auf url bzw auf die aktuelle Seite, wenn href nicht angegeben wurde. recordfield ID des Records href URL bx:login Das Tag login zeigt seinen Inhalt nur an, falls der User ein- bzw. ausgeloggt ist. Inhalt 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. . 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. Inhalt 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 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) Ist jetzt besser benannt. loop.count geht noch wegen Kompatibilität) loop.id Diese Funktion gibt die ID des aktuellen Datensatzes zurück. loop.if Inhalt Der Inhalt wird nur ausgewertet, wenn die entsprechende Bedingung zutrifft. Folgende Bedingungen können abgefragt werden: first: Datensatz ist der Erste der Liste notfirst: Datensatz ist nicht der Erste der Liste gerade: Datensatz ist der 2., 4., 6., ... ungerade: Datensatz ist der 1., 3., 5., ... Prüfen auf letztes Element {wird ausgeführt im Falle des letzten Elements} 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 Inhalt 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 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! Linktext Linktext Ü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! Ü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). zurück vor Ü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) Über den Parameter object kann die jeweilige Schleife angesteuert werden. loop.designtitle Dieses Tag gibt den Titel des Designbausteins aus. (ab V2.6.6) Wenn das umgebende Schleifentag keine Designschleife ist, wird eine Fehlermeldung  ausgegeben. 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 mit der Erweiterung, daß bei jedem Befehl der Name einer Map angegeben werden muß. ab V 2.6.2 mapping.put key=value 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 1=super-spitzenmäßig 2=jo, paßt scho 3=grot-ten-schlecht mapping.paste 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: .. (siehe obiges Beispiel - das füllt die hier genutzte Liste ) reagiert auf den Requestparameter "note". So spart man sich dreimaliges pagedata.request-Gewurschtl. bx:math Das Tag math führt Berechnungen durch. Ab Version 2.5.9. {Aufgabe} 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 8*(-3+7) gibt "32,00" aus + gibt einen Preis incl. Versandkosten aus **(1+/100) gibt einen Bruttopreis aus. Debug {Aufgabe} gibt nicht nur das Ergebnis aus, sondern die gesamte Formel Beispiele 8*(-3+7) gibt "calc{8*(-3+7)}=32.0" aus Rechnen mittels Datenbank {Aufgabe} Rechenoperationen werden mittels einer SQL-Formel gemacht. Beispiele POW(3,4) gibt "81" aus ( 34 ) Vergleich von Zahlen angezeigter Inhalt 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 3 4 5 * +* *rechtwinklig Vergleiche mit min und max {Vergleichszahl} {Vergleichszahl} {Vergleichszahl} 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 nächste Sortier-Position: +1 Innerhalb einer Schleife wird die größte Sortierungsposition ermittelt ... *1.19 ... ab Euro (für Größe ) ... 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. [] Gesamtpreis: Addiert alle Preise im Warenkorb zusammen. Anzahl Artikel mit 7% Mwst: Anzahl Artikel mit 19% Mwst: Zählen in verschiedenen Kategorien Hochzählen / Zusammenzählen {Wert} Beispiele ] Gesamtpreis: Addiert alle Preise im Warenkorb zusammen. Anzahl Artikel mit 7% Mwst: Anzahl Artikel mit 19% Mwst: Zählen in verschiedenen Kategorien Formatieren von Zahlenwerten Formatiert den Zahlenwert im Request-Attribut/Clipboard und gibt das Ergebnis aus. Vergleich von Datumsen angezeigter Inhalt 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 31.10.2011 1.11.2011 immer angezeigt nie angezeigt Datum modifizieren {Datum} 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 20110922 gibt „15. Oktober 11“ aus gibt aus und speichert im Clipboard “ Wed, Jan 3 2018 ” gibt aus “ mercredi, 3. janvier 18 ” gibt aus “ среда **, 3. января 18**” gibt aus “ mié, ene 3 2018 ” gibt aus “ Wednesday, 3. January 18 “ Feiertagsausgabe (ab V 2.3.) Datumsangabe im konfigurierten Format 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 30.12.2015 2015:31 Dez 2015:30 Dez 30.12.2015 31.12.2015 auch Datums-Modifizierer möglich: 31.12.2015 gibt "Neujahr" aus Feiertagsabfrage (ab V 2.3.) Inhalt 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 kein Feiertag beim Aufruf von ...detail.htm?pruefdatum=30.12.2015 würde "kein Feiertag" ausgegeben Feiertag: wär das gleiche wie Feiertag: Zwei Arten, einen Feiertag abzufragen. auch Datums-Modifizierer möglich: morgen ist ein Feiertag Tagesdifferenz zwischen zwei Daten // wandelt Datum in Millisekunden (seit 1970) und Wert //wandelt Millisekunden zu Datum Wert Die Angabe von  pattern ist jeweils optional möglich (Standard ist "dd.MM.yyyy"). Beispiele 25.3.2017 2.4.2017 (-)/ 1000 / 3600 /24 Da wird „ 7.958333333333333 “ Tage ausgegeben. Normalerweise glatte Zahl, aber hier ist Sommerzeitumstellung dazwischen. Wenn man bei schreibt, rundet es auf 8 Tage. bx:navdata Das Tag navdata gibt zum aktuellen Menüpunkt des Schleifendurchlaufs Daten aus. Es kann innerhalb von , , , verwendet werden. navdata.id Die Id des Menüpunkts wird ausgegeben. navdata.name Der virtuelle Verzeichnisname des Menüpunkts wird ausgegeben. navdata.path 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. navdata.link verlinkter Text Es wird ein Link zum Menüpunkt erzeugt. 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 Das eventuell beim Menüpunkt eingetragene Target wird ausgegeben. navdata.meta Metadaten zum Menüpunkt ausgeben werden ausgegeben oder zum Vergleich herangezogen. navdata.index 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 gibt "(no)index" bzw. "(no)follow" entsprechend der Menüpunkteinstellung aus. Wenn beide Parameter angegeben sind, werden die Werte beide, durch Komma getrennt, ausgegeben. ... Zeigt den Inhalt an, wenn die angefragte Bedingung für den Menüpunkt zutrifft Beispiele rel="nofollow"> … navdata.visible Inhalt Zeigt an, ob das Frontend-aktiv-Häkchen beim Nav-Punkt gesetzt ist. ab v2.6.6. Beispiele style="color:grey;"> Es werden aktive und inaktive Menüpunkte angezeigt, die inaktiven werden in Grau dargestellt. navdata.if Inhalt Inhalt 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) bx:navigation Das Tag navigation wird verwendet, um eine Navigationsstruktur darzustellen. Allgemeine Syntax Inhalt> 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
-
--
Beispiel für geschachtelte Navigation navigation.path Der virtuelle Pfad wird ohne "/www/webname/" und ohne "/" am Ende ausgegeben (siehe Beispiel oben). navigation.dir Es wird nur der aktuelle Verzeichnisname ausgegeben. navigation.name Dieses Tag gibt den angezeigten Name des Menüpunktes aus. navigation.target Das Zielframe wird ausgegeben. ziel Standard-Zielframe, wenn im Menüpunkt kein Zielframe angegeben wurde navigation.id Dieses Tag gibt die ID des Menüpunktes aus. Die ID der aktuellen Seite kann auch mit bx:pagedata.navid ausgegeben werden. 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 Inhalt Inhalt Mit diesem Tag kann entschieden werden, ob ein bestimmter Quelltext ausgegeben werden soll. Die ID der aktuellen Seite kann auch mit bx:pagedata.nav 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 navigation.link Linktext Es wird ein Link zum aktuellen Navigationspunkt des Schleifendurchlaufs erzeugt. Es werden alle angegebenen Parameter in das HTML-Tag übernommen. Als target für den Link wird der beim Menüpunkt gespeicherte Wert bevorzugt. Beispiele | 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 Inhalt Dieses Tag gibt Meta-Daten zum aktuellen Menüpunkt aus oder prüft, ob diese vorhanden sind. Es kann auch bx:navdata benutzt werden. bx:navlink Mit dem Tag navlink kann man auf Daten eines Menüpunktes zugreifen (z. B. bx:text, bx:bild usw). Kann inner- und außerhalb von einem Navigations-Tag verwendet werden. Es kann auch bx:navdata benutzt werden, um auf die Eigenschaften des Menüpunktes zugreifen zu können. Innerhalb eines Navigations-Tags Inhalt sucht das nächste umgebende navigation-Tag (navigation, sitemap) und es können so Daten des Navigationspunktes abgerufen werden Beispiele
"> Statt des Menüpunktnamen wird als Navigations-Link das Seitenbild des jeweiligen Menüpunkts ausgegeben. Außerhalb eines Navigations-Tags (ab v2.6.2) Inhalt von der Seite 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: 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 Achtung: bx:news Momentan nur für alte Container
  • ( Beiträge)
  • bx:option 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 Im weiteren Verlauf der Seite kann man dann das Clipboard abfragen und entsprechende Designs ausliefern. 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. Inhalt 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 Seitenbild bx:pagedata Mithilfe des Tags pagedata lassen sich die verschiedensten Informationen die Seite betreffend ausgeben. pagedata.parentnavid Es wird die Navigations-ID des Elternpunktes (oder leer) ausgegeben. pagedata.webid Gibt die ID des Webs (Projekts) aus pagedata.webdir gibt das virtuelle Verzeichnis des Webs aus. pagedata.webhost (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 ) gebraucht wird, sondern die Hauptdomain. pagedata.virtualpath 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 Inhalt 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 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 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 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 Inhalt 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 außen herum ist. Dies verursacht manchmal Probleme : SQL-Filter: wenn encode=sql fehlt, wird jetzt HTML-Encoded (aus WHERE Ort LIKE '%Köln%' wurde WHERE Ort LIKE '%Köln%' und es wurde nichts mehr gefunden) ... führt jetzt zu doppelten kodieren. Inhalt Inhalt Request-Parameter auswerten 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¶=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 | | --- | --- | --- | --- | | ... | leer | angezeigt | angezeigt | | ... | angezeigt | leer | leer | | ... | leer | leer | angezeigt | | ... | angezeigt | angezeigt | leer | seite.htm ... leer ... angezeigt ... leer ... 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 Fall 2 true/false es wird nicht der Wert abgefragt, sondern ob überhaupt der Parameter übergeben wurde 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 // schreibt erste Zeile
    zweite Zeile und damit sieht man einen Zeilenumbruch im Browser xml Inhalt Inhalt 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 Inhalt 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 Inhalt Inhalt 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 Inhalt 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 alle Request-Parameter werden als 'hidden' Formularfeld in die Seite geschrieben pagedata.querystring QueryString ausgeben Ein '?' am Anfang ist in der Ausgabe nicht enthalten. Ge POST ete 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 Inhalt Inhalt Metadaten auswerten name Name der Meta-Eigenschaft value beliebiger Text, der mit der Meta-Eigenschaft übereinstimmen muß (oder auch nicht bei not ) pagedata.cookie Inhalt Inhalt Wertet vom Browser übergebene Cookies aus. name Name des Cookies value beliebiger Text, der mit dem Cookie-Wert übereinstimmen muß (oder auch nicht bei not ) pagedata.hostname Inhalt 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: wir ausgegeben: www.batix.com  wird ausgegeben: http://www.batix.com (ab v2.5.8) Sie haben unsere net- oder com-Domain aufgerufen. 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 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 Session-URL-Komponente (;jsessionid=) ausgeben, falls Cookies ausgeschaltet sind pagedata.url 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 ... 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 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 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 Inhalt Inhalt Inhalt (ab v2.5.7 ) Beispiele Intranet  Inhalt nur für IP-Adressen im Bereich "123.210.12.*" zeigen pagedata.scheme Gibt das Protokoll zurück. ("http" oder "https") (ab* v2.5.8*) pagedata.compressed .bxmin 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 ... Zeigt abhängig vom Projektstatus den Taginhalt an (ab* v2.6.2*). Beispiele Wenn das System auf "Produktiv" gestellt ist, wird tools.bxmin.js ausgegeben, sonst tools.js 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 Gibt folgendes aus: Bisher wird es immer von Hand reingeschrieben und bei Änderung des Seiteneincodngs passen die Zeichensätze nicht mehr zusammen. pagedata.header Beispiele ">zurück Direkt eingetippt ¡hola! Hallo Suchmaschine! Verweise auf diese Seite: Container-Filteraction bx:tools bx:tools Support für not hinzufügen Google-Sitemap Datei erzeugen Container-Filteraction Google-Sitemap Datei erzeugen Support für not hinzufügen (8 Verweise) 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. 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. bx:paypal Mithilfe dieses Tags wird ein verschlüsselter Wert für ein -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:
    ">
    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: 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:plugin Mit dem Tag plugin kann man sicherstellen, daß Pluginseiten genauso aussehen wie normale Verwaltungsseiten. plugin.css Es werden die nötigen Styles in den Head geschrieben, die der Pluginseite ihr Aussehen geben. und zwar: plugin:headline Inhalt 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 Inhalt ... evtl. weiterer toolblock 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 <bx:pagedata.navname/> zurück zur Liste ">zurück zur Umfrage ">NEU Datum:
    Zeit:
    ...
    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 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 ... (ab V 2.7.) Erweiterung im Tag, vergleichbar mit dem Filter am Tag bei  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 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 Inhalt Ist das id-Feld leer, wird ein Dummy-Datensatz angezeigt, d.h., die im Inhalt angebenen Felder sind leer. Beispiel
     
    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 Inhalt Dieses Tag funktioniert wie bx:record, es können aber mehrere Datensätze ausgewählt werden. 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 Inhalt 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 ... Kategorien:
    aktivinaktiv"> ... 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
    ... Kategorie:
    ...
    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
    ">
    checked> 

    ausführliche Variante Inhalt 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 Inhalt 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 Die unter pool (im umgebenden Tag) angegebene ID wird ausgegeben. recordchoice.loop Inhalt 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. Inhalt 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
    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
    >
    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. 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 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 Wandelt die ID in Datum um. pattern Ausgabe-Pattern, Standard: dd.MM.yyyy locale Sprachausgabe, Standard: de recorddata.containerid Gibt die Container-ID aus (ab Version 2.6.2). 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 Inhalt Inhalt 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
    ">
    Beim letzten DS der Liste soll die Anzeigeliste mit einem Strich abgeschlossen werden. Ansonsten wird ein Abstand zwischen den einzelnen Divs angezeigt. ...... 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: ... Inhalt wird ausgeführt, wenn man sich gerade in einem Dummy-Datensatz befindet: v2.6.2 neu ... v2.6.3 neu ... v2.6.3-v2.6.4.1** Bug** bei v2.7.1 neu ... Inhalt wird ausgeführt, wenn die ID des Datensatzes einer der IDs im Parameter entspricht (oder #null): v2.6.3 ... v2.7.1 ... Bug v2.6.3-v2.6.4.1 : '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 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 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 ... 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
    style="margin-right:0;">
    Der letzte DS in der Reihe, die aus 5 Elementen besteht, soll keinen rechten Abstand haben. Danach soll ein Clear-Div stehen.
    ;">
    "/>
    Gleiches Beispiel wie oben, allerdings mit true|false
    ;">
    "/> Die Spalten sollen Regenbogenfarben als Hintergrund bekommen (issn dämliches Beispiel, ich weiß - Vorschläge willkommen) recorddata.active ... 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 ... 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
    ... | 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
    ... | 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
    ... | 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. Linktext Gibt einen Link zur vorherigen Seite der Listenansicht aus, falls es eine vorherige Seite gibt. Nicht alle Parameter sind gleichzeitig verwendbar (Standard ist "link"). 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) Linktext 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) Linktext 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) Linktext Datensatzweise blättern recorddata.previouselement Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen. Linktext 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) Linktext 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) Linktext 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) Linktext 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. 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. 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. 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. 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. 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. Dieses Tag gibt die Anzahl der Anzeigeseiten aus. recorddata.navlist / 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 gibt die Nummer der Seite bzw. Detailseite aus recorddata.navlistindex gibt die Indexnummer zurück, die zum Aufruf der im Schleifendurchlauf repräsentierten Seite benötigt wird recorddata.navdetailid gibt die Datensatz-ID zurück, die zum Aufruf der im Schleifendurchlauf repräsentierten Detailseite benötigt wird recorddata.navlistpath / recorddata.navdetailpath 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 Inhalt Inhalt 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 Inhalt Inhalt 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 Inhalt Inhalt führt den Inhalt nur aus, wenn die anzuzeigende Zahl die letzte Seite bzw Detailseite ist. not kehrt das Verhalten um. recorddata.navlink Hinweis: Dieses Tag kann innerhalb von recorddata.nav benutzt werden und von dort alle relvanten Parameter übernehmen. Linktext Dieses Tag schreibt einen Link zu einer vorhergehenden oder nachfolgenden Seite (falls mehrere Seiten vorhanden sind). 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. Linktext 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. ... repräsentiert den jeweiligen Containerdatensatz. Funktioniert wie recorddata.nextelement type="object" (oder die anderen artverwanden Tags) Beispiele Beispiel 1 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 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 Text 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 ( )
    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 Inhalt Der Inhalt wird nur ausgeführt, wenn in der Schleife keine Datensätze zum Anzeigen vorhanden sind. Wenn das Tag nicht innerhalb von 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 z. Z. keine Newsbeiträge vorhanden News vorhanden: oder z. Z. keine Newsbeiträge vorhanden News vorhanden: Beispiel 2 ... Leider wurde kein Tier mit dem gesuchten Begriff gefunden. 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 Inhalt 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

    ">
    Linkaufruf mit Übergabe der Kategorie in der inneren Schleife. Zugriff auf die Kategorie-ID mit baseloop .

    &anbieter=">
    Ähnliches Beispiel wie oben mit zusätzlicher Ebene. Zugriff auf die Kategorie-ID und die Anbeiter-ID mit parent . Filter 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.: Preis incl. MWSt: ... Innerhalb des Filters "Bruttopreis" wird der (Netto)Preis in Bruttopreis umgerechnet und anstelle des Wertes im Recordfield ausgegeben. Filtername aus Container ... Preis ohne MWSt.: Preis incl. MWSt: ... 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 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 Inhalt Inhalt Inhalt 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 keine gültige E-Mail-Adresse Achtung: matches funktioniert nicht oder nicht korrekt wenn RegEx-Sonderzeichen wie Klammern, „+“ „?“, „*“ im Request stehen Mit equals funktioniert es dann: Innerhalb einer Schleife: wenn übergebener Wert des Parameters param mit dem Kategorienamen übereinstimmt, wird dieser DS vorausgewählt. class="intern" 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 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 mehr Anteasern in einer Liste: es sollen max. 20 Wörter ausgegeben werden, dann wird ein ... gesetzt. Datum/Zeit 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 zeigt anstatt des gespeicherten Datums den 15. des folgenden Monats an. Abfrage Inhalt 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 Herzlichen Glückwunsch zum Geburtstag! 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 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 Inhalt 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 Inhalt (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. Inhalt 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 Anzahl fehlt oder ist 0 Ab Version 2.5.8 kann der Parameter alt verwendet werden um einen Alternativwert zu verwenden, falls keine Zahl gespeichert ist (auch keine 0). 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 Inhalt Inhalt Inhalt   Inhalt 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: Datenansicht: 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 Infomaterial gewünscht kein Infomaterial gewünscht Du hast dich bereits entschieden. Das Feld "Infomaterial_gewuenscht" kann nur einmal ausgewählt werden und dann nie wieder. 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“. ... 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) zeigt Block an, wenn das Feld angehakt ist zeigt Block an, wenn das Feld nicht angehakt oder leer ist zeigt Block an, wenn das Feld als nicht angehakt gespeichert ist zeigt Block an, wenn das Feld angehakt oder leer ist zeigt Block an, wenn das Feld leer ist zeigt Block an, wenn das Feld als angehakt oder nicht angehakt gespeichert ist Beispiele ... Infomaterial gewünscht? ... xml
    ...
    Bild 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
    " alt="">
    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; } ______________________
    ');">
    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 Bild-Daten ausgeben 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
    ');" title=""> Inhalt
    Anzeige als Hintergrundbild, aber nur, wenn auch ein Bild vorhanden ist. BEGIN:VCARD VERSION:2.1 N:; ;;; FN: PHOTO; ORG:; TITLE: NOTE;ENCODING=QUOTED-PRINTABLE: contact=0D=0A TEL;WORK;VOICE: TEL;HOME;VOICE: TEL;CELL;VOICE: TEL;WORK;FAX: ADR;WORK:;;;;;; LABEL;WORK;ENCODING=QUOTED-PRINTABLE:=0D=0A, =0D=0A URL: EMAIL;PREF;INTERNET: REV: END:VCARD Erzeugung einer Visitenkarte für Outlook Bild-Größenangaben ausgeben 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 Inhalt 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 Ausgabe: http://domain/files/{Batix-ID}/{Dateiname} setzt content-disposition:inline; filename=“{Dateiname}“, wird als Standard genommen, wenn nichts angegeben wird 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 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 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 > Inhalt > /> > Inhalt > 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 #all eine Kategorieid ... 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 Inhalt 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 : ... Inhalt 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 Inhalt > Inhalt > 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 Beispiel für den Einsatz von nofilter ... .. .. Filter für den Container "Kücheninhalt" (alle DS, die im UK "Lebensmittel" das Wort "brot" im Feld "Titel" enthalten).): Lebensmittel/Titel 1 brot 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. Verweise auf diese Seite: Container-Filteraction bx:tablefield Container bx:recordfield Container bx:tablefield Container-Filteraction bx:recordfield (8 Verweise) bx:relativelink Das Tag relativelink dient zum Erzeugen relativer Links. Unterpunkt des aktuellen Hauptmenüpunktes Inhalt  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 Inhalt 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 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. allgemeiner Link Inhalt 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:
    Eintragen: Eintragen!
    Deutsch:
    Englisch:

    Fehler 1: Nicht vorhanden!
    Fehler 2: Sprache unvollständig!

    Administration: Webseite: bx:scanner Die Ausgabe des Tags scanner 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 Inhalt 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 Inhalt 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 Inhalt Diese Funktion markiert Bereiche, die als Meta-Description im HTML-Kopf angezeigt werden sollen. 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 Inhalt 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 -
    Liste mit Link auf die Detailseite. Der Requestparameter für die Detailseite muß so heißen wie die Schleife (hier "Cats"). Detailseite

    Die Detailseite. Record ... secureform.field ... ... Dieses innere Tag wird um die einzelnen Werte von  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 s Beispiele 12345ABC"> "> "> "> 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: 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 Dieses innere Tag durchläuft alle gesammelten Parameter-Werte-Paare und bildet mit anderen, geheimen Faktoren einen Hashwert. Ohne Parameter wird ein 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 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 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: Sicheres Formular überprüfen (SecureformAction) Sicheres Formular überprüfen (SecureformAction) Manipulationsgeschützte Formulare mit Secureform Manipulationsgeschützte Formulare mit Secureform (4 Verweise) bx:sessiondata Das Tag sessiondata setzt, liest und vergleicht Werte von Session-Variablen. Auslesen eine Attributes, das mit dem Action geschrieben wurde Ein in die Session geschriebener Wert wird abgerufen. Dies gilt für Werte, die über das Action SaveInSessionAction in der Session geschrieben wurden. Falls 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 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 Inhalt Inhalt *(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 Tag-Body 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 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 Gibt die Uhrzeit aus zu der die Session inaktiv wird, falls keine weiteren Requests erfolgen.  (ab V 2.5.8 ) pattern Datumsmuster 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 Inhalt > 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 > 0 und kein -Tag außen herum steht) sitemap.text Gibt die Beschreibung des Punktes aus. . 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 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 : 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 Die Anzahl an unterschiedlichen Session-IDs, die das Web im angegebenen Zeitraum aufriefen. Die Auswertung erfolgt für das gesamte Projekt. statistik.hits Die Anzahl an Seitenaufrufen des aktuellen Menüpunktes im angegebenen Zeitraum. Die Auswertung erfolgt nur für den aktuellen Menüpunkt. statistik.totalhits Die Anzahl an Seitenaufrufen des gesamtem Webs im angegebenen Zeitraum. Die Auswertung erfolgt für das gesamte Projekt. statistik.pagelist Inhalt 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 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 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 Diese Funktion erfordert eine umgebende .pagelist. Es wird die URL des aktuellen Schleifenelements ausgegeben. statistik.name Diese Funktion erfordert eine umgebende .pagelist. Beispiele
    Zeitraum:
    von 01."> bis ">
    Beginn der Erfassung ...
      Seitenaufrufe Besucher
    Beispiel einer einfachen Statistik 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 Inhalt 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 Der Name des Menüpunktes wird ausgegeben. submenu.link Inhalt Es wird ein Link auf den Menüpunkt erzeugt. Als Linktext wird der Tag-Inhalt verwendet. submenu.description Dieses Tag gibt die Beschreibung des Menüpunktes aus, maxwords optional auf {n} Wörter begrenzt 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 Das Target aus dem Menüpunkt wird ausgegeben. 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 ... Zeigt abhängig von einer Spaltennummer einer Menüpunktliste Daten an. Beispiele style="margin-right:0;" Nur Spalte drei soll kein Rechts-Margin haben Wenn Spalte 2: zeige anderen Text als Spalte 1 und 3 Je nach Spalte anderer Text submenu.index Ausgabe einer laufenden Nummer des Schleifendurchlaufs. (Beginnend bei 1) Mit beginnt die Schleife ab 0 (z. B. für Javascript-Arrays) submenu.redirected ... ... Abfrage, ob der Punkt weitergeleitet ist Beispiele (extern) (intern) Zugriff auf Inhalte eines Untermenü-Punkts, wenn Weiterleitung im Unterpunkt submenu.redirecturl Rückgabe der Redirect-URL Schachtelung und Geschwister Beispiel 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). Geschwisternavigationspunkte ausgeben 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. Inhalt Um auch inaktive Punkte anzuzeigen, muss all angegeben werden. Folgende Tags können im Inhalt verwendet werden: submenuname Gibt den Name des Menüpunktes aus. submenudir Gibt den virtuellen Verzeichnisnamen des Menüpunktes aus. Verweise auf diese Seite: Keine Verweise gefunden. 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 Inhalt Inhalt 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 Inhalt Inhalt 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.: wenn in jedem Projekt eine Variable namens newslistid definiert wird, die eine passende Container-ID enthält oder: 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"%> <% String wert = variables.getVariable("test"); %> 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"); %> 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 . 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 . 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 . 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 . 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 . 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 . 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 . bx:tablesqlfilter Das Tag tablesqlfilter filtert einen Container über eine SQL-Anweisung, die in den Tag-Einstellungen der Administraton angegeben ist. Inhalt 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 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 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 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 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. 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 bx:textarea Das Tag textarea stellt in der Verwaltung ein Eingabefeld für einen beliebigen, mehrzeiligen Text zur Verfügung. 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: Ansicht in der Verwaltung (Formatierungen werden über den zweiten Balken oben vorgenommen): ....... Ansicht auf der Seite: 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: In der Administration: Auf der Seite: Bilder verlinken Durch Hinzufügen von href="bilder.htm" zum , weglassen von 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 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" Code in Bilder-Detailseite "bilder.htm" ...

    ... vorheriges Bild | zurück zum Artikel | nächstes Bild ... Textbaustein "Bild-links"
    Textbaustein "Bild-rechts"

    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:tools Das Tag tools vereint kleine Hilfen, um häufig auftretende Aufgaben zu vereinfachen. Hilfsmittel für Requestparameter tools.request Inhalt Es wird ein Request-Parameter ausgegeben oder dieser ausgewertet. Die erste Form gibt den Inhalt von 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 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 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 Inhalt Der Tag-Inhalt wird HTML-kodiert. Wenn man nur < > & " encoden möchte, muß man nehmen. Es werden folgende Ersetzungen vorgenommen: Originalwert ausgegebener Wert < < > > " " & & ' ' äöüÄÖÜß§€, deutsche Anführungszeichen unten und oben und langen Bindestrich alles ab ASCII-Code 128 zu "&#[code];" tools.urlencode Inhalt 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 Inhalt 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 Inhalt 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 Inhalt 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 Inhalt mit seltsamen Zeichen ]]> 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 Inhalt Der Inhalt wird zunächst durch .htmlencode umgewandelt, danach werden folgende Ersetzungen vorgenommen: Originalwert ausgegebener Wert Originalwert ausgegebener Wert \r nichts \n Leerzeichen
    \r\n
    \r\n
    \r\n

    \r\n\r\n nichts   Leerzeichen ü ü Ü Ü ä ä Ä Ä ö ö Ö Ö ß ß " " (gerade Anführungsz. oben) < < > > & & „ " (dopp. Anführungsz. unten) “ " (dopp. Anführungsz.oben) – - (Breite n) … ... – - (Breite n) € € ´ ´ ’ ' § § Zuletzt wird noch eventueller Whitespace am Anfang und Ende des Textes entfernt. tools.plain2html Inhalt Wandelt den plain-Text im body in HTML-Code um, indem er HTML encoded wird und bei jeden Zeilenumbruch ein oder gesetzt wird Wirkungsweise Erste Zeile Zweite Zeile Dritte Zeile Vierte Zeile Fünfte Zeile Wird zu «Erste Zeile
    Zweite Zeile
    Dritte Zeile
    Vierte Zeile
    Fünfte Zeile» tools.csvfield Inhalt Der Text wird mit " umgeben und allen " im Text wird ein zusätzliches " vorangestellt. (ab v2.5.9) tools.scriptencode Inhalt 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 Inhalt 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 & & " " ' \' \t \\t \ \\ tools.umlautencode Inhalt 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 Gasthaus 'Zur Tanne' 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 '%%' ... 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 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 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 Ausgabe der Menüpunkte ab der 2. Ebene, Trenner ist ein Pipe-Zeichen zwischen zwei Leerzeiche. tools.datum 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 <-- "heute", z.B. 08.06.2014 --> <-- "jetzt" wird ausgegeben, z.B. 3. Feb 12 13:42:55 --> <-- Tag des Monatsende vom aktuellen Monat, z.B. beim Aufruf im Februar: 28 --> <-- Ausgabe von "heute" im US-Format, z.B. 2001-07-04 --> xml <-- nächster Monats-Erster --> <-- Monatsletzter --> <-- in einer Woche --> <-- gestern Mittag --> <-- Silvester letztes Jahr --> tools.timeframe Inhalt 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 Wir haben geöffnet. Inhalt wird nur Montags von 6.00 bis 18.00 Uhr angezeigt. Beispiel 2 Wir haben geschlossen. entspricht: Beispiel 3 Bettruhe!!! tools.for / tools.forchar Inhalt Inhalt 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 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:
    | {i}| Es wurd eine verlinkte Buchstabenleiste  mit den Großbuchstaben von "A" bis "Z" erzeugt. tools.for-split Auswertung mit [Platzhalter] 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 :{i}: ergibt " :Hallo: :Welt: " AAA,BBB,CCC ... ... tools.random <-- zufälliger double-Wert zwischen 0 und 1, ca. 15 Nachkommastellen --> <-- zufälliger int-Wert zwischen 0 und {zahl} --> [Inhalt] <-- 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 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 Es wird ein Paßwort mit 10 Zeichen erzeugt, das Groß- und Kleinbuchstaben sowie Zahl enthält. tools.uuid Hiermit wird eine zufällige UUID (Typ 4) erzeugt (z.B. f3910a2f-63cf-433b-8117-1ac0d22bb4f5). tools.id Dieses Tag erzeugt eine neue Batix-ID und gibt diese aus (z.B. 12E241E47CB). Fehlersuche (Debugging) tools.showrequest Erzeugt eine Debug-Ausgabe des Request-Typs sowie sämtlicher Parameter, die im Request enthalten sind. tools.duration 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 ... Quelltext ... ... komplizierte SQL ... Verarbeitungsdauer SQL1: ... zu vergleichende SQL ... Verarbeitungsdauer SQL2: ... Quelltext ... Für beide SQL-Aufrufe wird die Ausführungszeit gemessen und ausgegeben - ein direkter Vergleich ist möglich. tools.log zu loggender Text 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 ... aufwändige Filterungen ... Verarbeitungsdauer: Die Zeit, die die "aufwändige Filterung" braucht, wird in die Log-Datei geschrieben Zeichenketten-Funktionen tools.replacetext Ersetzen-Modus Inhalt 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 Hello, World! Hier wird aus "Hello, World!" der Text "Hello, Batix!" Alice,123,ABC Umwandeln von CSV-Daten: Das Ergebnis wäre hier der Text "Wert 2=123; Wert 1=Alice; Wert 3=ABC". $1 Einen Text mit http://einer.url/zu/einem Text mit einem Link machen. 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 Inhalt 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_ 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: 300#g#Mehl 5##Eier 150#ml#Milch 1 = Anzahl 2 = Einheit 3 = Zutat Zutat : ( )
    Ausgabe: Zutat 0: Mehl (300 g) Zutat 1: Eier (5 ) Zutat 2: Milch (150 ml) Erkärung: Der zu durchsuchende Text wird in das Clipboard "zutaten" geschrieben, welches als source an replacetext übergeben wird. Der Regex lautet: (\d+)#([^#]+)?#(.*) Gruppe: \d+ (nur Ziffern) [^#]+ (alles außer #) .* (egal was) Beispielhaft die Clipboards im ersten Durchlauf: 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 Nach dem Durchlauf wird in das Clipboard "replacetext_match" zurückgeschrieben, was die Zeile im Original ersetzt. Hinweis: Da die zweite Gruppe mit einem Fragezeichen quantifiziert ist, ist sie optional. Im zweiten Durchlauf (die 5 Eier) ist das Clipboard "replacetext_group_2" also leer. tools.uppercase bring mich gross raus Wandelt alle Buchstaben im Body in Großbuchstaben um und gibt diese aus. tools.lowercase jetzt werd ich ganz klein Wandelt alle Buchstaben im Body in Kleinbuchstaben um und gibt diese aus. tools.substring 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 Hello World Gibt "World" aus 7318  gibt "07318" aus (wenn z. B. PLZ als Zahl gespeichert ist und demzufolge nur 4 Ziffern hat) bx:tools.trim Inhalt 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 Hallo Welt reduziert mehrfache Zeilenumbrüche zu einem Einzelnen würde also nur „Hallo“ und darunter „Welt“ schreiben Links erzeugen tools.absoluteurl Pfadangabe Erzeugt aus dem relativen URL-Pfad im Tag-Body eine absolute URL und schreibt sie anstelle des Tags in die Seite. Beispiele ../test.htm 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 Pfadangabe 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 ../test.htm 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. 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 Inhalt Inhalt Inhalt wird nur ausgeführt, wenn der User eingeloggt ist. userdata.out/userdata.logout Inhalt Inhalt Inhalt wird nur ausgeführt, wenn der User ausgeloggt ist. userdata.id Die ID des Benutzers wird zurückgegeben. userdata.name Der vollständige Name (Anrede + Vorname + Nachname) wird ausgegeben. userdata.email Die Email-Adresse des Users wird ausgegeben. userdata.isintrauser Inhalt 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 Inhalt 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 Inhalt 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 Inhalt 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 Inhalt 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 Gibt den Username des angemeldeten Benutzers zurück. userdata.meta Inhalt 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 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 Inhalt Hier wird der Inhalt des Datensatz-Feldes 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 Alle dem User zugeordneten Datensatz-IDs aus Merkliste mit Komma getrennt in die Seite schreiben 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 Inhalt 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: 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 ... Der Container-Datensatz, dessen ID im Meta-Wert 'meta' des Users steht oder nichts falls dort keine ID steht. Beispiele Eingeloggt als: Beim User gibt es eine Meta-Angabe namens "mitarbeiterID", in der die Datensatzid des zugehörigen Datensatzes im Container "Mitarbeiter" steht. 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 ... 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: 1 (0x01) benötigtes Feld ist leer 2 (0x02) falscher Datentyp 4 (0x04) regulärer Ausdruck passt nicht 8 (0x08) Bedingung nicht erfüllt Falls mehrere Fehlertypen auftreten, werden die Zahlen vom ValidationAction addiert. 5 (0x05) bedeutet z.B.: Das Feld ist leer und der reguläre Ausdruck passt nicht. Mit bx:valdiation können die Codes nun einzeln (code="1" und code="4") oder kombiniert (code="5") abgefragt werden. 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 Gibt die Anzahl der Validationsfehler aus. 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 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 Inhalt 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. lesen den neuen Parameter von der -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 gibt den Titel der Seite ( 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 websearch.link <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 . 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  true /  false 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: true wahr yes y ja j on x 1 1.0 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  true /  false 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: dd.MM.yy HH:mm:ss dd.MM.yy HH:mm dd.MM.yy HH.mm dd.MM.yy yyyy-MM-dd'T'HH:mm:ssZ ( ISO 8601 ) 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): year month (im Bereich 1 - 12) day weekday (s.u.) hour minute second 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): mo / di / mi / do / fr / sa / so mon / tue / wed / thu / fri / sat / sun 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: before-now after-now before-today after-today today (ist am heutigen Tag) 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 – Ü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. Ü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: Es werden Ihnen alle momentanen Aktionen mit folgenden Informationen angezeigt: der Titel der Aktion die Anzahl der in der Aktion vorhandenen Aktionsbausteine der Status der Aktion (Nur aktive Aktionen und Aktionsbausteine können angewendet werden. Deaktivierte Aktionen und Aktionsbausteine verursachen bei Verwendung einen Fehler.) Details der Aktion Klicken Sie auf den Titel einer Aktion, um deren Bausteine einzusehen und allgemeine Einstellungen zur Aktion vorzunehmen. Hier können Sie: die Aktion aktivieren/deaktivieren einen Titel sowie eine kurze Beschreibung der Aktion eingeben (wird auf der Übersichtsseite und anderen Bestandteilen des CMS als Erläuterung ausgegeben) die Aktionsbausteine ändern: Mittels "neuen Aktionsbaustein anhängen" generieren Sie assistengesteuert einen neuen Baustein (s.u.) Mit einem Klick auf die Zeile wechseln Sie zur Detailansicht des gewählten Aktionsbausteines (s.u.). Aktivieren/Deaktivieren Sie das Kontrollkästchen "ausführen", um die Nutzung des Bausteines festzulegen. In der Toolbox finden Sie die durch das CMS verwendete interne ID der Aktion, sowie eine Auflistung der Verwendungsarten und -orte. Neuen Aktionsbaustein anhängen Um eine neue Aktion anzulegen, klicken Sie - wenn Sie sich in der Übersichtsseite aller Aktionen befinden - auf den Button / in der Symbolleiste. Hier müssen Sie noch die Felder ausfüllen und die Aktion abspeichern ( / ). Anschließend werden Sie aufgefordert, einen neuen Aktionsbaustein hinzuzufügen. Klicken Sie auf diese Zeile und Sie sehen folgenden Assistenten: Klicken Sie auf den Auswahlbutton neben der gewünschten Aktion und anschließend zum Speichern auf / . Details des Aktionsbausteins Hier können Sie: den Baustein aktivieren/deaktivieren einen Titel sowie eine Kurzbeschreibung festlegen die Felder für die Inhalte des Aktionsbausteins bearbeiten (diese unterscheiden sich je nach Baustein erheblich) 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> 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 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): Ordner : folderid -> folderparam (wenn nicht angegeben, dann Standardwert "folderid") -> folderpath Titel : titel -> titelparam Autor : autor -> autorparam 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: bei fileparam muß "Bilder" stehen (Name im Formular) bei Scriptausführung je Bild: (url) steht die Weiterleitung zu einem Speicheraction, das die einzelnen Bilder im Untercontainer speichert, z.B. /www/beispielweb/menupunkt/savePic.act?Bild\=[[Bilder]]&Datum\=[[Datum]]&Bildergalerie\=[[galerieID]] Im anschließenden savePic.act wird in einem Bildercontainer das Bild mit Bildergalerie-Verknüpfung(Elterndatensatz-Verknüpfung) und Datum gespeichert 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> 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]] 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. 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. 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 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. 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") 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: Werte in Apostroph für Vergleich mit festen Wert Name eines anderen Feldes Spezialwerte #null" (Feldinhalt ist null) "#empty" (Feldinhalt ist Leerstring) "#nodata" (Feldinhalt ist null oder Leerstring) (ab v2.5.8) {Operator}: "=" prüft, ob Feld dem Testwert entspricht "!=" Prüft, ob Feld dem Testwert nicht entspricht (ab v2.5.8) "MATCH" Prüft, ob Feld dem regulären Ausdruck in Testwert entspricht (ab v2.5.8) Datumsfelder {Vergleichswert} Als Vergleichswert ist bisher (v2.5.8) nur ein fester Wert möglich. Er sollte wegen Kompatibilität zu zukünftigen Erweiterungen in Apostrophs eingeschlossen werden. Zeitfelder müssen in der Form "{Stunden}:{Minuten}[:{Sekunden}]" angegeben sein Datumsfelder müssen in der Form "{Tag}.{Monat}.{Jahr}" angegeben sein Datum-/Zeitfelder in der Form "{Tag}.{Monat}.{Jahr} {Stunden}:{Minuten}[:{Sekunden}]" Erweiterung mit ab v2.5.9: Schlüsselwort: "#today" (constraint="datum is #today+2") Erweiterung mit ab v2.5.9: Vergleich mit anderen Feld (constraint="vondatum before bisdatum" Bei zwei zu vergleichenden Feldern muß das Containerfeld als erstes angegeben werden.) {Operator} "<" (<) - Prüft, ob Feld zeitlich vor dem Testwert liegt ">" (>) - Prüft, ob Feld zeitlich nach dem Testwert liegt "before" - Prüft, ob Feld zeitlich vor dem Testwert liegt (ab v2.5.9) "after" - Prüft, ob Feld zeitlich nach dem Testwert liegt (ab v2.5.9) "=" oder "is" - Prüft, ob Feld gleich dem Testwert ist (gleicher Tag) (ab v2.5.9) "lt" - Prüft, ob Feld zeitlich vor dem Testwert liegt (ab v2.5.9) "gt" - Prüft, ob Feld zeitlich nach dem Testwert liegt (ab v2.5.9) "beforeOrEqual" - Prüft, ob Feld zeitlich vor oder genau auf dem Testwert liegt (ab v2.5.9) "afterOrEqual" - Prüft, ob Feld zeitlich nach oder genau auf dem Testwert liegt (ab v2.5.9) "lte" - Prüft, ob Feld zeitlich vor oder genau auf dem Testwert liegt (ab v2.5.9) "gte" - Prüft, ob Feld zeitlich nach oder genau auf dem Testwert liegt (ab v2.5.9) Zahlenfelder {Vergleichswert} Als Vergleichswert ist bisher (v2.5.8) nur ein fester Wert möglich. Als Dezimaltrenner muß das Komma verwendet werden. {Operator} "<" prüft, ob Feld kleiner als der Testwert ist ">" Prüft, ob Feld größer als der Testwert ist "=" Prüft, ob Feld gleich dem Testwert ist Häkchenfelder (Wahrheitswert) {Vergleichswert} 'j', 'ja', 'true', 'y', 'yes' für Test auf wahr '#null' für Test auf nicht gewählt (ab v2.5.8) alles andere für Test auf falsch {Operator} "=" prüft, ob Feld dem Testwert entspricht "!=" prüft, ob Feld nicht dem Testwert entspricht (ab v2.5.8) Verknüpfungen, Untercontainer werden in Version 2.5.8 noch nicht unterstützt 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): Ordner : folderid -> folderparam (wenn nicht angegeben, dann Standardwert "folderid") -> folderpath Titel : titel -> titelparam Autor : autor -> autorparam 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 . . 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 widthA, widthB ... Spaltenbreite nach Spaltenname 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). . 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 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 Intranet Logout Diese Aktion invalidiert die Session und loggt damit den Benutzer aus. Parameter nextpage auf diese Seite wird anschließend weitergeleitet 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. 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 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. Newsletter – Abo ändern Einstellungen des Newsletterabo werden geändert. Parameter nextpage die Folgeseite Request-Parameter id access rubrik email htmlmail passwort1 passwort2 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 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]] 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 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 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 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. 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. 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 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) 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 Sicheres Formular überprüfen (SecureformAction) Das SecureForm-Action wird benutzt, um Formulare gegen Manipulationen abzusichern. Es ist verfügbar ab Version 2.6.5. Unter diesem Link gibt es eine ausführliche Anleitung, wie dieses Action mit dem zugehörigen Tag zu benutzen ist. 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 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. 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. 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 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. 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. 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: Direkte URL angeben: Feld URL ausfüllen URL in Requestparameter: Request-Name ausfüllen URL in Containerfeld: "Container-"-Felder ausfüllen Ausgabemodi: Direkt streamen: Dokumentverwaltung = nein auswählen Speichern in Dokverwaltung: Dokumentverwaltung = ja auswählen 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. Ressourcen & Plugins Container, Mediendatenbank, Vorlagen, Plugin Newsletter, Zeitsteuerung. 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. 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: 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. Nach dem Import Ihrer Excel-Liste haben Sie die Daten nun im CMS. 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: 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 Wenn sich zum Beispiel bei einem Ansprechpartner die Telefonnummer ändert, muss der Eintrag nur einmal geändert werden. 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. 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. 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. 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. 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 / 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 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. 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: neues Design: Neues Bild hochladen Hier erhalten Sie folgende Informationen und haben folgende Möglichkeiten: Titel der Galerie und Bezeichnung des Ansichtsmodus Auswahl des Ansichtsmodus (Galerie-, Liste-, Detailansicht) sowie Wechsel zwischen verschiedenen Projekten eines Mandanten über ein Auswahlfeld (nur vorhanden bei mehreren Projekten) Wechsel zu einer anderen Kategorie Toolbox mit verschiedenen Möglichkeiten je nach Ansichtsmodus Anmerkung: Der Supervisor verfügt hier zusätzlich über die Möglichkeit eines Massenuploades. Dabei wird eine gewählte ZIP-Datei, welche die gewünschten Grafiken enthält durch das System in der gewählten Kategorie entpackt. Grafikübersicht mit folgenden Informationen: = Metadaten der Grafik (es öffnet sich ein Extrafenster) = Darstellung der Grafik in Originalgröße in einem neuen Fenster x-mal verwendet = Klicken Sie auf die Zahl (=Anzahl der Verwendungen) und Sie gelangen zu einer verlinkten Liste der Verwendungszwecke. Upload einer neuen Grafik: Aussuchen der Grafik von einem lokalen Datenträger durch Betätigung des Buttons "Durchsuchen". Realisierung des Uploads durch das Betätigen des Buttons "upload". Anmerkung: Falls Sie aus einem Menüpunkt heraus die Galerie aufgerufen haben, um z.B. eine im Menüpunkt verwendete Grafik auszutauschen, gelangen Sie nach Betätigung des Buttons "upload" direkt zurück zur Dateneingabe des Menüpunktes. Listenansicht bisheriges Design: neues Design: In der blätterbaren Listenansicht erhalten Sie überblicksweise folgende Informationen zu den einzelnen Grafiken: dynamisch generierte Bezeichnung zur Verwendung durch das CMS Originalname der Grafikdatei Originalgröße der Grafik Mit dem Link "bearbeiten" wechseln Sie zur Bearbeitungsseite der Grafik. Auch hier können Sie in der Toolbox die Kategorien der Galerie bearbeiten. Detailansicht bisheriges Design: neues Design: 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: neues Design: 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: neues Design: 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: neues Design: 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. Listenansicht 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 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 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 Speichern ). 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. 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: 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 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). 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. Übersichtsseite 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: Aktivieren/Deaktivieren der Dokumentvorlage (eine deaktivierte Dokumentvorlage kann keinem Menüpunkt zugewiesen werden) Titel der Dokumentvorlage Beschreibung zur Dokumentvorlage - erscheint als Hinweistext auf der Übersichtsseite Sicherungen: Das System speichert verschiedene Versionen der Dokumentvorlage. Diese können Sie auswählen. Fahren Sie mit der Maus über den Schriftzug Sicherungen . Ein Kontextmenü erscheint, dass Ihnen alle vorhandenen Versionen (Datum, Bearbeiter) auflistet. Klicken Sie auf das Datum der gewünschten Vorlage und betätigen Sie anschließend den Button Speichern in der Symbolleiste. Die gewählte Version ist nun übernommen. Jede Dokumentvorlage verwendet eine Stilvorlage (Stylesheet), die z.B. Schriftgröße, Hintergrundfarbe, Überschriften-Formatierungen usw. definiert. Hier suchen Sie eine vorhandene Stilvorlage aus. Jede Dokumentvorlage können Sie einer bestehenden Kategorie innerhalb des gewählten Typs zuordnen oder in einer neuen Kategorie abspeichern. Schreiben Sie dazu den Titel der neuen Kategorie in das dafür vorgesehen Feld, klicken Sie auf den Radiobutton vor diesem Feld und anschließend auf den Button Speichern . Im Feld Quelltext können Sie ein extern gespeichertes Template integrieren und bearbeiten. Für den Quelltext stehen Ihnen zwei Ansichtsmodi zur Verfügung: Überblick Sie gelangen auf eine Seite, auf der die im Quelltext vorhandenen Platzhalter des CMS (bx:Tags) farblich markiert sind. Änderungen am Quelltext können Sie in dieser Ansicht nicht vornehmen. Demo Anhand zufällig generierter Inhalte bietet Ihnen das System einen eingeschränkten Blick auf das ungefähre Aussehen einer Webseite, die die Dokumentvorlage verwendet. In der Toolbox stehen Ihnen folgende Möglichkeiten zur Verfügung: Verwendung Verlinkte Listung aller Menüpunkte, die die Dokmentvorlage verwenden. neu als Kopie Es wird eine komplette Kopie der Dokumentvorlage angelegt. Sie müssen nur noch den Titel ändern, alle anderen Einträge sind identisch. 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) 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. Übersichtsseite 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 Auf der Bearbeitungsseite können Sie folgende Einstellungen vornehmen: Anzeigen bei Navigation/Quelltextvorlagen: Diese Stilvorlage kann, sofern das Kontrollkästchen aktiviert ist, auf der Bearbeitungsseite einer Dokumentvorlage dieser zugewiesen werden. eine aussagekräftige Bezeichnung für die Stilvorlage vergeben den Quelltext Ihrer Stilvorlage ändern In der Toolbox können Sie die Stilvorlage als CSS-Datei downloaden. 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" . 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: Originalname ändern (bei Bildern) Vorschaubild auf dieser Seite anzeigen? wenn ja wie groß? (bei Textdateien) Inhalt der Datei ändern Mit einem Klick auf Datensatz 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! 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. 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) Link für Weiterleitung zusammenbasteln <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. Blättern (Pagination) Einfaches Listenblättern sieht so aus: 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>   | <strong>Seite:</strong>  <bx:recorddata.navlink move="-5"/> <bx:recorddata.navlist max="5" boundary=" · "/> <bx:recorddata.navlink move="5"/>  |   <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>   | <strong>Seite:</strong>  <bx:tabledata.navlink move="-5"/> <bx:tabledata.navlist max="5" boundary=" · "/> <bx:tabledata.navlink move="5"/>  |   <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: 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: 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> 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

    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; } Link zur Demo-Seite mit diesem Code http://dev.batix.local/www/dev/purecssmenu/ 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 ... 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. 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 Beispieldokument

    Hier landet das Ergebnis der Suche
    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 Google-Sitemap Datei erzeugen Diese Beispiel realisiert folgende Funktionen: eine dynamische Sitemap im XML-Format generieren, die Suchmaschinen beim Indizieren hilft Folgende Tags wurde verwendet: Bx:pagedata Bx:sitemap Bx:tools 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. http:///www/// T+00:00 weekly 1 http:///www/// T+00:00 weekly 0.75 http:///www/// T+00:00 weekly 0.5 http:///www/// weekly 0.25 http:///www/// weekly 0.20 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). 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. Kalender bauen Benutzt werden die beiden Tags bx:calendarloop und bx:calenderfield
    Mo Di Mi Do Fr Sa So
    othermonth we marked today"> ">
    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;} Locale bei Date-Pattern hinzufügen Projekt auswählen bei Dokumentvorlagen rechts unter Tools auf Quelltext ersetzen klicken in das erste Textfeld ( Suchbegriff ) eintragen: pattern="([^"]*(?:MMM|E)[^"]*)"(?! locale) in das zweite Textfeld ( Ersetzen durch ) eintragen: pattern="$1" locale="de" Haken regulärer Ausdruck setzen auf Vorschau klicken und prüfen, ob alles passt auf jetzt ersetzen klicken ggf. Schritte 6 und 7 wiederholen, falls viele Quelltexte betroffen sind 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 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
    Danach werden die zu schützenden Parameterwerte gesammelt. In den meisten Fällen wird der value eines einfach mit umschlossen. Parameter sammeln
    ">
    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 oder zum Einsatz. Der Parameter hidden-when-empty bewirkt, dass ein Feld mit leerem Wert von ignoriert wird. hidden-when-empty
    "> ">
    Zum Schluss wird der Hash generiert und in das Formular geschrieben. Die einfachste Methode ist vom System direkt ein generieren zu lassen. Hash ausgeben
    "> ">
    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 . Im Link Das Tag kann auch benutzt werden, um einen Link / Button abzusichern:
    &=">löschen
    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
    ">Herr
    ">Frau Das Tag in der geschlossenen Variante erzeugt automatisch ein mit passenden name und value Attributen. Im Link mehrere erlaubte Werte (Link) var url = "save.act?"; // ...andere (ggf. abgesicherte) Parameter, wie z.B. ID... url += "&Anrede=" + encodeURIComponent($("[name=Anrede]").val()); url += "&=" 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. 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 , 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 ... 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. 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
      • class="qmparent qmactive" href="/www///">
        • class="qmparent" href="/www///">
    Textbaustein 2 für den HTML-Head 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 Filteraction: prüft, ob's die angegebenen Email im Kontakt-Container gibt und ruft savetoken.act auf Weiterleitung auf Info-Seite Beispiele 1.) Actionbaustein "Container-Daten Filteraction" - Prüfen, ob's Email im "Kontakte" gibt list: ID des Kontakte-Containers xml: Kontakt_Email 4 email url: savetoken.act?Token=&Kontakt=&BCVerknuepfung=&Erstelldatum=&Email= failurl: pwvergessen.htm?fehler=1&email= [[ email ]] 2.) Actionbaustein "Weiterleitung" - Weiterleitung destination: mailverschickt.htm savetoken.act Speicheraction: erzeugt neuen Token-DS CMS-Seite verschicken: mit Link (mit Token und Email) 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 prüft, ob Paßwörter da und gleich sind Filteraction: sucht Token anhand von Parametern und Datum raus (prüfen, ob noch gültig), ruft changepw.act auf 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: Token 4 token Email 4 email Erstelldatum 4 TODAY url: changepw.act?user=&Token=&tokid=&password= [[ Passwort ]] failurl: changepw.htm?fehler=3 4.) Aktionsbaustein "Weiterleitung" - Weiterleitung destination: ok.htm changepw.act PW ändern: ändert in der Benutzerverwaltung das Paßwort speichern: löscht den Token im Token-DS, DS selbst bleibt aber erhalten Weiterleitung an Info-Seite (Benutzer muß sich nun mit neuem Paßwort einloggen) 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
    "> Bitte geben Sie Ihre E-Mail-Adresse an. Mit dieser Email sind Sie nicht angemeldet.
    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 Der Link aus der E-Mail ist nicht mehr gültig. Bitte fordern Sie einen neuen Link an.
    "> "> Bitte geben Sie Ihr Paßwort incl. Wiederholung an.
    Die beiden Paßwörter sind nicht gleich.
    ok.htm: Info-Seite, "So geht' weiter...", nachdem PW erfolgreich geändert wurde pwemail.htm: Mail mit dem Token Beispiele Paßwort vergessen Guten Tag, ,

    Sie hatten auf "Paßwort vergessen" geklickt. Wenn nicht, dann ignorieren Sie diese Mail.

    Bitte folgenden Link anklicken - Sie können dann ein neues Paßwort vergeben. Dieser Link ist einen Tag gültig und nur einmal verwendbar.
    **********************************************************************************************************************
    http://mrp.batix.net/www/nab/mitgliederbereich/changepw.htm?token=&email= **********************************************************************************************************************
    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.

    Mit freundlichen Grüßen
    Das Notarzt-Börse-Team
    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 `` 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 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. Regelmäßiges Neuladen von DIVs Aufbau der Hauptseite
    div 1



    div 2
    Der Inhalt einer nachgeladenen Seite sieht so aus: ... Content für oben steht hier ... 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 Support für „not" hinzufügen Dieses Beispiel realisiert folgende Funktionen: not für ein Tag emulieren, dass not nicht unterstützt Folgende Tags wurden verwendet: Bx:clipboard Bx:if Bx:pagedata Quellcode Als Beispiel dient hier das Tag bx:pagedata.navid , welches not für seine Bedingung nicht unterstützt. Inhalt der bei allen Menüpunkten außer dem Gesuchten angezeigt wird 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 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! 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 -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. 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
    Suche:
    Action: suche.act Typ der Aktion: Suche im Web resultpage: Pfad zur Ausgabeseite, z.B. /suche/ Ausgabeseite Sie suchten nach:
    Ergebnis bis von insgesamt  

    Es wurden leider keine Ergebnisse gefunden. .    


    Encodings Zeichenkodierungen und Escape-Funktionen. 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.: 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: javascript url xml html sql sql-like sql-rlike htmltext plain Informationen zu den einzelnen Encodings: HtmlEncode HtmlMask ScriptEncode UrlEncode XmlEncode Auf jeder Seite steht ganz unten, welche Tags oder sonstigen Funktionen diese Umwandlung benutzen bzw. unterstützen. HtmlEncode Es werden folgende Ersetzungen vorgenommen: Originalwert ausgegebener Wert < < > > " " ' ' & & 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 Hallo . ScriptEncode Einige Sonderzeichen und besondere Zeichen werden durch JavaScript Escape-Sequenzen ersetzt. Den folgenden Zeichen wird ein \ (Backslash) vorangestellt: Newline / Zeilenumbruch ( \n / 0x0a) Carriage return / Wagenrücklauf ( \r / 0x0d) Tab ( \t / 0x09) Single-Quote / Apostroph ( ' / 0x27) Double-Quote / Anführungszeichen ( " / 0x22) Backslash ( \ / 0x5c) 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). 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: Die Bereiche a-z, A-Z und 0-9 werden nicht ersetzt . (Punkt), - (Minus), * (Stern) und _ (Underscore) werden nicht ersetzt Leerzeichen wird durch + (Plus) ersetzt Alle anderen Zeichen sind "unsichere" Zeichen und werden in Hexadezimal dargestellt XmlEncode Es werden folgende Ersetzungen vorgenommen: Originalwert ausgegebener Wert < < > > " " & & 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. 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 } } 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. API — eine gekapselte Klasse mit statischen Methoden, die zusammengehörige Funktionalitäten enthält BatixUtils Logging — um einfach Logausgaben zu erzeugen, die den Name des Scripts vorangestellt haben Timings — nützlich, um einzelne Code-Teile zu profilen und so herauszufinden, was genau langsam ist 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: includeTag - Referenz zum ausführenden bx:groovy Tag, ansonsten null es können hier z.B. Tag-Parameter gelesen werden: Template Groovy-Baustein String format = includeTag.getStringParameter("format") println("gewähltes Format: $format") action - Referenz zum ausführenden Groovy-Action, ansonsten null kann z.B. benutzt werden, um Script-Attribute zu setzen oder das Action abzubrechen action.setScriptAttribute("thing", "value") action.cancel = true application - der ServletContext request - der aktuelle HttpServletRequest z.B. um Request-Parameter auszulesen, die der Seite oder dem Action übergeben wurden String kid = request.getParameter("kid") response - die aktuelle HttpServletResponse falls ein Action verwendet wird: action.originalResponse benutzen, um z.B. direkt Bytes zu schreiben session - die aktuelle Session, falls vorhanden pageData - enthält Infos zum Aufruf String file = pageData.filename // z.B. "detail.htm" navElement - der aufgerufene Menüpunkt ( NavigationElement ) web - das Projekt ( Customer ) variables - die Systemeinstellungen ( SystemVariables ) Das sind die pro Projekt überschreibbaren Variablen String portalId = variables.getVariable("PortalID") 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 BatixRecord s. 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 = '1 + 1' 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 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 function s 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 Comparator s. 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(""" Mustermann Musterfrau """) 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(""" Mustermann Musterfrau """) 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(""" """) // 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: */ 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 – Ü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). Verwendungsmöglichkeiten Groovy Syntax und Beispiele CMS-spezifische Helfer Tips Bibliothek – Übersicht 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}") 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 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 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 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. 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: Tag: der Text wird in die Seite geschrieben Action: der Text wird ausgegeben, falls action.sendJSPOutput() aufgerufen wurde, ansonsten kann auch action.originalResponse verwendet werden Entwickler-Tools: der Text wird im Output auf der Seite angezeigt 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 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 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. 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. 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