Closed lukepuplett closed 2 months ago
I moved the templates into their own folders and changed the globbing loader
ginRoutes.LoadHTMLGlob("templates/**/*")
*[main][~/Git/myapp_go/templates]$ tree
.
├── anon
│ └── index.html
├── authorized
│ └── sign_in_success.html
└── base
└── base.html
4 directories, 3 files
And altered the path in the handler.
package landing
import (
"net/http"
"myapp/internal/routes"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
)
func IndexGetHandler(ctx *gin.Context) {
log.Info().Msg("IndexGetHandler called")
urlToAuthorized, err := routes.GenerateURL("test_page", nil)
if err != nil {
ctx.JSON(500, gin.H{"error": "Failed to generate URL to authorized page"})
return
}
ctx.HTML(http.StatusOK, "anon/index.html", gin.H{
"title": "Go Web App",
"message": "Welcome to the Go Web App with Templates!",
"urlToAuthorized": urlToAuthorized,
})
}
But despite loading the templates, it now it cannot find it when the handler runs.
*[main][~/Git/myapp_go]$ go run cmd/server.go
7:48PM INF Project root path path=/Users/lukepuplett/Git/myapp_go
7:48PM INF Static folder path path=/Users/lukepuplett/Git/myapp_go/static
7:48PM INF Secrets folder path path=/Users/lukepuplett/Git/myapp_go/secrets
7:48PM INF Firestore key path path=/Users/lukepuplett/Git/myapp_go/secrets/cloud-run-sa.json
7:48PM INF Checking configuration
7:48PM ??? [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
7:48PM ??? [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
7:48PM INF Loading templates
7:48PM ??? [GIN-debug] Loaded HTML Templates (8):
- base.html
- footer
- header
-
- index.html
- title
- content
- sign_in_success.html
7:48PM INF Setting config on context
7:48PM INF Setting error handling middleware
7:48PM INF Registering routes
7:48PM ??? [GIN-debug] GET / --> myapp/internal/handlers/anon/landing.IndexGetHandler (5 handlers)
7:48PM ??? [GIN-debug] GET /static/*filepath --> myapp/internal/handlers.StaticGetHandler (5 handlers)
7:48PM ??? [GIN-debug] GET /test/logging --> myapp/internal/handlers.LoggingTestGetHandler (5 handlers)
7:48PM ??? [GIN-debug] GET /test/cookie --> myapp/internal/handlers/anon/landing.CookieGetHandler (5 handlers)
7:48PM ??? [GIN-debug] GET /original/:imageId --> myapp/internal/handlers/anon/landing.OriginalImageGetHandler (5 handlers)
7:48PM ??? [GIN-debug] GET /web/authorized --> myapp/internal/handlers/authorized.SignInSuccessGetHandler (6 handlers)
7:48PM ??? [GIN-debug] GET /v1/json/image --> myapp/internal/handlers/api.ImageExistGetHandler (6 handlers)
7:48PM INF Starting server on :8080 (isDev: true)
7:48PM ??? [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
7:48PM ??? [GIN-debug] Listening and serving HTTP on :8080
7:48PM INF IndexGetHandler called
7:48PM ERR Internal server error error="html/template: \"anon/index.html\" is undefined"
7:48PM ??? [GIN] 2024/09/19 - 19:48:16 | 200 | 1.021625ms | ::1 | GET "/"
Error #01: html/template: "anon/index.html" is undefined
And the message as seen from CURL printed by my logging middleware.
[master][~/Git/myapp]$ curl http://localhost:8080/
{"error":"html/template: \"anon/index.html\" is undefined\nmyapp/internal/hosting.SetupHostRoutes.errorHandlingMiddleware.func2\n\t/Users/lukepuplett/Git/myapp_go/internal/hosting/hosting.go:108\ngithub.com/gin-gonic/gin.(*Context).Next\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185\nmyapp/internal/hosting.SetupHostRoutes.func1\n\t/Users/lukepuplett/Git/myapp_go/internal/hosting/hosting.go:30\ngithub.com/gin-gonic/gin.(*Context).Next\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185\ngithub.com/gin-gonic/gin.CustomRecoveryWithWriter.func1\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/recovery.go:102\ngithub.com/gin-gonic/gin.(*Context).Next\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185\ngithub.com/gin-gonic/gin.LoggerWithConfig.func1\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/logger.go:249\ngithub.com/gin-gonic/gin.(*Context).Next\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/context.go:185\ngithub.com/gin-gonic/gin.(*Engine).handleHTTPRequest\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:633\ngithub.com/gin-gonic/gin.(*Engine).ServeHTTP\n\t/Users/lukepuplett/go/pkg/mod/github.com/gin-gonic/gin@v1.10.0/gin.go:589\nnet/http.serverHandler.ServeHTTP\n\t/opt/homebrew/Cellar/go/1.23.1/libexec/src/net/http/server.go:3210\nnet/http.(*conn).serve\n\t/opt/homebrew/Cellar/go/1.23.1/libexec/src/net/http/server.go:2092\nruntime.goexit\n\t/opt/homebrew/Cellar/go/1.23.1/libexec/src/runtime/asm_arm64.s:1223"}%
What I have noticed is that the gin documentation doesn't really go into detail about templating. Other people's websites do, and they seem to do it differently to the gin docs.
This is from the gin docs; notice how it uses .tmpl and also how it appears to define itself with its own file path?! That's weird anyway because it could become out-of-synch with its actual location and name.
From: https://gin-gonic.com/docs/examples/html-rendering/
Apparently this is templates/posts/index.tmpl
{{ define "posts/index.tmpl" }}
<html><h1>
{{ .title }}
</h1>
<p>Using posts/index.tmpl</p>
</html>
{{ end }}
Okay, so it seems that the blocks or something is not supported or I don't know.
Anyway, I followed someone's blog that instead of using defined blocks and base templates, it just created sandwiches with one of the templates simply containing </html>
which is simple and works.
By the way, the fact that it spat out the wrong template is concerning. This could potentially leak information the visitor is not supposed to see, if it were sitting in the "model" that's passed to the templater.
Background: I'm learning Go, and using gin. I have decades of coding experience.
Gin is rendering the wrong template file. I am globbing the templates folder with the following code:
Here is the handler code for the
/
route, which should renderindex.html
:Here is the handler code for a test
/web/authorized
route which uses a different template, this is important for later:Here is the output from the server logging to stdout.
You can see the routes and you can also see
IndexGetHandler called
in the logs, and you can see in the code above that the handler for this route does indeed log "IndexGetHandler called".Here is the output from CURL for
http://localhost:8080/
Here's the template for
index.html
which is what should be rendered when I go tohttp://localhost:8080/
And here's the template that seems to be being rendered, which is
sign_in_success.html
which is a different handler, which is not called (not in logs).I simply start the server with
> go run cmd/server.go
and then in another terminal tab run> CURL http://localhost:8080/
and I see the wrong HTML. I have stopped the server and run CURL again and it doesn't connect so it's not something silly like I left a different server running.I'm not sure why it's not rendering the
index.html
template.