LoginSignup
4
4

More than 3 years have passed since last update.

Golangのインクルード(include)対応テンプレート(goingtpl)を作ってみた

Last updated at Posted at 2018-07-28

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"}} のように記述します。

parent.html
<!DOCTYPE html>
<html><body>
    <h1>Test code</h1>
{{template "footer"}}{{include "footer.html"}}
</body></html>
footer.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の内容もパースされているのが分かると思います。

パース結果.png

テンプレートのキャッシュ機能

使い方は簡単で、事前に下記のようにして機能をONにしておくだけです。
これにより、一度パースしたテンプレートファイルはメモリ上にキャッシュされ、次回からはメモリ上からロードされるようになります。
ディスクアクセスを減らすことができるので、パフォーマンスの向上に期待できます。
逆にキャッシュ中はテンプレートファイルを変更しても反映されない為、開発中はOFFにしておくほうが効率的かもしれません。

キャッシュ機能ON
goingtpl.EnableCache(true)

さきほどのパースのサンプルコードで試してみます。
下記は元のソースのまま(キャッシュ機能OFFで)数回アクセスした際のログです。

API server listening at: 127.0.0.1:36704
ExecTime=568 MicroSec
ExecTime=495 MicroSec
ExecTime=496 MicroSec

では、キャッシュ機能をONにしてみます。
下記のように修正します。

キャッシュ機能を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()
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4