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  }