Maison  >  Article  >  développement back-end  >  Modèles Golang : l'utilisation de FuncMap avec html/template produit une réponse vide

Modèles Golang : l'utilisation de FuncMap avec html/template produit une réponse vide

王林
王林avant
2024-02-12 11:24:071087parcourir

Golang 模板:将 FuncMap 与 html/template 结合使用会产生空响应

Lorsque nous utilisons le moteur de modèles de Golang, nous avons souvent besoin de fonctions personnalisées pour gérer une logique spécifique. Cependant, lorsque nous combinons une fonction personnalisée avec FuncMap dans le package html/template, nous pouvons rencontrer un problème étrange : une réponse vide est produite. L'éditeur PHP Banana présentera la cause de ce problème dans cet article et fournira des solutions pour garantir que nous pouvons utiliser correctement le moteur de modèles Golang.

Contenu de la question

Utilisation de html/template J'essaie de remplir un champ de date dans un formulaire HTML en utilisant un champ de type template.FuncMaptime.Time mais cela ne fonctionne pas pour moi.

Le code suivant fonctionne,

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
}

Ma fonction découpée main,

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)
}

AddTask fonction,

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)
    }
}

Dans add_task.html, si je mets l'espace réservé suivant, lorsque je clique sur http://localhost:8080/project/1/add-task, il est capable de renseigner la date de début,

<input type="date" id="start_date" name="start_date" value="{{.FormattedStartDate}}">

Cependant, si je remplace la première ligne suivante dans AddTask(),

tmpl := template.Must(template.ParseFiles("static/add_task.html"))

Avec celui ci-dessous,

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"))

Si je modifie add_task.html comme suit,

<input type="date" id="start_date" name="start_date" value="{{.TaskDetails.StartDate | startdate}}">

Quand je clique sur http://localhost:8080/project/1/add-task, j'obtiens une réponse vide (mais j'obtiens 200 OK)

J'ai également évoqué la question suivante sans succès,

https://stackoverflow.com/a/35550730/8813473

Workaround

Comme @icza l'a mentionné dans les commentaires, la réception de l'erreur de Template.Execute() a révélé le problème.

J'ai eu une erreur, template: "" 是一个不完整或空的模板

Reportez-vous à la réponse de https://www.php.cn/link/949686ecef4ee20a62d16b4a2d7ccca3, j'ai changé template .New("") 调用 template.New("add_task.html") pour résoudre le problème.

Le code final est le suivant,

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"))

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer