flash

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package flash provides experimental request-scoped flash message helpers.

Index

Constants

View Source
const ClientName = "partial-flash.js"

ClientName is the name of the browser client in the file system of go-partial's clients package.

Variables

This section is empty.

Functions

func Add

func Add(ctx context.Context, messages ...Message) context.Context

Add stores messages on the context, creating a request store when needed.

func ClientScript added in v0.15.0

func ClientScript() []byte

ClientScript returns the browser client for flash messages. It hides the messages exp/flash's templates write after a time that depends on their level (success and info 5s, warn 8s, error never; change it with data-flash-autohide-<level>="3s" or data-flash-autohide="3s" on an ancestor, or on the message itself, "off" to keep it), keeps a message while the pointer or keyboard focus is on it, removes it when an element in it with data-flash-dismiss is clicked or Escape is pressed in it, and dispatches partial:flash on each message as it appears, with its level and text.

The messages it shows itself are clones of the <template data-flash-template> that {{ flashTemplate }} renders with the application's flash template, so they look like those of the server; without one, it writes the default markup.

With data-flash-request-error="Something went wrong" on the flash target (see WithRequestErrors, FlashTarget and TargetAttrs), requests of htmx 2 and 4, Unpoly or Turbo that fail, and exp/sse's partial:error events, show that text as an error message. A response with an error status that htmx swaps into its target, such as a form with its validation errors (422) with htmx 4, is shown by the swap and does not count as failed: with htmx 4 the client decides at htmx:finally:request, once htmx has swapped the response or not. More attributes on the target: data-flash-request-error-replace keeps one request error at a time, the next request removing it; data-flash-request-error-body shows the text/plain body of a refused request (4xx) when it is a sentence, such as flash.Respond writes for requests of no client library, without htmx swapping it; data-flash-request-error-skip-flash shows nothing for a failed response that brings its own message, such as those of ext/errors' WithFlash. Scripts call goPartialFlash.show(level, text).

The client needs no build step and no other library; serve it from the file system of go-partial's clients package, or include it in your own bundle.

func Flash

func Flash(ctx ...*partial.RenderContext) template.HTML

Flash renders flash messages for a render context with the default template.

go-doc:sig func() html/template.HTML

func FlashTarget

func FlashTarget(ctx ...*partial.RenderContext) template.HTML

FlashTarget renders the default flash target container.

go-doc:sig func() html/template.HTML

func FuncMap

func FuncMap() template.FuncMap

FuncMap returns placeholders for flash template helpers.

func Has

func Has(ctx context.Context) bool

Has reports whether the context has flash messages.

func HasFlashes

func HasFlashes(ctx ...*partial.RenderContext) bool

HasFlashes reports whether a render context has request-scoped flash messages.

go-doc:sig func() bool

func RenderOOB added in v0.15.0

func RenderOOB(ctx *partial.RenderContext, messages ...Message) (template.HTML, bool)

RenderOOB renders messages as an addition to the flash target, sent out of band with any response, with the flash template and target of the flash Stage of the render: a render stage that answers a request itself, such as ext/errors with WithFlash, adds them to the page the way the page's own flash messages appear. It reports false when the render has no flash stage.

if out, ok := flash.RenderOOB(ctx, flash.Error("The request failed.")); ok {
	return out, nil
}

func Respond added in v0.15.0

func Respond(w http.ResponseWriter, r *http.Request, parent *partial.Partial, status int, messages ...Message) error

Respond answers a request that is refused, rather than failed to render, such as one without the right permission or with an expired form, with messages: for a request of the client library of parent's connector, a response that adds them to the flash target out of band, with the flash template and target of parent's flash Stage, and leaves the request's own target as it is (htmx's HX-Reswap: none); for any other request, the texts of the messages as text/plain. Either is sent with status and never cached. Without a flash stage on parent, exp/flash's default template and target are used.

if !allowed {
	_ = flash.Respond(w, r, root, http.StatusForbidden, flash.Error("You may not do this."))
	return
}

