Skip to content

The project board

An optional dashboard: a horizontally scrolling kanban of open tasks, one column per active project, discovered from the wiki’s projects folder. It ships in templates/board/ and /setup-wiki offers to install it.

Tasks are read wherever they are already written, in Obsidian Tasks syntax, and routed to a column by the wikilinks at the start of the line. Nothing is copied into a board file, and no task ever moves between notes: the source note stays the only copy.

▶ Board settings Filter tasks… SORT Manual Reorder with the arrows in each column header Unassigned 2 + OPEN (2) chase the invoice from the print shop created 11 Jan find out who owns the old status page created 12 Jan website-redesign 4 + IN PROGRESS (1) rewrite the pricing page copy created 7 Jan OPEN (3) ⏫ ship the new navigation Alex Rivera due 9 Jan decide whether to retire legacy-export once the new site is live created 12 Jan add a contact link to the header, per the findings above due 2 Feb api-migration 2 + OPEN (2) 🔺 inventory every caller before touching the gateway Sam Okafor due 24 Jan decide whether to retire legacy-export or fold in created 11 Jan docs-refresh 2 + OPEN (2) draw the diagram for the install flow Alex Rivera 🔼 cut the guide down to one page due 31 Jan

The board above is rendered from templates/board/demo/, the invented wiki the tests run against, so every project and person in it is fictional.

  • One column per project whose lifecycle status the wiki lists as column-eligible. A dormant or completed project keeps its tasks off the board without them being deleted
  • A triage column for tasks that name no project, which is the signal that they need a home
  • Three lanes per column: in progress, open, and recently done
  • Eight column-order modes with a direction toggle, plus a manual order set by arrows in the column headers
  • A filter box that narrows every column as you type
  • Click a checkbox to complete a task, right-click it for the full status set, and use the + in a column header to add one through the Tasks plugin’s own modal
  • 20 display settings stored as board_* keys in the board note’s frontmatter, so two boards in one vault are configured independently
  • Switch pills in the column headers for any per-project boolean you declare, so a flag something else reads is visible and flippable where the projects are

A custom Obsidian plugin lives in .obsidian/, which most sync setups deliberately leave out. That means installing and reinstalling it on every device on every change. A DataviewJS view stored in the vault syncs with the notes.

The same reasoning rules out a CSS snippet in .obsidian/snippets/: the stylesheet has to live in the synced tree. It sits next to view.js and is loaded by the script itself, not by dv.view, which resolves a sibling stylesheet by wikilink and injects it with a scope attribute no browser implements.

The cost is enabling Dataview’s JavaScript Queries once per device.

  • Dataview with Enable JavaScript Queries switched on. That setting is per device, so it has to be switched on again in Obsidian on a phone or tablet. Without it the board note shows a raw code block, and the note carries a callout saying so
  • Tasks for the add and edit buttons. The board parses and writes Tasks syntax itself, so everything else works without it
  • A purpose: projects folder in the wiki. Without one the board would have no columns, and /setup-wiki will not offer it
▼ Board settings COLUMNS CHIPS LANES DENSITY Unassigned column Pin Unassigned (desktop only) Projects with no open tasks Column width (px) 280 Assignees Due date Created date Priority Done date Source note In progress lane Done lane Done lane window (days) 7 Compact cards (hide meta line) SCOPE Folders to scan demo Folders to skip demo/Archive FLAGS P Publish Remove Field publish Label Publish Glyph P When on Included the next time the site is built. Add flag Reset to defaults Filter tasks… SORT Manual Reorder with the arrows in each column header

Structure lives in the WIKIS table in view.js: folder layout, project depth, people folder, which statuses earn a column, where the add button writes, and what is in scope. These describe a wiki’s shape, so they are shared by every board on that wiki.

Appearance lives in the board note’s own frontmatter as board_* keys, and the settings panel on the board writes them for you.

Flags are the third, declared on the board note as board_flags and edited from the same panel. They are neither structure nor appearance: a flag says what boolean a project can carry, so it gets its own section below.

The setting to get right before any other is exclude_folders. Any folder holding checkbox lines that are not project tasks belongs in it: meeting transcripts, imported checklists, reading lists. A folder of transcripts can hold an order of magnitude more checkbox lines than a wiki has real tasks. Including it does not break the board, it buries every real task under the triage column, and nothing on screen says that is what happened.

A flag is a boolean you keep in a project’s frontmatter and something else reads: an opt-in to an export, a publish gate, a review marker, a field a script outside the vault greps for. Declare it on the board note and every project column grows a switch pill for it.

board_flags:
- field: publish
label: Publish
glyph: P
on_hint: Included the next time the site is built.
off_hint: Kept out of the site build.

field, label and glyph are required, the two hints optional. The glyph is what the pill shows, so one or two characters. Clicking a pill writes field: true or field: false to that project’s landing page and nothing else, never last_activity: flipping a flag is not work on the project, and stamping the date would make a dormant project look active in the board’s own activity sort.

The settings panel’s Flags group is the editor. Each declared flag gets a block with a field per key, a Remove button, and there is an Add flag button under the list. The frontmatter is the store either way, so editing it by hand works exactly as well.

Two things worth knowing:

  • The board does not know what reads the field. It writes a boolean where you told it to, and that is the whole contract. Whatever consumes the flag, an ingest procedure, a build script, a query in another note, is on its own side of that line
  • Absent means off. A project with no such key in its frontmatter shows the pill struck through, and so does an unparseable value. A consumer that treats a missing field as “no” therefore agrees with what the board shows

A flag whose declaration is wrong, no field, a glyph too long, two flags sharing a field, or one trying to write status or last_activity, is dropped with a banner over the board and a line in the panel saying which. It is never dropped silently: a pill that never appears looks exactly like a board with no flags declared.

Two or three pills is as many as a column header carries comfortably. Beyond that the header wraps and the project name stops being the first thing you read.

The board routes on the leading run of wikilinks:

- [ ] [[Person]] [[project-slug]] description ➕ 2026-01-05 📅 2026-01-09 🔼
  • Statuses: [ ] open, [/] in progress, [x] done, [-] cancelled
  • Dates: created, 📅 due, done, cancelled
  • Priorities, highest to lowest: 🔺 ⏫ 🔼 🔽 ⏬

Links after the leading run are mentions, not assignments. A task reading [[project-a]] decide whether to retire [[project-b]] belongs to project-a only, so it does not show up as outstanding work on the project it proposes retiring. A task naming two projects in its leading run does appear in both columns; that is deliberate.

Three code paths modify a task: ticking a checkbox, setting a status from the card menu, and adding a task. All three write one line to the task’s own source note, and all three fail closed. If the line the board parsed is no longer there, nothing is written and the board says it is stale rather than guessing which line was meant.

Three more write frontmatter rather than a task line: the column menu’s status change, which writes status and last_activity to a project’s landing page; a flag pill, which writes one boolean to a project’s landing page and nothing else; and the settings panel, which writes board_* keys to the board note. Each is a single named key, so a failed write leaves the note as it was.

Only the four statuses above are offered, because the parser reads exactly those characters. Writing a fifth would produce a line the board cannot read back, and the task would vanish from it.

A recurring task is refused rather than completed, since a line rewrite would not create the next occurrence. The edit pencil hands it to the Tasks plugin instead.

templates/board/demo/ is a small invented wiki that the board’s own tests run against. Copy it into a scratch vault alongside view.js and view.css, then open demo/Board.md.

templates/board/README.md is the install and usage guide. templates/board/DESIGN.md records why each decision went the way it did, and the traps found while building it.