adminregistry

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContextOf added in v0.7.0

func ContextOf(f FieldContext) context.Context

ContextOf returns the request context attached to f, or context.Background() when none was.

Types

type Display added in v0.4.0

type Display struct {
	Text string
	Href string
}

Display is what a changelist cell shows. Text is always HTML-escaped. Href, when set, makes the cell a link, but only if it is a relative URL or an absolute http or https URL; any other value falls back to plain text.

type DisplayFunc added in v0.4.0

type DisplayFunc func(context.Context, any) Display

DisplayFunc computes one changelist cell from a model row. The row is passed as a pointer to the model value (for example *Upload), so the function can read any of its fields, including ones that are not shown as columns. A panic in the function is the host's bug: admin does not recover it.

type FieldContext

type FieldContext struct {
	// Name is the model field's Go name — also the base name a simple
	// widget reads directly from the submitted form, and the stable prefix
	// a multi-input widget derives its own input names from.
	Name string
	// Label is the field's display label (from Options.Labels, or a
	// humanized default).
	Label string
	// HelpText is optional descriptive text for the field (from
	// Options.HelpText); empty if unset.
	HelpText string
	// Value is the field's current value, formatted for display. Empty for
	// a new (zero) instance.
	Value string
	// MaxLength is the field's declared maximum length in characters (a
	// tango:"varchar=n" string), or 0 when the field is unbounded. The
	// built-in input renders it as the maxlength attribute; the server stays
	// the authority, since browsers count in UTF-16 units.
	MaxLength int
	// Checked is the field's current boolean value, for checkbox-shaped
	// widgets.
	Checked bool
	// ReadOnly reports whether the field should render non-editably and
	// ignore submitted form data entirely (Options.ReadOnly). A Widget set
	// via Options.Widgets is never consulted for a ReadOnly field — the
	// admin package renders a single generic read-only presentation
	// instead, uniformly, regardless of which Widget the field would
	// otherwise use.
	ReadOnly bool
	// SelectOptions lists every row of the related model as a value/label
	// pair, populated only for a foreign key field whose related model is
	// registered — nil otherwise.
	SelectOptions []SelectOption
	// RelatedCreateURL links to the related model's admin create page for
	// foreign-key fields whose related model is also admin-registered.
	// Empty means no quick-create affordance should render.
	RelatedCreateURL string
	// PreviewURL is the absolute admin URL a preview widget posts its text
	// to; empty for a widget that is not a PreviewWidget.
	PreviewURL string
	// RelatedCreateLabel is the accessible label for RelatedCreateURL.
	// Empty means widgets may fall back to their own default.
	RelatedCreateLabel string
	// Error is the message the form shows beside this field after a failed
	// save, or empty when the field has no error. The built-in widgets mark
	// their control aria-invalid when it is set; a custom widget may do the
	// same.
	Error string
	// contains filtered or unexported fields
}

FieldContext carries what a Widget needs to render and parse one model field's create/edit form control. The same FieldContext is passed to both Render and Parse, so a widget can derive its own submitted form key(s) from Name identically on both sides — e.g. a multi-input widget might use Name+"_date" and Name+"_time" — rather than a render-time and parse-time convention drifting apart.

func WithContext added in v0.7.0

func WithContext(f FieldContext, ctx context.Context) FieldContext

WithContext returns f carrying the request context ctx.

func (FieldContext) DescribedBy added in v0.4.0

func (f FieldContext) DescribedBy() string

DescribedBy returns the value for the control's aria-describedby: the ids of the field's help text and error element, in that order, separated by a space. It is empty when the field has neither.

type FieldValues

type FieldValues interface {
	Get(key string) string
	Has(key string) bool
}

FieldValues is the whole submitted form, so a Widget's Parse can read more than one input for a single Go field (see FieldContext.Name).

type ModelRegistration

type ModelRegistration struct {
	Model   model.ModelMeta
	Options Options
}

ModelRegistration is the admin metadata for a registered model.

type Options

