...

パッケージ template

import "text/template"
概要
目次
サブディレクトリ

概要 ▾

template パッケージは,テキストを出力するデータ駆動テンプレートを実装します。

HTML 出力を生成するには,パッケージ html/template を参照してください。 このパッケージと同じインターフェースを持ちますが,特定の攻撃に対して HTML 出力を自動的に保護します。

テンプレートはデータ構造に適用することによって実行されます。 テンプレート内の注釈は,実行を制御し,表示される値を導出するためのデータ構造の要素 (通常は構造体のフィールドまたはマップ内のキー) を指します。 テンプレートを実行すると,構造体をたどり,ピリオド " 。 " で表されるカーソルが設定されます。 そして "dot" と呼ばれ,実行が進むにつれて構造内の現在の位置の値になります。

テンプレートの入力テキストは, UTF-8 でエンコードされた任意の形式のテキストです。 "アクション" - データ評価や制御構造 - は "{{" と "}}" で区切られます。 アクションの外側のすべてのテキストは変更されずに出力にコピーされます。 生の文字列を除いて,アクションは改行にまたがらないかもしれませんがコメントはできます。

一度解析されると,テンプレートは安全に並列に実行されますが,並列実行が Writer を共有する場合,出力はインターリーブされます。

これは "17 items are made of wool" という簡単な例です。

type Inventory struct {
	Material string
	Count    uint
}
sweaters := Inventory{"wool", 17}
tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
if err != nil { panic(err) }
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil { panic(err) }

より複雑な例を以下に示します。

テキストとスペース

デフォルトでは,テンプレートの実行時にアクション間のすべてのテキストが逐語的にコピーされます。 たとえば,上記の例の文字列 "itemsismade" は,プログラムの実行時に標準出力に表示されます。

ただし,テンプレートのソースコードのフォーマットを容易にするために,アクションの左の区切り文字 (デフォルトでは "{{") の直後にマイナス記号と ASCII スペース文字 ("{{- ") が続く場合,末尾のスペースはすべて切り捨てられます。 直前のテキスト同様に,右側の区切り文字 ("}}") の前にスペースとマイナス記号 (" -}}") がある場合,先頭の空白はすべて直後のテキストから切り捨てられます。 これらのトリムマーカーでは, ASCII スペースが存在しなければなりません。 "{{-3}}" は,数値 -3 を含むアクションとして解析します。

例えば,ソースが

"{{23 -}} < {{- 45}}"

生成された出力は

"23<45"

このトリミングの場合,空白文字の定義は Go の場合と同じです。 スペース,水平タブ,キャリッジリターン,および改行です。

行動

これがアクションのリストです。 " 引数 " と " パイプライン " はデータの評価であり,以下の対応するセクションで詳細に定義されています。

{{/* コメント */}}
{{- /* 前後のテキストから空白を削除したコメント */ -}}
	コメント。破棄されました。改行を含めることができます。
	ここに示されているように,コメントは入れ子にならず,区切り文字で始まりそして終わる必要があります。

{{pipeline}}
	pipeline の値のデフォルトのテキスト表現 (fmt.Print で表示されるものと同じ) が出力にコピーされます。

{{if pipeline}} T1 {{end}}
	pipeline の値が空の場合,出力は生成されません。
	そうでなければ, T1 が実行されます。
	空の値は false, 0 ,任意の nil ポインタまたはインターフェース値,および任意の配列,スライス,マップ,または長さゼロの文字列です。
	ドットは影響を受けません。

{{if pipeline}} T1 {{else}} T0 {{end}}
	pipeline の値が空の場合, T0 が実行されます。
	そうでなければ, T1 が実行されます。
	ドットは影響を受けません。

