Native Bases pages

What this demonstrates

@quartz-community/bases-page renders Obsidian Bases.base files — as database-like views over the vault’s own notes. It is the most ambitious plugin in this sandbox: it ships a small expression language (lexer, Pratt parser, bytecode compiler and stack interpreter) so that .base formulas evaluate at build time.

The base in this vault queries this very site: every Markdown page, grouped by area, with computed columns.

Open it: Sandbox notes base

Configuration used

  - source: "@quartz-community/bases-page"
    enabled: true
    options:
      defaultViewType: table
      linkResolution: shortest
    order: 50

linkResolution must match crawl-linksmarkdownLinkResolution (both shortest here), otherwise links rendered inside view cells resolve differently from links in prose.

Layout override for this page type:

layout:
  byPageType:
    bases:
      exclude:
        - table-of-contents
        - reader-mode

A base view has no prose headings, and reader mode’s narrow column fights a wide table.

Content used

filters:
  and:
    - file.ext == "md"
formulas:
  area: |
    if(file.inFolder("experiments"), "experiment",
    if(file.inFolder("config"), "configuration",
    if(file.inFolder("plugins"), "plugins", "entry")))
  updated: file.mtime.relative()
  tag_count: file.tags.length()
properties:
  title:
    displayName: Page
  formula.area:
    displayName: Area
views:
  - type: table
    name: Every sandbox page
    groupBy:
      property: formula.area
      direction: ASC
    sort:
      - property: formula.area
        direction: ASC
  - type: table
    name: Experiments only
    filters:
      and:
        - file.inFolder("experiments")
  - type: list
    name: Recently updated
    limit: 10
  - type: cards
    name: Cards
    limit: 24

Four views over one dataset: a grouped table, a filtered table, a capped list and a cards view. The reader switches between them with tabs; all four are materialised in the HTML.

What the rendered output proves

The base route emits a rendered table DOM — header cells carrying the displayNames from properties, one row per matching note, and computed cells for formula.area, formula.updated and formula.tag_count — plus a view switcher with the four view names. Because the views are server-side rendered at build time, the rows are in the static HTML: no client-side query runs.

It also proves the filter and the visibility interaction: experiments/unlisted-demo.md is a Markdown file in experiments/, so file.ext == "md" matches it, yet it is absent from every view because bases-page honours the unlisted convention and skips unlisted pages in both the entry loop and the internal lookup used by .asFile().

safe_for_shared_engine

false — not because it is fragile, but because it is the largest new surface here: a whole expression engine plus four view renderers evaluated for every matching note, and its views are baked at build time (they never re-hydrate client-side, unlike graph, explorer and search). Adopting it across 51 wikis would change build cost and introduce a second link resolution setting that must be kept in sync with crawl-links. Sandbox-only until someone measures it there.