Golang Gin基础HTML模板

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

Golang Gin Base HTML Template

问题

我有一个基本的HTML模板,并希望在所有HTML文件中使用它。

package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	// 加载模板文件
	r.LoadHTMLGlob("templates/*.html")

	r.GET("/page1", func(c *gin.Context) {
		c.HTML(200, "base.html", gin.H{
			"title":   "Page 1 IS HERE",
			"content": "page1.html",
		})
	})

	r.GET("/page2", func(c *gin.Context) {
		c.HTML(200, "base.html", gin.H{
			"title":   "Page 2 IS HERE",
			"content": "page2.html",
		})
	})

	r.Run("127.0.0.1:8080")
}

我的base.html模板如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{.title}}</title>
</head>
<body>
    <h1>BASELINE</h1>
    <div id="content">
        {{template "content" .}}
    </div>
</body>
</html>

page1.html的内容如下:

{{define "content"}}
<h2>Welcome to Page 1</h2>
<p>This is the content of Page 1.</p>
{{end}}

page2.html的内容如下:

{{define "content"}}
<h2>Welcome to Page 2</h2>
<p>This is the content of Page 2.</p>
{{end}}

打印结果:
/page1 = 欢迎来到Page 2
这是Page 2的内容。

/page2 = 欢迎来到Page 2
这是Page 2的内容。

当我运行这段代码时,两个链接都使用了page2.html的内容。我该如何修复它?

英文:

I have a base html template and want to work it with in all html files.

package main

import (
	&quot;github.com/gin-gonic/gin&quot;
)