{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
	if-else の書き方を簡単にするために, if の else アクションには別の if を直接含めることができます。
	効果は以下と同じです。
		{{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}

{{range pipeline}} T1 {{end}}
	pipeline の値は,配列,スライス,マップ,またはチャンネルである必要があります。
	pipeline の値の長さがゼロの場合,何も出力されません。
	それ以外の場合, dot は配列,スライス,またはマップの連続する要素に設定され, T1 が実行されます。
	値がマップで,キーが定義された順序 (" 比較可能 ") の基本型の場合,要素はソートされたキーの順序でアクセスされます。

{{range pipeline}} T1 {{else}} T0 {{end}}
	パイプラインの値は,配列,スライス,マップ,またはチャンネルである必要があります。
	パイプラインの値の長さがゼロの場合, dot は影響を受けず, T0 が実行されます。
	それ以外の場合, dot は配列,スライス,またはマップの連続する要素に設定され, T1 が実行されます。

{{template "name"}}
	指定された名前(name)のテンプレートは nil データで実行されます。

{{template "name" pipeline}}
	指定された名前(name)のテンプレートは,ドットをパイプラインの値に設定して実行されます。

{{block "name" pipeline}} T1 {{end}}
	ブロックは以下のテンプレートを定義して
		{{define "name"}} T1 {{end}}
	それをその場で実行することの省略形です
		{{template "name" pipeline}}
	典型的な使用法は,その中でブロックテンプレートを再定義することによってカスタマイズされる一連のルートテンプレートを定義することです。

{{with pipeline}} T1 {{end}}
	pipeline の値が空の場合,出力は生成されません。
	そうでなければ, dot は pipeline の値に設定され, T1 が実行されます。

{{with pipeline}} T1 {{else}} T0 {{end}}
	pipeline の値が空の場合, dot は影響を受けず, T0 が実行されます。
	そうでなければ, dot は pipeline の値に設定され, T1 が実行されます。

引数

引数は単純な値で,次のいずれかで表されます。

- Go 構文のブール,文字列,文字,整数,浮動小数点,虚数または複素定数。
  これらは Go の型なし定数のように振る舞います。
  Go と同様に,大きな整数定数が関数に割り当てられたとき,または関数に渡されたときにオーバーフローするかどうかは,ホストマシンの int が 32 ビットか 64 ビットかによって異なります。
- 型なしの Go nil を表すキーワード nil 。
- 文字 '.' (ピリオド):
	.
  結果はドットの値です。
- 変数名,ドル記号のあとに英数字文字列(空かもしれない)がつきます。たとえば,
	$piOver2
  または
	$
結果は変数の値です。
変数については後述します。
- データのフィールドの名前。
	.Field
  のように,構造体のフィールドの前にピリオドを付けます。
  結果はフィールドの値です。
  フィールド呼び出しは,連鎖させることができます。
	.Field1.Field2
  フィールドは,変数上で評価することもできます。
	$x.Field1.Field2
- データ(マップ)のキーの名前。
	.Key
  のように,ピリオドの後にキー名をつけます。
  結果は,キーでインデックス付けされたマップ要素の値です。
  キーの呼び出しは,フィールドと組み合わせて任意の深さまで連鎖することができます。
	.Field1.Key1.Field2.Key2
  キーはフィールド名とは異なり,英数字の識別子でなければなりませんが,大文字で始める必要はありません。
  キーは,連鎖を含む変数上で評価することもできます。
	$x.key1.key2
- データの niladic メソッドの名前。
	.Method
  のように,ピリオドの後にメソッド名をつけます。
  結果は,ドットをレシーバとして dot.Method() を呼び出した値です。
  そのようなメソッドは, (任意の型の) 1 つの戻り値,または 2 番目の戻り値がエラーである 2 つの戻り値を持つ必要があります。
  返されたエラーが nil 以外の場合,実行は終了し, Execute の値としてエラーが呼び出し側に返されます。
  メソッド呼び出しは,連鎖させてフィールドやキーと任意の深さで組み合わせることができます。
	.Field1.Key1.Method1.Field2.Key2.Method2
  メソッドは,連鎖を含めて変数上で評価することもできます。
	$x.Method1.Field
- niladic 関数の名前。
	fun
  のように書きます。結果は,関数 fun() を呼び出した値です。
  戻り値の型と値はメソッドと同じように動作します。
  関数と関数名は以下のとおりです。
- グループ化のため,上記を括弧で囲んだもの。
  結果は,フィールドまたはマップキーの呼び出しによってアクセスできます。
	print (.F1 arg1) (.F2 arg2)
	(.StructValuedMethod "arg").Field

引数は任意の型に評価できます。 ポインタの場合,必要に応じて自動的に基本型に間接化されます。 構造体の関数値フィールドなど,評価によって関数値が得られる場合,その関数は自動的には呼び出されませんが, if アクションなどの真理値として使用できます。 それを呼び出すには,以下に定義されている call 関数を使用してください。

パイプライン

パイプラインは,連鎖している可能性のある一連の "コマンド" です。 コマンドは単純な値 (引数) ,あるいは複数の引数を持つ関数またはメソッドの呼び出しです。

引数
	結果は引数を評価した値です。
.Method [Argument...]
	メソッドは単独でもチェーンの最後の要素でもかまいませんが,
	チェーンの途中のメソッドとは異なり,引数を取ることができます。
	結果は,引数を指定してメソッドを呼び出した値です。
		dot.Method(Argument1, など)
functionName [Argument...]
	結果は,関数名に関連付けられた関数を呼び出した値です。
		function(Argument1, など)
	関数と関数名は以下のとおりです。

パイプラインは,コマンドのシーケンスをパイプライン文字 "|" で区切ることによって " 連鎖 " させることができます。 連鎖パイプラインでは,各コマンドの結果は後続のコマンドの最後の引数として渡されます。 パイプラインの最後のコマンドの出力は,パイプラインの値です。

コマンドの出力は 1 つまたは 2 つの値になり, 2 番目の値には型エラーがあります。 その 2 番目の値が存在し,それが nil 以外に評価されると,実行は終了し,エラーは Execute の呼び出し側に返されます。

変数

アクション内のパイプラインは,結果を取得するために変数を初期化することがあります。 初期化の構文は

$variable := pipeline

$variable は変数の名前です。 変数を宣言するアクションは出力を生成しません。

以前に宣言された変数は,構文を使って代入することもできます。

$variable = pipeline

"range" アクションが変数を初期化すると,その変数は反復の連続する要素に設定されます。 また, "range" は,カンマで区切られた 2 つの変数を宣言することがあります。

range $index, $element := pipeline

その場合, $index と $element は,それぞれ配列 / スライスのインデックスまたはマップキーと要素の連続した値に設定されます。 変数が 1 つしかない場合は,要素に割り当てられます。 これは, Go の範囲句の規則と反対です。

変数の有効範囲は,それが宣言されている制御構造の "end" アクション ("if" , "with" ,または "range") ,またはそのような制御構造がない場合はテンプレートの最後まで拡張されます。 テンプレート呼び出しは,その呼び出しの時点からの変数を継承しません。

実行が始まると, $ は Execute に渡されたデータ引数,つまりドットの開始値に設定されます。

以下は,パイプラインと変数を説明する 1 行のテンプレートの例です。 すべて引用符で囲まれた単語 "output" を生成します。

{{"\"output\""}}
	文字列定数
{{`"output"`}}
	生の文字列定数
{{printf "%q" "output"}}
	関数呼び出し
{{"output" | printf "%q"}}
	最後の引数が前のコマンドからのものである関数呼び出し。
{{printf "%q" (print "out" "put")}}
	括弧で囲まれた引数。
{{"put" | printf "%s%s" "out" | printf "%q"}}
	より手の込んだ呼び出し。
{{"output" | printf "%s" | printf "%q"}}
	長いチェーン
{{with "output"}}{{printf "%q" .}}{{end}}
	ドットを使った with アクション
{{with $x := "output" | printf "%q"}}{{$x}}{{end}}
	変数を作成して使用する with アクション
{{with $x := "output"}}{{printf "%q" $x}}{{end}}
	変数を別のアクションで使用する with アクション
{{with $x := "output"}}{{$x | printf "%q"}}{{end}}
	同じですが,パイプライン化されています。

関数

実行中,関数は 2 つの関数マップにあります。 最初はテンプレート内,次にグローバル関数マップです。 デフォルトでは,テンプレートに関数は定義されていませんが, Funcs メソッドを使用してそれらを追加することができます。

定義済みグローバル関数は次のように命名されています。

and
	最初の空の引数または最後の引数を返すことによって,その引数の論理積 AND を返します。
	つまり, "and x y" は, "if x then y else x" のように動作します。
	すべての引数が評価されます。
call
	call 最初の引数 (関数でなければなりません) を呼び出した結果を,残りの引数をパラメーターとして返します。
	したがって, "call .X.Y 1 2" は Go 表記では dot.X.Y(1, 2) です。
	ここで, Y は関数値フィールド,マップエントリなどです。
	最初の引数は, (print などの事前定義関数とは異なり) 関数型の値をもたらす評価の結果である必要があります。
	関数は 1 つまたは 2 つの結果値を返さなければなりません。
	そのうちの 2 番目は error 型です。
	引数が関数と一致しない場合,または返されたエラー値が nil 以外の場合,実行は停止します。
html
	引数のテキスト表現に相当するエスケープされた HTML を返します。
	この関数は,いくつかの例外を除いて, html/template では使用できません。
index
	次の引数で最初の引数にインデックスを付けた結果を返します。
	したがって, "index x 1 2 3" は Go 構文では x[1][2][3] です。
	各インデックス項目は,マップ,スライス,または配列でなければなりません。
slice
	slice returns the result of slicing its first argument by the
	remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2],
	while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3"
	is x[1:2:3]. The first argument must be a string, slice, or array.
js
	引数のテキスト表現に相当するエスケープされた JavaScript を返します。
len
	引数の整数長を返します。
not
	単一引数のブール否定を返します。
or
	最初の空でない引数または最後の引数を返すことによって,その引数の論理和を返します。
	つまり, "or x y" は, "if x then x else y" のように動作します。
	すべての引数が評価されます。
print
	fmt.Sprintf のエイリアス
printf
	fmt.Sprintf のエイリアス
println
urlquery
	printlnfmt.Sprintln のエイリアス urlquery 引数のテキスト表現のエスケープ値を URL クエリに埋め込むのに適した形式で返します。
	この関数は,いくつかの例外を除いて, html/template では使用できません。

ブール関数は,任意のゼロ値を false と見なし,ゼロ以外の値を true と見なします。

関数として定義された二項比較演算子のセットもあります。

eq
	arg1 == arg2 の真理値を返します
ne
	arg1 != arg2 の真理値を返します
lt
	arg1 < arg2 の真理値を返します
le
	arg1 <= arg2 の真理値を返します
gt
	arg1 > arg2 の真理値を返します
ge
	arg1 >= arg2 の真理値を返します

より単純な多方向等価性テストの場合, eq (only) は 2 つ以上の引数を受け入れ, 2 番目とそれ以降の引数を比較して,有効になります。

arg1==arg2 || arg1==arg3 || arg1==arg4 ...

(ただし, Go の || とは異なり, eq は関数呼び出しであり,すべての引数が評価されます。)

比較関数は基本型 (または "type Celsius float32" のような名前付き基本型) でのみ機能します。 サイズと厳密な型が無視されることを除いて,それらは値の比較のために Go の規則を実装します。 そのため,符号付きまたは符号なしの整数値は他の整数値と比較できます。 (ビットパターンではなく算術値が比較されるため,すべての負の整数はすべての符号なし整数よりも小さくなります。) ただし,通常どおり, int と float32 などを比較することはできません。

関連付けられているテンプレート

各テンプレートは,作成時に指定された文字列によって名前が付けられます。 また,各テンプレートは,名前で呼び出すことができる 0 個以上の他のテンプレートに関連付けられています。 このような関連付けは推移的であり,テンプレートの名前空間を形成します。

テンプレートは,テンプレート呼び出しを使用して別の関連テンプレートをインスタンス化することができます。 上記の "template" アクションの説明を参照してください。 名前は,呼び出しを含むテンプレートに関連付けられているテンプレートの名前である必要があります。

ネストしたテンプレート定義

テンプレートを解析するときには,別のテンプレートを定義して,解析中のテンプレートに関連付けることができます。 テンプレート定義は, Go プログラムのグローバル変数と同じように,テンプレートの最上位に表示される必要があります。

このような定義の構文は,各テンプレート宣言を "define" および "end" アクションで囲むことです。

定義アクションは,文字列定数を提供することによって作成中のテンプレートに名前を付けます。 これは簡単な例です :

`{{define "T1"}}ONE{{end}}
{{define "T2"}}TWO{{end}}
{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
{{template "T3"}}`

これは 2 つのテンプレート, T1 と T2 ,および実行時に他の 2 つを呼び出す 3 番目の T3 を定義します。 最後に T3 を起動します。 実行すると,このテンプレートはテキストを生成します

ONE TWO

構成上,テンプレートは 1 つの関連にのみ存在できます。 テンプレートを複数の関連付けからアドレス指定できるようにする必要がある場合は,テンプレート定義を複数回解析して個別の *Template 値を作成するか,または Clone メソッドまたは AddParseTree メソッドを使用してコピーする必要があります。

解析は,関連するさまざまなテンプレートを組み立てるために複数回呼び出されることがあります。 ファイルに格納されている関連テンプレートを解析する簡単な方法については, ParseFiles および ParseGlob の関数とメソッドを参照してください。

テンプレートは直接実行することも,名前で識別された関連テンプレートを実行する ExecuteTemplate を介して実行することもできます。 上記の例を呼び出すには,次のように書きます。

err := tmpl.Execute(os.Stdout, "no data needed")
if err != nil {
	log.Fatalf("execution failed: %s", err)
}

特定のテンプレートを名前で明示的に呼び出す場合

err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed")
if err != nil {
	log.Fatalf("execution failed: %s", err)
}

目次 ▾

func HTMLEscape(w io.Writer, b []byte)
func HTMLEscapeString(s string) string
func HTMLEscaper(args ...interface{}) string
func IsTrue(val interface{}) (truth, ok bool)
func JSEscape(w io.Writer, b []byte)
func JSEscapeString(s string) string
func JSEscaper(args ...interface{}) string
func URLQueryEscaper(args ...interface{}) string
type ExecError
    func (e ExecError) Error() string
    func (e ExecError) Unwrap() error
type FuncMap
type Template
    func Must(t *Template, err error) *Template
    func New(name string) *Template
    func ParseFiles(filenames ...string) (*Template, error)
    func ParseGlob(pattern string) (*Template, error)
    func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error)
    func (t *Template) Clone() (*Template, error)
    func (t *Template) DefinedTemplates() string
    func (t *Template) Delims(left, right string) *Template
    func (t *Template) Execute(wr io.Writer, data interface{}) error
    func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error
    func (t *Template) Funcs(funcMap FuncMap) *Template
    func (t *Template) Lookup(name string) *Template
    func (t *Template) Name() string
    func (t *Template) New(name string) *Template
    func (t *Template) Option(opt ...string) *Template
    func (t *Template) Parse(text string) (*Template, error)
    func (t *Template) ParseFiles(filenames ...string) (*Template, error)
    func (t *Template) ParseGlob(pattern string) (*Template, error)
    func (t *Template) Templates() []*Template

