Documentation
¶
Overview ¶
Package schemaform renders a JSON Schema as an HTML form and reads the form back into JSON. Section and entity editors share one set of precedence rules, so they look and behave alike. Output is built by html/template from schema and values only: no content string ever becomes markup.
Index ¶
- Constants
- func Humanize(s string) string
- func Render(schema json.RawMessage, values map[string]any, opt Options) (template.HTML, error)
- func SortNames(names, order []string) []string
- func Structural(form url.Values) bool
- func WithoutProperties(schema json.RawMessage, names ...string) (json.RawMessage, error)
- type Errors
- type Node
- type Options
- type Prop
- type UIHint
Constants ¶
const MaxItems = 500
MaxItems caps the entries of one repeater/array a form may submit.
Variables ¶
This section is empty.
Functions ¶
func Render ¶
Render writes the form controls for schema, filled from values. The result is the trusted output of html/template (every dynamic string escaped); callers put it inside their own <form>. Submit buttons for repeaters (add, move, remove) are named _add./_move./_remove.; put a hidden default submit first in the form so Enter in a text field saves instead of moving an item.
func SortNames ¶
SortNames orders property names by an x-hm-order list: the names it lists first, in its order, then the others as they were. The database stores schemas as jsonb, which does not keep the order of an object's keys, so the order a person chose in the schema editor is kept in this list.
func Structural ¶
Structural reports whether the submission pressed an add/move/remove button: the handler then re-renders the (changed) form instead of saving it.
func WithoutProperties ¶
func WithoutProperties(schema json.RawMessage, names ...string) (json.RawMessage, error)
WithoutProperties returns schema with the named top-level properties (and their entries in "required") removed, keeping the order of the rest. A form that renders such a property elsewhere (the SEO panel) uses it so the field is not shown twice; values of removed properties still round-trip through Decode's prev map.
Types ¶
type Errors ¶
Errors maps a dotted path ("faqs.2.question") to friendly messages.
func Decode ¶
func Decode(schema json.RawMessage, form url.Values, prev map[string]any, opt Options) (map[string]any, Errors)
Decode reads the submitted form back into JSON-shaped values, driven by the schema (no type hints travel with the form). Only properties the schema lists are overlaid on prev: unknown keys (legacy WordPress fields, aliases) survive a save untouched, and editing a canonical property removes its x-hm-alias keys so the stale alias cannot shadow the new value. Inside nested objects and repeater items the unknown keys travel in the form itself (the hidden _keep.<path> inputs Render emits), so they survive reordering too.
Add/move/remove buttons (_add./_move./_remove.) are applied here; check Structural(form) to re-render instead of saving.
func Validate ¶
func Validate(schema, attrs json.RawMessage) Errors
Validate checks attrs against schema with the same validator the API uses and returns friendly messages keyed by dotted path. A schema or document failure that cannot be tied to a field lands under the "" key.
type Node ¶
type Node struct {
Type, Format, Title, Description, Pattern string
Enum []string
Default any
MinLength, MaxLength *int
MinItems, MaxItems *int
Minimum, Maximum *float64
Items *Node
Props []Prop
Required []string
WriteOnly bool // writeOnly: a secret the form never shows
XHm string // x-hm-field: plaintext richtext html url image code css lines (string arrays: one item per line)
XCode string // x-code-size: "tall"
XMedia bool // x-media
XEntitySchema string // x-entity-schema: slug of the referenced entity type
XMultiple *bool // x-multiple
Alias []string // x-hm-alias
Group string // x-hm-group: section heading of a top-level property
}
Node is the subset of JSON Schema the admin forms understand. Properties keep their schema order. $ref/oneOf/anyOf/allOf are banned at theme load (render/schema.go), so nothing here resolves references.
func ParseSchema ¶
func ParseSchema(raw json.RawMessage) (*Node, error)
ParseSchema parses a JSON Schema document.
type Options ¶
type Options struct {
// Prefix namespaces field names ("content."), so section forms do not
// clash with the entity's own fields.
Prefix string
// UI holds hints by dotted path without indices ("faqs.question").
UI map[string]UIHint
Disabled bool
// OpenPath opens one repeater item and collapses the rest
// ("faqs.2.question" opens item 2 of faqs).
OpenPath string
// Errors are rendered under their fields; repeater items holding an error
// are expanded.
Errors Errors
// Secrets lists the top-level writeOnly fields that hold a stored value.
// Such a field is never filled in: it is a password input that says a
// value is stored, and offers to clear it.
Secrets map[string]bool
}
Options configure Render and Decode.
type UIHint ¶
type UIHint struct {
Widget string
Placeholder string
Help string
Autofocus bool
Unorderable bool // ui:orderable === false
}
UIHint is the per-field uiSchema: widget (textarea | richtext | tags), placeholder, help, autofocus, orderable. ui:options is parsed by the caller and ignored here.