【问题标题】:ktor - is there a way to serialize sub-template Template<FlowContent> to txt/html?ktor - 有没有办法将子模板 Template<FlowContent> 序列化为 txt/html?
【发布时间】:2021-12-30 05:25:44
【问题描述】:

我在我的 ktor 项目中使用 HTML DSL 作为模板引擎。 我正在尝试将其中一个子模板模板作为文本响应发送(我不想发送完整的 HtmlTemplate)。

到目前为止,我得到了以下信息 - 为了使其工作,我必须将我的 TestTemplate 包装在另一个 div 中:

fun Route.test() {
    get("/test") {
        call.respondText(
            buildString {
                appendHTML().div {
                    insert(TestTemplate(), TemplatePlaceholder())
                }
            }
        )
    }
}

这给了我以下响应(内部 div 是我的 TestTemplate):

<div>
  <div>this is the element I want to get, without the outer element</div>
</div>

我想得到的只是 TestTemplate:

<div>this is the element I want to get, without the outer element</div>

有没有办法使用 HTML DSL 在 ktor 中实现它?

【问题讨论】:

    标签: ktor


    【解决方案1】:

    您可以使用HTMLStreamBuilder&lt;StringBuilder&gt; 类型参数而不是FlowContent 为模板创建一个类,以构建没有任何标记的最终HTML 字符串(FlowContent 继承Tag 接口)。

    import io.ktor.application.*
    import io.ktor.html.*
    import io.ktor.response.*
    import io.ktor.routing.*
    import io.ktor.server.engine.*
    import io.ktor.server.netty.*
    import kotlinx.html.*
    import kotlinx.html.stream.HTMLStreamBuilder
    
    suspend fun main() {
        embeddedServer(Netty, port = 3333) {
            routing {
                get("/test") {
                    val builder = StringBuilder()
                    val html: HTMLStreamBuilder<StringBuilder> = HTMLStreamBuilder(builder, prettyPrint = true, xhtmlCompatible = false)
                    html.insert(TestTemplate(), TemplatePlaceholder())
                    call.respondText(html.finalize().toString())
                }
            }
        }.start()
    }
    
    class TestTemplate : Template<HTMLStreamBuilder<StringBuilder>> {
        val articleTitle = Placeholder<FlowContent>()
        val articleText = Placeholder<FlowContent>()
    
        override fun HTMLStreamBuilder<StringBuilder>.apply() {
            article {
                h2 {
                    insert(articleTitle)
                }
                p {
                    insert(articleText)
                }
            }
        }
    }
    

    【讨论】:

    • 它有效,谢谢!但是,这种方法意味着在我将模板从 Template 更改为 Template> 后,我不能再将它们插入到主 HTML 模板中,因为它需要 。理想情况下,我想维护一组模板,最初将插入 HTML 模板,然后在需要时获取任何具有更新内容的子模板。还是我错过了什么?
    • 你能举个例子吗?
    • 如果我有我的孩子 TestTemplate 作为 FlowContent 类型,我可以通过设计将它插入到我的 HTML 类型的主 HomeTemplate 中。所以以下将起作用:class TestTemplate : Template&lt;FlowContent&gt; {override fun FlowContent.apply() {div {+"test" } }class HomeTemplate() : Template&lt;HTML&gt; { insert(TestTemplate(), TemplatePlaceholder()) },最后是路线get("/") { call.respondHtmlTemplate(HomeTemplate()) { } }。如果我将类型更改为 StringBuilder 并尝试将 Template&lt;HTMLStreamBuilder&lt;StringBuilder&gt;&gt; 插入到我的 Template&lt;HTML&gt; 中,则会出现错误。
    • 不幸的是,我不知道如何解决这两个问题。我创建了一个问题youtrack.jetbrains.com/issue/KTOR-3474 来解决它。
    • 谢谢,我会密切关注 yt 的问题。
    猜你喜欢
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2019-10-27
    • 2011-10-21
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多