How to do it...

These steps cover how to write and run your application:

  1. From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter1/templates.
  2. Navigate to this directory.
  1. Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter1/templates

You should see a file called go.mod that contains the following content:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter1/templates    
  1. Copy the tests from ~/projects/go-programming-cookbook-original/chapter1/templates or use this as an exercise to write some of your own code!
  2. Create a file called templates.go with the following contents:
        package templates

import (
"os"
"strings"
"text/template"
)

const sampleTemplate = `
This template demonstrates printing a {{ .Variable |
printf "%#v" }}.

{{if .Condition}}
If condition is set, we'll print this
{{else}}
Otherwise, we'll print this instead
{{end}}

Next we'll iterate over an array of strings:
{{range $index, $item := .Items}}
{{$index}}: {{$item}}
{{end}}

We can also easily import other functions like
strings.Split
then immediately used the array created as a result:
{{ range $index, $item := split .Words ","}}
{{$index}}: {{$item}}
{{end}}

Blocks are a way to embed templates into one another
{{ block "block_example" .}}
No Block defined!
{{end}}


{{/*
This is a way
to insert a multi-line comment
*/}}
`

const secondTemplate = `
{{ define "block_example" }}
{{.OtherVariable}}
{{end}}
`
  1. Add a function to the end of templates.go, as follows: 
        // RunTemplate initializes a template and demonstrates a 
// variety of template helper functions
func RunTemplate() error {
data := struct {
Condition bool
Variable string
Items []string
Words string
OtherVariable string
}{
Condition: true,
Variable: "variable",
Items: []string{"item1", "item2", "item3"},
Words:
"another_item1,another_item2,another_item3",
OtherVariable: "I'm defined in a second
template!",
}

funcmap := template.FuncMap{
"split": strings.Split,
}

// these can also be chained
t := template.New("example")
t = t.Funcs(funcmap)

// We could use Must instead to panic on error
// template.Must(t.Parse(sampleTemplate))
t, err := t.Parse(sampleTemplate)
if err != nil {
return err
}

// to demonstrate blocks we'll create another template
// by cloning the first template, then parsing a second
t2, err := t.Clone()
if err != nil {
return err
}

t2, err = t2.Parse(secondTemplate)
if err != nil {
return err
}

// write the template to stdout and populate it
// with data
err = t2.Execute(os.Stdout, &data)
if err != nil {
return err
}

return nil
}
  1. Create a file called template_files.go with the following contents:
        package templates

import (
"io/ioutil"
"os"
"path/filepath"
"text/template"
)

//CreateTemplate will create a template file that contains data
func CreateTemplate(path string, data string) error {
return ioutil.WriteFile(path, []byte(data),
os.FileMode(0755))
}

// InitTemplates sets up templates from a directory
func InitTemplates() error {
tempdir, err := ioutil.TempDir("", "temp")
if err != nil {
return err
}
defer os.RemoveAll(tempdir)

err = CreateTemplate(filepath.Join(tempdir, "t1.tmpl"),
`Template 1! {{ .Var1 }}
{{ block "template2" .}} {{end}}
{{ block "template3" .}} {{end}}
`)
if err != nil {
return err
}

err = CreateTemplate(filepath.Join(tempdir, "t2.tmpl"),
`{{ define "template2"}}Template 2! {{ .Var2 }}{{end}}
`)
if err != nil {
return err
}

err = CreateTemplate(filepath.Join(tempdir, "t3.tmpl"),
`{{ define "template3"}}Template 3! {{ .Var3 }}{{end}}
`)
if err != nil {
return err
}

pattern := filepath.Join(tempdir, "*.tmpl")

// Parse glob will combine all the files that match
// glob and combine them into a single template
tmpl, err := template.ParseGlob(pattern)
if err != nil {
return err
}

// Execute can also work with a map instead
// of a struct
tmpl.Execute(os.Stdout, map[string]string{
"Var1": "Var1!!",
"Var2": "Var2!!",
"Var3": "Var3!!",
})

return nil
}
  1. Create a file called html_templates.go with the following contents:
        package templates

import (
"fmt"
"html/template"
"os"
)

// HTMLDifferences highlights some of the differences
// between html/template and text/template
func HTMLDifferences() error {
t := template.New("html")
t, err := t.Parse("<h1>Hello! {{.Name}}</h1>n")
if err != nil {
return err
}

// html/template auto-escapes unsafe operations like
// javascript injection this is contextually aware and
// will behave differently
// depending on where a variable is rendered
err = t.Execute(os.Stdout, map[string]string{"Name": "
<script>alert('Can you see me?')</script>"})
if err != nil {
return err
}

// you can also manually call the escapers
fmt.Println(template.JSEscaper(`example
<[email protected]>`))
fmt.Println(template.HTMLEscaper(`example
<[email protected]>`))
fmt.Println(template.URLQueryEscaper(`example
<[email protected]>`))

return nil
}
  1. Create a new directory named example and navigate to it.
  2. Create a main.go file with the following contents:
        package main

import "github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter1/templates"

func main() {
if err := templates.RunTemplate(); err != nil {
panic(err)
}

if err := templates.InitTemplates(); err != nil {
panic(err)
}

if err := templates.HTMLDifferences(); err != nil {
panic(err)
}
}
  1. Run go run ..
  2. You may also run the following:
$ go build
$ ./example

You should see the following output (with a different path):

  1. If you copied or wrote your own tests, go up one directory and run go test, and ensure that all tests pass.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.151.106