Detail
The detail page shows one record. Without configuration every field renders
with a sensible default; Detail[T] customizes projection and presentation.
posts.Detail(func(d *steward.Detail[Post]) {
d.Field("Title")
d.Field("Status").Badge(map[any]string{"draft": "secondary", "published": "green"})
d.Field("Cover").Image(320, 0)
d.Field("Body").Markdown()
d.Field("Author.Name", "Author")
})Field renderers
As(func(v any, m *T) template.HTML) renders anything; the shorthands
cover the usual cases: Badge(colors), Bool(), Image(w, h), Link(),
JSON() (pretty-printed), Filesize() (bytes → human units),
Markdown(), Using(map).
Relation grids
Embed another registered resource’s grid, scoped to the shown record:
steward.RelationGrid[Author, Post](d, "Posts by this author",
func(q *steward.ListQuery, a *Author) {
q.Conds = append(q.Conds, steward.Cond{Path: "AuthorID", Op: steward.OpEq, Val: a.ID})
})The embedded table reuses the related resource’s grid columns and links to
its full listing. The related resource’s policy applies: its
RowScoper narrows the rows, and if its ViewAny denies the viewer the
section disappears entirely.
JSON
GET /{slug}/{id} with Accept: application/json returns the record
itself — see JSON API.