パッケージファイル

doc.go exec.go funcs.go helper.go option.go template.go

func HTMLEscape

func HTMLEscape(w io.Writer, b []byte)

HTMLEscape は,プレーンテキストデータ b に相当するエスケープ HTML を w に書き込みます。

func HTMLEscapeString

func HTMLEscapeString(s string) string

HTMLEscapeString は,プレーンテキストデータ s に相当するエスケープ HTML を返します。

func HTMLEscaper

func HTMLEscaper(args ...interface{}) string

HTMLEscaper は,引数のテキスト表現に相当するエスケープ HTML を返します。

func IsTrue 1.6

func IsTrue(val interface{}) (truth, ok bool)

IsTrue は,値がその型のゼロではないという意味で "true" であるかどうか,およびその値に意味のある真理値があるかどうかを報告します。 これは if や他のそのような行動によって使われる真理の定義です。

func JSEscape

func JSEscape(w io.Writer, b []byte)

JSEscape は,プレーンテキストデータ b と同等のエスケープされた JavaScript を w に書き込みます。

func JSEscapeString

func JSEscapeString(s string) string

JSEscapeString は,プレーンテキストデータ s に相当するエスケープされた JavaScript を返します。

func JSEscaper

func JSEscaper(args ...interface{}) string

JSEscaper は,引数のテキスト表現と同等の,エスケープされた JavaScript を返します。

