在 Go 模板中验证日期
Validate Date in Go Template
我试图确保我的模板文件中有一个有效日期,如果是这样,请填充 div,否则将其留空。数据类型为 mysql.NullTime.
这是我正在尝试做的事情:
{{ if .StartDate ne nil }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}">{{ .StartDate.Format "2006-01-02" }}</div>
{{ else }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}"></div>
{{ end }}
这似乎有效,我如何测试非空日期?
如果它是强制值,您应该在呈现模板之前对其进行验证。
但是,如果它是可选的and/or您正在编写一个模板驱动的应用程序,您至少有两个选项来实现您想要的。
仅使用零值
充分利用零值:对于 time.Time
即 epoch。因此,假设您过去不能有 StartDate
,您可以比较 StartDate 是否在纪元之后。
package main
import (
"html/template"
"os"
"time"
)
// Note the call to the `After` function of the date.
const templateText = `
{{ if .Data.StartDate.After .Epoch }}
<div class="box date-row" id="startdate-{{ .Data.DepartureTimeID }}">{{ .Data.StartDate.Format "2006-01-02" }}</div>
{{ else }}
<div class="box date-row" id="startdate-{{ .Data.DepartureTimeID }}">No date</div>
{{ end }}
`
func main() {
// shortcut for the sake of brevity.
tmpl := template.Must(template.New("titleTest").Parse(templateText))
// Create an anonymous wrapper struct for your data and the additional
// time value you need to compare against
tcx := struct {
// This of course may be of the type you actually use.
Data struct {
StartDate time.Time
DepartureTimeID int
}
Epoch time.Time
}{
Data: struct {
StartDate time.Time
DepartureTimeID int
}{time.Now(), 1},
Epoch: time.Time{},
}
tmpl.Execute(os.Stdout, tcx)
}
使用自定义函数
这几乎是不言自明的:只需定义一个自定义函数来验证您的日期。在这个例子中,我再次检查了零值。但是,您当然可以随心所欲地进行细化:
package main
import (
"html/template"
"os"
"log"
"time"
)
const templateText = `
{{ if afterEpoch .StartDate }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}">{{ .StartDate.Format "2006-01-02" }}</div>
{{ else }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}"></div>
{{ end }}
`
func AfterEpoch(t time.Time) bool {
return t.After(time.Time{})
}
type yourData struct {
DepartureTimeID int
StartDate time.Time
}
func main() {
funcMap := template.FuncMap{
"afterEpoch": AfterEpoch,
}
tmpl := template.Must(template.New("fmap").Funcs(funcMap).Parse(templateText))
log.Println("First run")
tmpl.Execute(os.Stdout, yourData{1, time.Now()})
log.Println("Second run")
tmpl.Execute(os.Stdout, yourData{DepartureTimeID:1})
}
编辑:
当然,你也可以使用管道符号来表示第二种解决方案,为了更具可读性,恕我直言:{{ if .StartDate | afterEpoch }}
我试图确保我的模板文件中有一个有效日期,如果是这样,请填充 div,否则将其留空。数据类型为 mysql.NullTime.
这是我正在尝试做的事情:
{{ if .StartDate ne nil }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}">{{ .StartDate.Format "2006-01-02" }}</div>
{{ else }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}"></div>
{{ end }}
这似乎有效,我如何测试非空日期?
如果它是强制值,您应该在呈现模板之前对其进行验证。
但是,如果它是可选的and/or您正在编写一个模板驱动的应用程序,您至少有两个选项来实现您想要的。
仅使用零值
充分利用零值:对于 time.Time
即 epoch。因此,假设您过去不能有 StartDate
,您可以比较 StartDate 是否在纪元之后。
package main
import (
"html/template"
"os"
"time"
)
// Note the call to the `After` function of the date.
const templateText = `
{{ if .Data.StartDate.After .Epoch }}
<div class="box date-row" id="startdate-{{ .Data.DepartureTimeID }}">{{ .Data.StartDate.Format "2006-01-02" }}</div>
{{ else }}
<div class="box date-row" id="startdate-{{ .Data.DepartureTimeID }}">No date</div>
{{ end }}
`
func main() {
// shortcut for the sake of brevity.
tmpl := template.Must(template.New("titleTest").Parse(templateText))
// Create an anonymous wrapper struct for your data and the additional
// time value you need to compare against
tcx := struct {
// This of course may be of the type you actually use.
Data struct {
StartDate time.Time
DepartureTimeID int
}
Epoch time.Time
}{
Data: struct {
StartDate time.Time
DepartureTimeID int
}{time.Now(), 1},
Epoch: time.Time{},
}
tmpl.Execute(os.Stdout, tcx)
}
使用自定义函数
这几乎是不言自明的:只需定义一个自定义函数来验证您的日期。在这个例子中,我再次检查了零值。但是,您当然可以随心所欲地进行细化:
package main
import (
"html/template"
"os"
"log"
"time"
)
const templateText = `
{{ if afterEpoch .StartDate }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}">{{ .StartDate.Format "2006-01-02" }}</div>
{{ else }}
<div class="box date-row" id="startdate-{{ .DepartureTimeID }}"></div>
{{ end }}
`
func AfterEpoch(t time.Time) bool {
return t.After(time.Time{})
}
type yourData struct {
DepartureTimeID int
StartDate time.Time
}
func main() {
funcMap := template.FuncMap{
"afterEpoch": AfterEpoch,
}
tmpl := template.Must(template.New("fmap").Funcs(funcMap).Parse(templateText))
log.Println("First run")
tmpl.Execute(os.Stdout, yourData{1, time.Now()})
log.Println("Second run")
tmpl.Execute(os.Stdout, yourData{DepartureTimeID:1})
}
编辑:
当然,你也可以使用管道符号来表示第二种解决方案,为了更具可读性,恕我直言:{{ if .StartDate | afterEpoch }}