GolangでRubyのerbみたいなテンプレートエンジンのegoを使ってみよう！

GolangでRubyのERBみたいな、テンプレートエンジンを探していて見つけました。

https://github.com/benbjohnson/ego

[README](https://github.com/benbjohnson/ego/blob/master/README.md)を見ると、確かに、Rubyの[erb](https://github.com/rails/rails/blob/7f18ea14c893cb5c9f04d4fda9661126758332b5/railties/lib/rails/generators/erb.rb)のように、`<%= colorName %>`のような表記で変数を展開できそうです。


本当に使えるのかな、ということでちょっと触ってみました。

まずは`go get`でライブラリを取得します。

```bash
go get github.com/benbjohnson/ego/cmd/ego
```

`ego`を実行するためのフォルダを作成します。

```bash
mkdir -p $GOPATH/src/github.com/letusfly85/example_ego

vim example_template.go
```

```example_template.go
<%! func MyTmpl(w io.Writer, u *User) error %>

<%% import "strings" %%>

<html>
  <body>
    <h1>Hello <%= strings.TrimSpace(u.FirstName) %>!</h1>

    <p>Here's a list of your favorite colors:</p>
    <ul>
      <% for _, colorName := range u.FavoriteColors { %>
        <li><%= colorName %></li>
      <% } %>
    </ul>
  </body>
</html>
```

`ego`を実行します。

```bash
ego ./
```

すると、`ego.go`というファイルが出来上がります。

```ego.go
// Generated by ego.
// DO NOT EDIT

package example_ego
import (
"fmt"
"html"
"io"
"strings"
)
var _ = fmt.Sprint("") // just so that we can keep the fmt import for now
//line example_template.ego:1
 func MyTmpl(w io.Writer, u *User) error  {
//line example_template.ego:2
_, _ = io.WriteString(w, "\n\n")
//line example_template.ego:4
_, _ = io.WriteString(w, "\n\n<html>\n  <body>\n    <h1>Hello ")
//line example_template.ego:7
_, _ = io.WriteString(w, html.EscapeString(fmt.Sprintf("%v",  strings.TrimSpace(u.FirstName) )))
//line example_template.ego:7
_, _ = io.WriteString(w, "!</h1>\n\n    <p>Here's a list of your favorite colors:</p>\n    <ul>\n      ")
//line example_template.ego:11
 for _, colorName := range u.FavoriteColors {
//line example_template.ego:12
_, _ = io.WriteString(w, "\n        <li>")
//line example_template.ego:12
_, _ = io.WriteString(w, html.EscapeString(fmt.Sprintf("%v",  colorName )))
//line example_template.ego:12
_, _ = io.WriteString(w, "</li>\n      ")
//line example_template.ego:13
 }
//line example_template.ego:14
_, _ = io.WriteString(w, "\n    </ul>\n  </body>\n</html>\n")
return nil
}
```

ランタイムに動的に評価されるような仕組みではないようです。ちょっとここら辺は残念ですね。

呼び出すファイルを実装してみます。

Userストラクトも実装します。

```user.go
package example_ego

type User struct {
        FirstName      string
        FavoriteColors []string
}
```

ビルドをしてパッケージングします。
（パッケージングが面倒な人たちは、上記のgoファイルのpackage名を全てmainにして実行してみてください。）

```bash
go build user.go ego.go
```

ホームディレクトリ移動して、ライブラリを利用できるか試してみました。

```bash
vim sample.go
```

```sample.go
package main

import "bytes"
import example_ego "github.com/letusfly85/example_ego"

func main() {
	myUser := &my_ego.User{
		FirstName:      "Bob",
		FavoriteColors: []string{"blue", "green", "mauve"},
	}

	var buf bytes.Buffer
	if err := example_ego.MyTmpl(&buf, myUser); err != nil {
		panic(err)
	}
	println(buf.String())
}
```

実行してみます。

```bash
go run sample.go
```

結果は以下のとおりです。

```html
<html>
  <body>
    <h1>Hello Bob!</h1>

    <p>Here's a list of your favorite colors:</p>
    <ul>

        <li>blue</li>

        <li>green</li>

        <li>mauve</li>

    </ul>
  </body>
</html>
```

おー、動きましたね。

事前に`ego`テンプレートファイルから`go`ファイルを生成しないといけないのかな、というところがちょっと疑問ですが、使えないこともないのかな、と思ったりしました。

時間があればもうちょっと深掘りしてみようと思います。