Golang模板template

news/2024/10/11 15:56:53

背景概述

当我们在进行json字段选取以及渲染时,我们经常会见到{{}},其实这就是我们今天要讲解的模板即是template。例如prometheusAlert中的模板就是使用了改语法。

必备技能

  1. 字段选取

    {{ . }} 表示json的所有域,例如:{"name":"anruo","age":18},我们使用{{ . }}就可以获取到所有的内容 {{ .name }} 就可以获取到anruo字符串。

    range: 循环,当json中有列表时,我们可以使用{{range $index,$value:=.xx}}{{$index,$value}}{{end}}来进行取值。

    {{-}}: 去重空格内容

  2. 自定义函数

    所谓自定义函数,即是我们可以自定义处理字段。例如:时间字段中的时区转换。

  3. 运算符

    eq: ==

    ge: >=

    gt: >

    le: <=

    lt: <

    ne: !=

案例演示

我们先模拟一下源数据,这里我们定义一个结构体

type Temp struct {
 Name  string
 Age   int64
 Like  []string
 Study []Study
}

type Study struct {
 Name string
       School string
}

初始化template

func NewTemplate(tmpl string) (*template.Template, error) {
 return template.New("anruo").Funcs(TmpFuncMap()).Parse(tmpl)
}

func TmpExcute(tmpl string, data interface{}) {
 t, _ := NewTemplate(tmpl)
 _ = t.Execute(os.Stdout, data)
}

func TmpFuncMap() template.FuncMap {
 return template.FuncMap{
  "GetLocalTime": func() string { return time.Now().String() },
  "SubTime": func(oldTime string) string {
   t1, _ := time.Parse("2006-01-02 15:04:05", oldTime)
   t2, _ := time.Parse("2006-01-02 15:04:05", time.Now().Format("2006-01-02 15:04:05"))
   return t2.Sub(t1).String()
  },
 }
}

这里我们使用了自定义函数,当然这是我们模拟使用的。

定义解析

姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like}}
爱好:{{$value}}
{{end}}
{{range $value := .Study}}
学科:{{$value.Name}}
学校:{{$value.School}}
{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05"}}

完整代码如下

package main

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

func main() {
 var temp = Temp{
  Name: "张三",
  Age:  18,
  Like: []string{"足球", "篮球"},
  Study: []Study{
   {Name: "语文", School: "铁岭小学"},
   {Name: "数学", School: "吉林中学"},
   {Name: "英语", School: "郑州大学"},
  },
 }
 tmpl := `
姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like}}
爱好:{{$value}}
{{end}}
{{range $value := .Study}}
学科:{{$value.Name}}
学校:{{$value.School}}
{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05"}}
`
 TmpExcute(tmpl, temp)
}

func NewTemplate(tmpl string) (*template.Template, error) {
 return template.New("anruo").Funcs(TmpFuncMap()).Parse(tmpl)
}

func TmpExcute(tmpl string, data interface{}) {
 t, _ := NewTemplate(tmpl)
 _ = t.Execute(os.Stdout, data)
}

func TmpFuncMap() template.FuncMap {
 return template.FuncMap{
  "GetLocalTime": func() string { return time.Now().String() },
  "SubTime": func(oldTime string) string {
   t1, _ := time.Parse("2006-01-02 15:04:05", oldTime)
   t2, _ := time.Parse("2006-01-02 15:04:05", time.Now().Format("2006-01-02 15:04:05"))
   return t2.Sub(t1).String()
  },
 }
}

type Temp struct {
 Name  string
 Age   int64
 Like  []string
 Study []Study
}

type Study struct {
 Name   string
 School string
}

运行结果为:

姓名:张三 年龄:18

爱好:足球

爱好:篮球

学科:语文 学校:铁岭小学

学科:数学 学校:吉林中学

学科:英语 学校:郑州大学

当前时间: 2024-09-09 16:48:40.7547471 +0800 CST m=+0.005393101 时间差:1h44m35s

图片image-20240910164257362

我们可以发现是有空行的,那么我们可以使用我们-来取消空行

姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like -}}
爱好:{{$value}}
{{end}}
{{- range $value := .Study -}}
学科:{{$value.Name}}
学校:{{$value.School}}
{{end -}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05"}}

运行结果为:

图片image-20240910164306692

我们可以发现,其中学科和学校是单独的行,如果我们要进行合并呢

姓名:{{- .Name}}
年龄:{{.Age}}
{{range $value := .Like -}}
爱好:{{$value}}
{{end -}}
学科:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.Name}}{{end}}
学校:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.School}}{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05" -}}

我们可以使用字符串拼接的方式,当然我们也可以使用自定义函数来进行。

看一个if判断的模板

姓名:{{- .Name}}
{{- if eq .Age 19}}
年龄:{{.Age}}
{{else}}
年龄:{{.Age}}+
{{end -}}
{{range $value := .Like -}}
爱好:{{$value}}
{{end -}}
学科:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.Name}}{{end}}
学校:{{range $index, $value := .Study}}{{if $index}}, {{end}}{{$value.School}}{{end}}
当前时间: {{GetLocalTime}}
时间差:{{SubTime "2024-09-09 15:04:05" -}}

这里我们使用了Age进行判断,其结果为:

图片image-20240910164118887

告警数据

我们这里以prometheus的告警数据为例,来简单说明一下template的用法

告警源数据

