Color mode

Query

Turn query code blocks into lists or tables of content. Filtering, sorting, and pagination run against frontmatter and tags at build time, so no client-side JavaScript is required.

日本語

Overview

queryPlugin() recognises fenced blocks

md
```query
filter:
  tags:
    any: [diary]
sort:
  field: date
  order: desc
limit: 5
```

and renders them using the content manifest (every note's frontmatter, tags, and permalink).

Usage

ts
import { defineConfig } from "@riebeckite/core";
import { queryPlugin } from "@riebeckite/plugin-query";
 
export default defineConfig({
  // ...
  plugins: [queryPlugin()],
});

Block syntax

The block body is a YAML mapping. Every field is optional.

Field Type Description
filter object Filtering conditions (below)
sort object | object[] field (a frontmatter key, title, slug, or permalink) and order (asc / desc, default asc). The default field is date
limit number Maximum number of entries
offset number Entries to skip from the top
format "table" | "list" Output format. Defaults to table
columns string[] Table columns: presets (title, date, updated, created, published, tags, description, permalink) or frontmatter keys
excludeSelf boolean Exclude the note hosting the block from its own results
empty string Message shown when nothing matches

filter

Field Type Description
tags.any string[] Has at least one of these tags
tags.all string[] Has every one of these tags
tags.none string[] Has none of these tags
folder string | string[] Slug prefix match
frontmatter object Frontmatter equality. An array matches any member; string comparisons are case-insensitive
date object field (default date) plus inclusive from / to bounds
yaml
filter:
  tags:
    any: [diary, note]
    none: [draft]
  folder: articles
  frontmatter:
    draft: false
  date:
    field: published
    from: 2024-01-01
    to: 2024-12-31
sort:
  - field: date
    order: desc
  - field: title
limit: 10
format: list

Options

Option Type Default Description
className string "rr-query" Root CSS class
language string "query" Fence language to target
defaultFormat "table" | "list" "table" Format when a block omits format
defaultColumns string[] ["title", "date"] Columns when a block omits columns
defaultSort object none Sort when a block omits sort
defaultLimit number none Row cap when a block omits limit
emptyMessage string "No matching content." Empty-state message
excludeSelf boolean false Exclude the host page by default

Diagnostics

A block that is not valid YAML (or not a mapping) renders an inline error and emits a content-query-invalid error diagnostic. Unknown fields emit a content-query-unknown-field warning.

Limitations

  • Links produced by a query are not added to the content graph (backlinks). Only links written in the source Markdown participate.
  • Results are fixed at build time. Rebuilding a host note when a queried note changes is future work; a full build always recomputes correctly.

Exports

  • queryPlugin(options?) — plugin factory
  • remarkQuery(options?) — remark transform usable on its own (options.language selects the fence language)
  • queryContentEntries(entries, spec) — the Core matching engine (also available from @riebeckite/core)
  • Types: QueryOptions, QuerySpec, QueryOutputFormat

See also

History

1 changesCollapseExpand
1 + <!-- Generated from packages/plugins/query/README.md. Do not edit this page directly; edit the package README and run `pnpm docs:sync`. -->
2 +
3 + # Query
4 +
5 + Turn `query` code blocks into lists or tables of content. Filtering, sorting,
6 + and pagination run against frontmatter and tags at build time, so no client-side
7 + JavaScript is required.
8 +
9 + [日本語](./query.md)
10 +
11 + ## Overview
12 +
13 + `queryPlugin()` recognises fenced blocks
14 +
15 + ````md
16 + ```query
17 + filter:
18 + tags:
19 + any: [diary]
20 + sort:
21 + field: date
22 + order: desc
23 + limit: 5
24 + ```
25 + ````
26 +
27 + and renders them using the content manifest (every note's frontmatter, tags, and
28 + permalink).
29 +
30 + ## Usage
31 +
32 + ```ts
33 + import { defineConfig } from "@riebeckite/core";
34 + import { queryPlugin } from "@riebeckite/plugin-query";
35 +
36 + export default defineConfig({
37 + // ...
38 + plugins: [queryPlugin()],
39 + });
40 + ```
41 +
42 + ## Block syntax
43 +
44 + The block body is a YAML mapping. Every field is optional.
45 +
46 + | Field | Type | Description |
47 + | ----- | ---- | ----------- |
48 + | `filter` | object | Filtering conditions (below) |
49 + | `sort` | object \| object[] | `field` (a frontmatter key, `title`, `slug`, or `permalink`) and `order` (`asc` / `desc`, default `asc`). The default field is `date` |
50 + | `limit` | number | Maximum number of entries |
51 + | `offset` | number | Entries to skip from the top |
52 + | `format` | `"table"` \| `"list"` | Output format. Defaults to `table` |
53 + | `columns` | string[] | Table columns: presets (`title`, `date`, `updated`, `created`, `published`, `tags`, `description`, `permalink`) or frontmatter keys |
54 + | `excludeSelf` | boolean | Exclude the note hosting the block from its own results |
55 + | `empty` | string | Message shown when nothing matches |
56 +
57 + ### `filter`
58 +
59 + | Field | Type | Description |
60 + | ----- | ---- | ----------- |
61 + | `tags.any` | string[] | Has at least one of these tags |
62 + | `tags.all` | string[] | Has every one of these tags |
63 + | `tags.none` | string[] | Has none of these tags |
64 + | `folder` | string \| string[] | Slug prefix match |
65 + | `frontmatter` | object | Frontmatter equality. An array matches any member; string comparisons are case-insensitive |
66 + | `date` | object | `field` (default `date`) plus inclusive `from` / `to` bounds |
67 +
68 + ```yaml
69 + filter:
70 + tags:
71 + any: [diary, note]
72 + none: [draft]
73 + folder: articles
74 + frontmatter:
75 + draft: false
76 + date:
77 + field: published
78 + from: 2024-01-01
79 + to: 2024-12-31
80 + sort:
81 + - field: date
82 + order: desc
83 + - field: title
84 + limit: 10
85 + format: list
86 + ```
87 +
88 + ## Options
89 +
90 + | Option | Type | Default | Description |
91 + | ------ | ---- | ------- | ----------- |
92 + | `className` | `string` | `"rr-query"` | Root CSS class |
93 + | `language` | `string` | `"query"` | Fence language to target |
94 + | `defaultFormat` | `"table"` \| `"list"` | `"table"` | Format when a block omits `format` |
95 + | `defaultColumns` | `string[]` | `["title", "date"]` | Columns when a block omits `columns` |
96 + | `defaultSort` | object | none | Sort when a block omits `sort` |
97 + | `defaultLimit` | `number` | none | Row cap when a block omits `limit` |
98 + | `emptyMessage` | `string` | `"No matching content."` | Empty-state message |
99 + | `excludeSelf` | `boolean` | `false` | Exclude the host page by default |
100 +
101 + ## Diagnostics
102 +
103 + A block that is not valid YAML (or not a mapping) renders an inline error and
104 + emits a `content-query-invalid` error diagnostic. Unknown fields emit a
105 + `content-query-unknown-field` warning.
106 +
107 + ## Limitations
108 +
109 + - Links produced by a query are not added to the content graph (backlinks).
110 + Only links written in the source Markdown participate.
111 + - Results are fixed at build time. Rebuilding a host note when a queried note
112 + changes is future work; a full build always recomputes correctly.
113 +
114 + ## Exports
115 +
116 + - `queryPlugin(options?)` — plugin factory
117 + - `remarkQuery(options?)` — remark transform usable on its own (`options.language` selects the fence language)
118 + - `queryContentEntries(entries, spec)` — the Core matching engine (also
119 + available from `@riebeckite/core`)
120 + - Types: `QueryOptions`, `QuerySpec`, `QueryOutputFormat`
121 +
122 + ## See also
123 +
124 + - [Plugin guide](../reference/plugin-api.en.md)
125 +