func main() {
	r := gin.Default()

	// Şablon dosyalarını y&#252;kleme
	r.LoadHTMLGlob(&quot;templates/*.html&quot;)

	r.GET(&quot;/page1&quot;, func(c *gin.Context) {
		c.HTML(200, &quot;base.html&quot;, gin.H{
			&quot;title&quot;:   &quot;Page 1 IS HERE&quot;,
			&quot;content&quot;: &quot;page1.html&quot;,
		})
	})

	r.GET(&quot;/page2&quot;, func(c *gin.Context) {
		c.HTML(200, &quot;base.html&quot;, gin.H{
			&quot;title&quot;:   &quot;Page 2 IS HERE&quot;,
			&quot;content&quot;: &quot;page2.html&quot;,
		})
	})

	r.Run(&quot;127.0.0.1:8080&quot;)
}

my base.html

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;{{.title}}&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;BASELINE&lt;/h1&gt;
    &lt;div id=&quot;content&quot;&gt;
        {{template &quot;content&quot; .}}
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

page1.html

{{define &quot;content&quot;}}
&lt;h2&gt;Welcome to Page 1&lt;/h2&gt;
&lt;p&gt;This is the content of Page 1.&lt;/p&gt;
{{end}}

page2.html

{{define &quot;content&quot;}}
&lt;h2&gt;Welcome to Page 2&lt;/h2&gt;
&lt;p&gt;This is the content of Page 2.&lt;/p&gt;
{{end}}

Print;
/page1 = Welcome to Page 2
This is the content of Page 2.

/page2 = Welcome to Page 2
This is the content of Page 2.

When I run this code, both link use page2.html content. How can I fix it?

答案1

得分: 2

我通过以下方式使用HTML模板实现了你所需的功能。首先,让我介绍一下我的项目结构:

  • appName
    • templates
      • footer.tmpl
      • header.tmpl
      • page1.tmpl
      • page2.tmpl
    • main.go

现在,让我们从模板定义开始。

模板定义

header.tmpl 文件

{{define "header.tmpl" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{.title}}</title>
</head>
<body>
    <h1>BASELINE</h1>
    <div id="content">
{{end}}

footer.tmpl 文件

{{define "footer.tmpl"}}
</div>
</body>
</html>
{{end}}

page1.tmpl 文件

{{template "header.tmpl"}}
<h2>Welcome to Page 1</h2>
<p>This is the content of Page 1.</p>
{{template "footer.tmpl"}}

page2.tmpl 文件

{{template "header.tmpl"}}
<h2>Welcome to Page 2</h2>
<p>This is the content of Page 2.</p>
{{template "footer.tmpl"}}

main.go 文件

package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	gin.SetMode(gin.DebugMode)
	r := gin.Default()

	// 加载模板
	r.LoadHTMLGlob("templates/*.tmpl")

	r.GET("/page1", func(c *gin.Context) {
		c.HTML(200, "page1.tmpl", gin.H{
			"title": "Page 1 IS HERE",
		})
	})

	r.GET("/page2", func(c *gin.Context) {
		c.HTML(200, "page2.tmpl", gin.H{
			"title": "Page 2 IS HERE",
		})
	})

	r.Run("127.0.0.1:8080")
}

首先,我们添加了对 gin.SetMode(gin.DebugMode) 的调用。通过这个调用,我们可以看到实际加载到 gin.Renderer 实例中的模板。
通过使用 LoadHTMLGlob 方法,我们加载了所有模板。该模式匹配我们在文件系统中定义的任何 *.tmpl 文件。
其余的代码与你在问题中编写的代码基本相同。
通过使用这种方法,你应该能够通过使用两个 tmpl 文件来避免常见结构的重复。
可能还有更加优雅的方法来实现这一点。如果有人找到了,请告诉我,谢谢!

英文:

I was able to achieve what you need by using the HTML templates in the following way. First, let me present my project structure:

  • appName
    • templates
      • footer.tmpl
      • header.tmpl
      • page1.tmpl
      • page2.tmpl
    • main.go

Now, let's start with templates definition.

Templates definition

header.tmpl file

{{define &quot;header.tmpl&quot; }}
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;{{.title}}&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;BASELINE&lt;/h1&gt;
    &lt;div id=&quot;content&quot;&gt;
{{end}}

footer.tmpl file

{{define &quot;footer.tmpl&quot;}}
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
{{end}}

page1.tmpl file

{{template &quot;header.tmpl&quot;}}
&lt;h2&gt;Welcome to Page 1&lt;/h2&gt;
&lt;p&gt;This is the content of Page 1.&lt;/p&gt;
{{template &quot;footer.tmpl&quot;}}

page2.tmpl file

{{template &quot;header.tmpl&quot;}}
&lt;h2&gt;Welcome to Page 2&lt;/h2&gt;
&lt;p&gt;This is the content of Page 2.&lt;/p&gt;
{{template &quot;footer.tmpl&quot;}}

The main.go file

package main

import (
	&quot;github.com/gin-gonic/gin&quot;
)

func main() {
	gin.SetMode(gin.DebugMode)
	r := gin.Default()

	// load templates
	r.LoadHTMLGlob(&quot;templates/*.tmpl&quot;)

	r.GET(&quot;/page1&quot;, func(c *gin.Context) {
		c.HTML(200, &quot;page1.tmpl&quot;, gin.H{
			&quot;title&quot;: &quot;Page 1 IS HERE&quot;,
		})
	})

	r.GET(&quot;/page2&quot;, func(c *gin.Context) {
		c.HTML(200, &quot;page2.tmpl&quot;, gin.H{
			&quot;title&quot;: &quot;Page 2 IS HERE&quot;,
		})
	})

	r.Run(&quot;127.0.0.1:8080&quot;)
}

First, we added the invocation to gin.SetMode(gin.DebugMode). Thanks to this, we're able to see which templates are actually loaded in our gin.Renderer instance.
By using the method LoadHTMLGlob we load all of them. The pattern matches any *.tmpl file we define on the file system.
The remaining code is more or less the same as you wrote within the question.
By using this method you should be able to avoid the duplication of the common structure by using two tmpl files.
Probably, there is an even more elegant way of achieving this. In case someone finds it, just let me know, thanks!

huangapple
  • 本文由 发表于 2023年6月12日 18:09:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76455596.html
匿名

发表评论

匿名网友

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

确定