Go基础学习记录之模板(template)[二]

{app.params.name}}{app.params.name}}{app.params.name}}

条件语句

如果需要检查模板中的条件,可以像使用常规Go程序一样使用if-else语法。如果管道为空,则默认值if为false。以下示例显示如何在模板中使用if-else:

package main

import (
    "os"
    "text/template"
)

func main() {
    tEmpty := template.New("template test")
    tEmpty = template.Must(tEmpty.Parse("Empty pipeline if demo: {{if ``}} will not be outputted. {{end}}\n"))
    tEmpty.Execute(os.Stdout, nil)

    tWithValue := template.New("template test")
    tWithValue = template.Must(tWithValue.Parse("Not empty pipeline if demo: {{if `anything`}} will be outputted. {{end}}\n"))
    tWithValue.Execute(os.Stdout, nil)

    tIfElse := template.New("template test")
    tIfElse = template.Must(tIfElse.Parse("if-else demo: {{if `anything`}} if part {{else}} else part.{{end}}\n"))
    tIfElse.Execute(os.Stdout, nil)
}

重新编译运行后结果如下

Empty pipeline if demo: 
Not empty pipeline if demo:  will be outputted. 
if-else demo:  if part

如您所见,在模板中使用if-else很容易。注意你不能在if中使用条件表达式,例如.Mail =="durban.zhang@gmail.com"只接受布尔值。

管道"|"

Unix用户应该熟悉管道运算符,比如ls | grep "gowhich"。此命令过滤文件,仅显示包含单词gowhich的文件。我喜欢Go模板的一件事是它们支持管道。{{}}中的任何内容都可以是管道数据。我们上面使用的电子邮件可能会使我们的应用程序容易受到XSS攻击。我们如何使用管道来解决这个问题?

{{. | html}}

我们可以使用此方法将电子邮件正文转义为HTML。它与编写Unix命令非常相似,并且可以方便地用于模板函数。

模板变量

有时我们需要在模板中使用局部变量。我们可以将它们与with,range和if关键字一起使用,它们的范围介于这些关键字和{{end}}之间。下面是一个声明全局变量的示例:

$variable := pipeline

其他的示例如下

{{with $x := "output" | printf "%q"}}{{$x}}{{end}}
{{with $x := "output"}}{{printf "%q" $x}}{{end}}
{{with $x := "output"}}{{$x | printf "%q"}}{{end}}

模板函数

Go使用fmt包来格式化模板中的输出,但有时我们需要做其他事情。例如,考虑以下场景:假设我们想在我们的电子邮件地址中用at替换@,就像将durban.zhang@gmail.com变为durban.zhangatgmail.com一样。此时,我们必须编写一个自定义函数。每个模板函数都有一个唯一的名称,并与Go程序中的一个函数相关联,如下所示:

type FuncMap map[string]interface{}

假设我们的Go程序中有一个与其EmailDealWith对应函数关联的emailDeal模板函数。我们可以使用以下代码来注册这个函数:

t = t.Funcs(template.FuncMap{"emailDeal": EmailDealWith})

EmailDealWith的定义如下

func EmailDealWith(args …interface{}) string

具体实例如下

package main

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

type Friend struct {
    Fname string
}

type Person struct {
    UserName string
    Emails   []string
    Friends  []*Friend
}

func EmailDealWith(args ...interface{}) string {
    ok := false
    var s string
    if len(args) == 1 {
        s, ok = args[0].(string)
    }
    if !ok {
        s = fmt.Sprint(args...)
    }
    // find the @ symbol
    substrs := strings.Split(s, "@")
    if len(substrs) != 2 {
        return s
    }
    // replace the @ by " at "
    return (substrs[0] + " at " + substrs[1])
}

func main() {
    f1 := Friend{Fname: "durban1"}
    f2 := Friend{Fname: "durban2"}
    t := template.New("fieldname example")
    t = t.Funcs(template.FuncMap{"emailDeal": EmailDealWith})
    t, _ = t.Parse(`hello {{.UserName}}!
                {{range .Emails}}
                    an emails {{.|emailDeal}}
                {{end}}
                {{with .Friends}}
                {{range .}}
                    my friend name is {{.Fname}}
                {{end}}
                {{end}}
                `)
    p := Person{UserName: "Durban",
        Emails:  []string{"durban.zhang@gmail.com", "durban.zhang@126.com"},
        Friends: []*Friend{&f1, &f2}}
    t.Execute(os.Stdout, p)
}

编译后运行得到的结果如下

hello Durban!
                
                    an emails durban.zhang at gmail.com
                
                    an emails durban.zhang at 126.com
                
                
                
                    my friend name is durban1
                
                    my friend name is durban2

以下是内置模板函数的列表:

var builtins = FuncMap{
    "and":      and,
    "call":     call,
    "html":     HTMLEscaper,
    "index":    index,
    "js":       JSEscaper,
    "len":      length,
    "not":      not,
    "or":       or,
    "print":    fmt.Sprint,
    "printf":   fmt.Sprintf,
    "println":  fmt.Sprintln,
    "urlquery": URLQueryEscaper,
}

今天的学习分享就到这里,继续关注。

版权声明

durban创作并维护的 小绒毛的足迹博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。

本文首发于 博客( https://www.xiaorongmao.com ),版权所有,侵权必究。

本文永久链接: https://www.xiaorongmao.com/blog/90


版权声明

durban创作并维护的 小绒毛的足迹博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。

本文首发于 小绒毛的足迹博客( https://www.xiaorongmao.com ),版权所有,侵权必究。

本文永久链接: https://www.xiaorongmao.com/blog/90