
Wiki Dashboard
- 2.4k installs
- 3.1k repo stars
- Updated August 4, 2026
- ar9av/obsidian-wiki
wiki-dashboard creates Obsidian Bases .base files or Dataview queries for dynamic vault content views.
About
The wiki-dashboard skill builds queryable Obsidian vault views using Obsidian Bases native YAML .base files or Dataview plugin SQL-like blocks. Config resolves OBSIDIAN_VAULT_PATH via the llm-wiki protocol before reading index.md for existing categories. Bases files use expression-string filters under and/or/not, never typed filter objects, with groupBy inside view definitions not top level. Property naming differs by context: note.tags in properties keys but bare tags in order and groupBy. Dataview supports TABLE, GROUP BY with rows. prefix, stale-page date math via file.mtime, and multi-folder FROM unions. Output lands in _meta/ with slugs like concepts-index.base or dashboard.md, optionally embedded via ![[_meta/name.base]]. Common recipes cover content indexes, entity card galleries, concepts by domain, ingestion logs, and thirty-day stale content trackers. log.md receives WIKI_DASHBOARD entries; optional QMD refresh follows vault markdown writes. Prefer Bases on Obsidian 1.8+ unless GROUP BY or computed columns require Dataview.
- Bases native .base YAML or Dataview plugin queries.
- Bases filters use and/or/not expression strings, not typed objects.
- groupBy goes inside view definition; omit grouped column from order.
- Dataview GROUP BY requires rows. prefix on file properties.
- Write to _meta/ slug; embed with ![[_meta/name.base]] syntax.
Wiki Dashboard by the numbers
- 2,415 all-time installs (skills.sh)
- +35 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #159 of 1,879 Documentation skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
wiki-dashboard capabilities & compatibility
- Capabilities
- obsidian bases canonical yaml schema with expres · dataview table group by and stale page date reci · computed formula columns via bases formulas bloc · dashboard embedding and _meta/ file conventions · log.md tracking and optional qmd refresh after w
- Works with
- obsidian
- Use cases
- documentation · planning
What wiki-dashboard says it does
Filters use expression strings, not typed objects.
npx skills add https://github.com/ar9av/obsidian-wiki --skill wiki-dashboardAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.4k |
|---|---|
| repo stars | ★ 3.1k |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 4, 2026 |
| Repository | ar9av/obsidian-wiki ↗ |
How do I build an auto-updating dashboard or content index over my Obsidian wiki vault?
Create dynamic Obsidian vault dashboards with native Bases .base files or Dataview queries.
Who is it for?
Obsidian wiki vaults needing live tables, card galleries, or grouped concept indexes.
Skip if: Skip for capturing new knowledge; use wiki-capture or wiki-ingest instead.
When should I use this skill?
User asks for vault dashboard, dynamic view, query my vault, or show all concepts as table.
What you get
A .base or Dataview dashboard in _meta/ filtering folders, tags, or staleness with correct syntax.
- Bases dashboard view
- Dataview query block
By the numbers
- Supports 2 dashboard tools: Obsidian Bases and Dataview
- Obsidian Bases is native to Obsidian 1.8+ with no plugin required
Files
Wiki Dashboard — Dynamic Vault Views
Two tools available: Obsidian Bases (native, GUI-driven, no plugin) and Dataview (community plugin, SQL-like, more powerful). Check which the user has and prefer Bases unless they ask for Dataview or need GROUP BY / computed columns.
Before You Start
1. Resolve config — follow the Config Resolution Protocol in llm-wiki/SKILL.md (walk up CWD for .env → ~/.obsidian-wiki/config → prompt setup). This gives OBSIDIAN_VAULT_PATH. 2. Read $OBSIDIAN_VAULT_PATH/index.md to understand what categories and pages exist. 3. Ask the user what they want to view if not specified — folder, tag, category, date range? 4. Ask if they have Dataview installed if you're unsure which tool to use.
---
Option A — Obsidian Bases (.base files)
Bases are YAML files that define live views over vault notes. Native to Obsidian 1.8+, no plugin needed.
Official canonical schema
Top-level keys:
filters: # Global filter applied to all views (expression strings under and/or/not)
formulas: # Named computed properties — referenced as formula.<name>
properties: # Display config per property — sets displayName for column headers
summaries: # Aggregation formulas (e.g. mean, sum)
views: # Array of view definitions (required)Each item in views::
views:
- type: table # table | list | cards | map
name: "View Name" # display label
limit: 50 # optional max rows
order: # column display order (list of property/formula names)
- file.name
- note.updated
groupBy: # grouping — goes INSIDE the view, NOT at top level
property: note.tags
direction: ASC # ASC | DESC
filters: # view-specific filter (merges with global filters)
and:
- 'note.status != "done"'
summaries:
formula.myFormula: AverageFilter syntax — CRITICAL
Filters use expression strings, not typed objects. Always wrap in and:, or:, or not: — a bare list causes a "may only have one of and/or/not keys" parse error.
# CORRECT
filters:
and:
- file.inFolder("concepts")
# WRONG — typed objects (parse error)
filters:
- type: folder
folder: conceptsFilters support nesting:
filters:
or:
- file.hasTag("book")
- and:
- file.inFolder("concepts")
- file.hasTag("research")
- not:
- file.hasTag("archived")Property name conventions
Different contexts use different naming — confirmed from Obsidian's auto-reformat behaviour:
| Context | Frontmatter field tags | File name | Formula |
|---|---|---|---|
properties: keys | note.tags | file.name | formula.<name> |
order: values | tags (bare) | file.name | formula.<name> |
groupBy.property: | tags (bare) | file.name | — |
filters: expressions | file.hasTag(...) / note.tags | file.name | formula.<name> |
formulas: expressions | note.tags, note.updated | file.name | — |
Basic table — folder filter
filters:
and:
- file.inFolder("concepts")
properties:
file.name:
displayName: Page
note.tags:
displayName: Tags
note.summary:
displayName: Summary
note.updated:
displayName: Updated
views:
- type: table
name: Table
order:
- file.name
- tags
- summary
- updatedCards view — folder filter
filters:
and:
- file.inFolder("entities")
properties:
file.name:
displayName: Entity
note.title:
displayName: Full Name
note.tags:
displayName: Tags
note.summary:
displayName: Summary
views:
- type: cards
name: Cards
order:
- file.name
- title
- tags
- summaryGroup by property — groupBy goes INSIDE the view
When groupBy is set, omit that property from `order:` — it becomes the group header row and adding it as a column too causes duplication.
filters:
and:
- file.inFolder("concepts")
properties:
file.name:
displayName: Concept
note.summary:
displayName: Summary
note.updated:
displayName: Updated
views:
- type: table
name: By Domain
groupBy:
property: tags # bare property name, no note. prefix
direction: ASC
order:
- file.name # do NOT include tags here — already the group header
- summary
- updatedTag filter
filters:
and:
- file.hasTag("machine-learning")
properties:
file.name:
displayName: Page
note.category:
displayName: Category
note.summary:
displayName: Summary
views:
- type: table
name: Table
order:
- file.name
- category
- summaryMulti-filter (folder AND tag)
filters:
and:
- file.inFolder("projects")
- file.hasTag("active")
properties:
file.name:
displayName: Project
note.summary:
displayName: Summary
note.updated:
displayName: Last Updated
views:
- type: cards
name: Cards
order:
- file.name
- summary
- updatedOR filter (two folders)
filters:
or:
- file.inFolder("concepts")
- file.inFolder("entities")
properties:
file.name:
displayName: Page
note.category:
displayName: Category
note.updated:
displayName: Updated
views:
- type: table
name: Table
order:
- file.name
- category
- updatedComputed column via formulas
filters:
and:
- file.inFolder("concepts")
formulas:
days_stale: "floor((now() - note.updated) / 86400000)"
properties:
file.name:
displayName: Page
note.updated:
displayName: Updated
formula.days_stale:
displayName: Days Stale
views:
- type: table
name: Stale
order:
- file.name
- updated
- formula.days_staleFilter expression reference
| Expression | What it does |
|---|---|
file.inFolder("path") | Pages in that folder |
file.hasTag("tag") | Pages with that tag (no # prefix) |
file.hasLink("Note Name") | Pages linking to a note |
file.name == "note-name" | Exact filename match |
file.ext == "md" | Filter by extension |
note.propertyName | Any frontmatter property |
formula.formulaName | A named formula result |
now() | Current timestamp in ms |
On Obsidian UI-generated format: When Obsidian's GUI writes or reformats a.basefile it may output a simplified shorthand with top-levelcolumns:,sort:, andview:keys instead of the canonical schema. That format also works — Obsidian accepts both. Manually authored files should use the canonical schema above.
---
Option B — Dataview (community plugin)
Dataview uses a SQL-like query language inside `dataview ` code blocks in any note. More powerful than Bases for computed columns, GROUP BY, and cross-folder queries.
Basic table — folder
````markdown
TABLE
tags AS "Tags",
summary AS "Summary",
file.mtime AS "Last Modified"
FROM "concepts"
SORT file.mtime DESC````
Table with clickable links (TABLE WITHOUT ID)
````markdown
TABLE WITHOUT ID
file.link AS "Entity",
tags AS "Tags",
summary AS "Summary"
FROM "entities"
SORT file.name ASC````
GROUP BY — use rows. prefix after grouping
After GROUP BY, individual file properties must be prefixed with rows. — otherwise the column is empty or errors.
````markdown
TABLE WITHOUT ID
rows.file.link AS "Concept",
rows.summary AS "Summary"
FROM "concepts"
GROUP BY tags[0] AS "Domain"````
Stale pages — use file.mtime for date math
Avoid choice(updated, date(updated), file.mtime) — mixed date formats in updated frontmatter cause arithmetic errors. file.mtime is always a valid DateTime.
````markdown
TABLE WITHOUT ID
file.link AS "Page",
category AS "Type",
file.mtime AS "Last Modified",
(date(today) - file.mtime).days + " days" AS "Age"
FROM "concepts" OR "entities" OR "projects"
WHERE file.name != file.folder
WHERE (date(today) - file.mtime).days > 30
SORT (date(today) - file.mtime).days DESC````
Multi-folder query
````markdown
TABLE
summary AS "Summary",
file.mtime AS "Last Modified"
FROM "projects"
WHERE file.name != file.folder
SORT file.mtime DESC````
Dataview reference
| Clause | Usage |
|---|---|
FROM "folder" | All notes in folder |
FROM #tag | All notes with tag |
FROM "a" OR "b" | Union of two folders |
WHERE file.name != file.folder | Exclude folder index pages |
GROUP BY field AS "Label" | Group rows — use rows. for properties after this |
SORT field DESC | Sort direction |
file.link | Clickable wikilink |
file.mtime | Last modified time (always valid DateTime) |
(date(today) - file.mtime).days | Days since last modification |
---
Step 3: Write the File
Bases: Target path $OBSIDIAN_VAULT_PATH/_meta/<dashboard-name>.base
Dataview: Write queries directly into any .md note. A dedicated dashboard note at $OBSIDIAN_VAULT_PATH/_meta/dashboard.md works well for multi-section views.
Slug examples:
- "All concepts" →
_meta/concepts-index.base - "Recent ingests" →
_meta/recent-ingests.base - "Project overview" →
_meta/projects-overview.base - "Stale pages" →
_meta/stale-pages.base - "Full dashboard" →
_meta/dashboard.md
Create _meta/ if it doesn't exist yet.
Step 4: Embed Bases (optional)
To embed a .base inside a note:
## Entities
![[_meta/entities-tracker.base]]Ask before modifying an existing note.
Step 5: Update Tracking
Append to $OBSIDIAN_VAULT_PATH/log.md:
- [TIMESTAMP] WIKI_DASHBOARD name="<slug>" tool=bases|dataview view=<type> filter="<description>"No manifest or index update needed — dashboards are live queries, not static pages.
Common Dashboard Recipes
| Dashboard | Best tool | What it shows |
|---|---|---|
| Content index | Bases or Dataview | All pages grouped by category, sorted by updated |
| Entity tracker | Bases (cards) | Entity pages as a visual card gallery |
| Concepts by domain | Dataview | Concepts grouped by first tag using GROUP BY |
| Ingestion log | Either | Pages sorted by created date |
| Stale content | Dataview | Pages not touched in 30+ days with day count |
| Project overview | Either | Project pages with last-sync date |
| Research tracker | Dataview | Synthesis pages tagged research |
Quality Checklist
- [ ] Bases: filters use expression strings under
and:/or:/not:, never typed objects - [ ] Bases:
groupBygoes inside the view definition — not as a top-level key - [ ] Bases: column headers set via
properties: <name>: displayName: "...", notcolumns: [{title}] - [ ] Bases:
formulas:used for computed columns, referenced asformula.<name>in order/properties - [ ] Dataview: GROUP BY queries use
rows.propertynot bareproperty - [ ] Dataview: date arithmetic uses
file.mtime, notchoice(updated, ...) - [ ] File written to
_meta/with a descriptive slug - [ ]
log.mdupdated - [ ] User told how to embed Bases (
![[_meta/<name>.base]]) or open the dashboard note
QMD Refresh After Vault Writes
QMD is a search index, not the source of truth. If $QMD_WIKI_COLLECTION is empty or unset, skip this step. Run it only after this skill has written or rewritten vault markdown. If QMD refresh fails, do not roll back the vault changes; report the QMD status separately.
Use $QMD_CLI if set; otherwise use qmd.
${QMD_CLI:-qmd} updateIf the output says vectors are needed or embeddings may be stale, run:
${QMD_CLI:-qmd} embedVerify the collection with either:
${QMD_CLI:-qmd} ls "$QMD_WIKI_COLLECTION"or, when a specific page path is known:
${QMD_CLI:-qmd} get "qmd://$QMD_WIKI_COLLECTION/<page>.md" -l 5Record one of:
QMD refreshed: update + embed + verifiedQMD refreshed: update only + verifiedQMD skipped: QMD_WIKI_COLLECTION unsetQMD skipped: qmd CLI unavailableQMD failed: <short error summary>
Related skills
How it compares
Pick wiki-dashboard for live Obsidian vault overviews rather than generic Markdown table generators outside Obsidian.
FAQ
Bases or Dataview?
Prefer native Bases on Obsidian 1.8+; use Dataview for GROUP BY or advanced computed columns.
Why do Bases filters fail with typed objects?
Filters must be expression strings under and/or/not; typed folder objects cause parse errors.
Where should dashboard files live?
In _meta/ with descriptive slugs like concepts-index.base or dashboard.md.
Is Wiki Dashboard safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.