Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gin HTML rendering documentation example incorrect #3801

Open
f1gjam opened this issue Dec 13, 2023 · 2 comments · May be fixed by gin-gonic/website#256
Open

Gin HTML rendering documentation example incorrect #3801

f1gjam opened this issue Dec 13, 2023 · 2 comments · May be fixed by gin-gonic/website#256

Comments

@f1gjam
Copy link

f1gjam commented Dec 13, 2023

Hi, looking at the page:

https://gin-gonic.com/docs/examples/html-rendering/

specifically this example:

func main() {
	router := gin.Default()
	router.LoadHTMLGlob("templates/**/*")
	router.GET("/posts/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title": "Posts",
		})
	})
	router.GET("/users/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
			"title": "Users",
		})
	})
	router.Run(":8080")
}

When you do

	router.LoadHTMLGlob("templates/**/*")

This looks for any files within the templates directory and any subsequent subdirectories.

However these templates/files are availble using their filename and NOT the path.

For example given the following directory structure

  • template/
    /base
    /file1.html
    /other
    /file2.html

When using using these templates in code

func fileOne(c *gin.Context) {
	c.HTML(http.StatusOK, "base/file1.html", nil)
}

you CANNOT use the path "base/file1.html" you have to just call the filename (see example below)

func fileOne(c *gin.Context) {
	c.HTML(http.StatusOK, "file1.html", nil)
}

I realised this when running the gin app you get the following output on console

[GIN-debug] Loaded HTML Templates (14):
- file1.html
- file2.html

Which basically means that Gin loads the files and makes them available, however when you want to use those file you just call the filename. The example shows that you call the base path etc.. but this does not work.

This also means you cannot have templates with the same filename.

@dreamjz
Copy link

dreamjz commented Dec 18, 2023

Do you wrap your html template in the {{define <template-path>}} - {{end}} block?

Here is my code try to reproduce your issue:

func main() {
	router := gin.Default()
	router.LoadHTMLGlob("templates/**/*")
	router.GET("/posts/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title": "Posts",
		})
	})
	router.GET("/users/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
			"title": "Users",
		})
	})

	router.GET("/base/file1", func(c *gin.Context) {
		c.HTML(http.StatusOK, "base/file1.tmpl", gin.H{
			"title": "base",
		})
	})

	router.GET("/other/file2", func(c *gin.Context) {
		c.HTML(http.StatusOK, "file2.tmpl", gin.H{
			"title": "other",
		})
	})

	router.GET("/other/file2-1", func(c *gin.Context) {
		c.HTML(http.StatusOK, "other/file2.tmpl", gin.H{
			"title": "other",
		})
	})

	router.Run(":8080")
}

The templates dir :

templates
├── base
│   └── file1.tmpl
├── other
│   └── file2.tmpl
├── posts
│   └── index.tmpl
└── users
    └── index.tmpl

file1:

{{ define "base/file1.tmpl" }}
    <html><h1>
        {{ .title }}
    </h1>
    </html>
{{ end }}

file2

    <html><h1>
        {{ .title }}
    </h1>
    </html>

Test cases:

$  curl http://localhost:8080/base/file1

    <html><h1>
        base
    </h1>
    </html>

$ curl  http://localhost:8080/other/file2-1
#  GIN Log: Error #01: html/template: "other/file2.tmpl" is undefined

$  curl http://localhost:8080/other/file2
    <html><h1>
        other
    </h1>
    </html>

If you forgot to define your template file in the {{define}}, I think add it will solve your issue.

@f1gjam
Copy link
Author

f1gjam commented Dec 18, 2023

@dreamjz you are correct, the templates are not wrapped {{define }} - {{end}} .

Thank you for tracking this down. The documentation should be updated to state this, dont you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants