GoにおけるQuicktemplate:PythonのJinja2のようなもの、決してhtml/templateではない
Lukas Schneider
DevOps Engineer · Leapcell

Quicktemplateテンプレートライブラリの使用ガイド
最近、プロジェクトのコードを整理している際に、多くのアクティビティのコードが構造と提供する機能において非常に類似していることに気づきました。今後の開発を容易にするため、反復作業を最小限に抑えるためのコードフレームワークを生成するツールを作成するのに時間を費やしました。コード自体は複雑ではなく、プロジェクトコードと密接に関連しているため、ここでは詳細には触れません。この過程で、Goの標準テンプレートライブラリであるtext/template
とhtml/template
は、むしろ制約が多く、使いにくいと感じました。GitHubでサードパーティ製のテンプレートライブラリであるquicktemplate
について知りました。これは強力で、シンプルな構文を持ち、使いやすいものです。今日は、quicktemplate
を紹介します。
クイックスタート
この記事のコードはGo Modulesを使用しています。
プロジェクトの初期化
まず、コードディレクトリを作成し、初期化します。
$ mkdir quicktemplate && cd quicktemplate $ go mod init github.com/leapcell/quicktemplate
依存関係のインストール
quicktemplate
は、私たちが書いたテンプレートコードをGo言語のコードに変換します。したがって、quicktemplate
パッケージとqtc
という名前のコンパイラをインストールする必要があります。
$ go get -u github.com/valyala/quicktemplate $ go get -u github.com/valyala/quicktemplate/qtc
テンプレートファイルの作成
まず、quicktemplate
形式でテンプレートファイルを作成する必要があります。テンプレートファイルの拡張子はデフォルトで.qtpl
です。ここでは、簡単なテンプレートファイル greeting.qtpl
を作成しました。
All text outside function is treated as comments. {% func Greeting(name string, count int) %} {% for i := 0; i < count; i++ %} Hello, {%s name %} {% endfor %} {% endfunc %}
テンプレート構文の説明
テンプレートの構文は非常に簡単です。次の2つの点を簡単に理解するだけで済みます。
- テンプレートは関数単位です。関数は任意の型と量のパラメータを受け入れることができ、これらのパラメータは関数内で使用できます。関数外のすべてのテキストはコメントであり、
qtc
コンパイラはコメントを無視します。 - 関数内のコンテンツは、構文構造を除いて、スペースや改行を含め、レンダリングされたテキストにそのまま出力されます。
テンプレートの生成と使用
greeting.qtpl
をtemplates
ディレクトリに保存し、qtc
コマンドを実行します。このコマンドは、対応するGoファイル greeting.qtpl.go
を生成し、パッケージ名はtemplates
になります。これで、このテンプレートを使用できます。
package main import ( "fmt" "github.com/leapcell/quicktemplate/get-started/templates" ) func main() { fmt.Println(templates.Greeting("leapcell", 5)) }
コードの実行
テンプレート関数を呼び出し、パラメータを渡して、レンダリングされたテキストを返します。
$ go run .
出力結果:
Hello, leapcell Hello, leapcell Hello, leapcell Hello, leapcell Hello, leapcell
{%s name %}
はテキストの置換を実行し、{% for %}
はループして繰り返しテキストを生成します。出力に複数のスペースと改行が表示されるのは、関数内の構文構造を除いて、他のコンテンツはスペースや改行を含め、そのまま保持されるためです。
注意点
quicktemplate
はテンプレートを Go コードに変換して使用するため、テンプレートが変更された場合は、最初に qtc
コマンドを実行して Go コードを再生成する必要があります。そうしないと、変更は有効になりません。
構文構造
quicktemplate
は、if
、for
、func
、import
、return
などの一般的な Go 構文構造をサポートしています。そして、書き方は Go コードを直接書くのとほとんど変わらず、学習コストはほとんどありません。ただし、これらの構文をテンプレートで使用する場合は、{%
と %}
で囲む必要があり、if
、for
などは、endif
、endfor
を追加して、終了を明確に示す必要があります。
変数
上記では、渡されたパラメータ name
を {%s name %}
を使用してレンダリングする方法をすでに見てきました。name
は string
型なので、{%
の後に s
を使用して型を指定します。quicktemplate
は他の型の値もサポートしています。
- 整数:
{%d int %}
,{%dl int64 %}
,{%dul uint64 %}
. - 浮動小数点数:
{%f float %}
. 出力精度を設定することもできます。{%f.precision float %}
を使用します。たとえば、{%f.2 1.2345 %}
は1.23
を出力します。 - バイトスライス (
[]byte
):{%z bytes %}
. - 文字列:
{%q str %}
またはバイトスライス:{%qz bytes %}
。引用符は"
としてエスケープされます。 - 文字列:
{%j str %}
またはバイトスライス:{%jz bytes %}
。引用符はありません。 - URL エンコード:
{%u str %}
,{%uz bytes %}
. {%v anything %}
: 出力はfmt.Sprintf("%v", anything)
と同等です。
サンプルコード
まず、テンプレートを記述します。
{% func Types(a int, b float64, c []byte, d string) %} int: {%d a %}, float64: {%f.2 b %}, bytes: {%z c %}, string with quotes: {%q d %}, string without quotes: {%j d %}. {% endfunc %}
次に、それを使用します。
func main() { fmt.Println(templates.Types(1, 5.75, []byte{'a', 'b', 'c'}, "hello")) }
実行します。
$ go run .
出力結果:
int: 1, float64: 5.75, bytes: abc, string with quotes: "hello", string without quotes: hello.
関数の呼び出し
quicktemplate
は、テンプレート内のテンプレート関数と標準ライブラリからの関数の呼び出しをサポートしています。qtc
は Go コードを直接生成するため、テンプレートが呼び出すために同じディレクトリに独自の関数を記述することもできます。テンプレート A で定義された関数は、テンプレート B で定義された関数を呼び出すこともできます。
カスタム関数の定義
まず、templates
ディレクトリに rank.go
ファイルを作成し、スコアを受け取り、評価を返す Rank
関数を定義します。
package templates func Rank(score int) string { if score >= 90 { return "A" } else if score >= 80 { return "B" } else if score >= 70 { return "C" } else if score >= 60 { return "D" } else { return "E" } }
テンプレートでカスタム関数を呼び出す
次に、テンプレートでこの関数を呼び出すことができます。
{% import "fmt" %} {% func ScoreList(name2score map[string]int) %} {% for name, score := range name2score %} {%s fmt.Sprintf("%s: score-%d rank-%s", name, score, Rank(score)) %} {% endfor %} {% endfunc %}
テンプレートのコンパイルと使用
テンプレートをコンパイルします。
$ qtc
プログラムを記述します。
func main() { name2score := make(map[string]int) name2score["leapcell"] = 85 name2score["bob"] = 86 name2score["alice"] = 22 fmt.Println(templates.ScoreList(name2score)) }
プログラムを実行して出力します。
$ go run .
出力結果:
leapcell: score-85 rank-B bob: score-86 rank-A alice: score-22 rank-E
テンプレートで fmt
パッケージを使用しているため、最初に {% import %}
を使用してパッケージをインポートする必要があります。テンプレートで別のテンプレートの関数を呼び出すのも同様です。テンプレートは最終的に Go コードに変換され、Go コードには同じシグネチャの関数があるためです。
Webアプリケーション
quicktemplate
は、HTML ページのテンプレートを作成するためによく使用されます。
{% func Index(name string) %} <html> <head> <title>Awesome Web</title> </head> <body> <h1>Hi, {%s name %} <p>Welcome to the awesome web!!!</p> </body> </html> {% endfunc %}
次に、簡単な Web サーバーを記述します。
func index(w http.ResponseWriter, r *http.Request) { templates.WriteIndex(w, r.FormValue("name")) } func main() { mux := http.NewServeMux() mux.HandleFunc("/", index) server := &http.Server{ Handler: mux, Addr: ":8080", } log.Fatal(server.ListenAndServe()) }
qtc
は Write*
メソッドを生成します。このメソッドは io.Writer
型のパラメータを受け入れます。テンプレートのレンダリング結果は、この io.Writer
に書き込まれます。http.ResponseWriter
をパラメータとして直接渡すことができ、非常に便利です。
Webサーバーの実行
$ qtc $ go run .
ブラウザで localhost:8080?name=leapcell
を入力して、結果を表示します。
結論
quicktemplate
には、少なくとも次の3つの利点があります。
- 構文は Go 言語の構文と非常によく似ており、学習コストはほとんどありません。
- 最初に Go に変換され、レンダリング速度が非常に速く、標準ライブラリの
html/template
より 20 倍以上高速です。 - セキュリティ上の理由から、攻撃を回避するためにいくつかのエンコードを実行します。
Leapcell: 最高のサーバーレスWebホスティング
最後に、Goサービスをデプロイするのに最適なプラットフォーム**Leapcell**をお勧めします。
🚀 お気に入りの言語で構築
JavaScript、Python、Go、またはRustであらゆる努力で開発します。
🌍 無制限のプロジェクトを無料でデプロイ
使用した分だけ支払います。リクエストも料金もかかりません。
⚡ 従量課金制、隠れたコストなし
アイドル料金はかからず、シームレスなスケーラビリティのみです。
🔹 Twitterでフォローする: @LeapcellHQ