技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

templateの分離と組み立て【Go】

templateを複数に分割して識別し、組み立てる時に識別名によって呼び出すことができます。

階層は次の通りになっているとします。

main.go
templates
    tpl.gohtml
    parts.gohtml


まずはmain.goです。

var tpl *template.Template

func init() {
    tpl = template.Must(template.ParseGlob("templates/*"))    // templates以下にあるファイル全てをparse、キャッシュする
}
func main() {
    nf, err := os.Create("index.html")
    if err != nil {
        log.Fatal(err)
    }

    err = tpl.ExecuteTemplate(nf, "tpl.gohtml", nil)    // index.htmlにコピーするtemplateは、大元であるtpl.gohtml
    if err != nil {
        log.Fatalln(err)
    }
}


続いてtpl.gohtmlです。
template "~"の形式でtemplateを呼び出しています。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
    {{template "notification"}}    // notificationという名前のtemplateを呼ぶ
    {{template "thanks"}}    // thanksという名前のtemplateを呼ぶ
</body>
</html>


"notifcation"と"thanks" のtemplate は、templates/parts.gohtml に記述しています。
define "~"の形式で、"~"と名付けたテンプレートを定義します。

{{define "notification"}}
    <p>This is from parts.</p>
{{end}}

{{define "thanks"}}
    <p>Thank you.</p>
{{end}}


index.htmlは次のようになります。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
    <p>This is from parts.</p>
    <p>Thank you.</p>
</body>
</html>

※空行は削除しています。

この通り、templateの名前はファイル名ではなく、自由に決めることができます。
一つのファイルに複数のtemplateを定義することができるのです。


また、次のように記述することで、goファイルから受け取ったdataをリレーすることができます。

main.goの一部抜粋

...
err = tpl.ExecuteTemplate(nf, "tpl.gohtml", "Mike")
...


tpl.gohtmlの一部抜粋

<body>
    {{template "notification"}}
    {{template "thanks" .}}    // goファイルから受け取った値を、「.」を通してthanks templateに渡す
</body>


parts.gohtml

{{define "notification"}}
    <p>This is from parts.</p>
{{end}}

{{define "thanks"}}
    <p>Thank you, {{.}}</p>    // tpl.gohtmlから受け取った値を、「.」を通して出力
{{end}}


index.htmlは次のようになります。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
    <p>This is from parts.</p>
    <p>Thank you, Mike</p>
</body>
</html>

※空行は削除しています。

例えばページの中でサイドバーやヘッダー部分のtemplateを分離する、などが考えられます。
分離できることで、作業も分割することができるでしょう。