参数
参数可以看做模板中的变量,参数值可以是布尔值、整型、字符串、还可以是结构体、结构体的字段、或者数组的索引。
我们可以这样设置参数值:
$variable := value
乍看起来没啥用,用在指令中则可以大放异彩:
{{ range $key, $value := . }} The key is {{ $key }} and the value is {{ $value }} {{ end }}
管道
管道是链接起来的参数、函数或者方法序列,和 Unix 管道一样:
{{ p1 | p2 | p3 }}
管道允许我们将上一个输出作为参数传递到下一个,不同元素之间通过 | 分隔。
服务端处理器示例代码:
package mainimport ( "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 代码:
<!DOCTYPE html> <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Pipeline Demo</title > </head > <body > {{ . | printf "%.2f" }}</body > </html >
上述管道代码会将传入视图模板的变量作为 printf 函数的参数,通过 %.2f 格式打印出来:
printf 函数封装了 fmt.Sprintf 方法,是 Go 模板引擎内置的函数,如果是自定义函数的话,需要通过指定语法将其绑定到模板引擎,否则系统不能识别,下面我们就来看看如何在 Go 视图模板中通过管道调用自定义函数。
自定义函数
Go 模板引擎内置了丰富的基础函数,其中有很多是 fmt.Sprint 的变体,比如前面示例中使用的 printf。此外,还支持开发者自定义的函数。
要自定义函数,需要这么做:
下面我们来看一个示例,这个示例中,我们通过自定义函数设置日期输出格式。
编写服务端处理器示例代码如下:
package mainimport ( "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 函数:
<!DOCTYPE html> <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Custom Function</title > </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 Programming</title > </head > <body > <div > The date/time is {{ fdate . }}</div > </body > </html >
两种方式实现的效果一样,但可以看出,管道的方式更加直观和灵活,我们还可以在后面继续追加其他函数对结果进行处理(链式调用)。
(全文完)
长按下面的二维码,即可订阅学院君最新发布的 Go Web 编程系列教程:
关于本系列教程的更多动态,请点击页面左下角的「阅读原文」链接查看。