repl.info

Goのtext/templateで、”{{“と”}}”を出力する

Goのtext/templateで、delimiterとして使われる”{{“と”}}”が含まれる文字列を出力したい。

まずは基本的な使い方を確認。”{{“と”}}”で囲んだ箇所は評価される。

https://play.golang.org/p/o0Y5CaZpIMN

package main



import (

	"log"

	"os"

	"text/template"

)





func main() {

	t := `

{{ .Foo }}

`

	tpl, err := template.New("t").Parse(t)

	if err != nil {

		log.Fatal(err)

	}

	data := map[string]interface{}{

		"Foo": "aaa",

	}

	tpl.Execute(os.Stdout, data)

}

結果は次の通り。

aaa

さて、ここからが本題。text/templateを使って、{{ foo }} というテキストを得たい場合どうするか。

素朴にエスケープしてもうまくいかない。

https://play.golang.org/p/loznU_SgNU2

package main



import (

	"log"

	"os"

	"text/template"

)



func main() {

	t := `

\{\{ foo \}\}

`

	tpl, err := template.New("t").Parse(t)

	if err != nil {

		log.Fatal(err)

	}

	data := map[string]interface{}{

		"Foo": "aaa",

	}

	tpl.Execute(os.Stdout, data)

}

\が結果に含まれてしまうため、これでは駄目。

\{\{ foo \}\}

ではどうするかというと、次のようにdelimiterの中で文字列を評価することで実現できる。

https://play.golang.org/p/ko6-P7p86fo

package main



import (

	"log"

	"os"

	"text/template"

)



func main() {

	t := `

{{ "{{ foo }}" }}

`

	tpl, err := template.New("t").Parse(t)

	if err != nil {

		log.Fatal(err)

	}

	data := map[string]interface{}{

		"Foo": "aaa",

	}

	tpl.Execute(os.Stdout, data)

}

次のように、期待した結果が出力される。テンプレートがややこしくなり、読みにくくなるが…

{{ foo }}

delimiterを変えることでも実現できる。

https://play.golang.org/p/IPUxNVPrw5Y

package main



import (

	"log"

	"os"

	"text/template"

)



func main() {

	t := `

{{ foo }}

`

	tpl, err := template.New("t").Delims("[[", "]]").Parse(t)

	if err != nil {

		log.Fatal(err)

	}

	data := map[string]interface{}{

		"Foo": "aaa",

	}

	tpl.Execute(os.Stdout, data)

}

この場合でも、期待した結果を得られる。テンプレートはスッキリするが、delimiterが普段と違うとそれはそれで混乱する気がする。

{{ foo }}

知っているとすぐ読めるけど、知らないとどうなってるのこれ?とハマりそうだな、これ。