func URLQueryEscaper

func URLQueryEscaper(args ...interface{}) string

URLQueryEscaper は,引数のテキスト表現のエスケープ値を URL クエリに埋め込むのに適した形式で返します。

type ExecError 1.6

ExecError は, Execute のテンプレートの評価中にエラーが発生したときに返されるカスタムエラー型です。 (書き込みエラーが発生した場合,実際のエラーが返されます。 ExcError 型にはなりません。)

type ExecError struct {
    Name string // テンプレートの名前
    Err  error  // フォーマット済みのエラーです。
}

func (ExecError) Error 1.6

func (e ExecError) Error() string

func (ExecError) Unwrap 1.13

func (e ExecError) Unwrap() error

type FuncMap

FuncMap は,名前から関数へのマッピングを定義するマップの型です。 各関数は, 1 つの戻り値,または 2 つ目の戻り値に 2 つの型エラーがあるかのいずれかでなければなりません。 その場合,実行中に 2 番目の (エラー) 戻り値が非 nil に評価されると,実行は終了し, Execute はそのエラーを返します。

テンプレートの実行が引数リストを使って関数を呼び出すとき,そのリストは関数のパラメータ型に代入可能でなければなりません。 任意の型の引数に適用することを目的とした関数は,interface{} 型または reflect.Value 型のパラメータを使用できます。 同様に,任意の型の結果を返すことを目的とした関数は,interface{} または reflect.Value を返すことができます。

