gotpl

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 14, 2026 License: MIT Imports: 10 Imported by: 0

README

gotpl

A layout-based HTML template renderer for Go, backed by embed.FS.

Install

go get github.com/rettenwander/gotpl

Directory Structure

gotpl expects templates to be organized as follows:

templates/
  layout.html              # layout files in the root
  app.html
  partials/                # shared partials included in every view (optional)
    header.html
    footer.html
  views/
    layout/                # views for "layout.html"
      home.html
    app/                   # views for "app.html"
      dashboard.html
  • Layouts are .html files in the template root. Each layout is a full page skeleton that references named templates (e.g. {{template "content" .}}).
  • Views live under views/<layout>/ where <layout> matches the layout filename without its extension. Each view defines the named templates the layout expects.
  • Partials are optional shared snippets in partials/. They are included in every view and can be referenced by any layout or view.

Usage

package main

import (
	"embed"
	"log"
	"os"

	"github.com/rettenwander/gotpl"
)

//go:embed templates/*
var templateFS embed.FS

func main() {
	tmpl := gotpl.NewTemplate(templateFS)

	if err := tmpl.Validate(); err != nil {
		log.Fatal(err)
	}

	if err := tmpl.Render(os.Stdout, "app/dashboard.html", nil); err != nil {
		log.Fatal(err)
	}
}

Options

WithTemplateRoot

Override the root directory inside the embed.FS. The default is "templates".

tmpl := gotpl.NewTemplate(fs, gotpl.WithTemplateRoot("web/templates"))

Errors

  • gotpl.ErrTemplateNotFound is returned by Render when the requested view has not been parsed by Validate.

Testing

go test ./...

Documentation

Overview

Package gotpl provides a layout-based HTML template renderer backed by embed.FS.

Templates are organized into layouts, views, and partials:

templates/
  layout.html          # layout files in the root
  app.html
  partials/            # shared partials included in every view
    header.html
  views/
    layout/            # views for "layout.html"
      home.html
    app/               # views for "app.html"
      dashboard.html

Call Template.Validate to parse all templates, then Template.Render to execute a view by its "[layout]/[page.html]" name (e.g. "app/dashboard.html").

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrTemplateNotFound = errors.New("template not found")
)

ErrTemplateNotFound is returned by Template.Render when the requested view has not been parsed by Template.Validate.

Functions

This section is empty.

Types

type Form added in v0.2.0

type Form struct {

	// Values holds the raw string values keyed by field name.
	Values map[string]string

	// FieldErrors holds a single validation error per field, keyed by field name.
	// In templates: {{with .Form.FieldErrors.email}}<p class="error">{{.}}</p>{{end}}
	FieldErrors map[string]string

	// Errors holds form-level errors not tied to a specific field
	// (e.g. "invalid credentials").
	Errors []string
	// contains filtered or unexported fields
}

func NewForm added in v0.2.0

func NewForm(csrfName, csrf string) *Form

NewForm returns an empty Form ready for use.

func (*Form) AddError added in v0.2.0

func (f *Form) AddError(message string)

AddError adds a form-level error not tied to a specific field.

func (*Form) AddFieldError added in v0.2.0

func (f *Form) AddFieldError(field, message string)

AddFieldError adds a validation error for a specific field. Only the first error per field is kept.

func (*Form) CSRF added in v0.3.0

func (f *Form) CSRF() template.HTML

CSRFField returns a hidden HTML input element containing the CSRF token. Use it in templates: {{.Form.CSRF}}

func (*Form) Get added in v0.2.0

func (f *Form) Get(field string) string

Get returns the value of a field, or "" if unset.

func (*Form) Set added in v0.2.0

func (f *Form) Set(field, value string)

Set stores a field value.

func (*Form) Valid added in v0.2.0

func (f *Form) Valid() bool

Valid reports whether the form has no errors of any kind.

type OptionFunc

type OptionFunc = func(c *option)

OptionFunc is a functional option for configuring a Template.

func WithCSRF added in v0.3.0

func WithCSRF(fieldName string, generator csrfTokenGenerator) OptionFunc

WithCSRF configures the CSRF field name and token generator used by [Template.RequestForm].

func WithTemplateRoot

func WithTemplateRoot(path string) OptionFunc

WithTemplateRoot sets the root directory inside the embed.FS that contains the layout files, views/, and partials/ directories. The default is "templates".

type PageData

type PageData struct {
	Title string
	Data  any
	Form  *Form
}

PageData is a convenience wrapper for passing a page title, arbitrary data, and an optional form to a template.

type Template

type Template struct {
	// contains filtered or unexported fields
}

Template holds parsed HTML templates organized by layout and view.

func NewTemplate

func NewTemplate(fs embed.FS, opts ...OptionFunc) *Template

NewTemplate creates a new Template from the given embed.FS. Use OptionFunc values such as WithTemplateRoot to customize behaviour. Call Template.Validate before rendering.

func (*Template) FormFromRequest added in v0.3.0

func (t *Template) FormFromRequest(r *http.Request) (*Form, error)

FormFromRequest creates a Form pre-populated with all POST body values from the given request, taking the first value for each field. If a CSRF generator was configured via WithCSRF, the token is set on the form.

func (*Template) Render

func (templ *Template) Render(w io.Writer, view string, data any) error

Render executes the named view template and writes the result to w.

The view name follows the pattern "[layout]/[page.html]", where layout is the layout filename without its extension. For example, given layouts "layout.html" and "app.html", a view "dashboard.html" under the "app" layout is rendered as:

templ.Render(w, "app/dashboard.html", data)

func (*Template) Validate

func (t *Template) Validate() error

Validate parses all templates contained in the embed.FS.

It must be called before Template.Render; rendering without prior validation will always return ErrTemplateNotFound.

Jump to

Keyboard shortcuts

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