KTOR DSL - 如何嵌套模板?
KTOR DSL - how to nest templates?
我正在尝试使用 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 完成的一件显而易见的事情——有人知道我可能遗漏了什么吗?
通过将路由更改为如下所示,我能够获得页面特定的模板以应用于页面内容:
get("/example-path") {
call.respondHtmlTemplate(PageTemplate(call.session?.username, call.session?.displayName)) {
pageContent {
insert(ExamplePathTemplate(call.session?.username)) { }
}
}
}
这满足了编译器的类型要求,并成功地用插入模板生成的 html 覆盖了 pageContent 占位符。
如果pageContent
属性是另一个模板的占位符,那么它的类型应该是TemplatePlaceholder
,而不是简单的Placeholder
.
如果事先不知道 Template
的类型,那么 PageTemplate
class 应该变成泛型并接受 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*/
}
}
}
我正在尝试使用 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 完成的一件显而易见的事情——有人知道我可能遗漏了什么吗?
通过将路由更改为如下所示,我能够获得页面特定的模板以应用于页面内容:
get("/example-path") {
call.respondHtmlTemplate(PageTemplate(call.session?.username, call.session?.displayName)) {
pageContent {
insert(ExamplePathTemplate(call.session?.username)) { }
}
}
}
这满足了编译器的类型要求,并成功地用插入模板生成的 html 覆盖了 pageContent 占位符。
如果pageContent
属性是另一个模板的占位符,那么它的类型应该是TemplatePlaceholder
,而不是简单的Placeholder
.
如果事先不知道 Template
的类型,那么 PageTemplate
class 应该变成泛型并接受 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*/
}
}
}