examplefiles_test.go - hugo - [fork] hugo port for 9front
 (HTM) git clone https://git.drkhsh.at/hugo.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       examplefiles_test.go (7726B)
       ---
            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 //go:build go1.13
            6 // +build go1.13
            7 
            8 package template_test
            9 
           10 import (
           11         "io"
           12         "log"
           13         "os"
           14         "path/filepath"
           15 
           16         template "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate"
           17 )
           18 
           19 // templateFile defines the contents of a template to be stored in a file, for testing.
           20 type templateFile struct {
           21         name     string
           22         contents string
           23 }
           24 
           25 func createTestDir(files []templateFile) string {
           26         dir, err := os.MkdirTemp("", "template")
           27         if err != nil {
           28                 log.Fatal(err)
           29         }
           30         for _, file := range files {
           31                 f, err := os.Create(filepath.Join(dir, file.name))
           32                 if err != nil {
           33                         log.Fatal(err)
           34                 }
           35                 defer f.Close()
           36                 _, err = io.WriteString(f, file.contents)
           37                 if err != nil {
           38                         log.Fatal(err)
           39                 }
           40         }
           41         return dir
           42 }
           43 
           44 // The following example is duplicated in text/template; keep them in sync.
           45 
           46 // Here we demonstrate loading a set of templates from a directory.
           47 func ExampleTemplate_glob() {
           48         // Here we create a temporary directory and populate it with our sample
           49         // template definition files; usually the template files would already
           50         // exist in some location known to the program.
           51         dir := createTestDir([]templateFile{
           52                 // T0.tmpl is a plain template file that just invokes T1.
           53                 {"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},
           54                 // T1.tmpl defines a template, T1 that invokes T2.
           55                 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
           56                 // T2.tmpl defines a template T2.
           57                 {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
           58         })
           59         // Clean up after the test; another quirk of running as an example.
           60         defer os.RemoveAll(dir)
           61 
           62         // pattern is the glob pattern used to find all the template files.
           63         pattern := filepath.Join(dir, "*.tmpl")
           64 
           65         // Here starts the example proper.
           66         // T0.tmpl is the first name matched, so it becomes the starting template,
           67         // the value returned by ParseGlob.
           68         tmpl := template.Must(template.ParseGlob(pattern))
           69 
           70         err := tmpl.Execute(os.Stdout, nil)
           71         if err != nil {
           72                 log.Fatalf("template execution: %s", err)
           73         }
           74         // Output:
           75         // T0 invokes T1: (T1 invokes T2: (This is T2))
           76 }
           77 
           78 // Here we demonstrate loading a set of templates from files in different directories
           79 func ExampleTemplate_parsefiles() {
           80         // Here we create different temporary directories and populate them with our sample
           81         // template definition files; usually the template files would already
           82         // exist in some location known to the program.
           83         dir1 := createTestDir([]templateFile{
           84                 // T1.tmpl is a plain template file that just invokes T2.
           85                 {"T1.tmpl", `T1 invokes T2: ({{template "T2"}})`},
           86         })
           87 
           88         dir2 := createTestDir([]templateFile{
           89                 // T2.tmpl defines a template T2.
           90                 {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
           91         })
           92 
           93         // Clean up after the test; another quirk of running as an example.
           94         defer func(dirs ...string) {
           95                 for _, dir := range dirs {
           96                         os.RemoveAll(dir)
           97                 }
           98         }(dir1, dir2)
           99 
          100         // Here starts the example proper.
          101         // Let's just parse only dir1/T0 and dir2/T2
          102         paths := []string{
          103                 filepath.Join(dir1, "T1.tmpl"),
          104                 filepath.Join(dir2, "T2.tmpl"),
          105         }
          106         tmpl := template.Must(template.ParseFiles(paths...))
          107 
          108         err := tmpl.Execute(os.Stdout, nil)
          109         if err != nil {
          110                 log.Fatalf("template execution: %s", err)
          111         }
          112         // Output:
          113         // T1 invokes T2: (This is T2)
          114 }
          115 
          116 // The following example is duplicated in text/template; keep them in sync.
          117 
          118 // This example demonstrates one way to share some templates
          119 // and use them in different contexts. In this variant we add multiple driver
          120 // templates by hand to an existing bundle of templates.
          121 func ExampleTemplate_helpers() {
          122         // Here we create a temporary directory and populate it with our sample
          123         // template definition files; usually the template files would already
          124         // exist in some location known to the program.
          125         dir := createTestDir([]templateFile{
          126                 // T1.tmpl defines a template, T1 that invokes T2.
          127                 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
          128                 // T2.tmpl defines a template T2.
          129                 {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
          130         })
          131         // Clean up after the test; another quirk of running as an example.
          132         defer os.RemoveAll(dir)
          133 
          134         // pattern is the glob pattern used to find all the template files.
          135         pattern := filepath.Join(dir, "*.tmpl")
          136 
          137         // Here starts the example proper.
          138         // Load the helpers.
          139         templates := template.Must(template.ParseGlob(pattern))
          140         // Add one driver template to the bunch; we do this with an explicit template definition.
          141         _, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}")
          142         if err != nil {
          143                 log.Fatal("parsing driver1: ", err)
          144         }
          145         // Add another driver template.
          146         _, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}")
          147         if err != nil {
          148                 log.Fatal("parsing driver2: ", err)
          149         }
          150         // We load all the templates before execution. This package does not require
          151         // that behavior but html/template's escaping does, so it's a good habit.
          152         err = templates.ExecuteTemplate(os.Stdout, "driver1", nil)
          153         if err != nil {
          154                 log.Fatalf("driver1 execution: %s", err)
          155         }
          156         err = templates.ExecuteTemplate(os.Stdout, "driver2", nil)
          157         if err != nil {
          158                 log.Fatalf("driver2 execution: %s", err)
          159         }
          160         // Output:
          161         // Driver 1 calls T1: (T1 invokes T2: (This is T2))
          162         // Driver 2 calls T2: (This is T2)
          163 }
          164 
          165 // The following example is duplicated in text/template; keep them in sync.
          166 
          167 // This example demonstrates how to use one group of driver
          168 // templates with distinct sets of helper templates.
          169 func ExampleTemplate_share() {
          170         // Here we create a temporary directory and populate it with our sample
          171         // template definition files; usually the template files would already
          172         // exist in some location known to the program.
          173         dir := createTestDir([]templateFile{
          174                 // T0.tmpl is a plain template file that just invokes T1.
          175                 {"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"},
          176                 // T1.tmpl defines a template, T1 that invokes T2. Note T2 is not defined
          177                 {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
          178         })
          179         // Clean up after the test; another quirk of running as an example.
          180         defer os.RemoveAll(dir)
          181 
          182         // pattern is the glob pattern used to find all the template files.
          183         pattern := filepath.Join(dir, "*.tmpl")
          184 
          185         // Here starts the example proper.
          186         // Load the drivers.
          187         drivers := template.Must(template.ParseGlob(pattern))
          188 
          189         // We must define an implementation of the T2 template. First we clone
          190         // the drivers, then add a definition of T2 to the template name space.
          191 
          192         // 1. Clone the helper set to create a new name space from which to run them.
          193         first, err := drivers.Clone()
          194         if err != nil {
          195                 log.Fatal("cloning helpers: ", err)
          196         }
          197         // 2. Define T2, version A, and parse it.
          198         _, err = first.Parse("{{define `T2`}}T2, version A{{end}}")
          199         if err != nil {
          200                 log.Fatal("parsing T2: ", err)
          201         }
          202 
          203         // Now repeat the whole thing, using a different version of T2.
          204         // 1. Clone the drivers.
          205         second, err := drivers.Clone()
          206         if err != nil {
          207                 log.Fatal("cloning drivers: ", err)
          208         }
          209         // 2. Define T2, version B, and parse it.
          210         _, err = second.Parse("{{define `T2`}}T2, version B{{end}}")
          211         if err != nil {
          212                 log.Fatal("parsing T2: ", err)
          213         }
          214 
          215         // Execute the templates in the reverse order to verify the
          216         // first is unaffected by the second.
          217         err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second")
          218         if err != nil {
          219                 log.Fatalf("second execution: %s", err)
          220         }
          221         err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first")
          222         if err != nil {
          223                 log.Fatalf("first: execution: %s", err)
          224         }
          225 
          226         // Output:
          227         // T0 (second version) invokes T1: (T1 invokes T2: (T2, version B))
          228         // T0 (first version) invokes T1: (T1 invokes T2: (T2, version A))
          229 }