type FuncMap map[string]interface{}

type Template

Template は,解析済みテンプレートの表現です。 *parse.Tree フィールドは, html/template 用にのみエクスポートされ,他のすべてのクライアントによってエクスポートされていないものとして扱われるべきです。

type Template struct {
    *parse.Tree
    // エクスポートされていないフィールドがあります
}

コード:

// テンプレートを定義します。
const letter = `
Dear {{.Name}},
{{if .Attended}}
It was a pleasure to see you at the wedding.
{{- else}}
It is a shame you couldn't make it to the wedding.
{{- end}}
{{with .Gift -}}
Thank you for the lovely {{.}}.
{{end}}
Best wishes,
Josie
`

// テンプレートに挿入するデータを準備します。
type Recipient struct {
    Name, Gift string
    Attended   bool
}
var recipients = []Recipient{
    {"Aunt Mildred", "bone china tea set", true},
    {"Uncle John", "moleskin pants", false},
    {"Cousin Rodney", "", false},
}

// 新しいテンプレートを作成し,それに letter を解析します。
t := template.Must(template.New("letter").Parse(letter))

// 各受信者に対してテンプレートを実行します。
for _, r := range recipients {
    err := t.Execute(os.Stdout, r)
    if err != nil {
        log.Println("executing template:", err)
    }
}

出力:

Dear Aunt Mildred,

It was a pleasure to see you at the wedding.
Thank you for the lovely bone china tea set.

Best wishes,
Josie

Dear Uncle John,

It is a shame you couldn't make it to the wedding.
Thank you for the lovely moleskin pants.

Best wishes,
Josie

Dear Cousin Rodney,

It is a shame you couldn't make it to the wedding.

Best wishes,
Josie

例 (Block)

コード:

const (
    master  = `Names:{{block "list" .}}{{"\n"}}{{range .}}{{println "-" .}}{{end}}{{end}}`
    overlay = `{{define "list"}} {{join . ", "}}{{end}} `
)
var (
    funcs     = template.FuncMap{"join": strings.Join}
    guardians = []string{"Gamora", "Groot", "Nebula", "Rocket", "Star-Lord"}
)
masterTmpl, err := template.New("master").Funcs(funcs).Parse(master)
if err != nil {
    log.Fatal(err)
}
overlayTmpl, err := template.Must(masterTmpl.Clone()).Parse(overlay)
if err != nil {
    log.Fatal(err)
}
if err := masterTmpl.Execute(os.Stdout, guardians); err != nil {
    log.Fatal(err)
}
if err := overlayTmpl.Execute(os.Stdout, guardians); err != nil {
    log.Fatal(err)
}

出力:

Names:
- Gamora
- Groot
- Nebula
- Rocket
- Star-Lord
Names: Gamora, Groot, Nebula, Rocket, Star-Lord

例 (Func)

この例は,テンプレートテキストを処理するカスタム関数を示しています。 strings.Title 関数をインストールし,それを使用して,テンプレートの出力でタイトルテキストを適切に表示します。

コード:

// 最初に,関数を登録する FuncMap を作成します。
funcMap := template.FuncMap{
    // "title" という名前は,テンプレートテキストで関数が呼び出される名前です。
    "title": strings.Title,
}

