Skip to content

Bases in Custom Views

Anup Chavan edited this page Jun 21, 2026 · 1 revision

Bases in Custom Views

Custom Views can collect native Obsidian Bases results and expose them to the template. This is useful when one note needs to render related notes: album notes listing songs, artist notes listing albums, project notes listing tasks, and so on.

Basic pattern

Place a {% base "Name" %} block before the HTML that needs the results.

{% base "Songs" %}
views:
  - type: table
    name: Songs
    filters:
      and:
        - list(album).contains(this)
    order:
      - track
      - file.name
      - artists
    sort:
      - property: track
        direction: ASC
{% endbase %}

{% for row in bases.Songs.rows %}
  <div>{{row.values.track}}. {{row.file.link}}</div>
{% endfor %}

The content inside the block is native Bases YAML. Custom Views strips the block from the final HTML and passes the YAML to Obsidian's Bases collector.

What the name means

In {% base "Songs" %}, Songs becomes the key used in the template:

Access path Meaning
bases.Songs Named access to the collected view.
baseViews.Songs Alias for named access.
bases[0] First collected Base view.
baseViews[0] First collected Base view through alias.
file.bases[0] Legacy file-scoped access.
file.baseViews[0] Legacy file-scoped alias.

Result shape

A normalized Base view has:

Field Meaning
key Stable key for access.
name Base view name from YAML.
type View type, usually table, cards, list, or map.
source Where the Base came from: template block, code block, or embedded .base file.
columns Visible/returned columns.
rows Query results.
rowCount Number of rows.
error Error text when collection fails.

Row shape

Each row includes:

Field Meaning
row.file File data for the matching note.
row.values Cell values from visible/returned Base columns.
row.text Text versions of cell values.
row.cells Lower-level cell metadata.

row.file includes file fields and frontmatter shortcuts:

row.file.name
row.file.basename
row.file.path
row.file.folder
row.file.ext
row.file.link
row.file.properties
row.file.<frontmatter-property>

row.values includes both full property IDs and display keys when available:

{{row.values["note.categories"]}}
{{row.values.categories}}
{{row.values.track}}

Why this works

In an embedded Base, Obsidian's this points at the current note. In the Albums tutorial, each song note has an album property that links back to the album note. The filter:

filters:
  and:
    - list(album).contains(this)

means: convert the song's album value into a list, then keep songs whose album list contains the current album note.

Supported source types

Custom Views can collect Bases from:

Source Example
Template block {% base "Songs" %}...{% endbase %}
Note-embedded fenced block A Markdown code block whose language is base.
Embedded .base file ![[Songs.base]]
Embedded .base file with view ![[Songs.base#Songs]]

Multiple Base blocks

You can define more than one Base in one template:

{% base "Songs" %}
views:
  - type: table
    name: Songs
    filters:
      and:
        - list(album).contains(this)
{% endbase %}

{% base "RelatedAlbums" %}
views:
  - type: table
    name: Related Albums
    filters:
      and:
        - list(artists).contains(this.artists.first())
{% endbase %}

Use distinct names. If two sources produce the same name, the safest approach is to rename the template block key.

Debugging Bases results

Start with this temporary markup:

<pre>rows: {{bases.Songs.rowCount}}</pre>
<pre>error: {{bases.Songs.error}}</pre>

If rowCount is 0, the Base query is valid but returns no files. If error is set, the YAML or Bases collector failed.

Common mistakes

  • Missing views: at the top level.
  • Invalid YAML indentation.
  • Using pipe filters inside Bases YAML. Bases uses its own expression syntax.
  • Forgetting that this means the current note, not the row currently being rendered.
  • Referencing a column through row.values when that property is not included in order or returned by the Bases view.

Wiki pages

Clone this wiki locally