$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

Goでtemplateファイルをembedして、コードとテンプレートを分離する

Goでtext/templateを使ってコードジェネレータを書いている時、コード内にテンプレート自体を文字列として埋め込むのはコードが見にくくなるため困っていた。例えばPerlのData::Section::Simpleみたいにコードとテンプレートを分離して、見やすくしておきたい。

調べてみるとembedを使うのがシンプルで良さそうだということでやってみた。参考例はこちら

Goのファイルからはgo:embedを使ってファイルからstringに埋め込んでおく。以下のsampleJsonTmplの部分。あとは埋め込んだ変数を利用してtext/templateを使って出力する。

package main

import (
    _ "embed"
    "fmt"
    "os"
    "strings"
    "text/template"
)

//go:embed sample.json.tmpl
var sampleJsonTmpl string

func main() {
    fmt.Println(sampleJsonTmpl)

    tmpl, err := template.New("sample").Parse(sampleJsonTmpl)
    if err != nil {
        os.Exit(1)
    }

    data := map[string]any{
        "Hoge": "hogehoge",
        "Foo":  "barbar",
    }

    var buf strings.Builder
    if err := tmpl.Execute(&buf, data); err != nil {
        os.Exit(1)
    }
    fmt.Println(buf.String())
}

sample.json.tmplはこんな感じ。

{
  "hoge": "{{ .Hoge }}",
  "foo": "{{ .Foo }}"
}

このようにすることで、テンプレートとコードを分離することができ、テンプレートが大きい時にコードが見づらくなってしまう問題が解消できた。