# Bases syntax

When you create a base in Obsidian, it is saved as a .base file. Bases are typically edited using the app interface, but the syntax can also be edited manually, and embedded in a code block.

The Bases syntax defines views, filters, and formulas. Bases must be valid YAML conforming to the schema defined below.

# Example

Here's an example of a base file. We'll walk through each section in detail.

filters:
  or:
    - file.hasTag("tag")
    - and:
        - file.hasTag("book")
        - file.hasLink("Textbook")
    - not:
        - file.hasTag("book")
        - file.inFolder("Required Reading")
formulas:
  formatted_price: 'if(price, price.toFixed(2) + " dollars")'
  ppu: "(price / age).toFixed(2)"
properties:
  status:
    displayName: Status
  formula.formatted_price:
    displayName: "Price"
  file.ext:
    displayName: Extension
views:
  - type: table
    name: "My table"
    limit: 10
    filters:
      and:
        - 'status != "done"'
        - or:
            - "formula.ppu > 5"
            - "price > 2.1"
    group_by: "status"
    order:
      - file.name
      - file.ext
      - note.age
      - formula.ppu
      - formula.formatted_price
  - type: map
    name: "Example map"
    filters: "has_coords == true"
    lat: lat
    long: long
    title: file.name

# Filters

By default a base includes every file in the vault. There is no from or source like in SQL or Dataview. The filters section lets you define conditions to narrow down the dataset.

filters:
  or:
    - file.hasTag("tag")
    - and:
        - file.hasTag("book")
        - file.hasLink("Textbook")
    - not:
        - file.hasTag("book")
        - file.inFolder("Required Reading")

There are two opportunities to apply filters:

  1. At the global filters level (shown above) where they apply to all views in the base.
  2. At the view level where apply only to a specific view.

These two sections are functionally equivalent and when evaluating for a view they will be concatenated with an AND.

The filters section contains either a single filter statement as a string, or a recursively defined filter object. Filter objects may contain one of and, or, or not. These keys are a heterogeneous list of other filter objects or filter statements in strings. A filter statement is a line which evaluates to truthy or falsey when applied to a note. It can be one of the following:

  • A basic comparison using standard arithmetic operators.
  • A function. A variety of functions are built-in, and plugins can add additional functions.

The syntax and available functions for filters and formulas are the same.

# Formulas

The formulas section defines formula properties that can be displayed across all views in the base file.

formulas:
  formatted_price: 'if(price, price.toFixed(2) + " dollars")'
  ppu: "(price / age).toFixed(2)"

Formula properties support basic arithmetic operators and a variety of built-in functions. In the future, plugins will be able to add functions for use in formulas.

Properties in formulas can be referenced in multiple ways, depending on the type of property:

  • Properties in the frontmatter are called note properties. For example note.price or note["price"]. If a property does not have a prefix it is assumed to be a note property.
  • Properties about the file (implicit properties) are called file properties. For example, file.size or file.ext. You may also use file to reference the file itself, for example file.hasLink().
  • Formulas are prefixed with formula, for example formula.formatted_price.

Formula properties can use values from other formula properties, as long as there is no circular reference. They are always defined as strings in the YAML, however the data type of the data and the function returns will be used to determine the output data type.

Note the use of nested quotes necessary to include text literals in the YAML field. Text literals must be enclosed in single or double quotes.

# Properties

The properties section allows storing configuration information about each property. It is up to the individual view how to use these configuration values. For example, in tables the display name is used for the column headers.

properties:
  status:
    displayName: Status
  formula.formatted_price:
    displayName: "Price"
  file.ext:
    displayName: Extension

Display names are not used in filters or formulas.

# Views

The views section defines how the data can be rendered. Each entry in the views list defines a separate view of the same data, and there can be as many different views as needed.

views:
  - type: table
    name: "My table"
    limit: 10
    filters:
      and:
        - 'status != "done"'
        - or:
            - "formula.ppu > 5"
            - "price > 2.1"
    order:
      - file.name
      - file.ext
      - note.age
      - formula.ppu
      - formula.formatted_price
  - type: map
    name: "Example map"
    filters: "has_coords == true"
    lat: lat
    long: long
    title: file.name
  • type selects from the built-in and plugin-added view types.
  • name is the display name, and can be used to define the default view.
  • filters are exactly the same as described above, but apply only to the view.

Views can add additional data to store any information needed to maintain state or properly render, however plugin authors should take care to not use keys already in use by the core Bases plugin. As an example, a table view may use this to limit the number of rows or to select which column is used to sort rows and in which direction. A different view type such as a map could use this for mapping which property in the note corresponds to the latitude and longitude and which property should be displayed as the pin title.

In the future, API will allow views to read and write these values, allowing the view to build its own interface for configuration.

# Properties

There are three kinds of properties used in bases:

  1. Note properties, stored in frontmatter of Markdown files.
  2. File properties, accessible for all file types.
  3. Formula properties, defined in the .base file itself (see above).

