A board_group is a homepage / overview page that previews several
referenced sub-containers at once. Each referenced container is rendered
as a Board-style card (title + own desc-as-markdown + first N children as
deep-link rows) with a trailing “View all →” link when there are more entries
than the preview cap. Rendering lives in src/content/board_group.rs.
Compared to board_list: a board_group’s sections
are real sub-folders (each section slug must be a child directory with
its own ctx.json). A board_list’s sections are virtual labels.
For each section slug in content, the page renders one
render_board_card(...) (from src/content/board.rs) using the section’s
own Header for the card title and markdown desc, the section’s first
preview_count children as rows, and view_all_href = Some("<slug>/") if
the section has more children than the preview window.
Each child row in a board_group card uses the deep-link prefix
<section_slug>/, so clicking a row jumps directly to
/<section_slug>/<leaf_slug>/ — skipping the intermediate section index.
An optional banner image is rendered at the very top of the page (above
all section cards) using the resolved language:
<img src="<banner_url>" class="img-fluid rounded mb-4" alt=""/>
{
"type": "board_group",
"name": {
"en": "FDS",
"ja": "FDS",
"zh": "FDS"
},
"desc": {
"en": "FDS overview — what we publish and where to find it."
},
"banner": {
"en": "/images/banner_en.png",
"ja": "/images/banner_ja.png"
},
"preview_count": 3,
"content": [
"policies",
"cooperation",
"news",
"doc"
]
}
| Field | Type | Required | Notes |
|---|---|---|---|
type | "board_group" | yes | Exact discriminator string. |
name | string or LangDict | yes | The page’s own header; used by a parent that references this group. See Common: Header and LangDict. |
desc | string or LangDict | no | Stored on the header; not auto-rendered at the top of the page (the section cards each render their own desc). |
icon | string | no | Same resolution rules as board; used by a parent that references this group. |
banner | string or LangDict | no | Per-language image URL rendered at the very top. |
preview_count | integer | no | How many leaf rows per section card. Default 3 (constant DEFAULT_PREVIEW_COUNT). Zero / negative / missing -> falls back to 3. |
content | array of strings | yes | Slugs of referenced sub-containers. Each must resolve to a list / board / etc. under <own_folder>/<slug>/ctx.json. |
content semanticsFor board_group, content is — like board and
list — a flat array of slug strings, parsed by the same
parse_slug_list helper. Each slug must be a child sub-folder. The
section title, desc, and preview rows are all derived from that child’s
ctx.json.
This is the key difference from board_list, where
content is an array of {name, items} objects and sections do not
correspond to sub-folders.
BoardGroup::read(path) reads ctx.json, builds the Header, the
banner: OptionLangDict, the slug list, and preview_count.BoardGroup::render writes the banner (if set), then for each section
slug:
ctx.json and Header (or Header::fallback(slug)).content list (the section’s children), takes
the first min(preview_count, total) entries, and resolves each to a
(slug, Header, folder) triple.href_prefix = "<section_slug>/" so each row’s <a href> becomes
<section_slug>/<leaf_slug>/.view_all_href = Some("<section_slug>/") if and only if
total > preview_n, producing a trailing “View all →” link.render_board_card(...) to render the section card.The current editor surface targets the leaf-board case more than the
overview case; for board_group editing typically means editing the
referenced section’s own ctx.json (rename, icon, desc) and adjusting the
content slug list on the group itself. There is no per-section override on
the group: a section card’s title, desc, and icon all come from the
section’s own Header.
board_group uses Header::write_into for the metadata block. Saving
preserves banner (an OptionLangDict — drops to disk if empty), the slug
list, and preview_count. The same rebuild-from-scratch pattern is used so
that clearing icon / desc / banner actually disappears from disk.
board_group deep-links from its overview rows straight to leaves
(/<section_slug>/<leaf_slug>/), bypassing the section index. Don’t rely
on the section page being visited first — it is not.preview_count only filters how many rows are shown in the card; the
full list is still reachable via the “View all →” link.ctx.json is missing,
the section card still renders, but with Header::fallback(slug) (slug as
title, no desc, no icon, no children). This is intentional — a broken link
stays visible rather than vanishing.banner is an OptionLangDict, so it accepts either a plain string (“same
banner for every language”) or a per-lang dict.board_group page does not render its own name /
desc at the top — only banner, then the section cards. The group’s
name is only visible from a parent that references it (or in the navbar
/ <title> if this is the site root, in which case prefer
board_list at /).