Kotlin Academy · Lektion

Eine typsichere HTML-/Config-DSL erstellen

Implementieren Sie eine einfache Konfigurations-DSL mit Builder-Patterns und Extension-Lambdas.

Lektion 3 von 414 Schritte

Eine typsichere HTML-/Config-DSL erstellen ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Ziel: Eine praxisnahe DSL

Wir erstellen eine minimale, aber realistische HTML-Builder-DSL in Kotlin. Dieselben Muster gelten für beliebige Konfigurations-, Test-Fixture- oder Report-Builder. Das Ergebnis ist eine typsichere, IDE-freundliche API, die String-Konkatenation ersetzt.

Basisklasse für Tags definieren

Alle HTML-Elemente haben dieselbe Grundstruktur: einen Namen, Attribute und untergeordnete Elemente. Beginnen Sie mit einer Basisklasse:

open class Tag(val name: String) {
    val attrs = mutableMapOf<String, String>()
    val children = mutableListOf<Tag>()
    fun render(indent: Int = 0): String {
        val pad = " ".repeat(indent)
        val attrStr = if (attrs.isEmpty()) "" else " " + attrs.entries.joinToString(" ") { "${it.key}=\"${it.value}\"" }
        val body = children.joinToString("\n") { it.render(indent + 2) }
        return "$pad<$name$attrStr>\n$body\n$pad</$name>"
    }
}

@DslMarker anwenden

Markieren Sie alle Builder-Klassen, damit innere Bereiche nicht versehentlich Methoden des äußeren Bereichs aufrufen können:

@DslMarker
annotation class HtmlDsl

@HtmlDsl class Html : Tag("html")
@HtmlDsl class Head : Tag("head")
@HtmlDsl class Body : Tag("body")
@HtmlDsl class Div  : Tag("div")
@HtmlDsl class P   : Tag("p")

Builder-Funktionen hinzufügen

Jede Tag-Klasse erhält eine Erweiterungsfunktion, die ein untergeordnetes Tag erstellt, den Block anwendet und es zu den untergeordneten Elementen hinzufügt:

fun Html.head(block: Head.() -> Unit) = Head().also { it.block(); children += it }
fun Html.body(block: Body.() -> Unit) = Body().also { it.block(); children += it }
fun Body.div(block: Div.() -> Unit) = Div().also { it.block(); children += it }
fun Div.p(text: String) = P().also { it.attrs["text"] = text; children += it }

Top-Level-Builder für html

Bieten Sie einen Top-Level-Einstiegspunkt, der das Wurzelelement erstellt und den Benutzerblock anwendet:

fun html(block: Html.() -> Unit): Html {
    val root = Html()
    root.block()
    return root
}

Die DSL verwenden

Das Ergebnis ist eine klare, gut lesbare DSL:

val page = html {
    head { }
    body {
        div {
            p("Hello, DSL!")
        }
    }
}
println(page.render())

Attribute hinzufügen

Fügen Sie eine attr-Hilfsfunktion hinzu, um beliebige Attribute auf flüssige Weise festzulegen:

fun Tag.attr(key: String, value: String) { attrs[key] = value }

// Usage
div {
    attr("class", "container")
    p("Content")
}

Muster für eine Konfigurations-DSL

Dasselbe Muster funktioniert für Konfigurationsobjekte. Verwenden Sie statt HTML-Tags Domänenklassen:

class ServerConfig {
    var host = "localhost"
    var port = 8080
    var db: DbConfig? = null
    fun database(block: DbConfig.() -> Unit) { db = DbConfig().apply(block) }
}
fun server(block: ServerConfig.() -> Unit) = ServerConfig().apply(block)

Verschachteln und zusammensetzen

Da jede Builder-Funktion das erstellte Objekt zurückgibt, können Sie Builder frei kombinieren. Die Verschachtelungstiefe der DSL entspricht der Tiefe der Datenhierarchie.

Fehlervermeidung durch Typen

Das Typsystem erzwingt die Struktur: Sie können body { } nicht innerhalb eines Head aufrufen, da Head keine body-Erweiterungsfunktion besitzt. Ungültige Strukturen führen zu Kompilierungsfehlern.

Rendering und Tests

Da die DSL einen einfachen Kotlin-Objektbaum erzeugt, sind Rendering und Tests unkompliziert: Rufen Sie render() auf und überprüfen Sie den Ausgabe-String, oder durchlaufen Sie den Objektbaum in Tests.

Die DSL später erweitern

Das Hinzufügen neuer Tags oder Konfigurationsoptionen erfordert lediglich neue Erweiterungsfunktionen in der entsprechenden Receiver-Klasse. Bestehende Aufrufstellen bleiben unverändert – das Open/Closed-Prinzip in der Praxis.

Schnelltest

Was macht eine Kotlin-HTML-/Konfigurations-DSL „typsicher“?

Zusammenfassung: Eine typsichere DSL erstellen

Wichtige Schritte:

  • Builder-Klassen für jede Ebene der Hierarchie definieren
  • Mit @DslMarker annotieren, um das Auslaufen von Receivern zu verhindern
  • Erweiterungsfunktionen schreiben, die untergeordnete Objekte erstellen, konfigurieren und hinzufügen
  • Eine Funktion als Einstiegspunkt auf oberster Ebene bereitstellen
  • Rendering und Tests funktionieren mit einfachen Kotlin-Objekten
Kostenlos starten

Lerne Kotlin mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
51
Lektionen
203

Häufig gestellte Fragen

Ist die Lektion „Eine typsichere HTML-/Config-DSL erstellen“ kostenlos?

Ja — der vollständige Text von „Eine typsichere HTML-/Config-DSL erstellen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Eine typsichere HTML-/Config-DSL erstellen“?

Implementieren Sie eine einfache Konfigurations-DSL mit Builder-Patterns und Extension-Lambdas. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Kotlin Academy zu starten?

Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Eine typsichere HTML-/Config-DSL erstellen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?

Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Lambda mit Receiver: Grundlage für DSLs
  2. @DslMarker: Receiver-Leaks verhindern
  3. Eine typsichere HTML-/Config-DSL erstellen
  4. DSLs testen und weiterentwickeln, ohne Nutzer zu beeinträchtigen
← Zurück zu Kotlin Academy