Go 视图模板篇(三):参数、管道和函数调用

共 2567字,需浏览 6分钟

 ·

2020-08-24 07:53

参数

参数可以看做模板中的变量,参数值可以是布尔值、整型、字符串、还可以是结构体、结构体的字段、或者数组的索引。

我们可以这样设置参数值:

$variable := value

乍看起来没啥用,用在指令中则可以大放异彩:

{{ range $key, $value := . }} 
    The key is {{ $key }} and the value is {{ $value }} 
{{ end }}

管道

管道是链接起来的参数、函数或者方法序列,和 Unix 管道一样:

{{ p1 | p2 | p3 }}

管道允许我们将上一个输出作为参数传递到下一个,不同元素之间通过 | 分隔。

服务端处理器示例代码:

package main

import (
    "html/template"
    "net/http"
)

func pipelineExample(w http.ResponseWriter, r *http.Request)  {
    t := template.Must(template.ParseFiles("pipeline.html"))
    t.Execute(w, 12.3456)
}

func main()  {
    http.HandleFunc("/pipeline", pipelineExample)
    http.ListenAndServe(":8080"nil)
}

对应的模板文件 pipeline.html 代码:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Pipeline Demotitle>
head>
<body>
    {{ . | printf "%.2f" }}
body>
html>

上述管道代码会将传入视图模板的变量作为 printf 函数的参数,通过 %.2f 格式打印出来:

printf 函数封装了 fmt.Sprintf 方法,是 Go 模板引擎内置的函数,如果是自定义函数的话,需要通过指定语法将其绑定到模板引擎,否则系统不能识别,下面我们就来看看如何在 Go 视图模板中通过管道调用自定义函数。

自定义函数

Go 模板引擎内置了丰富的基础函数,其中有很多是 fmt.Sprint 的变体,比如前面示例中使用的 printf。此外,还支持开发者自定义的函数。

要自定义函数,需要这么做:

  • 创建 FuncMap 字典,然后将函数名作为键,将函数体作为值。

  • FuncMap 应用到模板引擎。

下面我们来看一个示例,这个示例中,我们通过自定义函数设置日期输出格式。

编写服务端处理器示例代码如下:

package main

import (
    "html/template"
    "net/http"
    "time"
)

func formatDate(t time.Time) string {
    layout := "2006-01-02 15:04:05"
    return t.Format(layout)
}

func customFunctionExample(w http.ResponseWriter, r *http.Request)  {
    funcMap := template.FuncMap{
        "fdate": formatDate,
    }
    t := template.New("function.html").Funcs(funcMap)
    t, _ = t.ParseFiles("function.html")
    t.Execute(w, time.Now())
}

func main()  {
    http.HandleFunc("/date_format", customFunctionExample)
    http.ListenAndServe(":8080"nil)
}

可以看到,我们通过模板引擎提供的 FuncMap 方法将自定义的 formatDate 函数注册到 fdate 键,然后将返回的 funcMap 通过 Funcs 方法注入到视图模板中,这样,在对应的视图模板中就可以调用 funcMap 中注册的自定义函数了。

对应的模板文件 function.html 代码如下,我们在里面通过管道的方式调用了 fdate 函数:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Custom Functiontitle>
head>
<body>
    <div> The date/time is {{ . | fdate }} div>
body>
html>

这里需要注意的是,我们必须在解析模板之前应用自定义函数到模板引擎(前后顺序不能颠倒):

t := template.New("function.html").Funcs(funcMap)
t, _ = t.ParseFiles("function.html")

这是因为在解析模板时需要确定模板中使用的函数。另外,当我们通过 New 方法创建模板时,需要手动设置模板名(之前都是自动将文件名作为模板名),然后在模板上调用 ParseFiles 时再次传递的实际上是待解析的模板文件,而不是模板名,这里需要区分下。

运行服务端代码启动服务器,在浏览器中访问 http://localhost:8080/date_format,输出结果如下,表明自定义日期格式函数调用成功:

除了管道之外,还可以在指令中使用自定义的函数,这个时候可以将 . 作为参数传递过来:

<html> 
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
        <title>Go Web Programmingtitle
    head
    <body> 
        <div>The date/time is {{ fdate . }}div
    body
html>

两种方式实现的效果一样,但可以看出,管道的方式更加直观和灵活,我们还可以在后面继续追加其他函数对结果进行处理(链式调用)。

(全文完)




推荐阅读



学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注



浏览 21
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报