# Note properties

Note properties are only available for Markdown files, and are stored in the YAML frontmatter of each note. These properties can be accessed using the format note.author or simply author as a shorthand.

# File properties

File properties refer to the file currently being tested or evaluated. File properties are available for all file types, including attachments.

For example, a filter file.ext == "md" will be true for all Markdown files and false otherwise.

Property Type Description
file.ctime Date Created time
file.embeds List List of all embeds in the note
file.ext String File extension
file.file File File object, only usable in specific functions
file.folder String Path of the file folder
file.mtime Date Modified time
file.name String File name
file.path String Path of the file
file.size Number File size
file.links List List of all internal links in the note, including frontmatter

# Access properties of the current file

Embedded bases can use this to access properties of the current file. For example, this.file.name will resolve to the name of the file which has embedded the base, instead of the file being evaluated.

In a sidebar, this takes on the special meaning of "the currently active file". This allows you to create contextual queries based on the active file in the main content area. For example, this can be used to replicate the backlinks pane with this filter: file.hasLink(this.file).

# Operators

# Arithmetic operators

Arithmetic operators perform arithmetic on numbers. For example, radius * (2 * 3.14).

Operator Description
+ plus
- minus
* multiply
/ divide
% modulo
( ) parenthesis

# Date arithmetic

Dates can be modified by adding and subtracting durations. Duration units accept multiple formats:

Unit Duration
y, year, years year
M, month, months month
d, day, days day
w, week, weeks week
h, hour, hours hour
m, minute, minutes minute
s, second, seconds second

To modify or offset Date objects, use the + or - operator with a duration string. For example, date + "1M" adds 1 month to the date, while date - "2h" subtracts 2 hours from the date.

The global function today() can be used to get the current date, and now() can be used to get the current date with time.

  • now() + "1 day" returns a datetime exactly 24 hours from the time of execution.
  • file.mtime > now() - "1 week" returns true if the file was modified within the last week.
  • date("2024-12-01") + "1M" + "4h" + "3m" returns a Date object representing 2025-01-01 04:03:00.
  • Subtract two dates to get the millisecond difference between the two, for example, now() - file.ctime.
  • To get the date portion of a Date with time, use datetime.date().
  • To format a Date object, use the format() function, for example datetime.format("YYYY-MM-DD").

# Comparison operators

Comparison operators can be used to compare numbers, or Date objects. Equal and not equal can be used with any kind of value, not just numbers and dates.

Operator Description
== equals
!= not equal
> greater than
< less than
>= greater than or equal to
<= less than or equal to

# Boolean operators

Boolean operators can be used to combine or invert logical values, resulting in a true or false value.

Operator Description
! logical not
&& logical and
|| logical or

# Functions

See the list of functions that can be used in formulas and filters.

# Types

Bases have a type system which is used by formulas and filters to apply functions to properties.

# Strings, numbers, and booleans

Strings, numbers, and booleans are "primitive" values which do not require a function to create.

  • Strings are enclosed in single or double quotes, for example "message".
  • Numbers are written as digits, and may optionally be enclosed in parenthesis for clarity. For example, 1 or (2.5).
  • Booleans are written as true or false without quotes.

# Dates and durations

Dates represent a specific date, or a date and time depending on the function used to create them, or that type that has been assigned to the property.

  • To construct a date, use the date function, for example date("2025-01-01 12:00:00")
  • To modify a date, add or remove a duration, for example now() + "1 hour" or today() + "7d"
  • Compare dates using comparison operators (e.g. > or <) and arithmetic operators (for example, (now() + "1d") - now() returns 86400000 milliseconds.)
  • To extract portions of a date, use the available fields (now().hour), or a convenience function (now.time()).
  • Many other fields and functions are available on date objects.

# Objects and lists

  • Turn a single element into a list using the list() function. This is especially helpful for properties which may contain a mixture of lists or single values.
  • Access list elements using square brackets, and a 0-based index. For example, property[0] returns the first element from the list.
  • Access object elements using square brackets and the element name or dot notation. For example, property.subprop or property["subprop"].

# Files and links

Wikilinks in frontmatter properties are automatically recognized as Link objects. Links will render as a clickable link in the view.

  • To construct a link, use the global link function, for example link("filename") or link("https://obsidian.md").
  • You can create a link from any string, for example, link(file.ctime.date().toString()).
  • To set the display text, pass in an optional string or icon as a second parameter, for example link("filename", "display") or link("filename", "plus".icon()).

A File object can be turned into a link using file.asLink() with an optional display text.

Links can be compared with == and !=. They are equivalent as long as they point to the same file, or if the file does not exist when looked up, their link text must be identical.

Links can be compared to files such as file or this. They will equate if the link resolves to the file. For example, author == this.

Links can also be checked in list contains, for example, authors.contains(this).