Dataview
Evaluate declarative dataview code blocks against the content manifest at
build time and render them as lists, tables, task lists, or calendars. No
client-side JavaScript is required.
Overview
dataviewPlugin() recognises fenced blocks whose language is dataview:
```dataview
TABLE file.name AS "Name", status
FROM #project
WHERE status = "active"
SORT file.name asc
LIMIT 10
```
and renders them from the manifest using each public note's frontmatter, tags,
links, and permalink. Unlisted, draft, and scheduled notes are excluded from
queries. DataviewJS (dataviewjs) is not supported: those blocks stay
code blocks and produce a diagnostic.
Usage
import { defineConfig } from "@riebeckite/core";
import { dataviewPlugin } from "@riebeckite/plugin-dataview";
export default defineConfig({
// ...
plugins: [dataviewPlugin()],
});
Query syntax
A block starts with a query type (LIST, TABLE, TASK, or CALENDAR)
followed by optional clauses:
LIST|TABLE|TASK|CALENDAR [expression or columns]
FROM <source expression>
WHERE <boolean expression>
SORT <field> [asc|desc][, ...]
GROUP BY <field>
LIMIT <n>
Clauses are case-insensitive. Each clause starts on its own line, but a clause body may span multiple lines.
LIST
LIST renders an unordered list of matching notes. An optional trailing
expression is shown as metadata next to the link:
Dataview query
LIST file.date
FROM #diary
SORT file.date descTABLE
TABLE renders a table. When no columns are given, a single file.link column
is used. Columns are field paths, optionally renamed with AS:
| Name | status | priority |
|---|---|---|
| dataview.en | ||
| dataview | ||
| showcase.en | ||
| showcase |
Dataview query
TABLE file.name AS "Name", status, priority
FROM #projectTASK
TASK extracts the task list items (- [ ] / - [x]) from every matching
note and renders them as <ul class="rb-dataview__tasks">. FROM and WHERE
select the pages, not individual tasks:
No matching content.
Dataview query
TASK
FROM #projectCALENDAR
CALENDAR renders a month grid. The optional trailing expression selects the
date field (default date). The month of the most recent matched date is shown:
No matching content.
Dataview query
CALENDAR date
FROM #projectClauses
FROM
FROM selects candidate notes. Sources are:
| Source | Meaning |
|---|---|
#tag |
Has the tag |
"folder" |
Slug is the folder or lives under it |
[[note]] |
Links to note (incoming links) |
Combine sources with and / or, negate with ! or -, and group with
parentheses. Adjacent sources are treated as and.
Dataview block in `docs/plugins/dataview.en` unsupported query type `FROM`; expected LIST, TABLE, TASK, or CALENDAR.
Dataview query
FROM (#project or #area) and "notes" and !#archiveWHERE
WHERE filters notes with a boolean expression over file.* and frontmatter
fields.
| Feature | Examples |
|---|---|
| Comparison | status = "active", priority > 2, date <= "2026-12-31" |
| Boolean | status = "active" and !draft, a or b |
contains() |
contains(file.tags, "#project"), contains(tags, "project") |
date() |
date(due) >= date("2026-01-01") |
number() / string() |
number(weight) > 3 |
String =/!= comparisons and contains() are case-insensitive. date()
returns a millisecond timestamp (or null), so date(a) < date(b) compares
chronologically. null/missing values never satisfy </> comparisons.
file.* fields: file.name, file.title, file.slug, file.path,
file.folder, file.link, file.permalink, file.url, file.tags,
file.date, file.created, file.updated, file.published. Other frontmatter
keys are read directly by name (status, priority, due, ...).
SORT
SORT accepts a comma-separated list of fields with an optional direction
(asc, the default, or desc). Notes with a missing field sort last.
Dataview block in `docs/plugins/dataview.en` unsupported query type `SORT`; expected LIST, TABLE, TASK, or CALENDAR.
Dataview query
SORT priority desc, file.name ascGROUP BY
GROUP BY <field> groups the matched notes. Each group is headed by the group
value; LIST and TASK render one list per group, and TABLE inserts a group
row. Groups keep the order established by SORT.
LIMIT
LIMIT <n> caps the number of rendered notes (before grouping). It can also be
set for every block with the limit option.
Options
| Option | Type | Default | Description |
|---|---|---|---|
className |
string |
"rb-dataview" |
Root CSS class |
language |
string |
"dataview" |
Fence language to target |
hideFallback |
boolean |
false |
Hide the raw-query <details> fallback |
limit |
number |
none | Default LIMIT when a block omits one |
Rendering
Each block becomes:
<div class="rb-dataview" data-dataview data-dataview-type="list">
<!-- list, table, task, or calendar output -->
<details class="rb-dataview__fallback">
<summary>Dataview query</summary>
<pre><code>LIST FROM #project</code></pre>
</details>
</div>
The readable <details> fallback contains the raw query and can be disabled
with hideFallback.
Diagnostics
-
dataviewjsblocks are left untouched and emit adataview-unsupported-languagewarning. The markdown-time remark transform also records afile.messagewithsource: "@riebeckite/plugin-dataview". -
Blocks the parser or evaluator cannot handle render an inline error box and
emit a
dataview-invaliderror diagnostic. Unsupported syntax is also reported throughfile.messagewhile the markdown is parsed.
Limitations
- No DataviewJS.
dataviewjsis intentionally unsupported. - No inline fields (
field:: value). Only frontmatter is read. -
TABLEcolumns are field paths, not arbitrary expressions. Rename withAS "Label"; computed columns (for examplefile.size / 1024) are not supported. -
TASKfilters pages, not tasks.WHERE/FROMapply to the notes that contain tasks. CALENDARshows one month — the month of the most recent matched date.-
file.size,file.mtime, andfile.ctimeare not available from the manifest and evaluate toundefined. - Results are fixed at build time and links produced by a dataview block are not added to the content graph (backlinks). A full build always recomputes correctly.
Exports
dataviewPlugin(options?)/dataview(options?)— plugin factoryremarkDataview(options?)— remark transform usable on its ownparseDataview(source)— parse a block body into aDataviewSpecselectDataviewEntries(spec, manifest, defaultLimit)— matching engine-
evaluateDataviewExpression(expression, scope)andmatchesDataviewFrom(from, entry, manifest)— expression helpers renderDataview(selection, spec, options, source)— HTML rendererresolveDataviewOptions(options?)— normalise plugin optionsDATAVIEW_ATTRIBUTE— placeholder attribute name-
Types:
DataviewOptions,DataviewSpec,DataviewQueryType,DataviewExpression,DataviewFrom, and friends