go template基本使用

来源:互联网 发布:logstash 性能优化 编辑:程序博客网 时间:2024/05/21 22:51

go template是个模板替换的包,如果是普通text就使用text/template,如果是html还有html/template,其实有过jsp开发经验的人对这个东西应该很容易上手,它比那些jstl表达式要简单很多。下面看看基本使用

package mainimport (    "text/template"    "os")type Friend struct {    Fname string}type Person struct {    UserName string    Emails   []string    Friends  []*Friend}func main() {    f1 := Friend{Fname: "minux.ma"}    f2 := Friend{Fname: "xushiwei"}    t := template.New("fieldname example")    //because f1 and f2 is struct(object)    t, _ = t.Parse(`hello {{.UserName}}!                {{range .Emails}}                    an email {{.}}                {{end}}                {{with .Friends}}                {{range .}}                    my friend name is {{.Fname}}                {{end}}                {{end}}                `)    p := Person{UserName: "Astaxie",        Emails:  []string{"astaxie@beego.me", "astaxie@gmail.com"},        Friends: []*Friend{&f1, &f2}}    t.Execute(os.Stdout, p)}

通过range遍历,with是用户获取对象的,输出结果
hello Astaxie!
an email astaxie@beego.me
an email astaxie@gmail.com
my friend name is minux.ma
my friend name is xushiwei

当然如果想对数据进行更复杂点的操作,可以通过独立的pipeline来处理数据。下面说一个复杂一点的用函数处理的例子:

package mainimport (    "fmt"    "text/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: "minux.ma"}    f2 := Friend{Fname: "xushiwei"}    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: "Astaxie",        Emails:  []string{"astaxie@beego.me", "astaxie@gmail.com"},        Friends: []*Friend{&f1, &f2}}    t.Execute(os.Stdout, p)}

上面的 {{.|emailDeal}}是重点, {{.}}取的数据通过管道”|”交给函数处理,输出结果如下:
hello Astaxie!
an emails astaxie at beego.me
an emails astaxie at gmail.com
my friend name is minux.ma
my friend name is xushiwei

最后和大家一起看看ingress里面对模板的使用,先看看模板:

    {{range $name, $upstream := $backends}}    upstream {{$upstream.Name}} {        {{ if eq $upstream.SessionAffinity.AffinityType "cookie" }}        sticky hash={{$upstream.SessionAffinity.CookieSessionAffinity.Hash}} name={{$upstream.SessionAffinity.CookieSessionAffinity.Name}}  httponly;        {{ else }}        least_conn;        {{ end }}        {{ range $server := $upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }};        {{ end }}    }    {{ end }}{{ $limits := buildRateLimit $location }}

上面的代码是从nginx.tmpl文件里面截取的两个点,一个是upstream构建用到range和下面limits构建用的函数buildRateLimit,遍历直接替换没有上面,看看函数定义吧:

funcMap = text_template.FuncMap{        "empty": func(input interface{}) bool {            check, ok := input.(string)            if ok {                return len(check) == 0            }            return true        },        "buildLocation":                buildLocation,        "buildAuthLocation":            buildAuthLocation,        "buildProxyPass":               buildProxyPass,        "buildRateLimitZones":          buildRateLimitZones,        "buildRateLimit":               buildRateLimit,        "buildSSLPassthroughUpstreams": buildSSLPassthroughUpstreams,        "buildResolvers":               buildResolvers,        "isLocationAllowed":            isLocationAllowed,        "buildLogFormatUpstream":       buildLogFormatUpstream,        "contains":                     strings.Contains,        "hasPrefix":                    strings.HasPrefix,        "hasSuffix":                    strings.HasSuffix,        "toUpper":                      strings.ToUpper,        "toLower":                      strings.ToLower,    }

定义了buildRateLimit,函数具体实现是

func buildRateLimit(input interface{}) []string {    limits := []string{}    loc, ok := input.(*ingress.Location)    if !ok {        return limits    }    if loc.RateLimit.Connections.Limit > 0 {        limit := fmt.Sprintf("limit_conn %v %v;",            loc.RateLimit.Connections.Name, loc.RateLimit.Connections.Limit)        limits = append(limits, limit)    }    if loc.RateLimit.RPS.Limit > 0 {        limit := fmt.Sprintf("limit_req zone=%v burst=%v nodelay;",            loc.RateLimit.RPS.Name, loc.RateLimit.RPS.Burst)        limits = append(limits, limit)    }    return limits}

ok,介绍完毕

1 0
原创粉丝点击