在 kotlinx.html DSL 中编写原始 html 代码

Write raw html code inside kotlinx.html DSL

我正在使用 Kotlin 的 html 库 kotlinx.html 进行动态 html 构建。

为了调试建议,我想将标签写成原始 html。但我找不到任何方法可以做到这一点。简单的文本添加将 < 之类的字符替换为其代码,因此无济于事:

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()
    }
}

appendHTML 中的任何内容都将被编码。如果你想附加原始文本,你可以使用 appendln.

示例来自 Streaming · Kotlin/kotlinx.html Wiki · GitHub

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

一个(有限的)解决方案是破解 DSL 并使用 onTagContentUnsafe:

this.consumer.onTagContentUnsafe { +"hello"}

每个 Tag 都有一个 属性 consumer。这是一个实际处理 DOM 的对象。在 HTML 代的情况下,此对象为 HTMLStreamBuilder。它有一个方法 onTagContentUnsafe 可以让您访问流生成器。

我使用辅助函数:

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

正如@orangy 所指出的,此解决方案适用于代码生成,但您不能将其用于创建 JVM DOM 等。为此,有一张票:https://github.com/Kotlin/kotlinx.html/issues/8

只需在您的代码中使用 unsafe 即可防止 HTML 编码。

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