Description
As part of a microservice, I'm attempting to use a gin context's HTML template function to dynamically generate documents.
While the templating itself works, I need a way to assign the resulting HTML to a string.
Since g.HTML in the example below offers no return value, how do I assign the templated HTML to a string variable?
How to reproduce
router.R.Engine().LoadHTMLGlob("templ/pdf/*.html")
router.R.POST("/pdf", func(c *Hello, g *gin.Context) int {
g.HTML(http.StatusOK, "hello.html", gin.H{
"salutation": c.Salutation,
"name": c.Name,
})
Environment
- go version: 1.19.1
- gin version (or commit ref): 1.7.7 (I'm using gNext, but it bundles gin internally and I use the exposed raw functionality most of the time)
- operating system: Windows 11 (WSL2)
Comment From: markusbkk
Not sure if this is canonical (found in an older Stack Overflow thread) but this is how I implemented it now.
type htmlWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (w htmlWriter) Write(b []byte) (int, error) {
w.body.Write(b)
return w.ResponseWriter.Write(b)
}
func returnHTML(c *gin.Context) htmlWriter {
html := &htmlWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
c.Writer = html
c.Next()
statusCode := c.Writer.Status()
if statusCode >= 400 {
//ok this is an request with error, let's make a record for it
// now print body (or log in your preferred way)
fmt.Println("Response body: " + html.body.String())
}
return *html
}
It can then be used by providing the context from within the POST function.
i e:
html := returnHTML(g)
(where g is *gin.Context
The result can then be accessed in string form by calling html.body.String()