在使用Golang的模板引擎時(shí),我們經(jīng)常需要自定義函數(shù)來處理一些特定的邏輯。然而,當(dāng)我們將自定義函數(shù)與html/template包中的FuncMap結(jié)合使用時(shí),可能會(huì)遇到一種奇怪的問題:產(chǎn)生空響應(yīng)。php小編香蕉將在本文中介紹這個(gè)問題的原因,并提供解決方案,以確保我們能夠正確地使用Golang模板引擎。
問題內(nèi)容
使用 html/template 我試圖使用 template.FuncMap
從 time.Time
類型的字段填充 HTML 表單中的日期字段,但它對(duì)我不起作用。
以下代碼有效,
type Task struct { ID int ProjectID int Description string StartDate time.Time Duration float32 } type ProjectTaskData struct { ProjectID int ProjectName string TaskDetails Task FormattedStartDate string // this field is a hack/workaround for me }
登錄后復(fù)制
我修剪后的 main
函數(shù),
func main() { db := GetConnection() r := mux.NewRouter() // other handlers here are removed r.HandleFunc("/project/{project-id}/add-task", AddTask(db)) r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static/")))) http.ListenAndServe(":8080", r) }
登錄后復(fù)制
AddTask
函數(shù),
func AddTask(db *sql.DB) func(w http.ResponseWriter, r *http.Request) { //tmpl := template.Must(template.New("").Funcs(template.FuncMap{ // "startdate": func(t time.Time) string { return t.Format("2006-01-02") }, //}).ParseFiles("static/add_task.html")) tmpl := template.Must(template.ParseFiles("static/add_task.html")) return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) projectID, err := strconv.Atoi(vars["project-id"]) if err != nil { log.Fatal(err) } var projectName string var projectStartDate time.Time err = db.QueryRow(`select name, start_date from projects where id = ?`, projectID).Scan(&projectName, &projectStartDate) switch { case err == sql.ErrNoRows: log.Printf("No project with id %d\n", projectID) return case err != nil: log.Fatalf("Query error: %v\n", err) default: log.Printf("Got project %v with id %d\n", projectName, projectID) } if r.Method != http.MethodPost { data := ProjectTaskData{ ProjectID: projectID, ProjectName: projectName, TaskDetails: Task{ ProjectID: projectID, Description: "", StartDate: projectStartDate, Duration: 1, }, FormattedStartDate: projectStartDate.Format(time.DateOnly), } tmpl.Execute(w, data) return } // rest of code handling the post action here http.Redirect(w, r, "/project/"+fmt.Sprint(projectID)+"/tasks", http.StatusFound) } }
登錄后復(fù)制
在 add_task.html
中,如果我放置以下占位符,則當(dāng)我點(diǎn)擊 http://localhost:8080/project/1/add-task 時(shí),它能夠填充開始日期,
登錄后復(fù)制
但是,如果我替換 AddTask() 中的以下第一行,
tmpl := template.Must(template.ParseFiles("static/add_task.html"))
登錄后復(fù)制
與下面的一個(gè),
tmpl := template.Must(template.New("").Funcs(template.FuncMap{ "startdate": func(t time.Time) string { return t.Format("2006-01-02") }, }).ParseFiles("static/add_task.html"))
登錄后復(fù)制
如果我按如下方式更改 add_task.html,
登錄后復(fù)制
當(dāng)我點(diǎn)擊 http://localhost:8080/project/1/add-task 時(shí),我得到一個(gè)空響應(yīng)(但我得到 200 OK)
我還提到了以下問題,但沒有成功,
https://stackoverflow.com/a/35550730/8813473
解決方法
正如 @icza 在評(píng)論中提到的,從 Template.Execute()
收到錯(cuò)誤揭示了這個(gè)問題。
我收到錯(cuò)誤,
template: "" 是一個(gè)不完整或空的模板
參考https://www.php.cn/link/949686ecef4ee20a62d16b4a2d7ccca3的答案,我更改了template .New("")
調(diào)用 template.New("add_task.html")
來解決該問題。
最終代碼如下所示,
tmpl := template.Must(template.New("add_task.html").Funcs(template.FuncMap{ "startdate": func(t time.Time) string { return t.Format("2006-01-02") }, }).ParseFiles("static/add_task.html"))
登錄后復(fù)制