One set of mail variables for every mail, and {link} in state mails
{site} and {site_name} everywhere; a state mail adds {self_link} (the
submitter's own page, when their record's state allows a move there),
{desk_link} and {link}, which picks by who the mail is to. gullberg's
{link} mails went out blank until now. Documented in docs/mail.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MznPTC31w5mSUK4XMehcpi
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ae119af987
commit
6b91258ebe
@@ -7,6 +7,7 @@
|
||||
- [Getting started](getting-started.md)
|
||||
- [Content reference](content-reference.md)
|
||||
- [State machines](state-machines.md)
|
||||
- [Mail](mail.md)
|
||||
- [Access](access.md)
|
||||
- [Storylines](storylines.md)
|
||||
- [Memberships](memberships.md)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# Mail
|
||||
|
||||
Portal writes every mail itself and hands it to gdo to deliver
|
||||
(`portal.mail.send`); a reply comes back as a note beside the record
|
||||
(`portal.mail.received`). A mail is a subject and a markdown body with
|
||||
`{placeholders}`, sent as text with an HTML alternative. The kinds of
|
||||
mail are the ones content declares on a state (see
|
||||
[State machines](state-machines.md#mail)), the invite and its
|
||||
rewording (`invite: { group, mail }`, `mail.invite` in site.yaml), the
|
||||
note to a person named responsible for a question, and the answers to
|
||||
a suggested change.
|
||||
|
||||
## Variables
|
||||
|
||||
A placeholder is `{` letters, digits, `_`, `-` or `.` `}`. One that
|
||||
names nothing renders as nothing; a brace that opens no name stays a
|
||||
brace. The variables come in layers, so a template written for one
|
||||
kind of mail reads the same in another.
|
||||
|
||||
**On every mail**
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `{site}` | the instance's public URL, no trailing slash |
|
||||
| `{site_name}` | site.yaml's `title` |
|
||||
|
||||
**On a mail about a record** (every state mail)
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `{field}` | any field of the record, as the form sent it |
|
||||
| `{chain}` | the record's id |
|
||||
| `{email}` | the record's `email` field, trimmed |
|
||||
| `{bucket}`, `{state}` | where it is and the state it just entered |
|
||||
| `{notice.field}` | a field of the record this one belongs to, through its `type: record` field `notice` |
|
||||
| `{self_link}` | the record's own page for the person it belongs to: a page offering a self-service move (`self_transition`) on the bucket from the state the record is in, with the `?chain=&email=` that lets them act without signing in. Empty when there is no such page or no address |
|
||||
| `{desk_link}` | the desk that moves the record: the page whose list over the bucket has `transitions`, else one that reads it. Empty when no page reads the bucket |
|
||||
| `{link}` | where this reader acts: `{self_link}` in a mail `to: submitter`, `{desk_link}` in one to anyone else, and `{site}` when that link is empty |
|
||||
|
||||
`{link}` is the one to reach for. "Se meldingen og avtal befaring:
|
||||
{link}" sent to the caretaker opens the desk the report is on; "Feilen
|
||||
du meldte om er utbedret. {link}" sent to the tenant opens their own
|
||||
case where they can still act on it, or the site when there is
|
||||
nothing left for them to do.
|
||||
|
||||
**On an invite and the note to someone responsible**, beside every
|
||||
field of the invite's form: `{name}`, `{username}`, `{email}`,
|
||||
`{group}` (invite), `{questions}` (responsible), `{expires}`, and
|
||||
`{link}`, which here is the one-time sign-in link.
|
||||
|
||||
## What the lint holds a mail to
|
||||
|
||||
A state mail that sends from a state no record reaches warns; one that
|
||||
names a field no form recording into the bucket collects fails, since
|
||||
it would go out with a blank where the field should be. The lint
|
||||
knows every variable above, so `{link}` and the rest are never
|
||||
flagged. `to: submitter` requires a required `email` on every form
|
||||
filling the bucket, and `to: "{notice.email}"` requires the `notice`
|
||||
field.
|
||||
@@ -57,7 +57,9 @@ a record arrives in it.
|
||||
```
|
||||
|
||||
`{field}` is any field of the record, plus `{site}`, `{chain}`,
|
||||
`{email}`, `{bucket}` and `{state}`. The body is markdown; it is sent
|
||||
`{email}`, `{bucket}`, `{state}` and `{link}` - the page where the
|
||||
reader acts on the record, their own or the desk's (every variable is
|
||||
in [Mail](mail.md#variables)). The body is markdown; it is sent
|
||||
as text with an HTML alternative. `to: submitter` means the record's
|
||||
`email` field, and the lint then requires every form filling that
|
||||
bucket to collect a required `email`.
|
||||
|
||||
Reference in New Issue
Block a user