【问题标题】:golang html/template templates with same names in different directories不同目录中具有相同名称的golang html /模板模板
【发布时间】:2021-12-01 13:24:49
【问题描述】:

问题: 如果它们位于不同的文件夹中并且名称相同,我如何为特定方法(具有不同的路由)指定特定的模板?

描述:

例如,我在数据库、用户和代理商中有两个表,它们具有不同的字段。对于它们中的每一个,我都通过 SELECT 函数为列表对象制作了路由器。 路由器:

r := mux.NewRouter() // gorilla/mux
r.HandleFunc("/user", handlers.UserList).Methods("GET")
r.HandleFunc("/agency", handlers.AgencyList).Methods("GET")

其中 handlers 是一个带有数据库指针和模板的结构体,

type Handler struct {
    DB   *sql.DB
    Tmpl *template.Template
}

它有一个捕捉响应的方法:

func (h *Handler) AgencyList(w http.ResponseWriter, r *http.Request) {
    Agencys := []*Agency{}
    rows, err := h.DB.Query(`SELECT Id, Name, IsActive FROM Agencys`)
    // etc code for append objects into Agencys and error handling
    err = h.Tmpl.ExecuteTemplate(w, "index.html", struct{ Agencys []*Agency }{Agencys: Agencys})
    // etc code and error handling
}

处理用户列表功能的原则相同。 这个处理程序还有 GET(一个对象)POST 和 DELETE 方法的方法,对于每个方法,我需要特定的模板来工作(用于编辑等)。 所以。 在此示例中,我有目录模板,其中我有两个子目录“用户”和“代理”,其中每个“主题”(用户和代理)的文件 index.html(用于列出对象)。

templates\
  \agency
   --\edit.html
   --\index.html
   ... etc htmls for agency
  \user
   --\edit.html
   --\index.html
   ... etc htmls for users
  ... etc dirs for other DB-objects

我正在使用这个:

func main() {
    handlers := &handler.Handler{
        DB:   db,
        Tmpl: template.Must(template.ParseGlob("templates/*.html")), // for root templates
    }
    // next code is avoid panic: read templates/agency: is a directory
    template.Must(handlers.Tmpl.ParseGlob("templates/user/*.html"))
    template.Must(handlers.Tmpl.ParseGlob("templates/agency/*.html"))
    r := mux.NewRouter()
    r.HandleFunc("/", handlers.Index).Methods("GET") // root
    r.HandleFunc("/user", handlers.UserList).Methods("GET")
    r.HandleFunc("/agency", handlers.AgencyList).Methods("GET")
// etc code with ListenAndServe()
}

毕竟我在模板中发现了错误

template: index.html:26:12: executing "index.html" at <.Agencys>: can't evaluate field Agencys in type struct { Users []*handler.User } 

当我尝试在浏览器中调用本地主机/用户列表时(当然,因为它是具有不同字段的不同“对象”)。看起来 ParseGlob(agency/) 在 ParseGlob(user/) 之后重新定义了同名的模板

我正在尝试找到这样的解决方案:

err = h.Tmpl.ExecuteTemplate(w, "templates/user/index.html", post)

在方法 UserList() 中用于指向需要哪个模板。

也许这一切都不是好的解决方案;也许会很好,如果我在模板名称中使用前缀(如模板目录中的 listAgency.html 和 listUser.html),而不是像现在这样为每个对象使用不同的目录。我试过这种方式,但看起来没有那么漂亮和美丽。

【问题讨论】:

  • 您需要关联所有模板吗?如果没有,只需创建并使用不同的template.Templates。如果是,请使用唯一名称(例如,将它们重命名为 user-index.htmlagency-index.html)。
  • 是的。对不同名称的相同想法。同时,如果使用不同的template.Templates,这将在模板中产生类似命名空间的东西,并且需要存储在handler 对象中(同样不是美)。我猜如果没有关联就无法使用继承。

标签: go go-html-template


【解决方案1】:

我正在尝试找到这样的解决方案:

err = h.Tmpl.ExecuteTemplate(w, "templates/user/index.html", post)

您可以将每个文件的内容包装在“定义操作”中,然后将其命名为您想要的名称。

例如,打开文件templates\user\index.html并在顶部添加这一行

{{ define "templates/user/index.html" }}

还有这条线在底部

{{ end }}

然后是下面

err = h.Tmpl.ExecuteTemplate(w, "templates/user/index.html", post)

会起作用的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多