Appearance
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.
kotlin
fun registerTag(tagInfo: TagInfo)
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 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.
kotlin
registerTag(TagInfo.frontend("tagname", MyFrontendTag::class.java, null))
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 werden mithilfe von TagInfo.backend
registriert und müssen von com.batix.plugins.PluginBackendTag
abgeleitet sein. Hier müssen nebst addFrontendSourceText(StringBuffer)
noch die Methoden getDataTable()
und addAdminSourceText(StringBuffer)
überschrieben werden.
kotlin
registerTag(TagInfo.backend("tagname", MyBackendTag::class.java, null))
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 optonales 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.
html
<bx:tagname mode="short" maxlen="5" pretty />
<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.
kotlin
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
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>
vom Typ 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(StrungBuffer)
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.
kotlin
override fun load() {
registerTag(TagInfo.frontend("unixtime", UnixTimeTag::class.java, null))
}
override fun load() {
registerTag(TagInfo.frontend("unixtime", UnixTimeTag::class.java, null))
}
Dieses Beispiel-Tag gibt den aktuellen Epoch-Timestamp aus.
kotlin
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
}
}
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.
html
<bx:unixtime />
<bx:unixtime />
Die Ausgabe im Frontend ist dann z. B. 1584620787.
Beispiel Backend-Tag
In der Plugin-Hauptklasse wird das Tag mit TagInfo.backend
registriert.
kotlin
override fun load() {
registerTag(TagInfo.backend("formattedtime", FormattedTimeTag::class.java, null))
}
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.
kotlin
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
}
}
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.
html
<bx:formattedtime.Datum_1 />
<bx:formattedtime.Datum_2 locale="en-US" />
<bx:formattedtime.Datum_1 />
<bx:formattedtime.Datum_2 locale="en-US" />
In der Verwaltung können Eingaben getätigt werden.
Im Frontend wird dann z. B. folgender Text ausgegeben.
13:28
19. March
13:28
19. March