type Options struct {
	ListDisplay []string
	// Display computes changelist cells, keyed by a name in ListDisplay: a
	// registered field (overriding its value) or a synthetic column, which
	// needs a Labels entry for its header. See DisplayFunc.
	Display  map[string]DisplayFunc
	Search   []string
	Ordering []string
	// Label names one of this model's own fields to display whenever it is
	// shown as a related object elsewhere (e.g. on a Post's admin page for
	// a Post.AuthorID foreign key). Unset falls back to showing the raw
	// primary key value — never a hard error.
	Label string
	// Labels overrides a field's humanized default display label, keyed by
	// Go field name.
	Labels map[string]string
	// HelpText adds descriptive text below a field's form control, keyed by
	// Go field name.
	HelpText map[string]string
	// ReadOnly lists fields that render non-editably in create/edit forms.
	// On edit, a read-only field keeps its existing stored value regardless
	// of submitted form data; on create, it stays at its Go zero value.
	// Submitted data for a read-only field is always ignored, never parsed.
	ReadOnly []string
	// FieldOrder lists fields in the order they should render; fields not
	// listed keep their existing default order after the ordered ones.
	FieldOrder []string
	// Widgets overrides how a field renders and parses in create/edit
	// forms, keyed by Go field name. See Widget — best-effort, not a
	// stable contract.
	Widgets map[string]Widget
	// Filters lists boolean and foreign key fields the changelist can be
	// filtered by, in the order they appear above the list.
	Filters []string
	// BulkDelete lets a staff account delete the rows checked on one
	// changelist page, after a confirmation, in one all-or-nothing
	// transaction. Rows that reference a deleted row are deleted with it,
	// exactly as in a single-row delete. Off by default; it needs JavaScript
	// in the browser and never spans more than one page of rows.
	BulkDelete bool
}

Options controls how a model appears in the admin.

type PreviewWidget added in v0.4.0

type PreviewWidget interface {
	Preview(ctx context.Context, source string) (template.HTML, error)
}

PreviewWidget is the optional extension a Widget implements when its field can show a preview of the submitted text. Only the Markdown widget uses it today. Admin owns the preview route: it calls Preview for the one derived, staff-only endpoint of a preview field and wraps the result, so a widget cannot register a route. Preview receives a context derived from the request's and must not persist anything; the caller applies the deadline and output limits.

type Registry

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

Registry stores admin registrations by model name.

func NewRegistry

func NewRegistry(models *model.Registry) *Registry

NewRegistry returns an empty, ready-to-use admin Registry.

func (*Registry) Get

func (r *Registry) Get(name string) (ModelRegistration, bool)

Get returns an admin registration by model name.

func (*Registry) Register

func (r *Registry) Register(value any, opts Options) error

Register stores admin presentation options for a model.

func (*Registry) Registrations

func (r *Registry) Registrations() []ModelRegistration

Registrations returns every registered model in unspecified order.

type SelectOption

type SelectOption struct {
	Value    string
	Text     string
	Selected bool
}

SelectOption is one <option> in a foreign key field's <select>.

type Widget

type Widget interface {
	Render(f FieldContext) template.HTML
	Parse(f FieldContext, form FieldValues, dest reflect.Value) error
}

Widget renders one model field's create/edit form control and parses its submitted value back into the Go field, replacing tanGO's default behavior for that field alone — nothing else about the form changes. tanGO's built-in field behaviors (a generic text/number/date-time input, a checkbox, a textarea, and the foreign-key select) are themselves Widgets, set via Options.Widgets like any custom one.

This interface, tanGO's built-in widgets, and Options' Widgets/Labels/ HelpText/ReadOnly/FieldOrder fields are best-effort, not a stable contract — see docs/limitations.md. A widget's Render output may include its own <link>/<script> tags for CSS/JS (served via its owning app's own embed.FS route, per the convention reusable apps already use for static assets); since there is no shared deduplication, that output must be idempotent — safe to emit once per rendered instance — because the same widget on multiple fields will render its tags more than once.

Jump to

Keyboard shortcuts

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