Documentation
¶
Overview ¶
Package render renders HTML, JSON, and CSV responses from templates loaded out of an io/fs.FS.
A Renderer is created with New and configured with Option values. It caches parsed templates and reuses a pool of buffers so that a rendering error never results in a partially-written response. The default template FuncMap provides string, time, i18n, and asset helpers (see funcs.go); callers can add to or override it with WithFuncs and WithTextFuncs.
Templates are discovered by walking the FS: files ending in ".html" become HTML templates and files ending in ".txt" become text templates. Assets under "static/js" and "static/css" are exposed to templates as Subresource Integrity (SRI) tags via the jsIncludeTag and cssIncludeTag functions.
Index ¶
- type CSVMarshaler
- type Option
- type Renderer
- func (r *Renderer) AllowedResponseCode(code int) bool
- func (r *Renderer) RenderCSV(w http.ResponseWriter, code int, filename string, data CSVMarshaler)
- func (r *Renderer) RenderHTML(w http.ResponseWriter, tmpl string, data any)
- func (r *Renderer) RenderHTML500(w http.ResponseWriter, err error)
- func (r *Renderer) RenderHTMLStatus(w http.ResponseWriter, code int, tmpl string, data any)
- func (r *Renderer) RenderJSON(w http.ResponseWriter, code int, data any)
- func (r *Renderer) RenderJSON500(w http.ResponseWriter, err error)
- func (r *Renderer) RenderText(w io.Writer, name string, data any) error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CSVMarshaler ¶
CSVMarshaler is implemented by values that can render themselves as CSV. It is the input to Renderer.RenderCSV.
type Option ¶
type Option func(*Renderer)
Option configures a Renderer in New.
func WithBuildID ¶
WithBuildID sets a build identifier appended to asset URLs (as a query string) for cache-busting. Change it on each deploy so clients fetch fresh assets.
func WithDevMode ¶
WithDevMode enables development mode, in which templates are reloaded on every render and real error details are shown. Do not enable it in production.
func WithFuncs ¶
func WithFuncs(f htmltemplate.FuncMap) Option
WithFuncs merges the provided functions into the HTML template FuncMap. The provided functions override the defaults on key collision, so callers can both add new helpers and replace built-in ones.
func WithLogger ¶
WithLogger sets the fallback logger used by the renderer's methods. If unset, the renderer uses logging.DefaultLogger.
func WithTextFuncs ¶
func WithTextFuncs(f texttemplate.FuncMap) Option
WithTextFuncs merges the provided functions into the text template FuncMap, overriding the defaults on key collision.
type Renderer ¶
type Renderer struct {
// contains filtered or unexported fields
}
Renderer renders HTML, JSON, and CSV responses. It caches templates and uses a pool of buffers. A Renderer is safe for concurrent use by multiple goroutines.
func New ¶
New creates a new Renderer that loads templates from fsys, configured by the provided options. It returns an error if the initial template load fails.
func (*Renderer) AllowedResponseCode ¶
AllowedResponseCode reports whether code is a permitted response code.
func (*Renderer) RenderCSV ¶
func (r *Renderer) RenderCSV(w http.ResponseWriter, code int, filename string, data CSVMarshaler)
RenderCSV renders data as a downloadable CSV file with the given status code and filename. It buffers the marshaled bytes before writing, so a marshaling error does not produce a partial response. If filename is empty, "data.csv" is used. On marshaling failure a 500 is returned (with the error detail in dev mode).
func (*Renderer) RenderHTML ¶
func (r *Renderer) RenderHTML(w http.ResponseWriter, tmpl string, data any)
RenderHTML renders the named HTML template with a 200 OK status. It is shorthand for Renderer.RenderHTMLStatus with http.StatusOK.
Example ¶
package main
import (
"fmt"
"net/http/httptest"
"testing/fstest"
"github.com/mikehelmick/go-bananas/render"
)
func main() {
// Templates are loaded from any fs.FS — an embed.FS in production, or an
// in-memory FS here.
fsys := fstest.MapFS{
"home.html": &fstest.MapFile{Data: []byte(
`{{define "home"}}<h1>{{.title}}</h1>{{end}}`)},
}
r, err := render.New(fsys, render.WithDevMode(true))
if err != nil {
panic(err)
}
w := httptest.NewRecorder()
r.RenderHTML(w, "home", map[string]any{"title": "Welcome"})
fmt.Println(w.Body.String())
}
Output: <h1>Welcome</h1>
func (*Renderer) RenderHTML500 ¶
func (r *Renderer) RenderHTML500(w http.ResponseWriter, err error)
RenderHTML500 renders err using the "500" template with a 500 status. In production it shows a generic message; in dev mode it shows the actual error.
func (*Renderer) RenderHTMLStatus ¶
RenderHTMLStatus renders the named HTML template with the given status code. It renders into a pooled buffer first and only flushes to w on success, so a template error never produces a partial response.
If template execution fails, a generic 500 page is returned; in dev mode the error detail is included. If flushing the buffer fails, the error is logged but no recovery is attempted. The code must be in the renderer's allowed set (see Renderer.AllowedResponseCode).
func (*Renderer) RenderJSON ¶
func (r *Renderer) RenderJSON(w http.ResponseWriter, code int, data any)
RenderJSON renders data as JSON with the given status code, buffering first so a marshaling error never produces a partial response.
If data is nil and code is a 2xx, the body is `{"ok":true}`; for a non-2xx code with nil data, the body is `{"error":"<status text>"}`. An error value (or a slice of errors, or an error that unwraps to several via errors.Join) is rendered as `{"error":...}` or `{"errors":[...]}`.
If marshaling fails, a generic 500 JSON response is returned; in dev mode the error detail is included. The code must be in the renderer's allowed set.
Example ¶
package main
import (
"fmt"
"net/http/httptest"
"testing/fstest"
"github.com/mikehelmick/go-bananas/render"
)
func main() {
r, err := render.New(fstest.MapFS{})
if err != nil {
panic(err)
}
w := httptest.NewRecorder()
r.RenderJSON(w, 200, map[string]string{"status": "ok"})
fmt.Print(w.Body.String())
}
Output: {"status":"ok"}
func (*Renderer) RenderJSON500 ¶
func (r *Renderer) RenderJSON500(w http.ResponseWriter, err error)
RenderJSON500 renders err as a JSON 500 response. In production it shows a generic message; in dev mode it shows the actual error.
func (*Renderer) RenderText ¶
RenderText executes the named text template (loaded from a ".txt" file) into w with the provided data. Unlike the HTML/JSON helpers it writes to any io.Writer and sets no HTTP headers, so it is suitable for rendering plain text such as emails, config files, or CLI output. The text FuncMap is configured with WithTextFuncs.
It renders into a buffer first and only copies to w on success, so a template error never produces partial output. In dev mode templates are reloaded on each call.