A reusable element tree with typed parameters.
Views
A view is a reusable piece of a page: an element tree with typed
parameters that a page, or another view, mounts with use. A parameter
is an entity's record or a query's row, and every value inside the view
is written against those parameters, so a view carries no data of its
own and cannot read anything its caller did not hand it:
app projects "Projects" {}
entity Project {
name: text
client: text
due: date
status: text
}
entity Invoice {
number: text
project: ref Project on delete cascade
}
view project-card (project: Project) {
card title project.name {
columns {
column {
text project.client style muted
}
column {
badge project.status colour by state
}
}
text "Due " + project.due format relative when project.due != null
each invoice in Invoice where project == project.id sort due desc limit 3 {
text invoice.number
}
}
}
page projects "Projects" list Project {
each project in Project where status != "closed" layout grid {
use project-card (project)
}
}
page project-detail "Project" detail Project {
use project-card (this)
}
The elements are card, columns and column, tabs and tab, text,
badge, image, link, each and use. Any element takes a trailing
when <expr> that hides it; text takes style and format, badge
takes colour by, image takes alt, and link takes to. An each
runs a tenant-scoped query and binds each row to a name; use mounts a
view and passes its arguments by position or by name.
Views cannot mount themselves, directly or through another view, and a
use must pass exactly the parameters the view declares, each of the
declared kind. A view may also carry the detail sugar (section,
related, jobs, action) when it has exactly one entity parameter,
which those blocks bind to. Everything a view shows comes from the
records it was given and from its own each elements, and an each runs
through the same tenant-scoped data layer as a query.