// 機能をテストするための簡単なテンプレート定義。入力テキストをいくつかの方法で表示します。
// - オリジナル
// - タイトルケース
// - タイトルケースしてから %q で表示する
// - %q で表示してからタイトルケースする
const templateText = `
Input: {{printf "%q" .}}
Output 0: {{title .}}
Output 1: {{title . | printf "%q"}}
Output 2: {{printf "%q" . | title}}
`

// テンプレートを作成し,関数マップを追加して,テキストを解析します。
tmpl, err := template.New("titleTest").Funcs(funcMap).Parse(templateText)
if err != nil {
    log.Fatalf("parsing: %s", err)
}

// テンプレートを実行して,出力を確認します。
err = tmpl.Execute(os.Stdout, "the go programming language")
if err != nil {
    log.Fatalf("execution: %s", err)
}

出力:

Input: "the go programming language"
Output 0: The Go Programming Language
Output 1: "The Go Programming Language"
Output 2: "The Go Programming Language"

例 (Glob)

ここでは,ディレクトリから一連のテンプレートをロードする方法を示します。

コード:

// ここで,一時ディレクトリを作成し,サンプルのテンプレート定義ファイルを作成します。通常,テンプレートファイルはプログラムで認識されている場所に既に存在します。
dir := createTestDir([]templateFile{
    // T0.tmpl は, T1 を呼び出すだけの単純なテンプレートファイルです。
    {"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},
    // T1.tmpl は, T2 を呼び出すテンプレート T1 を定義します。
    {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
    // T2.tmpl は,テンプレート T2 を定義します。
    {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
})
// テスト後にクリーンアップします。例として実行する別の癖。
defer os.RemoveAll(dir)

// pattern は,すべてのテンプレートファイルを見つけるために使用される glob パターンです。
pattern := filepath.Join(dir, "*.tmpl")

// ここから適切な例を開始します。 T0.tmpl は一致する最初の名前であるため, ParseGlob によって返される値である開始テンプレートになります。
tmpl := template.Must(template.ParseGlob(pattern))

err := tmpl.Execute(os.Stdout, nil)
if err != nil {
    log.Fatalf("template execution: %s", err)
}

出力:

T0 invokes T1: (T1 invokes T2: (This is T2))

例 (Helpers)

この例は,いくつかのテンプレートを共有し,それらを異なるコンテキストで使用する 1 つの方法を示しています。このバリアントでは,複数のドライバーテンプレートを既存のテンプレートバンドルに手動で追加します。

コード:

// ここで,一時ディレクトリを作成し,サンプルのテンプレート定義ファイルを作成します。通常,テンプレートファイルはプログラムで認識されている場所に既に存在します。
dir := createTestDir([]templateFile{
    // T1.tmpl は, T2 を呼び出すテンプレート T1 を定義します。
    {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
    // T2.tmpl は,テンプレート T2 を定義します。
    {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
})
// テスト後にクリーンアップします。例として実行する別の癖。
defer os.RemoveAll(dir)

// pattern は,すべてのテンプレートファイルを見つけるために使用される glob パターンです。
pattern := filepath.Join(dir, "*.tmpl")

// ここから適切な例を開始します。ヘルパーをロードします。
templates := template.Must(template.ParseGlob(pattern))
// 1 つのドライバーテンプレートを束に追加します。明示的なテンプレート定義でこれを行います。
_, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}")
if err != nil {
    log.Fatal("parsing driver1: ", err)
}
// 別のドライバーテンプレートを追加します。
_, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}")
if err != nil {
    log.Fatal("parsing driver2: ", err)
}
// 実行前にすべてのテンプレートをロードします。このパッケージはその動作を必要としませんが, html/template のエスケープが必要なので,良い習慣です。
err = templates.ExecuteTemplate(os.Stdout, "driver1", nil)
if err != nil {
    log.Fatalf("driver1 execution: %s", err)
}
err = templates.ExecuteTemplate(os.Stdout, "driver2", nil)
if err != nil {
    log.Fatalf("driver2 execution: %s", err)
}
// 出力 : ドライバー 1 は T1 を呼び出します : (T1 は T2 を呼び出します : (これは T2 です)) ドライバー 2 は T2 を呼び出します : (これは T2 です)

例 (Share)

この例は,ドライバーテンプレートの 1 つのグループをヘルパーテンプレートの異なるセットで使用する方法を示しています。

コード:

// ここで,一時ディレクトリを作成し,サンプルのテンプレート定義ファイルを作成します。通常,テンプレートファイルはプログラムで認識されている場所に既に存在します。
dir := createTestDir([]templateFile{
    // T0.tmpl は, T1 を呼び出すだけの単純なテンプレートファイルです。
    {"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"},
    // T1.tmpl は, T2 を呼び出すテンプレート T1 を定義します。注 T2 は定義されていません
    {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
})
// テスト後にクリーンアップします。例として実行する別の癖。
defer os.RemoveAll(dir)

// pattern は,すべてのテンプレートファイルを見つけるために使用される glob パターンです。
pattern := filepath.Join(dir, "*.tmpl")

// ここから適切な例を開始します。ドライバーをロードします。
drivers := template.Must(template.ParseGlob(pattern))

// T2 テンプレートの実装を定義する必要があります。最初にドライバーのクローンを作成してから, T2 の定義をテンプレートネームスペースに追加します。

// 1. ヘルパーセットを複製して,実行元の新しい名前空間を作成します。
first, err := drivers.Clone()
if err != nil {
    log.Fatal("cloning helpers: ", err)
}
// 2. T2 ,バージョン A を定義し,解析します。
_, err = first.Parse("{{define `T2`}}T2, version A{{end}}")
if err != nil {
    log.Fatal("parsing T2: ", err)
}

// T2 の異なるバージョンを使用して,全体を繰り返します。 1. ドライバーを複製します。
second, err := drivers.Clone()
if err != nil {
    log.Fatal("cloning drivers: ", err)
}
// 2. T2 ,バージョン B を定義し,解析します。
_, err = second.Parse("{{define `T2`}}T2, version B{{end}}")
if err != nil {
    log.Fatal("parsing T2: ", err)
}

// テンプレートを逆の順序で実行して,最初のテンプレートが 2 番目のテンプレートの影響を受けないことを確認します。
err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second")
if err != nil {
    log.Fatalf("second execution: %s", err)
}
err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first")
if err != nil {
    log.Fatalf("first: execution: %s", err)
}

出力:

T0 (second version) invokes T1: (T1 invokes T2: (T2, version B))
T0 (first version) invokes T1: (T1 invokes T2: (T2, version A))

func Must

func Must(t *Template, err error) *Template

(*Template, error) を返す関数への呼び出しをラップするヘルパーでなければならず,エラーが nil 以外であればパニックします。 次のような変数の初期化での使用を目的としています。

var t = template.Must(template.New("name").Parse("text"))

func New

func New(name string) *Template

New は,指定された名前の新しい未定義のテンプレートを割り当てます。

func ParseFiles

func ParseFiles(filenames ...string) (*Template, error)

ParseFiles は新しいテンプレートを作成し,指定されたファイルからテンプレート定義を解析します。 返されたテンプレートの名前は,最初のファイルのベース名と解析済みの内容になります。 少なくとも 1 つのファイルがなければなりません。 エラーが発生した場合,解析は停止し,返された *Template は nil です。

異なるディレクトリにある同じ名前の複数のファイルを解析する場合,最後に挙げたものが結果として得られます。 たとえば, ParseFiles("a/foo", "b/foo") は "b/foo" を "foo" という名前のテンプレートとして格納しますが, "a/foo" は使用できません。

func ParseGlob

func ParseGlob(pattern string) (*Template, error)

ParseGlob は新しいテンプレートを作成し,パターンで識別されたファイルからテンプレート定義を解析します。ファイルはファイルパス .Match のセマンティクスに従って一致し,パターンは少なくとも 1 つのファイルと一致する必要があります。返されるテンプレートには,パターンと一致する最初のファイルの (ベース) 名と (解析された) コンテンツが含まれます。 ParseGlob は,パターンに一致するファイルのリストを使用して ParseFiles を呼び出すことと同等です。

異なるディレクトリにある同じ名前の複数のファイルを解析する場合,最後に挙げたものが結果として得られます。

func (*Template) AddParseTree

func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error)

AddParseTree は与えられた名前のテンプレートの解析木を追加し,それを t と関連付けます。 テンプレートがまだ存在しない場合は,新しいテンプレートが作成されます。 テンプレートが存在する場合は置き換えられます。

func (*Template) Clone

func (t *Template) Clone() (*Template, error)

Clonse は,関連付けられているすべてのテンプレートを含むテンプレートの複製を返します。 実際の表現はコピーされませんが,関連付けられたテンプレートの名前空間はコピーされるため,コピー内でさらに Parse を呼び出すと,コピーにテンプレートが追加されますが,元のテンプレートには追加されません。 クローンは,クローン作成後にバリアントを追加することによって,一般的なテンプレートを準備し,それらを他のテンプレートのバリアント定義とともに使用するために使用できます。

func (*Template) DefinedTemplates 1.5

func (t *Template) DefinedTemplates() string

DefinedTemplates は,定義済みのテンプレートをリストした文字列の先頭に "; defined templates are: " という文字列を付けたものを返します。 何もない場合は,空の文字列を返します。 ここと html/template でエラーメッセージを生成します。

func (*Template) Delims

func (t *Template) Delims(left, right string) *Template

Delims は,その後の Parse, ParseFiles ,または ParseGlob の呼び出しで使用されるアクション区切り文字を指定された文字列に設定します。 ネストしたテンプレート定義は設定を継承します。 空の区切り文字は,対応するデフォルトの {{ または }} を表します。 戻り値はテンプレートなので,呼び出しは連鎖できます。

func (*Template) Execute

func (t *Template) Execute(wr io.Writer, data interface{}) error

Execute は,解析されたテンプレートを指定されたデータオブジェクトに適用し,その出力を wr に書き込みます。 テンプレートの実行中またはその出力の書き込み中にエラーが発生した場合,実行は停止しますが,部分的な結果はすでに出力ライターに書き込まれている可能性があります。 並列実行が Writer を共有する場合,出力はインターリーブされますが,テンプレートは安全に並列実行されます。

データが reflect.Value の場合, fmt.Print のように,テンプレートは reflect.Value が保持する具象値に適用されます。

func (*Template) ExecuteTemplate

func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error

ExecuteTemplate は,指定された名前を持つ t に関連付けられたテンプレートを指定されたデータオブジェクトに適用し,出力を wr に書き込みます。 テンプレートの実行中またはその出力の書き込み中にエラーが発生した場合,実行は停止しますが,部分的な結果はすでに出力ライターに書き込まれている可能性があります。 並列実行が Writer を共有する場合,出力はインターリーブされますが,テンプレートは安全に並列実行されます。

func (*Template) Funcs

func (t *Template) Funcs(funcMap FuncMap) *Template

Funcs は引数マップの要素をテンプレートの関数マップに追加します。 テンプレートが解析される前に呼び出されなければなりません。 マップ内の値が適切な戻り型の関数ではない場合,または名前をテンプレート内の関数として構文的に使用できない場合は,パニックが発生します。 マップの要素を上書きすることは合法です。 戻り値はテンプレートなので,呼び出しは連鎖できます。

func (*Template) Lookup

func (t *Template) Lookup(name string) *Template

Lookup は, t に関連付けられている指定の名前のテンプレートを返します。 そのようなテンプレートがない場合,またはテンプレートに定義がない場合は nil を返します。

func (*Template) Name

func (t *Template) Name() string

Name はテンプレートの名前を返します。

func (*Template) New

func (t *Template) New(name string) *Template

New は,指定されたテンプレートと同じ区切り文字で関連付けられた新しい未定義のテンプレートを割り当てます。 推移的な関連付けにより, 1 つのテンプレートが {{template}} アクションを使用して別のテンプレートを呼び出すことができます。

関連するテンプレートは内部のデータを共有するため,テンプレートの構築を安全に並行して行うことはできません。テンプレートが作成されると,それらを並行して実行できます。

func (*Template) Option 1.5

func (t *Template) Option(opt ...string) *Template

Option はテンプレートのオプションを設定します。 オプションは単純な文字列か "key=value" のどちらかの文字列で記述されます。 オプション文字列には,最大で 1 つの等号を含めることができます。 オプション文字列が認識されない,または無効な場合, Option はパニックします。

既知のオプション :

missingkey: マップがマップに存在しないキーでインデックス付けされている場合の実行中の動作を制御します。

"missingkey=default" または "missingkey=invalid"
	デフォルトの動作: 何もしないで実行を続行します。
	表示された場合,インデックス操作の結果は文字列 "<no value>" です。
"missingkey=zero"
	操作はマップ型の要素のゼロ値を返します。
"missingkey=error"
	実行はエラーで直ちに停止します。

func (*Template) Parse

func (t *Template) Parse(text string) (*Template, error)

Parse は,テキストを t のテンプレート本体として解析します。 テキスト内の名前付きテンプレート定義 ({{define ...}} または {{block ...}} ステートメント) は, t に関連する追加のテンプレートを定義し, t の定義から削除されます。

Parse を連続して呼び出すと,テンプレートを再定義できます。 空白とコメントのみを含むボディを持つテンプレート定義は空と見なされ,既存のテンプレートのボディを置き換えることはありません。 これにより, Parse を使用して,メインのテンプレート本体を上書きせずに新しい名前付きテンプレート定義を追加できます。

func (*Template) ParseFiles

func (t *Template) ParseFiles(filenames ...string) (*Template, error)

ParseFiles は名前付きファイルを解析し,結果のテンプレートを t に関連付けます。 エラーが発生した場合,解析は停止し,返されたテンプレートは nil です。 それ以外の場合は t です。 少なくとも 1 つのファイルがなければなりません。 ParseFiles によって作成されたテンプレートは引数ファイルのベース名で命名されるので, t は通常ファイルの (ベース) 名の 1 つの名前を持つべきです。 そうでない場合, ParseFiles を呼び出す前の t の内容によっては, t.Execute が失敗する可能性があります。 その場合は, t.ExecuteTemplate を使用して有効なテンプレートを実行してください。

異なるディレクトリにある同じ名前の複数のファイルを解析する場合,最後に挙げたものが結果として得られます。

func (*Template) ParseGlob

func (t *Template) ParseGlob(pattern string) (*Template, error)

ParseGlob は,パターンによって識別されたファイル内のテンプレート定義を解析し,結果のテンプレートを t に関連付けます。ファイルはファイルパス .Match のセマンティクスに従って一致し,パターンは少なくとも 1 つのファイルと一致する必要があります。 ParseGlob は,パターンに一致するファイルのリストを指定して t.ParseFiles を呼び出すことと同等です。

異なるディレクトリにある同じ名前の複数のファイルを解析する場合,最後に挙げたものが結果として得られます。

func (*Template) Templates

func (t *Template) Templates() []*Template

Templates は, t に関連付けられた定義済みテンプレートのスライスを返します。

サブディレクトリ

名前 概要
..
parse parse パッケージは,text/template と html/template で定義されたテンプレートのパース木を構築します。