GoでPugを使う
Go(GAE)でちょっとしたHTMLを返すアプリを作っているんですが、生HTML書きたくないのとhtml/template
は避けたいのでPugのライブラリをさわってみました。
Pug(Jade)ライブラリ
いくつかあるっぽいですが、以下の2つがメジャー?なようでした。
- Joker/jade: Jade.go - template engine for Go (golang)
- eknkc/pug: Go port of Pug (jade) template engine
前者の方がPugとしての機能は充実してそうなんですが、今回そんなに複雑な機能はいらないのと、I/Fが後者の方がシンプルでこれで十分だなって思えたのでそちらを使うことにしました。
*.pug
ファイルへのpath
若干はまりました。
GAE+dupで開発しており、GOPATH
以下にgoのソースをおいて、app.yaml
があるディレクトリにはmain.go
のみ、という構成にしていたので*.pug
ファイルもGOPATH
以下におこうとしてました。
pug.CompileFile
の第二引数でdirを指定できるのでそれでやろうとしたのですが、GAEだとうまくいかなかったです。
import (
"net/http"
"path/filepath"
"github.com/eknkc/pug"
"github.com/eknkc/pug/compiler"
)
func Render(w http.ResponseWrite) error {
path, err := filepath.Abs("../lib/view")
if err != nil {
return err
}
t, err := pug.CompileFile("index.pug", pug.Options{Dir: compiler.FsDir(path)})
if err != nil {
return err
}
params := map[string]string{
Key1: "foo",
Key2: "bar",
}
if err := t.Execute(w, params); err != nil {
return err
}
return nil
}
compiler.FsDir
が../
みたいのをうけつけないので、filepath.Abs
で絶対パスを渡してあげます。
これだとlocalでdev_appserver.py
とかする分には動きます。
ただdeployすると、index.pug
にpermissionがないっていわれてエラーになってしまいます。
これはGAEだと読み込めるpathが制限されているからです。
app.yaml
があるディテクトリ以下のファイルしか開けないようなので、そちらにview
ディレクトリを作るようにします。
path, err := filepath.Abs("view")
if err != nil {
return err
}
t, err := pug.CompileFile("index.pug", pug.Options{Dir: compiler.FsDir(path)})
if err != nil {
return err
}
最初こんな感じで絶対パスにしてたんですが、これだとapp.yaml
以下であってもpermission errorになってしまい、動きませんでした。
絶対パスだと有無をいわさずダメっぽいですね。(documentに書いてありそうですがみつけられておらず…)
そもそも絶対パスは最早不要なので、素直にmain.go
からのpathを渡すようにします。
import (
"net/http"
"github.com/eknkc/pug"
)
func Render(w http.ResponseWrite) error {
t, err := pug.CompileFile("view/index.pug")
if err != nil {
return err
}
params := map[string]string{
Key1: "foo",
Key2: "bar",
}
if err := t.Execute(w, params); err != nil {
return err
}
return nil
}
全体はこんな感じに。
だいぶスッキリしましたね!
これでGAE上でpugをrenderできるようになりました。