0Pricing
Kotlin Academy · Leçon

Construire un DSL HTML/de configuration sûr du point de vue des types

Implémentez un DSL de configuration simple avec des modèles de construction et des lambdas d’extension.

Construire un DSL HTML/de configuration sûr du point de vue des types est une leçon Kotlin Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Kotlin Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Kotlin Academy comprend 4 leçons au total.

Objectif : un DSL pratique

Nous allons créer un DSL minimal, mais réaliste, de construction HTML en Kotlin. Les mêmes modèles s'appliquent à tout constructeur de configuration, de scénario de test ou de rapport. Le résultat est une API sécurisée par le type et adaptée à l'IDE, qui remplace la concaténation de chaînes.

Définir la classe de base Tag

Tous les éléments HTML partagent une structure commune : un nom, des attributs et des enfants. Commencez par une classe de base :

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>"
    }
}

Appliquer @DslMarker

Marquez toutes les classes de construction afin que les portées internes ne puissent pas appeler accidentellement des méthodes de la portée externe :

@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")

Ajouter des fonctions de construction

Chaque classe de balise reçoit une fonction d'extension qui crée une balise enfant, lui applique le bloc, puis l'ajoute aux enfants :

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 }

Constructeur html de niveau supérieur

Fournissez un point d'entrée de niveau supérieur qui crée l'élément racine et applique le bloc fourni par l'utilisateur :

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

Utiliser le DSL

Le résultat est un DSL propre et lisible :

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

Ajouter des attributs

Ajoutez un utilitaire attr pour définir des attributs arbitraires de manière fluide :

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

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

Modèle de DSL de configuration

Le même modèle fonctionne pour les objets de configuration. Au lieu de balises HTML, utilisez des classes du domaine :

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)

Imbriquer et composer

Comme chaque fonction de construction retourne l'objet créé, vous pouvez composer librement les constructeurs. La profondeur d'imbrication du DSL correspond à la profondeur de la hiérarchie des données.

Prévenir les erreurs grâce aux types

Le système de types impose la structure : vous ne pouvez pas appeler body { } dans un Head, car Head ne possède aucune fonction d'extension body. Les structures non valides provoquent des erreurs de compilation.

Rendu et tests

Comme le DSL produit un simple arbre d'objets Kotlin, le rendu et les tests sont simples : appelez render() et vérifiez la chaîne produite, ou parcourez l'arbre d'objets dans les tests.

Étendre le DSL par la suite

L'ajout de nouvelles balises ou options de configuration ne nécessite que de nouvelles fonctions d'extension sur la classe réceptrice appropriée. Les sites d'appel existants ne sont pas affectés — le principe ouvert/fermé en pratique.

Vérification rapide

Qu'est-ce qui rend un DSL HTML/configuration Kotlin « sûr du point de vue des types » ?

Récapitulatif : créer un DSL sûr du point de vue des types

Étapes clés :

  • Définir des classes de construction pour chaque niveau de la hiérarchie
  • Annoter avec @DslMarker pour empêcher la fuite des récepteurs
  • Écrire des fonctions d'extension qui créent, configurent et ajoutent des objets enfants
  • Exposer une fonction d'entrée de niveau supérieur
  • Le rendu et les tests fonctionnent sur de simples objets Kotlin

Questions Fréquemment Posées

La leçon « Construire un DSL HTML/de configuration sûr du point de vue des types » est-elle gratuite ?

Oui — le texte complet de « Construire un DSL HTML/de configuration sûr du point de vue des types » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Kotlin Academy, passe à CoddyKit PRO. Le cours Kotlin Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Construire un DSL HTML/de configuration sûr du point de vue des types » ?

Implémentez un DSL de configuration simple avec des modèles de construction et des lambdas d’extension. Tu pratiques Kotlin Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Kotlin Academy ?

Aucune expérience préalable n'est requise. Kotlin Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Construire un DSL HTML/de configuration sûr du point de vue des types » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Kotlin Academy ?

Oui. Chaque leçon Kotlin Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Lambda avec récepteur : fondement des DSL
  2. @DslMarker : empêcher les fuites de récepteurs
  3. Construire un DSL HTML/de configuration sûr du point de vue des types
  4. Tester et faire évoluer des DSL sans perturber les utilisateurs
← Retour à Kotlin Academy