模板在使用嵌入式FS时无法正确解析。

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

Template is not parsing correctly with embed FS

问题

我有以下代码:

package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"
	"onsen/resources"
)

var view *template.Template
var err error

func init() {
	fmt.Println("Starting up.")
	view = template.Must(template.ParseFS(resources.Views, "templates/layouts/*.html", "templates/views/*.html", "templates/partials/*.html"))
	if err != nil {
		log.Fatal("Error loading templates:" + err.Error())
	}
}

func main() {
	server := http.Server{
		Addr: "127.0.0.1:8070",
	}

	http.Handle("/webUI/", http.StripPrefix("/webUI/", http.FileServer(http.FS(resources.WebUI))))

	http.HandleFunc("/process", process)
	http.HandleFunc("/home", home)
	http.HandleFunc("/test", test)

	server.ListenAndServe()
}

其中 onsen/resources 是:

package resources

import (
	"embed"
)

// Views 是我们的静态 Web 服务器布局、带有动态内容的视图和静态视图的部分内容。
//go:embed templates/layouts templates/views templates/partials
var Views embed.FS

路由函数如下:

package main

import (
	"log"
	"net/http"
)

func home(w http.ResponseWriter, r *http.Request) {
	err = view.ExecuteTemplate(w, "home.html", nil)
	if err != nil {
		log.Fatalln(err)
	}
}

func test(w http.ResponseWriter, r *http.Request) {
	err = view.ExecuteTemplate(w, "test.html", nil)
	if err != nil {
		log.Fatalln(err)
	}
}

func process(w http.ResponseWriter, r *http.Request) {
	err = view.ExecuteTemplate(w, "process.html", nil)
	if err != nil {
		log.Fatalln(err)
	}
}

我的模板如下:

base.html

<!-- base.html 的内容: -->
{{define "base"}}
<!doctype html>
 <html lang="en">
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta charset="utf-8">
 </head>
 <body>
            {{template "content" .}}
</body>
</html>
{{end}}

视图如下:

<!-- home.html 的内容: -->
{{template "base" .}}
{{define "content"}}
This is home
{{end}}

以及:

<!-- test.html 的内容: -->
{{template "base" .}}
{{define "content"}}
test file is here
{{end}}

还有:

<!-- process.html 的内容: -->
{{template "base" .}}
{{define "content"}}
process goes here
{{end}}

但是所有的路由都显示相同的结果,与模板 test.html 相同。

我参考了 这个链接 来构建我的模板结构,但似乎与 embed 有关!

模板在使用嵌入式FS时无法正确解析。

我参考了 这个链接 来构建我的模板结构,但似乎与 embed 有关!

英文:

I've the below code:

package main

import (
	&quot;fmt&quot;
	&quot;html/template&quot;
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;onsen/resources&quot;
)

var view *template.Template
var err error

