Skip to main content

Tag

Das Framework kann durch Plugins um Batix-Tags (<bx:tagname>) erweitert werden, welche dann in normalen Quelltexten wie Komplettseiten oder Textbausteinen verwendet werden können.

fun registerTag(tagInfo: TagInfo)

Es gibt zwei Arten von Tags: Frontend- und Backend-Tags. Der Unterschied besteht darin, dass sich Backend-Tags in der Verwaltung darstellen oder dort konfiguriert werden können (wie z. B. <bx:text> oder <bx:containerfilter>), Frontend-Tags hingegen können dies nicht.

Frontend-Tags

Frontend-Tags werden mithilfe von TagInfo.frontend registriert und müssen von com.batix.plugins.PluginFrontendTag abgeleitet sein. Es reicht im einfachsten Fall, die Methode addFrontendSourceText(StringBuffer) zu überschreiben. An den StringBuffer hängt man die Ausgabe an und gibt diesen am Ende wieder zurück.

registerTag(TagInfo.frontend("tagname", MyFrontendTag::class.java, null))

Injection Vulnerability
Es müssen (HTML-)Steuerzeichen passend encoded werden, um Injectionlücken zu vermeiden.

Es empfiehlt sich daher die Methode writeEncodedOutput(String, StringBuffer) zu benutzen. Dieser übergibt man als ersten Parameter den gewünschten (uncodierten) Ausgabetext und reicht als zweiten Parameter den StringBuffer durch, den man übergeben bekommen hat. Die Methode sorgt automatisch dafür, dass entsprechend der aktuellen Frontendseite das passende Encoding (z. B. htmlencode bei HTML-Seiten) gewählt wird. Außerdem unterstützt das Tag damit automatisch den Parameter encode (also z. B. <bx:tagname encode="plain" />).

Backend-Tags

Backend-Tags werden mithilfe von TagInfo.backend registriert und müssen von com.batix.plugins.PluginBackendTag abgeleitet sein. Hier müssen neben addFrontendSourceText(StringBuffer) noch die Methoden getDataTable() und addAdminSourceText(StringBuffer) überschrieben werden.

registerTag(TagInfo.backend("tagname", MyBackendTag::class.java, null))

Der erste Parameter ("tagname") ist dabei der Name des Tags, wie er dann auch hinter <bx: verwendet wird. Als zweiter Parameter wird die implementierende Klasse übergeben. Der letzte Parameter ist ein optionales String-Array, falls das Tag nur für bestimmte Projekte (anhand webdir) zur Verfügung stehen soll.

Ist das Tag offen verwendbar (also z. B. <bx:tagname>etwas Inhalt...</bx:tagname>), kann der Inhalt (Body) mittels computeBody() ausgeführt und das Ergebnis ausgelesen werden. Eventuelle Batix-Tags im Body werden damit auch evaluiert.

Parameter

Einem Tag können im Quelltext Parameter übergeben werden.

<bx:tagname mode="short" maxlen="5" pretty />

Diese Parameter können mit den get*Parameter(key: String)-Methoden ausgelesen werden – key ist der Name des Parameters. Mit containsParameter(key: String) kann festgestellt werden, ob ein Parameter angegeben wurde oder nicht.

fun getStringParameter(key: String): String?
fun getStringParameter(key: String, defaultValue: String?): String?

fun getIntParameter(key: String): Integer
fun getIntParameter(key: String, defaultValue: Integer): Integer

fun getBooleanParameter(key: String): Boolean

Backend-Tag Speicherung

Backend-Tags stellen ein Eingabeelement für Redakteure oder Admins bereit. Dafür muss im Quellcode ein sogenannter Titel am Tag vergeben werden. Bei <bx:tagname.Anrede /> ist der Titel beispielsweise "Anrede". Dieser wird dem Benutzer im Backend angezeigt.

Das bedeutet, dass die vom Benutzer getätigten Eingaben in der Datenbank gespeichert werden müssen. Die Methode getDataTable() teilt dem Framework mit, in welcher Tabelle die Daten zu speichern sind. Für kurze, einzeilige Texte ist das "EZT", für längere Texte "MZT". Der entsprechende Wert ist von getDataTable() einfach als String zurückzugeben.

