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  }