htmx 2 swaps no response with an error status: send its requests status 200, or let its browser client show the text/plain body (see ClientScript). parent is not changed.

func Stage

func Stage(opts ...Option) partial.RenderStage

Stage gives templates the flash helpers, made only for the templates that call them.

func TargetAttrs added in v0.15.0

func TargetAttrs(args ...any) template.HTMLAttr

TargetAttrs returns the attributes of an element of the template's own that is the flash target: its id and, with the flash Stage's WithRequestErrors, the attributes that tell the browser client how to show failed requests, such as data-flash-request-error="..."; a text argument replaces the stage's text, such as a translated one:

<div {{ flashTargetAttrs (t "The request failed.") }} {{ oobAttr "beforeend" }} class="toasts">

Without the stage, the id is the default flash target's and a text argument is the only request error setting.

go-doc:sig func(text ...string) html/template.HTMLAttr

func Template added in v0.15.0

func Template(args ...any) template.HTML

Template renders, for each level, the default flash template as a <template data-flash-template="level"> for the browser client, which clones it for the messages it shows itself; see Stage for the template of the application's flash template. It renders nothing in a partial rendered out of band, such as a flash target that a response adds its messages to: the page has the templates already.

go-doc:sig func(levels ...string) html/template.HTML

func WithStore

func WithStore(ctx context.Context, store *Store) context.Context

WithStore stores an app-owned flash store on the context.

Types

type Cookie struct {
	// Name is the cookie name; "flash" when empty.
	Name string
	// Path is the cookie path; "/" when empty.
	Path string
	// Domain is the cookie domain; the request's host when empty.
	Domain string
	// MaxAge is how long the messages wait for the next request; a minute
	// when zero.
	MaxAge time.Duration
	// Secure sends the cookie over HTTPS only.
	Secure bool
	// SameSite is the cookie's same-site mode; http.SameSiteLaxMode when
	// zero, so the messages survive a redirect from another site.
	SameSite http.SameSite
	// Key signs the cookie with HMAC-SHA256; Restore ignores cookies with
	// another signature.
	Key []byte
	// MaxBytes caps the cookie value; 3072 when zero, below the 4096 bytes
	// browsers keep. Messages that do not fit are dropped, the last first,
	// and long texts are shortened.
	MaxBytes int
}

Cookie keeps flash messages across a redirect, such as the "Saved" message after a form posts and the browser follows to another page:

cookie := flash.Cookie{Key: key}

cookie.Persist(w, flash.Success("Saved"))
http.Redirect(w, r, "/items", http.StatusSeeOther)

and, for every request, in middleware or before rendering:

r = cookie.Restore(w, r)

Restore moves the messages into the request's flash store, where templates show them with {{ flash }}, and clears the cookie, so they show once. Messages keep their level.

The zero Cookie works; its fields change the cookie. Without a Key the cookie is not signed: anyone who can set cookies for the site can make it show a message, escaped like any other text. Set Key to accept only messages the application persisted.

func (Cookie) Persist added in v0.15.0

func (c Cookie) Persist(w http.ResponseWriter, messages ...Message)

Persist keeps messages for the next request, replacing any persisted earlier in this response. Without messages it clears the cookie.

func (Cookie) Read added in v0.15.0

func (c Cookie) Read(r *http.Request) []Message

Read returns the messages persisted for the request without clearing them.

func (Cookie) Restore added in v0.15.0

func (c Cookie) Restore(w http.ResponseWriter, r *http.Request) *http.Request

Restore moves the messages persisted for this request into its flash store, after the messages the store already has, and clears the cookie. It returns the request with the store in its context; a request without persisted messages is returned as it is.

type Data

type Data struct {
	Messages []Message
	TargetID string
	// RequestErrorAttrs are the attributes of the flash target that
	// tell the browser client how to show failed requests, as the
	// stage's WithRequestErrors configures them, each after a space;
	// empty without. A flash target template writes them on its
	// element, as the default one does; see also flashTargetAttrs.
	RequestErrorAttrs template.HTMLAttr
}

