go template基本使用

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

package main

import (
    "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 main

import (
    "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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳清风09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值