Die Methode addAdminSourceText(StringBuffer) ist für das Rendern des entsprechenden Eingabefeldes zuständig. Für kurze Texte kann das ein <input type="text"> sein. Der Name des Inputs muss als Prefix die Tabelle (gleicher Wert wie bei getDataTable()), einen Punkt als Separator und als Suffix den Titel des Tags enthalten (dieser ist als Feld titel verfügbar). Er muss also beispielsweise "EZT.Anrede" lauten. Ist bereits ein Wert gespeichert, ist das Feld dataId gefüllt. Dessen Wert muss dann noch, inklusive einem weiteren Punkt, an den Name angehangen werden.

Vorgefertigte Methoden
Als Best-Practice empfiehlt sich die Verwendung der Methoden appendAdminHeadline(StringBuffer) und appendPublishStatus(StringBuffer), um eine konsistente Ausgabe des Titels und des Veröffentlichungsstatus zu erreichen.

Der Aufruf getData("INHALT") gibt den aktuell in der Datenbank gespeicherten Wert zurück. Dieser kann dann zur Ausgabe im Frontend sowie zur Vorbefüllung des Eingabefelds im Backend verwendet werden.

Beispiel

Frontend-Tag

Das Tag wird in der Plugin-Hauptklasse mithilfe von TagInfo.frontend registriert.

override fun load() {
  registerTag(TagInfo.frontend("unixtime", UnixTimeTag::class.java, null))
}

Dieses Beispiel-Tag gibt den aktuellen Epoch-Timestamp aus.

import com.batix.plugins.PluginFrontendTag
import com.batix.tags.BatixTagData
import java.time.Instant

class UnixTimeTag(data: BatixTagData?) : PluginFrontendTag(data) {
  override fun addFrontendSourceText(sb: StringBuffer): StringBuffer {
    val time = Instant.now().epochSecond
    writeEncodedOutput(time.toString(), sb)
    return sb
  }
}

Der Aufruf im Quellcode ist minimal.

<bx:unixtime />

Die Ausgabe im Frontend ist dann z. B. 1584620787.

Backend-Tag

In der Plugin-Hauptklasse wird das Tag mit TagInfo.backend registriert.

override fun load() {
  registerTag(TagInfo.backend("formattedtime", FormattedTimeTag::class.java, null))
}

Die Tag-Klasse implementiert die Frontend-Logik sowie die Anzeige des Eingabeelements im Backend.

import com.batix.Tools
import com.batix.plugins.PluginBackendTag
import com.batix.tags.BatixTagData
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*

class FormattedTimeTag(data: BatixTagData?) : PluginBackendTag(data) {
  override fun addFrontendSourceText(sb: StringBuffer): StringBuffer {
    // Backendeingabe lesen
    val pattern = getData("INHALT") as String? ?: "dd.MM.yyyy HH:mm:ss"

    // Parameter aus Quelltext lesen
    val locale = Locale.forLanguageTag(getStringParameter("locale", "de-DE"))

    val now = LocalDateTime.now()
    val formatter = DateTimeFormatter.ofPattern(pattern, locale)
    writeEncodedOutput(formatter.format(now), sb)
    return sb
  }

  override fun getDataTable(): String {
    return "EZT"
  }

  override fun addAdminSourceText(sb: StringBuffer): StringBuffer {
    val inhalt = getData("INHALT") as String? ?: ""

    appendAdminHeadline(sb)
    appendPublishStatus(sb)

    var inputName = "$dataTable.$titel"
    if (dataId != null && dataId != "del") {
      inputName += ".$dataId"
    }

    sb.append("""<input type="text" name="${Tools.htmlEncode(inputName)}" """)
    sb.append("""value="${Tools.htmlEncode(inhalt)}">""")

    return sb
  }
}

Im Quelltext wird das Tag dann inklusive Titel verwendet.

<bx:formattedtime.Datum_1 />

<bx:formattedtime.Datum_2 locale="en-US" />

In der Verwaltung können Eingaben getätigt werden.

tag-beispiel.png

Im Frontend wird dann z. B. folgender Text ausgegeben:

13:28

19. March