Skip to content

HTML DSL

必要な依存関係: io.ktor:ktor-server-html-builder

コード例: html

Nativeサーバー
Ktor supports Kotlin/Native and allows you to run a server without an additional runtime or virtual machine.
のサポート: ✅

HTML DSLは、kotlinx.htmlライブラリをKtorに統合し、HTMLブロックでクライアントに応答できるようにします。HTML DSLを使用すると、Kotlinで純粋なHTMLを記述したり、ビューに変数を補間したり、テンプレートを使用して複雑なHTMLレイアウトを構築したりできます。

依存関係の追加

HTML DSLはインストールを必要としませんが、ktor-server-html-builderアーティファクトが必要です。次のようにビルドスクリプトに含めることができます。

Kotlin
Groovy
XML

HTMLをレスポンスとして送信

HTMLレスポンスを送信するには、必要なルート内で[respondHtml](https://api.ktor.io/ktor-server/ktor-server-plugins/ktor-server-html-builder/io.ktor.server.html/respond-html.html)メソッドを呼び出します。 以下の例は、サンプルHTML DSLと、クライアントに送信される対応するHTMLを示しています。

kotlin
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
<html>
<head>
    <title>Ktor</title>
</head>
<body>
<h1>Hello from Ktor!</h1>
</body>
</html>

以下のは、ユーザーから認証情報を収集するために使用されるHTMLフォームで応答する方法を示しています。

kotlin
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
<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 wikiを参照してください。

テンプレート

プレーンなHTMLを生成することに加えて、Ktorは複雑なレイアウトを構築するために使用できるテンプレートエンジンを提供します。HTMLページの異なる部分にテンプレートの階層を作成できます。たとえば、ページ全体用のルートテンプレート、ページヘッダーとフッター用のチャイルドテンプレートなどです。Ktorはテンプレートを操作するための以下のAPIを公開しています。

  1. 指定されたテンプレートに基づいて構築されたHTMLで応答するには、[respondHtmlTemplate](https://api.ktor.io/ktor-server/ktor-server-plugins/ktor-server-html-builder/io.ktor.server.html/respond-html-template.html)メソッドを呼び出します。
  2. テンプレートを作成するには、[Template](https://api.ktor.io/ktor-server/ktor-server-plugins/ktor-server-html-builder/io.ktor.server.html/-template/index.html)インターフェースを実装し、HTMLを提供するTemplate.applyメソッドをオーバーライドする必要があります。
  3. 作成されたテンプレートクラス内では、異なるコンテンツタイプ用のプレースホルダーを定義できます。
    • [Placeholder](https://api.ktor.io/ktor-server/ktor-server-plugins/ktor-server-html-builder/io.ktor.server.html/-placeholder/index.html)はコンテンツを挿入するために使用されます。[PlaceholderList](https://api.ktor.io/ktor-server/ktor-server-plugins/ktor-server-html-builder/io.ktor.server.html/-placeholder-list/index.html)は、複数回出現するコンテンツ(例:リスト項目)を挿入するために使用できます。
    • [TemplatePlaceholder](https://api.ktor.io/ktor-server/ktor-server-plugins/ktor-server-html-builder/io.ktor.server.html/-template-placeholder/index.html)は、子テンプレートを挿入し、ネストされたレイアウトを作成するために使用できます。

テンプレートを使用して階層的なレイアウトを作成する方法のを見てみましょう。次のようなHTMLがあるとします。

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>

このページのレイアウトを2つの部分に分割できます。

  • ページヘッダー用のルートレイアウトテンプレートと、記事用のチャイルドテンプレート。
  • 記事コンテンツ用のチャイルドテンプレート。

これらのレイアウトを段階的に実装してみましょう。

  1. respondHtmlTemplateメソッドを呼び出し、テンプレートクラスをパラメータとして渡します。この場合、これはTemplateインターフェースを実装するLayoutTemplateクラスです。
kotlin
get("/") {
    call.respondHtmlTemplate(LayoutTemplate()) {
        // ...
    }
}

このブロック内では、テンプレートにアクセスし、そのプロパティ値を指定できます。これらの値は、テンプレートクラスで指定されたプレースホルダーを置き換えます。次のステップでLayoutTemplateを作成し、そのプロパティを定義します。

  1. ルートレイアウトテンプレートは次のようになります。
kotlin
class LayoutTemplate: Template<HTML> {
    val header = Placeholder<FlowContent>()
    val content = TemplatePlaceholder<ArticleTemplate>()
    override fun HTML.apply() {
        body {
            h1 {
                insert(header)
            }
            insert(ArticleTemplate(), content)
        }
    }
}

このクラスは2つのプロパティを公開しています。

  • headerプロパティはh1タグ内に挿入されるコンテンツを指定します。
  • contentプロパティは記事コンテンツ用のチャイルドテンプレートを指定します。
  1. チャイルドテンプレートは次のようになります。
kotlin
class 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)
        }
    }
}

このテンプレートはarticleTitlearticleTextlistプロパティを公開しており、これらの値はarticle内に挿入されます。

  1. 値のリストをテンプレートとして提供するには、次の新しいクラスを作成します。
kotlin
class 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>要素で囲みます。

  1. これで、指定されたプロパティ値を使用して構築されたHTMLを送信する準備ができました。
kotlin
get("/") {
    call.respondHtmlTemplate(LayoutTemplate()) {
        header {
            +"Ktor"
        }
        content {
            articleTitle {
                +"Hello from Ktor!"
            }
            articleText {
                +"Kotlin Framework for creating connected systems."
            }
            list {
                item { +"One" }
                item { +"Two" }
            }
        }
    }
}

完全な例はこちらで見つけることができます: html-templates