HTML DSL
필수 의존성: io.ktor:ktor-server-html-builder
코드 예시: html
HTML DSL은 kotlinx.html 라이브러리를 Ktor에 통합하여 클라이언트에 HTML 블록으로 응답할 수 있도록 합니다. HTML DSL을 사용하면 Kotlin으로 순수 HTML을 작성하고, 변수를 뷰에 삽입하며, 템플릿을 사용하여 복잡한 HTML 레이아웃을 구축할 수도 있습니다.
의존성 추가
HTML DSL은 설치가 필요 없지만 ktor-server-html-builder
아티팩트가 필요합니다. 빌드 스크립트에 다음과 같이 포함할 수 있습니다:
HTML 응답 전송
HTML 응답을 전송하려면, 필요한 경로 내에서 respondHtml 메서드를 호출하세요. 아래 예시는 HTML DSL 샘플과 클라이언트에 전송될 해당 HTML을 보여줍니다:
import io.ktor.server.application.*
import io.ktor.server.html.*
import io.ktor.http.*
import io.ktor.server.routing.*
import kotlinx.html.*
fun Application.module() {
routing {
get("/") {
val name = "Ktor"
call.respondHtml(HttpStatusCode.OK) {
head {
title {
+name
}
}
body {
h1 {
+"Hello from $name!"
}
}
}
}
}
}
<html>
<head>
<title>Ktor</title>
</head>
<body>
<h1>Hello from Ktor!</h1>
</body>
</html>
다음 예시는 사용자로부터 인증 정보를 수집하는 데 사용되는 HTML 폼으로 응답하는 방법을 보여줍니다:
get("/login") {
call.respondHtml {
body {
form(action = "/login", encType = FormEncType.applicationXWwwFormUrlEncoded, method = FormMethod.post) {
p {
+"Username:"
textInput(name = "username")
}
p {
+"Password:"
passwordInput(name = "password")
}
p {
submitInput() { value = "Login" }
}
}
}
}
}
<html>
<body>
<form action="/login" enctype="application/x-www-form-urlencoded" method="post">
<p>Username:<input type="text" name="username"></p>
<p>Password:<input type="password" name="password"></p>
<p><input type="submit" value="Login"></p>
</form>
</body>
</html>
서버 측에서 폼 파라미터를 수신하는 방법은 폼 파라미터에서 알아볼 수 있습니다.
kotlinx.html을 사용하여 HTML을 생성하는 방법에 대해 자세히 알아보려면, kotlinx.html 위키를 참조하세요.
템플릿
일반 HTML을 생성하는 것 외에도, Ktor는 템플릿 엔진을 제공하여 복잡한 레이아웃을 구축하는 데 사용할 수 있습니다. HTML 페이지의 다른 부분에 대한 템플릿 계층을 만들 수 있습니다. 예를 들어, 전체 페이지의 루트 템플릿, 페이지 헤더 및 푸터에 대한 자식 템플릿 등을 만들 수 있습니다. Ktor는 템플릿 작업을 위한 다음 API를 제공합니다:
- 지정된 템플릿을 기반으로 구축된 HTML로 응답하려면, respondHtmlTemplate 메서드를 호출하세요.
- 템플릿을 생성하려면, Template 인터페이스를 구현하고 HTML을 제공하는
Template.apply
메서드를 오버라이드(override)해야 합니다. - 생성된 템플릿 클래스 내에서 다양한 콘텐츠 유형에 대한 플레이스홀더를 정의할 수 있습니다:
- Placeholder는 콘텐츠를 삽입하는 데 사용됩니다. PlaceholderList는 콘텐츠가 여러 번 나타나는 경우(예: 목록 항목) 삽입하는 데 사용될 수 있습니다.
- TemplatePlaceholder는 자식 템플릿을 삽입하고 중첩된 레이아웃을 생성하는 데 사용될 수 있습니다.
예시
템플릿을 사용하여 계층적 레이아웃을 생성하는 방법에 대한 예시를 살펴보겠습니다. 다음 HTML이 있다고 상상해 봅시다:
<body>
<h1>Ktor</h1>
<article>
<h2>Hello from Ktor!</h2>
<p>Kotlin Framework for creating connected systems.</p>
<ul>
<li><b>One</b></li>
<li>Two</li>
</ul>
</article>
</body>
이 페이지의 레이아웃을 두 부분으로 나눌 수 있습니다:
- 페이지 헤더를 위한 루트 레이아웃 템플릿과 기사(article)를 위한 자식 템플릿.
- 기사 콘텐츠를 위한 자식 템플릿.
이러한 레이아웃을 단계별로 구현해 보겠습니다:
``respondHtmlTemplate
메서드를 호출하고 템플릿 클래스를 파라미터로 전달하세요. 이 경우,
LayoutTemplate클래스는
Template인터페이스를 구현해야 합니다:
kotlinget("/") { call.respondHtmlTemplate(LayoutTemplate()) { // ... } }
블록 내에서, 템플릿에 접근하여 속성 값을 지정할 수 있습니다. 이 값들은 템플릿 클래스에 지정된 플레이스홀더를 대체합니다. 다음 단계에서
LayoutTemplate
을 생성하고 그 속성을 정의할 것입니다.루트 레이아웃 템플릿은 다음과 같이 보일 것입니다:
kotlinclass LayoutTemplate: Template<HTML> { val header = Placeholder<FlowContent>() val content = TemplatePlaceholder<ArticleTemplate>() override fun HTML.apply() { body { h1 { insert(header) } insert(ArticleTemplate(), content) } } }
이 클래스는 두 가지 속성을 노출합니다:
header
속성은h1
태그 내에 삽입되는 콘텐츠를 지정합니다.content
속성은 기사 콘텐츠를 위한 자식 템플릿을 지정합니다.
자식 템플릿은 다음과 같이 보일 것입니다:
kotlinclass ArticleTemplate : Template<FlowContent> { val articleTitle = Placeholder<FlowContent>() val articleText = Placeholder<FlowContent>() val list = TemplatePlaceholder<ListTemplate>() override fun FlowContent.apply() { article { h2 { insert(articleTitle) } p { insert(articleText) } insert(ListTemplate(), list) } } }
이 템플릿은
articleTitle
,articleText
,list
속성을 노출하며, 이 값들은article
내에 삽입될 것입니다.템플릿으로 값 목록을 제공하려면, 다음과 같은 새 클래스를 생성하세요:
kotlinclass ListTemplate : 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) } } } } } } }
이 템플릿은
PlaceholderList
클래스를 사용하여 제공된 항목으로부터 비순서 목록(UL
)을 생성합니다. 또한 첫 번째 항목을 강조하기 위해<b>
요소로 감쌉니다.이제 지정된 속성 값을 사용하여 HTML을 구축하고 보낼 준비가 되었습니다:
kotlinget("/") { call.respondHtmlTemplate(LayoutTemplate()) { header { +"Ktor" } content { articleTitle { +"Hello from Ktor!" } articleText { +"Kotlin Framework for creating connected systems." } list { item { +"One" } item { +"Two" } } } } }
전체 예시는 다음에서 찾을 수 있습니다: html-templates.