func init() {
	fmt.Println(&quot;Starting up.&quot;)
	view = template.Must(template.ParseFS(resources.Views, &quot;templates/layouts/*.html&quot;, &quot;templates/views/*.html&quot;, &quot;templates/partials/*.html&quot;))
	if err != nil {
		log.Fatal(&quot;Error loading templates:&quot; + err.Error())
	}
}

func main() {
	server := http.Server{
		Addr: &quot;127.0.0.1:8070&quot;,
	}

	http.Handle(&quot;/webUI/&quot;, http.StripPrefix(&quot;/webUI/&quot;, http.FileServer(http.FS(resources.WebUI))))

	http.HandleFunc(&quot;/process&quot;, process)
	http.HandleFunc(&quot;/home&quot;, home)
	http.HandleFunc(&quot;/test&quot;, test)

	server.ListenAndServe()
}

Where onsen/resources is:

package resources

import (
	&quot;embed&quot;
)

// Views is our static web server layouts, views with dynamic content and partials content that is a static view.
//go:embed templates/layouts templates/views templates/partials
var Views embed.FS

And the routes functions are:

package main

import (
	&quot;log&quot;
	&quot;net/http&quot;
)

func home(w http.ResponseWriter, r *http.Request) {
	err = view.ExecuteTemplate(w, &quot;home.html&quot;, nil)
	if err != nil {
		log.Fatalln(err)
	}
}

func test(w http.ResponseWriter, r *http.Request) {
	err = view.ExecuteTemplate(w, &quot;test.html&quot;, nil)
	if err != nil {
		log.Fatalln(err)
	}
}

func process(w http.ResponseWriter, r *http.Request) {
	err = view.ExecuteTemplate(w, &quot;process.html&quot;, nil)
	if err != nil {
		log.Fatalln(err)
	}
}

My templates are:
base.html

&lt;!-- Content of base.html: --&gt;
{{define &quot;base&quot;}}
&lt;!doctype html&gt;
 &lt;html lang=&quot;en&quot;&gt;
 &lt;head&gt;
    &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
 &lt;/head&gt;
 &lt;body&gt;
            {{template &quot;content&quot; .}}
&lt;/body&gt;
&lt;/html&gt;
{{end}}

And the views are:

&lt;!-- Content of home.html: --&gt;
{{template &quot;base&quot; .}}
{{define &quot;content&quot;}}
This is home
{{end}}

And;

&lt;!-- Content of test.html: --&gt;
{{template &quot;base&quot; .}}
{{define &quot;content&quot;}}
test file is here
{{end}}

And

&lt;!-- Content of process.html: --&gt;
{{template &quot;base&quot; .}}
{{define &quot;content&quot;}}
process goes here
{{end}}

But ALL the routes are showing the same result, which is same as template test.html

模板在使用嵌入式FS时无法正确解析。

I referred to this for my template structure, but looks something related to embed!

答案1

得分: 0

感谢Cerise的评论。

应用程序将所有模板文件解析为一个模板集。
test.html中的“content”模板是最后一个添加到集合中的“content”模板。这是您在每个页面上看到的内容。将每个页面的模板解析为单独的集合。

所以,这里是正确的工作代码

package main

import (
	"html/template"
	"log"
	"net/http"
	"onsen/resources"
)

func process(w http.ResponseWriter, r *http.Request) {
	view := template.Must(template.ParseFS(resources.Views, "templates/layouts/base.html", "templates/views/other.html", "templates/partials/*.html"))

	type approval struct {
		Status bool
	}

	workflow := approval{Status: false}
	err = view.ExecuteTemplate(w, "process.html", workflow)
	if err != nil {
		log.Fatalln(err)
	}
}

而模板process.html是:

<!-- Content of other.html: -->
{{template "base" .}}
{{define "content"}}
process goes here
 {{ .Status }}

     {{if .Status}} 
        {{template "approved"}}
    {{else}} 
        {{template "rejected"}}
    {{end}}

{{end}}
英文:

Thanks to the comment by Cerise

> The application parses all of the template files to one template set.
> The "content" template in test.html is the last "content" template to
> be added to the set. That's the one you see for each page. Parse the
> template for each page to a separate set.

So, here the correct working code

package main

import (
	&quot;html/template&quot;
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;onsen/resources&quot;
)

func process(w http.ResponseWriter, r *http.Request) {
	view := template.Must(template.ParseFS(resources.Views, &quot;templates/layouts/base.html&quot;, &quot;templates/views/other.html&quot;, &quot;templates/partials/*.html&quot;))

	type approval struct {
		Status bool
	}

	workflow := approval{Status: false}
	err = view.ExecuteTemplate(w, &quot;process.html&quot;, workflow)
	if err != nil {
		log.Fatalln(err)
	}
}

And template process.html is:

&lt;!-- Content of other.html: --&gt;
{{template &quot;base&quot; .}}
{{define &quot;content&quot;}}
process goes here
 {{ .Status }}

     {{if .Status}} 
        {{template &quot;approved&quot;}}
    {{else}} 
        {{template &quot;rejected&quot;}}
    {{end}}

{{end}}

huangapple
  • 本文由 发表于 2021年10月23日 04:50:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/69682953.html
匿名

发表评论

匿名网友

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

确定