技術向上

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

templateと組み込み関数【Go】

templateでは、組み込み関数(ビルドイン関数)を、自作のgoファイルに定義せずに使用することができます。
templateファイルに直接記入することができるのです。

main.goが次のようになっているとします。

type user struct {
    Name  string
    Admin bool
}

func init() {
    tpl = template.Must(template.ParseFiles("tpl.gohtml"))
}

func main() {

    u1 := user{
        Name:  "Mike",
        Admin: false,
    }

    u2 := user{
        Name:  "Karen",
        Admin: true,
    }

    u3 := user{
        Name:  "",
        Admin: true,
    }

    users := []user{u1, u2, u3}

    err := tpl.Execute(os.Stdout, users)    // usersをtemplateに渡して画面出力
    if err != nil {
        log.Fatalln(err)
    }
}


tpl.gohtmlの内容です。
EXAMPLE #1では、単純にusersの中身をループで取り出しています。
EXAMPLE #2では、usesの中身が存在する場合にusersをスライスのまま出力します。
EXAMPLE #3では、usersをループ処理し、その中のuserのNameが空でない場合に、Nameを出力します。
EXAMPLE #4では、#3の条件にAdminがtrueであることをandを使って条件追加しています。
NameとAdminどちらもtrueのuserについて、NameとAdminを出力します。

EXAMPLE #1
{{range .}}
    {{.}}
{{end}}

EXAMPLE #2
{{if .}}
    EXAMPLE #2 - {{.}}
{{end}}

EXAMPLE #3
{{range .}}
    {{if .Name}}
       EXAMPLE #3 - {{.Name}}
    {{end}}
{{end}}

EXAMPLE #4
{{range .}}
    {{if and .Name .Admin}}
        EXAMPLE #4 - Name: {{.Name}}
        EXAMPLE #4 - Admin: {{.Admin}}
    {{end}}
{{end}}


以上の条件で実行すると、次の内容が出力されます。

EXAMPLE #1
    {Mike false}
    {Karen true}
    { true}

EXAMPLE #2
    EXAMPLE #2 - [{Mike false} {Karen true} { true}]

EXAMPLE #3
       EXAMPLE #3 - Mike
       EXAMPLE #3 - Karen

EXAMPLE #4
        EXAMPLE #4 - Name: Karen
        EXAMPLE #4 - Admin: true

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

なお、「and」が組み込み関数にあたり、「if」はアクションにあたります。


ここでもう一つ、比較関数を使用する例をお見せします。
まずはmain.goです。

var tpl *template.Template

func init() {
    tpl = template.Must(template.ParseFiles("tpl.gohtml"))
}
func main() {
    nf, err := os.Create("index.html")    // 同階層にindex.htmlを作成
    if err != nil {
        log.Fatal(err)
    }
    ss := struct {
        Score1 int
        Score2 int
    }{
        Score1: 9,
        Score2: 15,
    }

    err = tpl.Execute(nf, ss)    // ssをtpl.gohtmlに渡した上で、index.htmlに出力する
    if err != nil {
        log.Fatalln(err)
    }
}


続いてtpl.gohtmlです。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
    {{if lt .Score1 .Score2}}    // less than(先に記述したものが、後に記述したものより小さい)
        Score1: {{.Score1}} < Score2: {{.Score2}} 
    {{end}}

    {{if gt .Score1 .Score2}}    // greater than(先に記述したものが、後に記述したものより大きい)
        Score1: {{.Score1}} > Score2: {{.Score2}} 
    {{end}}

    {{if eq .Score1 .Score2}}    // equal(先に記述したものと後に記述したものが等しい)
        Score1: {{.Score1}} == Score2: {{.Score2}} 
    {{end}}
</body>
</html>


実行すると、index.htmlは次のようになります。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
        Score1: 9 &lt; Score2: 15     // ltに合致する。html/templateをimportしているため、「<」が実体参照に変換されている
</body>
</html>

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

他の例については、下記ドキュメントを参照ください。
template - The Go Programming Language