Write raw html code inside kotlinx.html DSL

2019-07-17 19:38发布

问题:

I am using Kotlin's html library kotlinx.html for dynamic html building.

For debugging proposes I want to write a tag as a raw html. But I can't find any method that would do it. Simple text addition replaces characters like < to their codes, so it does not help:

StringBuilder().appendHTML().html {
    body {
        +"""
        <form action="http://courier-voddan.rhcloud.com/customer/new_task" method="get">
            get=form
            id=3333
            <button type="submit">ok</button>
        </form>
        """.trimIndent()
    }
}

回答1:

Simply use unsafe inside your tag to prevent HTML encoding.

body {
    unsafe {
       +"""<form class="formClass"/>"""
    }
}


回答2:

Anything inside appendHTML will be encoded. If you want to append raw text you can use appendln.

Example from Streaming · Kotlin/kotlinx.html Wiki · GitHub:

val text = StringBuilder {
    appendln("<!DOCTYPE html>")
    appendHTML().html {
        body {
            a("http://kotlinlang.org") { +"link" }
        }
    }
    appendln()
}


回答3:

A (limited) solution would be to hack the DSL and use onTagContentUnsafe:

this.consumer.onTagContentUnsafe { +"hello"}

Every Tag has a property consumer. This is an object that actually deals with the DOM. In case of HTML generation this object is HTMLStreamBuilder. It has a method onTagContentUnsafe which gives you the access to the stream builder.

I use a helper function:

fun Tag.rawHtml(html: String) {
    assert(this.consumer is HTMLStreamBuilder)
    this.consumer.onTagContentUnsafe { +"$html\n"}
}

As @orangy pointed out, this solution works for code generation, but you can't use it for creating JVM DOM, etc. For that there is a ticket: https://github.com/Kotlin/kotlinx.html/issues/8



标签: html kotlin