Data is passed to the flash template.

type Level

type Level string

Level describes the intent of a flash message.

const (
	LevelSuccess Level = "success"
	LevelInfo    Level = "info"
	LevelWarn    Level = "warn"
	LevelError   Level = "error"
)

type Message

type Message struct {
	Level Level
	Text  string
}

Message is one request-scoped flash message.

func Drain

func Drain(ctx context.Context) []Message

Drain removes and returns the current context flash messages.

func Error

func Error(text string) Message

Error creates an error flash message.

func Flashes

func Flashes(ctx ...*partial.RenderContext) []Message

Flashes returns request-scoped flash messages for a render context.

go-doc:sig func() []github.com/donseba/go-partial/exp/flash.Message

func Info

func Info(text string) Message

Info creates an informational flash message.

func Messages

func Messages(ctx context.Context) []Message

Messages returns the current context flash messages.

func New

func New(level Level, text string) Message

New creates a flash message with the provided level and text.

func Success

func Success(text string) Message

Success creates a success flash message.

func Warn

func Warn(text string) Message

Warn creates a warning flash message.

type Option

type Option func(*options)

Option configures the flash renderer.

func WithPartial

func WithPartial(p *partial.Partial) Option

WithPartial renders flash messages with a user-provided partial.

func WithRequestErrors added in v0.15.0

func WithRequestErrors(errors RequestErrors) Option

WithRequestErrors makes the flash target tell the browser client (ClientScript) to show failed requests as errors, as errors configures: {{ flashTarget }} and {{ flashTargetAttrs }} write the attributes the client reads, such as data-flash-request-error="The request failed.", and flash target templates get them as Data.RequestErrorAttrs.

flash.Stage(flash.WithRequestErrors(flash.RequestErrors{
	Text:      "The request failed. Please try again.",
	Replace:   true,
	Body:      true,
	SkipFlash: true,
}))

func WithTargetID

func WithTargetID(id string) Option

WithTargetID changes the DOM ID used by the default flash target and the data passed to flash templates.

func WithTargetPartial

func WithTargetPartial(p *partial.Partial) Option

WithTargetPartial renders flashTarget with a user-provided partial.

func WithTargetTemplate

func WithTargetTemplate(path string) Option

WithTargetTemplate renders flashTarget with a user template from the active partial tree filesystem.

func WithTemplate

func WithTemplate(path string) Option

WithTemplate renders flash messages with a user template from the active partial tree filesystem.

type RequestErrors added in v0.15.0

type RequestErrors struct {
	// Text is the error message shown for a failed request, such as
	// "The request failed. Please try again."; a template gives one of
	// its own, such as a translated one, as the argument of
	// {{ flashTargetAttrs }}.
	Text string
	// Replace keeps one request error at a time: a new one replaces the
	// last, and the next request removes it.
	Replace bool
	// Body shows the text/plain sentence of a refused request (4xx),
	// such as Respond writes for requests of no client library,
	// instead of Text; htmx does not swap that body.
	Body bool
	// SkipFlash shows nothing for a failed response that brings its own
	// flash message, such as those of Respond, RenderOOB and ext/errors'
	// WithFlash.
	SkipFlash bool
}

RequestErrors configures how the browser client (ClientScript) shows requests that fail; see WithRequestErrors.

type Store

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

Store holds flash messages for one request or app-owned session handoff.

Store is safe for concurrent Add, Messages, and Drain calls, but most applications should still treat a store as request/session-owned state.

func FromContext

func FromContext(ctx context.Context) *Store

FromContext returns the flash store from ctx, if present.

func NewStore

func NewStore(messages ...Message) *Store

NewStore creates an empty flash store.

func (*Store) Add

func (s *Store) Add(messages ...Message)

Add appends messages to the store.

func (*Store) Drain

func (s *Store) Drain() []Message

Drain removes and returns all messages.

func (*Store) Messages

func (s *Store) Messages() []Message

Messages returns a snapshot of the current messages.

Jump to

Keyboard shortcuts

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