Skip to content

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.