Golang模板在使用httprouter时无法正常工作。

huangapple go评论81阅读模式
英文:

golang templates not working with httprouter

问题

我已经创建了嵌套模板,当我使用"net/http"和http.HandleFunc时可以正常工作,但是我决定以后使用"github.com/julienschmidt/httprouter",因为我想要更灵活性,但是现在我的模板不起作用,我得到了一个404错误。

请问,你能帮忙吗?

目录结构

/
/main.go
/templates
/templates/tstats/file.go.html

这段代码是有效的

func init() {
    tpl = template.Must(template.ParseGlob("templates/*.go.html"))
}
http.HandleFunc("/tstats/", serveTemplate)

func serveTemplate(w http.ResponseWriter, r *http.Request) {
    lp := filepath.Join("templates", "layout.html")
    fp := filepath.Join("templates", filepath.Clean(r.URL.Path))
    gh := filepath.Join("templates", "INC_Header.go.html")
    gn := filepath.Join("templates", "INC_Nav.go.html")
    gf := filepath.Join("templates", "INC_Footer.go.html")
    //log.Println(r.URL.Path)

tpl, err := template.ParseFiles(lp, fp, gh, gn, gf)
if err := tpl.ExecuteTemplate(w, "layout", nil); err != nil {
    log.Println(err.Error())
    http.Error(w, http.StatusText(500), 500)
}

这段新代码产生了404错误

func serveTemplate(w http.ResponseWriter, r *http.Request, _ 
    httprouter.Params) {
    lp := filepath.Join("templates", "layout.html")
    fp := filepath.Join("templates", filepath.Clean(r.URL.Path))
    gh := filepath.Join("templates", "INC_Header.go.html")
    gn := filepath.Join("templates", "INC_Nav.go.html")
    gf := filepath.Join("templates", "INC_Footer.go.html")
    //log.Println(r.URL.Path)

    tmpl, err := template.ParseFiles(lp, fp, gh, gn, gf)
    if err := tmpl.ExecuteTemplate(w, "layout", nil); err != nil {
        log.Println(err.Error())
        http.Error(w, http.StatusText(500), 500)
   }
英文:

I've created nested templating that works when I use "net/http" and http.HandelFunc , however, I've decided to use "github.com/julienschmidt/httprouter" going forward as I want to have move flexibility and now my templates don't work, I get a 404 error.

Please, can you help?

Directory structure

/
/main.go
/templates
/templates/tstats/file.go.html

This code works

func init() {
    tpl = template.Must(template.ParseGlob("templates/*.go.html"))
}
http.HandleFunc("/tstats/", serveTemplate)

func serveTemplate(w http.ResponseWriter, r *http.Request) {
    lp := filepath.Join("templates", "layout.html")
    fp := filepath.Join("templates", filepath.Clean(r.URL.Path))
    gh := filepath.Join("templates", "INC_Header.go.html")
    gn := filepath.Join("templates", "INC_Nav.go.html")
    gf := filepath.Join("templates", "INC_Footer.go.html")
    //log.Println(r.URL.Path)

tpl, err := template.ParseFiles(lp, fp, gh, gn, gf)
if err := tpl.ExecuteTemplate(w, "layout", nil); err != nil {
    log.Println(err.Error())
    http.Error(w, http.StatusText(500), 500)
}

The new code that is producing a 404

func serveTemplate(w http.ResponseWriter, r *http.Request, _ 
    httprouter.Params) {
    lp := filepath.Join("templates", "layout.html")
    fp := filepath.Join("templates", filepath.Clean(r.URL.Path))
    gh := filepath.Join("templates", "INC_Header.go.html")
    gn := filepath.Join("templates", "INC_Nav.go.html")
    gf := filepath.Join("templates", "INC_Footer.go.html")
    //log.Println(`enter code here`r.URL.Path)

    tmpl, err := template.ParseFiles(lp, fp, gh, gn, gf)
    if err := tmpl.ExecuteTemplate(w, "layout", nil); err != nil {
        log.Println(err.Error())
        http.Error(w, http.StatusText(500), 500)
   }

答案1

得分: 0

在评论回复之后进行修改。我查看了https://play.golang.org/p/iHUqZQQcv3

你有以下问题:

  1. 路由处理程序注册问题 r.GET("/tstats/", serveTemplate) - 它只匹配 http://localhost:8080/tstats/,其他的都是 404
    • 例如:404 -> http://localhost:8080/tstats/myfile1.html
  2. 计算模板路径文件的方式 filepath.Join("templates", filepath.Clean(r.URL.Path))

老实说,很难猜测你是如何计划/设计你的应用程序的。无论如何-

请按照以下方式更新你的代码:

  • /tstats/ 改为 /tstats/*tmpl 在路由映射中
  • fp := filepath.Join("templates", filepath.Clean(r.URL.Path)) 改为 fp := filepath.Join("templates", "tstats", params.ByName("tmpl"))

现在,对于请求 http://localhost:8080/tstats/myfile1.html,它将在这里查找模板 templates/tstats/myfile1.html


(这是最初的回答)

似乎是 HandlerFunc 注册问题导致了 404。

我根据你的代码创建了一个示例,你可以尝试一下 https://play.golang.org/p/6ilS0htj-I

顺便说一句,我相信在你的第一个示例代码中,func init 中的 tpl 变量没有被使用。因为你在 serveTemplate 中有同名的局部变量。

英文:

Revising after the comment response. I had a look https://play.golang.org/p/iHUqZQQcv3

You have following issues:

  1. Router handler register issue r.GET("/tstats/", serveTemplate) - It will only match http://localhost:8080/tstats/ rest everything is 404
    • For e.g.: 404 -> http://localhost:8080/tstats/myfile1.html
  2. The way you calculate the template path file filepath.Join("templates", filepath.Clean(r.URL.Path))

Honestly it is very hard to guess, how you're planning/designing your application. Anyway-

Update your code like below:

  • Change /tstats/ => /tstats/*tmpl in the router mapping
  • Change fp := filepath.Join("templates", filepath.Clean(r.URL.Path)) => fp := filepath.Join("templates", "tstats", params.ByName("tmpl"))

Now, for the request http://localhost:8080/tstats/myfile1.html. It will look for template here templates/tstats/myfile1.html.


(This was initial response)

It seems like HandlerFunc register issue that leading to 404.

I have created sample from your code, can you try https://play.golang.org/p/6ilS0htj-I

BTW, I believe; in your first sample code tpl variable in the func init is not used. Since you have local variable of same name in the serveTemplate.

huangapple
  • 本文由 发表于 2017年6月14日 13:39:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/44536284.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定