Golang標準の html/template
がインクルード記述に対応していなかったので、独自に作ってみました。
作ったといっても html/template
をラップして少し拡張した程度ですが。(笑
続きもあるので、良ければどうぞ。
Golangの継承(extends)対応テンプレート(goingtpl)を作ってみた
goingtpl
- テンプレートファイルから別テンプレートファイルのインクルード記述に対応
- ついでにテンプレートのキャッシュ機能
下記GitHubで公開中です。
https://github.com/playree/goingtpl
使い方などの詳細は下記
https://github.com/playree/goingtpl/blob/master/README.JP.md
簡単に機能を紹介します。
テンプレートのインクルード機能
テンプレートファイルに別のテンプレートファイルをパースすることができます。
テンプレートファイルに {{include "xxx.html"}}
のように記述します。
<!DOCTYPE html>
<html><body>
<h1>Test code</h1>
{{template "footer"}}{{include "footer.html"}}
</body></html>
{{define "footer"}}
<p>Footer</p>
{{end}}
あとは下記のように専用のパースメソッドを使用して、親となるテンプレートファイルをパースするだけで、include指定したファイルも一緒にパースされます。
tpl := template.Must(goingtpl.ParseFile("parent.html"))
html/template
互換というか、テンプレートファイルをパースした結果は template.Template
となっています。
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"time"
"github.com/playree/goingtpl"
)
func main() {
// テンプレートのディレクトリを設定
goingtpl.SetBaseDir("./templates")
http.HandleFunc("/test", handleTest)
log.Fatal(http.ListenAndServe(":8088", nil))
}
func handleTest(w http.ResponseWriter, r *http.Request) {
start := time.Now().UnixNano()
// parent.htmlをパース
tpl := template.Must(goingtpl.ParseFile("parent.html"))
tpl.Execute(w, nil)
fmt.Printf("ExecTime=%d MicroSec\n",
(time.Now().UnixNano()-start)/int64(time.Microsecond))
}
実行結果はこんな感じ。
footer.htmlの内容もパースされているのが分かると思います。
テンプレートのキャッシュ機能
使い方は簡単で、事前に下記のようにして機能をONにしておくだけです。
これにより、一度パースしたテンプレートファイルはメモリ上にキャッシュされ、次回からはメモリ上からロードされるようになります。
ディスクアクセスを減らすことができるので、パフォーマンスの向上に期待できます。
逆にキャッシュ中はテンプレートファイルを変更しても反映されない為、開発中はOFFにしておくほうが効率的かもしれません。
goingtpl.EnableCache(true)
さきほどのパースのサンプルコードで試してみます。
下記は元のソースのまま(キャッシュ機能OFFで)数回アクセスした際のログです。
API server listening at: 127.0.0.1:36704
ExecTime=568 MicroSec
ExecTime=495 MicroSec
ExecTime=496 MicroSec
では、キャッシュ機能をONにしてみます。
下記のように修正します。
func main() {
// テンプレートのディレクトリを設定
goingtpl.SetBaseDir("./templates")
goingtpl.EnableCache(true)
これで数回アクセスしてみます。
API server listening at: 127.0.0.1:41719
ExecTime=597 MicroSec
ExecTime=0 MicroSec
ExecTime=0 MicroSec
初回アクセス以降の処理時間が短縮されているのが分かると思います。
キャッシュ機能をONにした場合、プログラムが稼働している間は実際のテンプレートファイルを編集しても反映されません。(メモリにキャッシュしたものを参照する為)
その為、キャッシュを一度クリアするメソッドも用意しています。
goingtpl.ClearCache()