Docs: the examples in English
Test / test (pull_request) Successful in 1m5s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
This commit is contained in:
Bendik Aagaard Lynghaug
2026-09-30 15:31:59 +02:00
co-authored by Claude Fable 5.1
parent 96b3746643
commit 48cba5cd8e
5 changed files with 24 additions and 24 deletions
+5 -5
View File
@@ -66,7 +66,7 @@ place: # this page is about somewhere
lat: 59.8938 lat: 59.8938
lon: 11.0332 lon: 11.0332
zoom: 15 zoom: 15
name: Tomter name: The town hall
alternatives: [ ... ] alternatives: [ ... ]
``` ```
@@ -207,14 +207,14 @@ The other half is a listing that asks for the children:
And the way there from a list: `link` puts a link on every listed And the way there from a list: `link` puts a link on every listed
record to a page about it, with `{id}` for the record's id and record to a page about it, with `{id}` for the record's id and
`{field}` for any of its fields. A notice on a public board links to `{field}` for any of its fields. A notice on a public board links to
`/oppslag/{id}`, the dynamic page `/oppslag/[key]` whose form carries `/notices/{id}`, the dynamic page `/notices/[key]` whose form carries
the notice's id back in with `value: "{key}"`: the notice's id back in with `value: "{key}"`:
```yaml ```yaml
resource: resource:
source: { kind: kv, bucket: oppslag } source: { kind: kv, bucket: notices }
public: true public: true
link: { to: "/oppslag/{id}", label: Jeg kan låne ut eller låne denne } link: { to: "/notices/{id}", label: I can lend or borrow this }
``` ```
## A resource ## A resource
@@ -231,7 +231,7 @@ reads is never a client-supplied parameter.
where: { field: case, equals: "{key}" } where: { field: case, equals: "{key}" }
jq: ".[] | {name, url: .html_url}" jq: ".[] | {name, url: .html_url}"
empty: Nothing decided yet. empty: Nothing decided yet.
link: { to: "/oppslag/{id}", label: Answer this } # a page per record link: { to: "/notices/{id}", label: Answer this } # a page per record
transitions: # the desk's buttons transitions: # the desk's buttons
- { from: complete, to: on_hearing, label: Send it out } - { from: complete, to: on_hearing, label: Send it out }
``` ```
+9 -9
View File
@@ -32,11 +32,11 @@ Three things in the content decide who needs an account:
|---|---|---| |---|---|---|
| `responsible: { name, contact }` on a page | the person answering for that question | an account, and a mail saying they are listed as responsible for asking it | | `responsible: { name, contact }` on a page | the person answering for that question | an account, and a mail saying they are listed as responsible for asking it |
| `responsible: { name, contact, group }` | a group answering for it | nothing: the inbox is not a person; the group's members have the desk, and each of them may suggest changes to the page | | `responsible: { name, contact, group }` | a group answering for it | nothing: the inbox is not a person; the group's members have the desk, and each of them may suggest changes to the page |
| `qualifies: styret` on a page or `_section.yaml` | members of that group | the pages and desks under it | | `qualifies: board` on a page or `_section.yaml` | members of that group | the pages and desks under it |
| `invite: { group: kasserer }` on a desk page | the desk's own group | the right to bring people into `kasserer` | | `invite: { group: treasurer }` on a desk page | the desk's own group | the right to bring people into `treasurer` |
The desk whose group may invite into the most groups is the site's most The desk whose group may invite into the most groups is the site's most
privileged one; on a vel that is the board. Portal works that out from privileged one; for an association that is the board. Portal works that out from
the content (see step 4). the content (see step 4).
## 2. Set up Kanidm for portal ## 2. Set up Kanidm for portal
@@ -58,7 +58,7 @@ $K group add-members idm_people_pii_read portal-onboarding
# One group per `qualifies:` in the content, managed by that account: # One group per `qualifies:` in the content, managed by that account:
# adding a member to a group takes the right to manage it. # adding a member to a group takes the right to manage it.
for g in styret kasserer trafikk; do for g in board treasurer traffic; do
$K group create "$g" portal-onboarding $K group create "$g" portal-onboarding
done done
@@ -67,7 +67,7 @@ done
$K system oauth2 create portal "My site" https://site.example.no $K system oauth2 create portal "My site" https://site.example.no
$K system oauth2 add-redirect-url portal https://site.example.no/auth/callback $K system oauth2 add-redirect-url portal https://site.example.no/auth/callback
$K system oauth2 update-scope-map portal idm_all_persons openid profile email $K system oauth2 update-scope-map portal idm_all_persons openid profile email
for g in styret kasserer trafikk; do for g in board treasurer traffic; do
$K system oauth2 update-claim-map portal groups "$g" "$g" $K system oauth2 update-claim-map portal groups "$g" "$g"
done done
$K system oauth2 update-claim-map-join portal groups array $K system oauth2 update-claim-map-join portal groups array
@@ -94,7 +94,7 @@ and on an empty Kanidm there is no desk anyone can open yet.
| `SEED_ADMIN_EMAIL` | the first person's address | | `SEED_ADMIN_EMAIL` | the first person's address |
| `SEED_ADMIN_NAME` | their name, as it should appear (optional) | | `SEED_ADMIN_NAME` | their name, as it should appear (optional) |
| `SEED_GROUP` | a group to put them in, if not the most privileged one (optional) | | `SEED_GROUP` | a group to put them in, if not the most privileged one (optional) |
| `RESPONSIBLE_GROUP` | a group every responsible person joins, e.g. `redaktor` (optional) | | `RESPONSIBLE_GROUP` | a group every responsible person joins, e.g. `editors` (optional) |
## 4. Start portal ## 4. Start portal
@@ -151,7 +151,7 @@ A desk that lists the bucket offers the way back with a transition from
```yaml ```yaml
resource: resource:
source: { kind: kv, bucket: portal_invites } source: { kind: kv, bucket: portal_invites }
requires_group: styret requires_group: board
transitions: transitions:
- { from: open, to: done, label: Is in } - { from: open, to: done, label: Is in }
- { from: expired, to: open, label: Send again } - { from: expired, to: open, label: Send again }
@@ -172,7 +172,7 @@ list, and whoever sits there takes it up and settles it:
```yaml ```yaml
resource: resource:
source: { kind: kv, bucket: portal_edit_suggestions } source: { kind: kv, bucket: portal_edit_suggestions }
requires_group: styret requires_group: board
transitions: transitions:
- { from: open, to: discussed, label: Looking at it } - { from: open, to: discussed, label: Looking at it }
- { from: open, to: done, label: Changed } - { from: open, to: done, label: Changed }
@@ -187,7 +187,7 @@ where each one stands. A content repo that declares the bucket itself
in `aggregates.yaml`, with a `mail:` on a state, sends that instead. in `aggregates.yaml`, with a `mail:` on a state, sends that instead.
Their group can also be the way into other tools. The vel's Their group can also be the way into other tools. The vel's
`redaktor` group signs in to the project Gitea with the same account: `editors` group signs in to the project Gitea with the same account:
a second OAuth2 client scoped to that group alone. a second OAuth2 client scoped to that group alone.
## When it does not work ## When it does not work
+1 -1
View File
@@ -33,7 +33,7 @@ Because it is a case, a desk lists it like any other bucket:
```yaml ```yaml
resource: resource:
source: { kind: kv, bucket: portal_memberships } source: { kind: kv, bucket: portal_memberships }
requires_group: styret requires_group: board
transitions: transitions:
- { from: invited, to: removed, label: Withdraw } - { from: invited, to: removed, label: Withdraw }
- { from: active, to: removed, label: Take out } - { from: active, to: removed, label: Take out }
+8 -8
View File
@@ -6,13 +6,13 @@ Anywhere content says something to a person, it may say it in several
ways by giving a list instead of one string: ways by giving a list instead of one string:
```yaml ```yaml
name: Vil du hjelpe til i nabolaget? name: Want to help out in the neighbourhood?
description: description:
- Dugnad, 17. mai og komiteene trenger flere hender. Si hva du kan. - The work day, the spring fair and the committees need more hands. Say what you can do.
- Naboene gjør det meste selv. Her melder du deg til det du har lyst på. - The neighbours do most things themselves. Sign up here for whatever you fancy.
alternatives: alternatives:
- name: [Bli med, Meld deg] - name: [Join in, Sign me up]
consequence: [[Send], [Meld meg]] consequence: [[Send], [Count me in]]
``` ```
Each index is a *storyline*. A visitor is given one at their first Each index is a *storyline*. A visitor is given one at their first
@@ -49,12 +49,12 @@ warm front door is not thanked in the plain voice.
```json ```json
{ "storylines": 2, { "storylines": 2,
"buckets": { "hjelpebehov": { "0": { "open": 3, "ordnet": 9 }, "buckets": { "requests": { "0": { "open": 3, "solved": 9 },
"1": { "open": 5, "ordnet": 14 } } } } "1": { "open": 5, "solved": 14 } } } }
``` ```
Storylines are assigned evenly, so those numbers are the comparison: Storylines are assigned evenly, so those numbers are the comparison:
which words brought more people to send, and how their cases went. No which words brought more people to send, and how their cases went. No
record, field, address or time leaves the site. The trainer reads this record, field, address or time leaves the site. The trainer reads this
(`portal-trainer report`) next to what its personas scored offline, and (`portal report`) next to what its personas scored offline, and
the plan's `tones` are where the storylines are written. the plan's `tones` are where the storylines are written.
+1 -1
View File
@@ -42,7 +42,7 @@ gets it back.
### Onboarding from the plan ### Onboarding from the plan
`invites_by: [styret]` on a plan, or `invited_by: [...]` on a group, `invites_by: [board]` on a plan, or `invited_by: [...]` on a group,
puts an invite form on the inviting group's desk for each group it may puts an invite form on the inviting group's desk for each group it may
fill, and a list of the invites sent. Portal does the rest (an account fill, and a list of the invites sent. Portal does the rest (an account
in Kanidm, the group, a one-time credential link) through `invite:` on in Kanidm, the group, a one-time credential link) through `invite:` on