render

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CSVMarshaler

type CSVMarshaler interface {
	MarshalCSV() ([]byte, error)
}

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

func WithBuildID(id string) Option

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

func WithDevMode(debug bool) Option

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

func WithLogger(l *slog.Logger) Option

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

func New(fsys fs.FS, opts ...Option) (*Renderer, error)

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

func (r *Renderer) AllowedResponseCode(code int) bool

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

func (r *Renderer) RenderHTMLStatus(w http.ResponseWriter, code int, tmpl string, data any)

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

func (r *Renderer) RenderText(w io.Writer, name string, data any) error

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL