Hello everyone!
I wrote a little kotlin-html DSL:
@file:JvmName("DOM")
// flatten Element.attributes
fun Array<out Pair<String, String>>.join(quote: String = "'") = if (this.isEmpty()) ""
else " " + this.map { "${it.first}=${quote + it.second + quote}" }.joinToString(" ") { it }
// Join element context into innerHTML
fun Array<out String>.join(separator: String = "") = if (this.isEmpty()) ""
else this.joinToString(separator) { it }
/* DOM API */
fun html(vararg attributes: Pair<String, String> = arrayOf(),
content: Array<String> = arrayOf(),
func: (String) -> String) = "<html${attributes.join()}>${func(content.join())}</html>"
fun head(vararg attributes: Pair<String, String> = arrayOf(),
content: Array<String> = arrayOf(),
func: (String) -> String) = "<head${attributes.join()}>${func(content.join())}</head>"
fun title(vararg attributes: Pair<String, String> = arrayOf(),
content: Array<String> = arrayOf(),
func: (String) -> String) = "<title${attributes.join()}>${func(content.join())}</title>"
fun body(vararg attributes: Pair<String, String> = arrayOf(),
content: Array<String> = arrayOf(),
func: (String) -> String) = "<body${attributes.join()}>${func(content.join())}</body>"
fun div(vararg attributes: Pair<String, String> = arrayOf(),
content: Array<String> = arrayOf(),
//vararg content: String = arrayOf(),
func: (String) -> String) = "<div${attributes.join()}>${func(content.join())}</div>"
//...
And it’s working perfectly fine if I’m explicitly concatenate element content head { /*...*/ } + body { /*...*/ }
:
render(
html("lang" to "en", "ng-app" to "my-app") {
head {
title {
"Kotlin awesome!"
}
} +
body {
div("class" to "container-fluid") {
"DSL as 1-2-3"
}
}
}
)
output expected:
<html lang='en' ng-app='my-app'><head><title>Kotlin awesome!</title></head><body><div class='container-fluid'>DSL as 1-2-3</div></body></html>
what I need is understand if there is a way to make it possible avoid using +
(plus operator)? I would like to use my DSL like so:
render(
html("lang" to "en", "ng-app" to "my-app") {
head {
title {
"Kotlin awesome!"
}
}
body {
div("class" to "container-fluid") {
"DSL as 1-2-3"
}
}
}
)
Code above compiling fine, but of course, output is wrong (only latest content item is rendering):
<html lang='en' ng-app='my-app'><body><div class='container-fluid'>DSL as 1-2-3</div></body></html>
Thanks for any help!
Regards,
Maksim