Ejemplo: Html Builder (KotlinJS)
Ejemplo para crear una web html con Kotlin ilustrando y ampliando el contenido expuesto en la entrada Introducción a KotlinJS: Desarrollo web con Kotlin.
Observa en el código que getHTML se refiere a una función que toma como argumento una expresión lambda que utiliza una instancia de la clase HTML, y headTag y bodyTag son funciones miembro de la clase HTML, y agregamos el texto a las etiquetas html invocando el operador String.unaryPlus(). Para más detalles puedes ver (en inglés): Type-Safe Builders
<!--index.html--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <script src="out/production/html/lib/kotlin.js"></script> <script src="out/production/html/html.js"></script> </body> </html>
//html.kt package html import kotlin.browser.document fun main() { val codeHTML = getHTML { // <head> headTag { title { +"KotlinJS" } } // <body> bodyTag { h1Tag { +"Desarrollo web con Kotlin" } pTag { +"Página web con etiquetas de marcado" +"HTML <h1>, <p>, <b>, <a>, <ul>, <li>" +"desarrollada con Kotlin" } pTag { bTag { +"Kotlin Doc" } +"comparte y divulga en español" +"información y ejemplos sobre programación con Kotlin y Android. Visita" aTag(href = "https://kotlindoc.blogspot.com") { +"Kotlin Doc" } } pTag { +"La tabla de multiplicar del 2 iterando sobre un rango con un bucle for:" ulTag { for (i in 1..10) li { +"$i * 2 = ${i * 2}" } } } } } document.body?.appendChild(codeHTML.elemento) } // Clase abstracta abstract class TagHTML(name: String) { val elemento = document.createElement(name) protected fun <T : TagHTML> initTag(tag: T, init: T.() -> Unit): T { tag.init() elemento.appendChild(tag.elemento) return tag } } // Clase Abstracta que herada de TagHTML abstract class TagTextHTML(name: String) : TagHTML(name) { operator fun String.unaryPlus() { elemento.appendChild(document.createTextNode("$this ")) } } // Clases que heredan de TagTextHTML class HTML : TagTextHTML("html") { fun headTag(init: Head.() -> Unit) = initTag(Head(), init) fun bodyTag(init: Body.() -> Unit) = initTag(Body(), init) } class Head : TagTextHTML("head") { fun title(init: Title.() -> Unit) = initTag(Title(), init) } class Title : TagTextHTML("title") // Clase abstracta abstract class BodyTag(name: String) : TagTextHTML(name) { fun bTag(init: B.() -> Unit) = initTag(B(), init) fun pTag(init: P.() -> Unit) = initTag(P(), init) fun h1Tag(init: H1.() -> Unit) = initTag(H1(), init) fun ulTag(init: UL.() -> Unit) = initTag(UL(), init) fun aTag(href: String, init: A.() -> Unit) { val a = initTag(A(), init) a.href = href } } // Clases que heredan de BodyTag class Body : BodyTag("body") class UL : BodyTag("ul") { fun li(init: LI.() -> Unit) = initTag(LI(), init) } class B : BodyTag("b") class LI : BodyTag("li") class P : BodyTag("p") class H1 : BodyTag("h1") class A : BodyTag("a") { var href: String get() = elemento.getAttribute("href") ?: "" set(value) = elemento.setAttribute("href", value) } // función que toma como argumento una expresión lambda que utiliza una instancia de la clase HTML fun getHTML(init: HTML.() -> Unit): HTML { val html = HTML() html.init() return html }
Lo que se visualiza en el navegador de esta manera:
Comentarios
Publicar un comentario