KTOR DSL - 如何嵌套模板?
Posted
技术标签:
【中文标题】KTOR DSL - 如何嵌套模板?【英文标题】:KTOR DSL - how to nest templates? 【发布时间】:2021-07-02 17:11:49 【问题描述】:我正在尝试使用 KTOR DSL 将 html 模板相互嵌套,看起来应该非常简单,但文档让我无处可去,而且我尝试过的任何东西都没有编译或工作。
我定义了一个根级页面模板,它需要一个名为“pageContent”的占位符,我正在尝试使用路由来确定应该将哪个页面级模板作为 HTML 内容注入。所以 PageTemplate 看起来像这样:
class PageTemplate(private val username: String, private val displayName: String) : Template<HTML>
val pageContent = Placeholder<FlowContent>()
override fun HTML.apply()
head
title +"Page Title"
stylelink("lots of style and script, etc")
body("body classes")
header ... //display logged-in user's name here, nav, etc
main("some classes")
insert(pageContent)
我的路由看起来像这样:
get("/example-path")
call.respondHtmlTemplate(PageTemplate(call.session?.username, call.session?.displayName))
pageContent
ExamplePathTemplate(call.session?.username)
这个想法是让每个路由都用自己的路径特定模板覆盖 pageContent。
上面的代码编译。但是,当我运行它时,实际上从未调用过 ExamplePathTemplate。我也尝试过在insert(ExamplePathTemplate(...), pageContent)
上使用变体,但由于某种类型不匹配而无法编译。感觉这应该是我应该能够使用 KTOR 完成的一件显而易见的事情——有人知道我可能会错过什么吗?
【问题讨论】:
显示您的PageTemplate
课程
由于 API 笨拙,这一点并不明显。
@МихаилНафталь 我已经用 PageTemplate 类的示例更新了这个问题
【参考方案1】:
如果pageContent
属性应该是另一个模板的占位符,那么它的类型应该是TemplatePlaceholder
,而不仅仅是简单的Placeholder
。
如果事先不知道Template
的类型,那么PageTemplate
类应该成为泛型并接受Template
的实例作为参数:
class PageTemplate<T : Template<FlowContent>>(private val username: String, private val displayName: String, private val template: T) : Template<HTML>
val pageContent = TemplatePlaceholder<T>()
override fun HTML.apply()
head
title +"Page Title"
body("body classes")
header /*...*/ //display logged-in user's name here, nav, etc
main("some classes")
insert(template, pageContent)
用法:
get("/example-path")
call.respondHtmlTemplate(PageTemplate(call.session?.username, call.session?.displayName, ExamplePathTemplate(call.session?.username)))
pageContent //this: ExamplePathTemplate
/*set inner template parameters here*/
【讨论】:
【参考方案2】:通过将路由更改为如下所示,我能够将特定于页面的模板应用于页面内容:
get("/example-path")
call.respondHtmlTemplate(PageTemplate(call.session?.username, call.session?.displayName))
pageContent
insert(ExamplePathTemplate(call.session?.username))
这样就满足了编译器的类型要求,成功地用插入的模板生成的html覆盖了pageContent占位符。
【讨论】:
以上是关于KTOR DSL - 如何嵌套模板?的主要内容,如果未能解决你的问题,请参考以下文章
通过 Docker 启动 Ktor 应用程序会导致:未配置 Koin 上下文。请使用 startKoin 或 koinApplication DSL
如何使用 Ktor 服务器向其他服务器发送 POST 请求?