#
Bases syntax
Work in progress
Bases are still in beta and the syntax is continuing to evolve with feedback we receive during the early access phase. Expect the syntax to change.
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:
- At the global
filters
level (shown above) where they apply to all views in the base. - 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 examplenote.price
ornote["price"]
. If a property does not have a prefix it is assumed to be anote
property. - Properties about the file (implicit properties) are called
file
properties. For example,file.size
orfile.ext
. You may also usefile
to reference the file itself, for examplefile.hasLink()
. - Formulas are prefixed with
formula
, for exampleformula.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:
- Note properties, stored in frontmatter of Markdown files.
- File properties, accessible for all file types.
- 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.
#
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)
.
#
Date arithmetic
Dates can be modified by adding and subtracting durations. Duration units accept multiple formats:
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"
returnstrue
if the file was modified within the last week.date("2024-12-01") + "1M" + "4h" + "3m"
returns a Date object representing2025-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 exampledatetime.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.
#
Boolean operators
Boolean operators can be used to combine or invert logical values, resulting in a true or false value.
#
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
orfalse
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 exampledate("2025-01-01 12:00:00")
- To modify a date, add or remove a duration, for example
now() + "1 hour"
ortoday() + "7d"
- Compare dates using comparison operators (e.g.
>
or<
) and arithmetic operators (for example,(now() + "1d") - now()
returns86400000
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
orproperty["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 examplelink("filename")
orlink("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")
orlink("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)
.