hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

examplefiles_test.go (6274B)

    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 //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 	"text/template"
   16 )
   17 
   18 // templateFile defines the contents of a template to be stored in a file, for testing.
   19 type templateFile struct {
   20 	name     string
   21 	contents string
   22 }
   23 
   24 func createTestDir(files []templateFile) string {
   25 	dir, err := os.MkdirTemp("", "template")
   26 	if err != nil {
   27 		log.Fatal(err)
   28 	}
   29 	for _, file := range files {
   30 		f, err := os.Create(filepath.Join(dir, file.name))
   31 		if err != nil {
   32 			log.Fatal(err)
   33 		}
   34 		defer f.Close()
   35 		_, err = io.WriteString(f, file.contents)
   36 		if err != nil {
   37 			log.Fatal(err)
   38 		}
   39 	}
   40 	return dir
   41 }
   42 
   43 // Here we demonstrate loading a set of templates from a directory.
   44 func ExampleTemplate_glob() {
   45 	// Here we create a temporary directory and populate it with our sample
   46 	// template definition files; usually the template files would already
   47 	// exist in some location known to the program.
   48 	dir := createTestDir([]templateFile{
   49 		// T0.tmpl is a plain template file that just invokes T1.
   50 		{"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},
   51 		// T1.tmpl defines a template, T1 that invokes T2.
   52 		{"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
   53 		// T2.tmpl defines a template T2.
   54 		{"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
   55 	})
   56 	// Clean up after the test; another quirk of running as an example.
   57 	defer os.RemoveAll(dir)
   58 
   59 	// pattern is the glob pattern used to find all the template files.
   60 	pattern := filepath.Join(dir, "*.tmpl")
   61 
   62 	// Here starts the example proper.
   63 	// T0.tmpl is the first name matched, so it becomes the starting template,
   64 	// the value returned by ParseGlob.
   65 	tmpl := template.Must(template.ParseGlob(pattern))
   66 
   67 	err := tmpl.Execute(os.Stdout, nil)
   68 	if err != nil {
   69 		log.Fatalf("template execution: %s", err)
   70 	}
   71 	// Output:
   72 	// T0 invokes T1: (T1 invokes T2: (This is T2))
   73 }
   74 
   75 // This example demonstrates one way to share some templates
   76 // and use them in different contexts. In this variant we add multiple driver
   77 // templates by hand to an existing bundle of templates.
   78 func ExampleTemplate_helpers() {
   79 	// Here we create a temporary directory and populate it with our sample
   80 	// template definition files; usually the template files would already
   81 	// exist in some location known to the program.
   82 	dir := createTestDir([]templateFile{
   83 		// T1.tmpl defines a template, T1 that invokes T2.
   84 		{"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
   85 		// T2.tmpl defines a template T2.
   86 		{"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
   87 	})
   88 	// Clean up after the test; another quirk of running as an example.
   89 	defer os.RemoveAll(dir)
   90 
   91 	// pattern is the glob pattern used to find all the template files.
   92 	pattern := filepath.Join(dir, "*.tmpl")
   93 
   94 	// Here starts the example proper.
   95 	// Load the helpers.
   96 	templates := template.Must(template.ParseGlob(pattern))
   97 	// Add one driver template to the bunch; we do this with an explicit template definition.
   98 	_, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}")
   99 	if err != nil {
  100 		log.Fatal("parsing driver1: ", err)
  101 	}
  102 	// Add another driver template.
  103 	_, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}")
  104 	if err != nil {
  105 		log.Fatal("parsing driver2: ", err)
  106 	}
  107 	// We load all the templates before execution. This package does not require
  108 	// that behavior but html/template's escaping does, so it's a good habit.
  109 	err = templates.ExecuteTemplate(os.Stdout, "driver1", nil)
  110 	if err != nil {
  111 		log.Fatalf("driver1 execution: %s", err)
  112 	}
  113 	err = templates.ExecuteTemplate(os.Stdout, "driver2", nil)
  114 	if err != nil {
  115 		log.Fatalf("driver2 execution: %s", err)
  116 	}
  117 	// Output:
  118 	// Driver 1 calls T1: (T1 invokes T2: (This is T2))
  119 	// Driver 2 calls T2: (This is T2)
  120 }
  121 
  122 // This example demonstrates how to use one group of driver
  123 // templates with distinct sets of helper templates.
  124 func ExampleTemplate_share() {
  125 	// Here we create a temporary directory and populate it with our sample
  126 	// template definition files; usually the template files would already
  127 	// exist in some location known to the program.
  128 	dir := createTestDir([]templateFile{
  129 		// T0.tmpl is a plain template file that just invokes T1.
  130 		{"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"},
  131 		// T1.tmpl defines a template, T1 that invokes T2. Note T2 is not defined
  132 		{"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
  133 	})
  134 	// Clean up after the test; another quirk of running as an example.
  135 	defer os.RemoveAll(dir)
  136 
  137 	// pattern is the glob pattern used to find all the template files.
  138 	pattern := filepath.Join(dir, "*.tmpl")
  139 
  140 	// Here starts the example proper.
  141 	// Load the drivers.
  142 	drivers := template.Must(template.ParseGlob(pattern))
  143 
  144 	// We must define an implementation of the T2 template. First we clone
  145 	// the drivers, then add a definition of T2 to the template name space.
  146 
  147 	// 1. Clone the helper set to create a new name space from which to run them.
  148 	first, err := drivers.Clone()
  149 	if err != nil {
  150 		log.Fatal("cloning helpers: ", err)
  151 	}
  152 	// 2. Define T2, version A, and parse it.
  153 	_, err = first.Parse("{{define `T2`}}T2, version A{{end}}")
  154 	if err != nil {
  155 		log.Fatal("parsing T2: ", err)
  156 	}
  157 
  158 	// Now repeat the whole thing, using a different version of T2.
  159 	// 1. Clone the drivers.
  160 	second, err := drivers.Clone()
  161 	if err != nil {
  162 		log.Fatal("cloning drivers: ", err)
  163 	}
  164 	// 2. Define T2, version B, and parse it.
  165 	_, err = second.Parse("{{define `T2`}}T2, version B{{end}}")
  166 	if err != nil {
  167 		log.Fatal("parsing T2: ", err)
  168 	}
  169 
  170 	// Execute the templates in the reverse order to verify the
  171 	// first is unaffected by the second.
  172 	err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second")
  173 	if err != nil {
  174 		log.Fatalf("second execution: %s", err)
  175 	}
  176 	err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first")
  177 	if err != nil {
  178 		log.Fatalf("first: execution: %s", err)
  179 	}
  180 
  181 	// Output:
  182 	// T0 (second version) invokes T1: (T1 invokes T2: (T2, version B))
  183 	// T0 (first version) invokes T1: (T1 invokes T2: (T2, version A))
  184 }