テンプレート

やあ、フィリップだよ!
私のプラットフォームGo Web Examples Coursesがリリースされたことをお知らせします。GoでのWeb開発に関する、わかりやすいビデオコースをお楽しみください。早期サポーター向けの特別オファーもご確認ください。
そこでお会いしましょう!:)
詳細はこちら

はじめに

Goのhtml/templateパッケージは、HTMLテンプレートのための豊富なテンプレート言語を提供します。これは主にWebアプリケーションで、クライアントのブラウザに構造化された方法でデータを表示するために使用されます。Goのテンプレート言語の大きな利点の1つは、データの自動エスケープです。GoはHTMLテンプレートを解析し、ブラウザに表示する前にすべての入力をエスケープするため、XSS攻撃を心配する必要はありません。

最初のテンプレート

Goでテンプレートを作成するのは非常に簡単です。この例では、HTMLの順序なしリスト(ul)として記述されたTODOリストを示します。テンプレートをレンダリングするとき、渡されるデータはGoのデータ構造であればどのような種類でもかまいません。単純な文字列または数値でも、以下の例のようにネストされたデータ構造でもかまいません。テンプレート内のデータにアクセスするには、最上位の変数は{{.}}でアクセスします。中括弧内のドットはパイプラインと呼ばれ、データのルート要素です。

data := TodoPageData{
    PageTitle: "My TODO list",
    Todos: []Todo{
        {Title: "Task 1", Done: false},
        {Title: "Task 2", Done: true},
        {Title: "Task 3", Done: true},
    },
}
<h1>{{.PageTitle}}</h1>
<ul>
    {{range .Todos}}
        {{if .Done}}
            <li class="done">{{.Title}}</li>
        {{else}}
            <li>{{.Title}}</li>
        {{end}}
    {{end}}
</ul>

制御構造

テンプレート言語には、HTMLをレンダリングするための豊富な制御構造のセットが含まれています。ここでは、最も一般的に使用されるものの概要を説明します。可能なすべての構造の詳細なリストについては、text/templateを参照してください。

制御構造 定義
{{/* コメント */}} コメントを定義します
{{.}} {{.}}
ルート要素をレンダリングします {{.Title}}
ネストされた要素の「Title」フィールドをレンダリングします {{if .Done}} {{else}} {{end}}
if文を定義します {{range .Todos}} {{.}} {{end}}
すべての「Todos」をループし、{{.}}を使用してそれぞれをレンダリングします {{block "content" .}} {{end}}

「content」という名前のブロックを定義します

ファイルからのテンプレートの解析

tmpl, err := template.ParseFiles("layout.html")
// or
tmpl := template.Must(template.ParseFiles("layout.html"))

テンプレートは、文字列またはディスク上のファイルから解析できます。通常、テンプレートはディスクから解析されるため、この例ではその方法を示します。この例では、Goプログラムと同じディレクトリにlayout.htmlというテンプレートファイルがあります。

リクエストハンドラーでのテンプレートの実行

func(w http.ResponseWriter, r *http.Request) {
    tmpl.Execute(w, "data goes here")
}

テンプレートがディスクから解析されると、リクエストハンドラーで使用する準備が整います。Execute関数は、テンプレートを書き出すためのio.Writerと、テンプレートにデータを渡すためのinterface{}を受け入れます。関数がhttp.ResponseWriterで呼び出されると、Content-TypeヘッダーはHTTPレスポンスで自動的にContent-Type: text/html; charset=utf-8に設定されます。

コード(コピー/ペースト用)

package main

import ( "html/template" "net/http" )

type Todo struct { Title string Done bool }

type TodoPageData struct { PageTitle string Todos []Todo }

func main() { tmpl := template.Must(template.ParseFiles("layout.html")) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { data := TodoPageData{ PageTitle: "My TODO list", Todos: []Todo{ {Title: "Task 1", Done: false}, {Title: "Task 2", Done: true}, {Title: "Task 3", Done: true}, }, } tmpl.Execute(w, data) }) http.ListenAndServe(":80", nil) }

<h1>{{.PageTitle}}</h1>
<ul>
    {{range .Todos}}
        {{if .Done}}
            <li class="done">{{.Title}}</li>
        {{else}}
            <li>{{.Title}}</li>
        {{end}}
    {{end}}
</ul>