This feature integrates with kotlinx.html to directly emit HTML using Chunked transfer encoding without having to keep memory for the whole HTML.
io.ktor:ktor-html-builder:$ktor_version
中的
io.ktor.html.HtmlContent
类中定义。
dependencies {
implementation "io.ktor:ktor-html-builder:$ktor_version"
}
dependencies {
implementation("io.ktor:ktor-html-builder:$ktor_version")
}
<project>
...
<dependencies>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-html-builder</artifactId>
<version>${ktor.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
This feature doesn’t require installation.
When generating the response, instead of calling the respond
/respondText
methods, you have to call ApplicationCall.respondHtml
:
call.respondHtml {
head {
title { +"Async World" }
}
body {
h1(id = "title") {
+"Title"
}
}
}
For documentation about generating HTML using kotlinx.html, please check its wiki.
In addition to plain HTML generation with the DSL, ktor exposes a simple typed templating engine. You can use it to generate complex layouts in a typed way. It is pretty simple, yet powerful:
call.respondHtmlTemplate(MulticolumnTemplate()) {
column1 {
+"Hello, $name"
}
column2 {
+"col2"
}
}
class MulticolumnTemplate(val main: MainTemplate = MainTemplate()) : Template<HTML> {
val column1 = Placeholder<FlowContent>()
val column2 = Placeholder<FlowContent>()
override fun HTML.apply() {
insert(main) {
menu {
item { +"One" }
item { +"Two" }
}
content {
div("column") {
insert(column1)
}
div("column") {
insert(column2)
}
}
}
}
}
class MainTemplate : Template<HTML> {
val content = Placeholder<HtmlBlockTag>()
val menu = TemplatePlaceholder<MenuTemplate>()
override fun HTML.apply() {
head {
title { +"Template" }
}
body {
h1 {
insert(content)
}
insert(MenuTemplate(), menu)
}
}
}
class MenuTemplate : Template<FlowContent> {
val item = PlaceholderList<UL, FlowContent>()
override fun FlowContent.apply() {
if (!item.isEmpty()) {
ul {
each(item) {
li {
if (it.first) b {
insert(it)
} else {
insert(it)
}
}
}
}
}
}
}
You have to define classes implementing Template<TFlowContent>
,
overriding the TFlowContent.apply
method and optionally define
Placeholder
or TemplatePlaceholder
properties just like
in the example.
When generating the template with call.respondHtmlTemplate(MulticolumnTemplate()) { }
,
you will get the template as receiver, and will be able to access the placeholders
defined as properties in a typed way.