{
  "receiver": "webhook-zja",
  "status": "firing",
  "alerts": [
    {
      "status": "firing",
      "labels": {
        "alertname": "服务线程数超过1500",
        "container": "data-center",
        "namespace": "bigdata",
        "severity": "warning"
      },
      "annotations": {
        "description": "bigdata data-center 线程数超过1500!!当前值1.629k% ",
        "summary": "bigdata data-center 线程数超过1500!"
      },
      "startsAt": "2023-08-09T15:23:17.0967074Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "fingerprint": "4e4b8a9d78edaacd"
    },
    {
      "status": "firing",
      "labels": {
        "alertname": "服务线程数超过1500",
        "container": "english-server",
        "namespace": "english",
        "severity": "warning"
      },
      "annotations": {
        "description": "english english-server 线程数超过1500!!当前值2.011k% ",
        "summary": "english english-server 线程数超过1500!"
      },
      "startsAt": "2023-08-10T06:35:17.0967074Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "fingerprint": "16e2c7f3733ec786"
    },
    {
      "status": "firing",
      "labels": {
        "alertname": "服务线程数超过1500",
        "container": "english-web",
        "namespace": "english",
        "severity": "warning"
      },
      "annotations": {
        "description": "english english-web 线程数超过1500!!当前值2.51k% ",
        "summary": "english english-web 线程数超过1500!"
      },
      "startsAt": "2023-08-10T06:24:17.0967074Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "fingerprint": "259577587fd712fb"
    },
    {
      "status": "firing",
      "labels": {
        "alertname": "服务线程数超过1500",
        "container": "english-web2",
        "namespace": "english",
        "severity": "warning"
      },
      "annotations": {
        "description": "english english-web2 线程数超过1500!!当前值1.541k%",
        "summary": "english english-web2 线程数超过1500!"
      },
      "startsAt": "2023-08-10T07:35:17.0967074Z",
      "endsAt": "0001-01-01T00:00:00Z",
      "fingerprint": "fd899e29b5a3d4a8"
    }
  ],
  "groupLabels": {
    "alertname": "服务线程数超过1500"
  },
  "commonLabels": {
    "alertname": "服务线程数超过1500",
    "severity": "warning"
  },
  "commonAnnotations": {},
  "externalURL": "http://kube-prometheus-alertmanager.monitoring:9093",
  "version": "4",
  "groupKey": "{}:{alertname=\"服务线程数超过1500\"}",
  "truncatedAlerts": 0
}

模板

{{- $alertDesc := "" -}}
{{- range $k, $v := .alerts -}}
  {{- if eq $k 0 -}}
    {{- $alertDesc = $v.annotations.description -}}
  {{- end -}}
{{- end -}}
告警名称:{{.groupLabels.alertname}}
告警服务: {{ range $k,$v:=.alerts }}{{if $k}},{{end}}{{$v.labels.container}}{{if $v.labels.namespace}}({{$v.labels.namespace}}){{end}}{{end}}
告警描述:{{$alertDesc}}

结果为:

告警名称:服务线程数超过1500

告警服务: data-center-point-server(bigdata-prod),english-parent-web(english-prod),english-student-web(english-prod),english-student-web3(english-prod)

告警描述:bigdata-prod data-center-point-server 线程数超过1500!!当前值1.629k%

总结

到此我们template就大致结束了,当我们在进行程序开发时,我们可以利用该包进行一些模板的渲染,例如Go+Ansible+Nginx的实现即是利用了该包,还有prometheusAlert也是如此。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/70253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

如何在springboot中,全局配置produces=text/plain;charset=UTF-8

为什么要使用produces="text/plain;charset=UTF-8"? 当不用这个配置时,接口返回的数据,是有斜杠的 配置后,就正常了 以前我的配置方式,是在每个接口上,都添加上produces="text/plain;charset=UTF-8"。但是这样显示不太好,每个接口都加的话,会比较…

鸿蒙发送消息通知

注意:发送消息通知要开启设置中的消息通知import notify from @ohos.notificationManager import image from @ohos.multimedia.image import { BusinessError } from @kit.BasicServicesKit@Entry @Component struct NotificationPage {// 全局任务ididx: number = 100// 图象…

域名解析错误是不是被限制了?

在我们畅游互联网的过程中,有时会遭遇域名解析错误的情况,这无疑会给我们的上网体验带来困扰。而很多人在遇到域名解析错误时,不禁会疑惑:这是不是意味着被限制了呢? 首先,域名解析错误并不一定意味着被限制。 域名解析是将域名转换为对应的IP地址的过程,就如同在电话簿…

Xshell:需要Xmanager软件来处理X11转发请求.....

关闭这个连接,然后重新连接即可。本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18458533

nodejs 和 npm 版本对应关系

本文简单列了一下nodejs和npm版本的对应关系,另外记录里版本更新的方法,最后列了一下博主日常碰到的错误和解决方案,供参考。一、nodejs 和 npm 的版本是有适配的 首先看下官网列明的大概匹配关系: 官网链接地址:https://nodejs.org/zh-cn/about/previous-releases可以查看…

打造你的专属语音助手,基于函数计算托管 CosyVoice 语音模型

目前,声音的推理和合成在很多领域都有广泛的应用,比如儿童/成人教育、疗愈/陪伴、销售/客服、游戏 NPC、车载通信,工/农业线下辅助等。CosyVoice 是一款优秀的语音合成模型,支持语音合成、情感控制、多语言语音合成等诸多功能,效果体验极佳。作者:寒斜 目前,声音的推理和…

10.11

放了签就是爽,这种题多来几套!! 100+100+100+10。 A.树的构造 如果 \(x>\lfloor\frac{n}{2}\rfloor+1\) 那么无解,若 \(n>1\) 且 \(x=1\) 无解。 对于有解的情况我们链套菊花构造。B.后缀 字符串哈希+二分+树状数组优化简单 dp C.子序列 感觉不是很签啊,为啥赛时过的…