github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/text/template/examplefiles_test.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package template_test 6 7 import ( 8 "github.com/shogo82148/std/log" 9 "github.com/shogo82148/std/os" 10 "github.com/shogo82148/std/path/filepath" 11 "github.com/shogo82148/std/text/template" 12 ) 13 14 // ここでは、ディレクトリから一連のテンプレートをロードする方法を示します。 15 func ExampleTemplate_glob() { 16 // ここでは、一時的なディレクトリを作成し、それをサンプルの 17 // テンプレート定義ファイルで満たします。通常、テンプレートファイルはすでに 18 // プログラムが知っている何らかの場所に存在します。 19 dir := createTestDir([]templateFile{ 20 // T0.tmplは、単にT1を呼び出すプレーンなテンプレートファイルです。 21 {"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`}, 22 // T1.tmplは、T2を呼び出すテンプレート、T1を定義します。 23 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`}, 24 // T2.tmplは、テンプレートT2を定義します。 25 {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`}, 26 }) 27 // テスト後のクリーンアップ;これも例として実行する際の特性です。 28 defer os.RemoveAll(dir) 29 30 // patternは、すべてのテンプレートファイルを見つけるために使用されるglobパターンです。 31 pattern := filepath.Join(dir, "*.tmpl") 32 33 // ここからが実際の例です。 34 // T0.tmplは最初にマッチした名前なので、それが開始テンプレートとなり、 35 // ParseGlobによって返される値となります。 36 tmpl := template.Must(template.ParseGlob(pattern)) 37 38 err := tmpl.Execute(os.Stdout, nil) 39 if err != nil { 40 log.Fatalf("template execution: %s", err) 41 } 42 // Output: 43 // T0 invokes T1: (T1 invokes T2: (This is T2)) 44 } 45 46 // この例は、いくつかのテンプレートを共有し、それらを異なるコンテキストで 47 // 使用する一つの方法を示しています。このバリアントでは、既存のテンプレートの 48 // バンドルに手動で複数のドライバーテンプレートを追加します。 49 func ExampleTemplate_helpers() { 50 // ここでは、一時的なディレクトリを作成し、それをサンプルの 51 // テンプレート定義ファイルで満たします。通常、テンプレートファイルはすでに 52 // プログラムが知っている何らかの場所に存在します。 53 dir := createTestDir([]templateFile{ 54 // T1.tmplは、T2を呼び出すテンプレート、T1を定義します。 55 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`}, 56 // T2.tmplは、テンプレートT2を定義します。 57 {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`}, 58 }) 59 // テスト後のクリーンアップ;これも例として実行する際の特性です。 60 defer os.RemoveAll(dir) 61 62 // patternは、すべてのテンプレートファイルを見つけるために使用されるglobパターンです。 63 pattern := filepath.Join(dir, "*.tmpl") 64 65 // ここからが実際の例です。 66 // ヘルパーをロードします。 67 templates := template.Must(template.ParseGlob(pattern)) 68 // 明示的なテンプレート定義を使用して、一連のテンプレートに一つのドライバーテンプレートを追加します。 69 _, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}") 70 if err != nil { 71 log.Fatal("parsing driver1: ", err) 72 } 73 // 別のドライバーテンプレートを追加します。 74 _, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}") 75 if err != nil { 76 log.Fatal("parsing driver2: ", err) 77 } 78 // 実行前にすべてのテンプレートをロードします。このパッケージはそのような振る舞いを 79 // 必要としませんが、html/templateのエスケープ処理はそれを必要とするので、それは良い習慣です。 80 err = templates.ExecuteTemplate(os.Stdout, "driver1", nil) 81 if err != nil { 82 log.Fatalf("driver1 execution: %s", err) 83 } 84 err = templates.ExecuteTemplate(os.Stdout, "driver2", nil) 85 if err != nil { 86 log.Fatalf("driver2 execution: %s", err) 87 } 88 // Output: 89 // Driver 1 calls T1: (T1 invokes T2: (This is T2)) 90 // Driver 2 calls T2: (This is T2) 91 } 92 93 // この例は、一つのグループのドライバーテンプレートを、異なるセットのヘルパーテンプレートと 94 // どのように使用するかを示しています。 95 func ExampleTemplate_share() { 96 // ここでは、一時的なディレクトリを作成し、それをサンプルの 97 // テンプレート定義ファイルで満たします。通常、テンプレートファイルはすでに 98 // プログラムが知っている何らかの場所に存在します。 99 dir := createTestDir([]templateFile{ 100 // T0.tmplは、単にT1を呼び出すプレーンなテンプレートファイルです。 101 {"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"}, 102 // T1.tmplは、T2を呼び出すテンプレート、T1を定義します。注意:T2は定義されていません 103 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`}, 104 }) 105 // テスト後のクリーンアップ;これも例として実行する際の特性です。 106 defer os.RemoveAll(dir) 107 108 // patternは、すべてのテンプレートファイルを見つけるために使用されるglobパターンです。 109 pattern := filepath.Join(dir, "*.tmpl") 110 111 // ここからが実際の例です。 112 // ドライバーをロードします。 113 drivers := template.Must(template.ParseGlob(pattern)) 114 115 // 我々はT2テンプレートの実装を定義しなければなりません。まず、 116 // ドライバーをクローンし、その後、テンプレート名前空間にT2の定義を追加します。 117 118 // 1. ヘルパーセットをクローンして、それらを実行するための新しい名前空間を作成します。 119 first, err := drivers.Clone() 120 if err != nil { 121 log.Fatal("cloning helpers: ", err) 122 } 123 // 2. T2、バージョンAを定義し、解析します。 124 _, err = first.Parse("{{define `T2`}}T2, version A{{end}}") 125 if err != nil { 126 log.Fatal("parsing T2: ", err) 127 } 128 129 // 今度は全体を繰り返しますが、T2の別のバージョンを使用します。 130 // 1. ドライバーをクローンします。 131 second, err := drivers.Clone() 132 if err != nil { 133 log.Fatal("cloning drivers: ", err) 134 } 135 // 2. T2、バージョンBを定義し、解析します。 136 _, err = second.Parse("{{define `T2`}}T2, version B{{end}}") 137 if err != nil { 138 log.Fatal("parsing T2: ", err) 139 } 140 141 // テンプレートを逆の順序で実行して、 142 // 最初のものが二番目のものに影響を受けないことを確認します。 143 err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second") 144 if err != nil { 145 log.Fatalf("second execution: %s", err) 146 } 147 err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first") 148 if err != nil { 149 log.Fatalf("first: execution: %s", err) 150 } 151 152 // Output: 153 // T0 (second version) invokes T1: (T1 invokes T2: (T2, version B)) 154 // T0 (first version) invokes T1: (T1 invokes T2: (T2, version A)) 155 }