github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/html/template/examplefiles_test.go (about) 1 // Copyright 2016 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は、すべてのテンプレートファイルを見つけるために使用されるグロブパターンです。 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 func ExampleTemplate_parsefiles() { 48 // ここでは、異なる一時ディレクトリを作成し、それらをサンプルの 49 // テンプレート定義ファイルで満たします。通常、テンプレートファイルはすでに 50 // プログラムが知っている何らかの場所に存在します。 51 dir1 := createTestDir([]templateFile{ 52 // T1.tmplは、単にT2を呼び出すだけのプレーンなテンプレートファイルです。 53 {"T1.tmpl", `T1 invokes T2: ({{template "T2"}})`}, 54 }) 55 56 dir2 := createTestDir([]templateFile{ 57 // T2.tmplは、テンプレートT2を定義します。 58 {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`}, 59 }) 60 61 // テストの後片付けをします。これも例として実行する際の特性です。 62 defer func(dirs ...string) { 63 for _, dir := range dirs { 64 os.RemoveAll(dir) 65 } 66 }(dir1, dir2) 67 68 // ここからが実際の例です。 69 // dir1/T0とdir2/T2だけをパースしましょう 70 paths := []string{ 71 filepath.Join(dir1, "T1.tmpl"), 72 filepath.Join(dir2, "T2.tmpl"), 73 } 74 tmpl := template.Must(template.ParseFiles(paths...)) 75 76 err := tmpl.Execute(os.Stdout, nil) 77 if err != nil { 78 log.Fatalf("template execution: %s", err) 79 } 80 // Output: 81 // T1 invokes T2: (This is T2) 82 } 83 84 // この例では、いくつかのテンプレートを共有し、それらを異なるコンテキストで使用する方法を示しています。 85 // このバリアントでは、既存のテンプレートバンドルに手動で複数のドライバーテンプレートを追加します。 86 func ExampleTemplate_helpers() { 87 // ここでは、一時ディレクトリを作成し、それをサンプルの 88 // テンプレート定義ファイルで満たします。通常、テンプレートファイルはすでに 89 // プログラムが知っている何らかの場所に存在します。 90 dir := createTestDir([]templateFile{ 91 // T1.tmplは、T2を呼び出すテンプレート、T1を定義します。 92 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`}, 93 // T2.tmplは、テンプレートT2を定義します。 94 {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`}, 95 }) 96 // テストの後片付けをします。これも例として実行する際の特性です。 97 defer os.RemoveAll(dir) 98 99 // patternは、すべてのテンプレートファイルを見つけるために使用されるグロブパターンです。 100 pattern := filepath.Join(dir, "*.tmpl") 101 102 // ここからが実際の例です。 103 // ヘルパーをロードします。 104 templates := template.Must(template.ParseGlob(pattern)) 105 // 明示的なテンプレート定義を使用して、一連のテンプレートに1つのドライバーテンプレートを追加します。 106 _, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}") 107 if err != nil { 108 log.Fatal("parsing driver1: ", err) 109 } 110 // 別のドライバーテンプレートを追加します。 111 _, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}") 112 if err != nil { 113 log.Fatal("parsing driver2: ", err) 114 } 115 // 実行前にすべてのテンプレートをロードします。このパッケージはそのような振る舞いを必要としませんが、 116 // html/templateのエスケープはそれを必要とするので、それは良い習慣です。 117 err = templates.ExecuteTemplate(os.Stdout, "driver1", nil) 118 if err != nil { 119 log.Fatalf("driver1 execution: %s", err) 120 } 121 err = templates.ExecuteTemplate(os.Stdout, "driver2", nil) 122 if err != nil { 123 log.Fatalf("driver2 execution: %s", err) 124 } 125 // Output: 126 // Driver 1 calls T1: (T1 invokes T2: (This is T2)) 127 // Driver 2 calls T2: (This is T2) 128 } 129 130 // この例では、一連のヘルパーテンプレートと異なる一連のヘルパーテンプレートを使用して、 131 // 一つのグループのドライバーテンプレートを使用する方法を示しています。 132 func ExampleTemplate_share() { 133 // ここでは、一時ディレクトリを作成し、それをサンプルの 134 // テンプレート定義ファイルで満たします。通常、テンプレートファイルはすでに 135 // プログラムが知っている何らかの場所に存在します。 136 dir := createTestDir([]templateFile{ 137 // T0.tmplは、単にT1を呼び出すだけのプレーンなテンプレートファイルです。 138 {"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"}, 139 // T1.tmplは、T2を呼び出すテンプレート、T1を定義します。T2は定義されていないことに注意してください。 140 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`}, 141 }) 142 // テストの後片付けをします。これも例として実行する際の特性です。 143 defer os.RemoveAll(dir) 144 145 // patternは、すべてのテンプレートファイルを見つけるために使用されるグロブパターンです。 146 pattern := filepath.Join(dir, "*.tmpl") 147 148 // ここからが実際の例です。 149 // ドライバーをロードします。 150 drivers := template.Must(template.ParseGlob(pattern)) 151 152 // T2テンプレートの実装を定義する必要があります。まず、ドライバーをクローンし、 153 // 次にT2の定義をテンプレート名前空間に追加します。 154 155 // 1. ヘルパーセットをクローンして、それらを実行するための新しい名前空間を作成します。 156 first, err := drivers.Clone() 157 if err != nil { 158 log.Fatal("cloning helpers: ", err) 159 } 160 // 2. T2のバージョンAを定義し、それを解析します。 161 _, err = first.Parse("{{define `T2`}}T2, version A{{end}}") 162 if err != nil { 163 log.Fatal("parsing T2: ", err) 164 } 165 166 // 今度は、T2の別のバージョンを使用して、全体を繰り返します。 167 // 1. ドライバーをクローンします。 168 second, err := drivers.Clone() 169 if err != nil { 170 log.Fatal("cloning drivers: ", err) 171 } 172 // 2. Define T2, version B, and parse it. 173 _, err = second.Parse("{{define `T2`}}T2, version B{{end}}") 174 if err != nil { 175 log.Fatal("parsing T2: ", err) 176 } 177 178 // テンプレートを逆の順序で実行して、 179 // 最初のテンプレートが2番目のテンプレートに影響されないことを確認します。 180 err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second") 181 if err != nil { 182 log.Fatalf("second execution: %s", err) 183 } 184 err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first") 185 if err != nil { 186 log.Fatalf("first: execution: %s", err) 187 } 188 189 // Output: 190 // T0 (second version) invokes T1: (T1 invokes T2: (T2, version B)) 191 // T0 (first version) invokes T1: (T1 invokes T2: (T2, version A)) 192 }