Help us shape the future of Go! Take the 2026 Go Developer Survey

view

package
v0.30.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package view renders html/template views with layouts, partials and fragments (single blocks, for htmx), plus request-aware helpers: route, asset, csrfField, old, errors, flash, cspNonce, t and locale.

Layout of the views directory:

layouts/app.html        {{block "content" .}}{{end}} inside the page shell
partials/nav.html       included with {{template "partials/nav" .}}
components/alert.html   same, by convention for reusable widgets
posts/index.html        a page: {{define "content"}}...{{end}}

A page uses the default layout ("app") unless its first line is a comment naming another one: {{/* layout: admin */}} or {{/* layout: none */}}.

New parses every view at boot into an Engine, which implements web.Renderer: handlers call c.Render("posts/index", data) for a page and c.Fragment("posts/index", "items", data) for one block (htmx swaps).

See https://github.com/AlexGalhardo/vukem/blob/main/docs/frontend.md.

Example
package main

import (
	"context"
	"fmt"
	"os"
	"testing/fstest"

	"github.com/AlexGalhardo/vukem/view"
)

func main() {
	// Apps use os.DirFS("resources/views") or an embed.FS.
	views := fstest.MapFS{
		"layouts/app.html": {Data: []byte(`<main>{{block "content" .}}{{end}}</main>`)},
		"posts/index.html": {Data: []byte(`{{define "content"}}{{range .}}<p>{{.}}</p>{{end}}{{end}}`)},
	}
	e, err := view.New(view.Config{FS: views})
	if err != nil {
		fmt.Println(err)
		return
	}

	// Values are escaped by html/template.
	_ = e.Render(context.Background(), os.Stdout, "posts/index", []string{"Hello", "<b>world</b>"})
}
Output:
<main><p>Hello</p><p>&lt;b&gt;world&lt;/b&gt;</p></main>

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// FS holds the views (os.DirFS("resources/views") or an embed.FS).
	FS fs.FS
	// Ext is the view file extension (default ".html").
	Ext string
	// DefaultLayout is used by pages without a layout comment (default
	// "app"; ignored when layouts/app.html does not exist).
	DefaultLayout string
	// Reload re-parses views on every render (development).
	Reload bool
	// Funcs adds custom template functions. A name already used by a
	// built-in ("route", "csrfField", "cspNonce"...) is an error.
	Funcs template.FuncMap
	// URLs resolves named routes for the "route" function.
	URLs web.URLGenerator
	// AssetPrefix is prepended by "asset" (default "/").
	AssetPrefix string
	// Vite backs the "vite" and "viteReactRefresh" functions; "asset"
	// resolves files Vite processed through it first.
	Vite *vite.Vite
	// I18n backs the "t" and "locale" functions, in the locale that
	// i18n.Middleware stored in the request context (the bundle's default
	// otherwise). Without it, the bundle in the context is used, and "t"
	// returns the key when there is none.
	I18n *i18n.Bundle
}

Config configures an Engine.

type Engine

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

Engine renders views; it implements web.Renderer.

func New

func New(cfg Config) (*Engine, error)

New parses every view, so syntax errors surface at boot.

func (*Engine) Has

func (e *Engine) Has(name string) bool

Has implements web.Renderer.

func (*Engine) Names

func (e *Engine) Names() []string

Names lists the page names.

func (*Engine) Render

func (e *Engine) Render(ctx context.Context, w io.Writer, name string, data any) error

Render implements web.Renderer: it renders the page (inside its layout).

func (*Engine) RenderBlock

func (e *Engine) RenderBlock(ctx context.Context, w io.Writer, name, block string, data any) error

RenderBlock implements web.Renderer: it renders a single {{block}} or {{define}} of the page, without the layout.

Example
package main

import (
	"context"
	"os"
	"testing/fstest"

	"github.com/AlexGalhardo/vukem/view"
)

func main() {
	views := fstest.MapFS{
		"posts/index.html": {Data: []byte(
			`{{/* layout: none */}}<ul>{{block "items" .}}{{range .}}<li>{{.}}</li>{{end}}{{end}}</ul>`,
		)},
	}
	e, _ := view.New(view.Config{FS: views})

	// An htmx request gets only the fragment.
	_ = e.RenderBlock(context.Background(), os.Stdout, "posts/index", "items", []string{"a", "b"})
}
Output:
<li>a</li><li>b</li>

Jump to

Keyboard shortcuts

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