diff --git a/examples.txt b/examples.txt index 6aca285..c0b7498 100644 --- a/examples.txt +++ b/examples.txt @@ -48,7 +48,7 @@ Collection Functions String Functions String Formatting Regular Expressions -Templates +Text Templates JSON XML Time diff --git a/examples/templates/templates.hash b/examples/templates/templates.hash deleted file mode 100644 index b341c81..0000000 --- a/examples/templates/templates.hash +++ /dev/null @@ -1,2 +0,0 @@ -f890e1eca9f39b0a4a7d09e6d866effe2cc70a33 -NfWmk0KSkgy diff --git a/examples/templates/templates.go b/examples/text-templates/text-templates.go similarity index 51% rename from examples/templates/templates.go rename to examples/text-templates/text-templates.go index e0ad5e6..cd0d9a0 100644 --- a/examples/templates/templates.go +++ b/examples/text-templates/text-templates.go @@ -5,9 +5,10 @@ package main // Go has two template packages. one is "text/template" for // regular text manipulation, and another one is "html/template" -// mostly used in web applications. -// Here we show some of "text/template" features. +// which has the same API as "text/template" but has additional security features. +// It should be used when generating HTML. import ( + "log" "os" "text/template" ) @@ -15,90 +16,100 @@ import ( func main() { // New creates a template with a specific name and returns a pointer to it. - t := template.New("my-template") + t1 := template.New("t1") // Parse parses its parameter as template body. // We use {{.}} to access the value passed to the template when it's getting executed. - t, _ = t.Parse("Value is {{.}}\n") + t1, err := t1.Parse("Value is {{.}}\n") + if err != nil { + log.Fatal(err) + } // If we want to ignore the errors we can use Must function. // It will panic if an error occurs when parsing the template. - t = template.Must(t.Parse("Value is {{.}}\n")) + t1 = template.Must(t1.Parse("Value is {{.}}\n")) // Execute applies parsed template to the data we pass to it and writes the output to the io.Writer. - t.Execute(os.Stdout, t.Name()) - t.Execute(os.Stdout, "some text") - t.Execute(os.Stdout, true) - t.Execute(os.Stdout, 5) - t.Execute(os.Stdout, []string{ + t1.Execute(os.Stdout, t1.Name()) + t1.Execute(os.Stdout, "some text") + t1.Execute(os.Stdout, true) + t1.Execute(os.Stdout, 5) + t1.Execute(os.Stdout, []string{ "Go", "Rust", "C++", "C#", }) - t.Execute(os.Stdout, struct{ name string }{ - name: "Arash", + t1.Execute(os.Stdout, struct{ name string }{ + name: "Jane Doe", }) // If the data is a struct we can use the {{.FieldName}} action to access its fields. // The fields should be exported to be accessible when template is executing. - t, _ = t.Parse("Firstname: {{.Firstname}}" + - ", Lastname: {{.Lastname}}\n") + t2, _ := template. + New("t2"). + Parse("Fullname: {{.Fullname}}\n") - t.Execute(os.Stdout, struct { - Firstname, Lastname string + t2.Execute(os.Stdout, struct { + Fullname string }{ - Firstname: "Arash", - Lastname: "Sameni", + Fullname: "Jane Doe", }) - // Samething applies for maps. But it's not necessary to have uppercase fields. - t.Execute(os.Stdout, map[string]string{ - "Firstname": "Robert", - "Lastname": "Griesemer", + // The same applies to maps; with maps there is no restriction on the case of key names. + t2.Execute(os.Stdout, map[string]string{ + "Fullname": "Mickey Mouse", }) // You can use if control structure to show data conditionally. // The data between if block will be shown if the field is truthy. // Means it is not false boolean, empty string, nil or zero length slice, nil map/pointer. - t, _ = t.Parse(`{{if .Field1}} - If block => {{.Field1}} - {{ else if .Field2}} - Else if block => {{.Field2}} - {{ else }} - Else block - {{ end }}`) + t3, _ := template. + New("t3"). + Parse(`{{if .Field1}} + If block => {{.Field1}} + {{ else if .Field2}} + Else if block => {{.Field2}} + {{ else }} + Else block + {{ end }}`) s := struct { - Field1, Field2 interface{} + Field1 string + Field2 []string }{} s.Field1 = "" s.Field2 = []string{} - t.Execute(os.Stdout, s) + t3.Execute(os.Stdout, s) - s.Field1 = nil - s.Field2 = "Some text" - t.Execute(os.Stdout, s) + s.Field1 = "Some text" + s.Field2 = nil + t3.Execute(os.Stdout, s) // Using a range action you can loop through a slice. // Each time the range block is getting executed dot will be set // to current item of slice. - // You can use $ in blocks to access outside data. - t, _ = t.Parse(`Range: {{ range . }} + t4, _ := template. + New("t4"). + Parse(`Range: {{ range . }} {{.}} - {{ end }}`) - t.Execute(os.Stdout, []string{ - "Go", - "Rust", - "C++", - "C#", - }) + {{ end }}`) + t4.Execute(os.Stdout, + []string{ + "Go", + "Rust", + "C++", + "C#", + }) // You can assign and reassign a value to a variable in templates. - t, _ = t.Parse(`Variables: {{ $language := "go" }} - {{ $language }} + t5, _ := template. + New("t5"). + Parse(`Variables: + {{ $language := "go" }} + {{ $language }} {{ $language = "C" }} - {{ $language }}`) - t.Execute(os.Stdout, nil) + {{ $language }}`) + t5.Execute(os.Stdout, nil) } diff --git a/examples/text-templates/text-templates.hash b/examples/text-templates/text-templates.hash new file mode 100644 index 0000000..d0418a6 --- /dev/null +++ b/examples/text-templates/text-templates.hash @@ -0,0 +1,2 @@ +69a28314f7ebd877b184b35a8166e2fcaab56754 +-mRr-NuSB6f diff --git a/examples/templates/templates.sh b/examples/text-templates/text-templates.sh similarity index 66% rename from examples/templates/templates.sh rename to examples/text-templates/text-templates.sh index 3f40037..3cf70b9 100644 --- a/examples/templates/templates.sh +++ b/examples/text-templates/text-templates.sh @@ -1,12 +1,12 @@ $ go run templates.go -Value is my-template +Value is t1 Value is some text Value is true Value is 5 Value is [Go Rust C++ C#] -Value is {Arash} -Firstname: Arash, Lastname: Sameni -Firstname: Robert, Lastname: Griesemer +Value is {Jane Doe} +Fullname: Jane Doe +Fullname: Mickey Mouse Else block diff --git a/public/index.html b/public/index.html index 9405309..5dbce34 100644 --- a/public/index.html +++ b/public/index.html @@ -127,7 +127,7 @@
  • Regular Expressions
  • -
  • Templates
  • +
  • Text Templates
  • JSON
  • diff --git a/public/json b/public/json index 9191834..c437bd1 100644 --- a/public/json +++ b/public/json @@ -9,7 +9,7 @@ onkeydown = (e) => { if (e.key == "ArrowLeft") { - window.location.href = 'templates'; + window.location.href = 'text-templates'; } diff --git a/public/regular-expressions b/public/regular-expressions index 2e422d8..806d67f 100644 --- a/public/regular-expressions +++ b/public/regular-expressions @@ -14,7 +14,7 @@ if (e.key == "ArrowRight") { - window.location.href = 'templates'; + window.location.href = 'text-templates'; } } @@ -329,7 +329,7 @@ the regexp package docs

    - Next example: Templates. + Next example: Text Templates.

    diff --git a/public/templates b/public/templates index d8fd096..3a58d31 100644 --- a/public/templates +++ b/public/templates @@ -42,7 +42,7 @@ dynamic content or showing customized output to the user called Template.

    - +
    package main
     
    @@ -51,8 +51,9 @@ dynamic content or showing customized output to the user called Template.

    Go has two template packages. one is “text/template” for -regular text manipulation, and another one is “html/template” -mostly used in web applications. +regular text manipulation, and another one is “html/template”. +“html/template” has the same API as text/template which has additional security features. +It should be used when generating HTML Here we show some of “text/template” features.

    diff --git a/public/text-templates b/public/text-templates new file mode 100644 index 0000000..1f03b49 --- /dev/null +++ b/public/text-templates @@ -0,0 +1,402 @@ + + + + + Go by Example: Text Templates + + + + +
    +

    Go by Example: Text Templates

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    Go offers built-in support for creating +dynamic content or showing customized output to the user called Template.

    + +
    + + +
    + + + +
    package main
    +
    +
    +

    Go has two template packages. one is “text/template” for +regular text manipulation, and another one is “html/template” +which has the same API as “text/template” but has additional security features. +It should be used when generating HTML.

    + +
    + +
    +import (
    +    "log"
    +    "os"
    +    "text/template"
    +)
    +
    +
    + + + +
    func main() {
    +
    +
    +

    New creates a template with a specific name and returns a pointer to it.

    + +
    + +
    +    t1 := template.New("t1")
    +
    +
    +

    Parse parses its parameter as template body. +We use {{.}} to access the value passed to the template when it’s getting executed.

    + +
    + +
    +    t1, err := t1.Parse("Value is {{.}}\n")
    +    if err != nil {
    +        log.Fatal(err)
    +    }
    +
    +
    +

    If we want to ignore the errors we can use Must function. +It will panic if an error occurs when parsing the template.

    + +
    + +
    +    t1 = template.Must(t1.Parse("Value is {{.}}\n"))
    +
    +
    +

    Execute applies parsed template to the data we pass to it and writes the output to the io.Writer.

    + +
    + +
    +    t1.Execute(os.Stdout, t1.Name())
    +    t1.Execute(os.Stdout, "some text")
    +    t1.Execute(os.Stdout, true)
    +    t1.Execute(os.Stdout, 5)
    +    t1.Execute(os.Stdout, []string{
    +        "Go",
    +        "Rust",
    +        "C++",
    +        "C#",
    +    })
    +    t1.Execute(os.Stdout, struct{ name string }{
    +        name: "Jane Doe",
    +    })
    +
    +
    +

    If the data is a struct we can use the {{.FieldName}} action to access its fields. +The fields should be exported to be accessible when template is executing.

    + +
    + +
    +    t2, _ := template.
    +        New("t2").
    +        Parse("Fullname: {{.Fullname}}\n")
    +
    +
    + + + +
        t2.Execute(os.Stdout, struct {
    +        Fullname string
    +    }{
    +        Fullname: "Jane Doe",
    +    })
    +
    +
    +

    The same applies to maps; with maps there is no restriction on the case of key names.

    + +
    + +
    +    t2.Execute(os.Stdout, map[string]string{
    +        "Fullname": "Mickey Mouse",
    +    })
    +
    +
    +

    You can use if control structure to show data conditionally. +The data between if block will be shown if the field is truthy. +Means it is not false boolean, empty string, nil or zero length slice, nil map/pointer.

    + +
    + +
    +    t3, _ := template.
    +        New("t3").
    +        Parse(`{{if .Field1}}
    +                    If block => {{.Field1}}
    +                {{ else if .Field2}}
    +                    Else if block => {{.Field2}}
    +                {{ else }}
    +                    Else block
    +                {{ end }}`)
    +
    +
    + + + +
        s := struct {
    +        Field1 string
    +        Field2 []string
    +    }{}
    +
    +
    + + + +
        s.Field1 = ""
    +    s.Field2 = []string{}
    +    t3.Execute(os.Stdout, s)
    +
    +
    + + + +
        s.Field1 = "Some text"
    +    s.Field2 = nil
    +    t3.Execute(os.Stdout, s)
    +
    +
    +

    Using a range action you can loop through a slice. +Each time the range block is getting executed dot will be set +to current item of slice.

    + +
    + +
    +    t4, _ := template.
    +        New("t4").
    +        Parse(`Range: {{ range . }}
    +                        {{.}}
    +                      {{ end }}`)
    +    t4.Execute(os.Stdout,
    +        []string{
    +            "Go",
    +            "Rust",
    +            "C++",
    +            "C#",
    +        })
    +
    +
    +

    You can assign and reassign a value to a variable in templates.

    + +
    + +
    +    t5, _ := template.
    +        New("t5").
    +        Parse(`Variables: {{ $language := "go" }}
    +                    {{ $language }}
    +                    {{ $language = "C" }}
    +                    {{ $language }}`)
    +    t5.Execute(os.Stdout, nil)
    +}
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    $ go run templates.go 
    +Value is my-template
    +Value is some text
    +Value is true
    +Value is 5
    +Value is [Go Rust C++ C#]
    +Value is {Jane Doe}
    +Fullname: Jane Doe
    +Fullname: Mickey Mouse
    +
    + + + +
            Else block
    +
    + + + +
            Else if block => Some text
    +Range: 
    +        Go
    +
    + + + +
            Rust
    +
    + + + +
            C++
    +
    + + + +
            C#
    +Variables: 
    +go
    +C
    +
    + + +

    + Next example: JSON. +

    + + + + +
    + + + +