Obsidian Bases
This skill enables Claude Code to create and edit valid Obsidian Bases (.base files) including views, filters, formulas, and all related configurations.
Overview
Obsidian Bases are YAML-based files that define dynamic views of notes in an Obsidian vault. A Base file can contain multiple views, global filters, formulas, property configurations, and custom summaries.
When to Use This Skill
-
Creating database-like views of notes in Obsidian
-
Building task trackers, reading lists, or project dashboards
-
Filtering and organizing notes by properties or tags
-
Creating calculated/formula fields
-
Setting up table, card, list, or map views
-
Working with .base files in an Obsidian vault
File Format
Base files use the .base extension and contain valid YAML. They can also be embedded in Markdown code blocks.
Complete Schema
Global filters apply to ALL views in the base
filters:
Can be a single filter string
OR a recursive filter object with and/or/not
and: [] or: [] not: []
Define formula properties that can be used across all views
formulas: formula_name: 'expression'
Configure display names and settings for properties
properties: property_name: displayName: "Display Name" formula.formula_name: displayName: "Formula Display Name" file.ext: displayName: "Extension"
Define custom summary formulas
summaries: custom_summary_name: 'values.mean().round(3)'
Define one or more views
views:
- type: table | cards | list | map
name: "View Name"
limit: 10 # Optional: limit results
groupBy: # Optional: group results
property: property_name
direction: ASC | DESC
filters: # View-specific filters
and: []
order: # Properties to display in order
- file.name
- property_name
- formula.formula_name summaries: # Map properties to summary formulas property_name: Average
Filter Syntax
Filters narrow down results. They can be applied globally or per-view.
Filter Structure
Single filter
filters: 'status == "done"'
AND - all conditions must be true
filters: and: - 'status == "done"' - 'priority > 3'
OR - any condition can be true
filters: or: - file.hasTag("book") - file.hasTag("article")
NOT - exclude matching items
filters: not: - file.hasTag("archived")
Nested filters
filters: or: - file.hasTag("tag") - and: - file.hasTag("book") - file.hasLink("Textbook") - not: - file.hasTag("book") - file.inFolder("Required Reading")
Filter Operators
Operator Description
==
equals
!=
not equal
greater than
<
less than
=
greater than or equal
<=
less than or equal
&&
logical and
||
logical or
!
logical not
Properties
Three Types of Properties
-
Note properties - From frontmatter: note.author or just author
-
File properties - File metadata: file.name , file.mtime , etc.
-
Formula properties - Computed values: formula.my_formula
File Properties Reference
Property Type Description
file.name
String File name
file.basename
String File name without extension
file.path
String Full path to file
file.folder
String Parent folder path
file.ext
String File extension
file.size
Number File size in bytes
file.ctime
Date Created time
file.mtime
Date Modified time
file.tags
List All tags in file
file.links
List Internal links in file
file.backlinks
List Files linking to this file
file.embeds
List Embeds in the note
file.properties
Object All frontmatter properties
The this Keyword
-
In main content area: refers to the base file itself
-
When embedded: refers to the embedding file
-
In sidebar: refers to the active file in main content
Formula Syntax
Formulas compute values from properties. Defined in the formulas section.
formulas:
Simple arithmetic
total: "price * quantity"
Conditional logic
status_icon: 'if(done, "check", "pending")'
String formatting
formatted_price: 'if(price, price.toFixed(2) + " dollars")'
Date formatting
created: 'file.ctime.format("YYYY-MM-DD")'
Complex expressions
days_old: '((now() - file.ctime) / 86400000).round(0)'
Functions Reference
Global Functions
Function Signature Description
date()
date(string): date
Parse string to date
duration()
duration(string): duration
Parse duration string
now()
now(): date
Current date and time
today()
today(): date
Current date (time = 00:00:00)
if()
if(condition, trueResult, falseResult?)
Conditional
min()
min(n1, n2, ...): number
Smallest number
max()
max(n1, n2, ...): number
Largest number
number()
number(any): number
Convert to number
link()
link(path, display?): Link
Create a link
list()
list(element): List
Wrap in list if not already
file()
file(path): file
Get file object
image()
image(path): image
Create image for rendering
icon()
icon(name): icon
Lucide icon by name
html()
html(string): html
Render as HTML
escapeHTML()
escapeHTML(string): string
Escape HTML characters
Date Functions & Fields
Fields: date.year , date.month , date.day , date.hour , date.minute , date.second , date.millisecond
Function Signature Description
date()
date.date(): date
Remove time portion
format()
date.format(string): string
Format with Moment.js pattern
time()
date.time(): string
Get time as string
relative()
date.relative(): string
Human-readable relative time
isEmpty()
date.isEmpty(): boolean
Always false for dates
Date Arithmetic
Duration units: y/year/years, M/month/months, d/day/days,
w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds
Add/subtract durations
"date + "1M"" # Add 1 month "date - "2h"" # Subtract 2 hours "now() + "1 day"" # Tomorrow "today() + "7d"" # A week from today
Subtract dates for millisecond difference
"now() - file.ctime"
Complex duration arithmetic
"now() + (duration('1d') * 2)"
String Functions
Field: string.length
Function Description
contains(value)
Check substring
containsAll(...values)
All substrings present
containsAny(...values)
Any substring present
startsWith(query)
Starts with query
endsWith(query)
Ends with query
isEmpty()
Empty or not present
lower()
To lowercase
title()
To Title Case
trim()
Remove whitespace
replace(pattern, replacement)
Replace pattern
repeat(count)
Repeat string
reverse()
Reverse string
slice(start, end?)
Substring
split(separator, n?)
Split to list
Number Functions
Function Description
abs()
Absolute value
ceil()
Round up
floor()
Round down
round(digits?)
Round to digits
toFixed(precision)
Fixed-point notation
isEmpty()
Not present
List Functions
Field: list.length
Function Description
contains(value)
Element exists
containsAll(...values)
All elements exist
containsAny(...values)
Any element exists
filter(expression)
Filter by condition (uses value , index )
map(expression)
Transform elements (uses value , index )
reduce(expression, initial)
Reduce to single value (uses value , index , acc )
flat()
Flatten nested lists
join(separator)
Join to string
reverse()
Reverse order
slice(start, end?)
Sublist
sort()
Sort ascending
unique()
Remove duplicates
isEmpty()
No elements
File Functions
Function Description
asLink(display?)
Convert to link
hasLink(otherFile)
Has link to file
hasTag(...tags)
Has any of the tags
hasProperty(name)
Has property
inFolder(folder)
In folder or subfolder
View Types
Table View
views:
- type: table
name: "My Table"
order:
- file.name
- status
- due_date summaries: price: Sum count: Average
Cards View
views:
- type: cards
name: "Gallery"
order:
- file.name
- cover_image
- description
List View
views:
- type: list
name: "Simple List"
order:
- file.name
- status
Map View
Requires latitude/longitude properties and the Maps plugin.
views:
- type: map name: "Locations"
Default Summary Formulas
Name Input Type Description
Average
Number Mathematical mean
Min
Number Smallest number
Max
Number Largest number
Sum
Number Sum of all numbers
Range
Number Max - Min
Median
Number Mathematical median
Stddev
Number Standard deviation
Earliest
Date Earliest date
Latest
Date Latest date
Checked
Boolean Count of true values
Unchecked
Boolean Count of false values
Empty
Any Count of empty values
Filled
Any Count of non-empty values
Unique
Any Count of unique values
Complete Examples
Task Tracker Base
filters: and: - file.hasTag("task") - 'file.ext == "md"'
formulas: days_until_due: 'if(due, ((date(due) - today()) / 86400000).round(0), "")' is_overdue: 'if(due, date(due) < today() && status != "done", false)' priority_label: 'if(priority == 1, "High", if(priority == 2, "Medium", "Low"))'
properties: status: displayName: Status formula.days_until_due: displayName: "Days Until Due" formula.priority_label: displayName: Priority
views:
-
type: table name: "Active Tasks" filters: and: - 'status != "done"' order:
- file.name
- status
- formula.priority_label
- due
- formula.days_until_due groupBy: property: status direction: ASC summaries: formula.days_until_due: Average
-
type: table name: "Completed" filters: and: - 'status == "done"' order:
- file.name
- completed_date
Reading List Base
filters: or: - file.hasTag("book") - file.hasTag("article")
formulas: reading_time: 'if(pages, (pages * 2).toString() + " min", "")' status_icon: 'if(status == "reading", "reading", if(status == "done", "done", "to-read"))' year_read: 'if(finished_date, date(finished_date).year, "")'
properties: author: displayName: Author formula.status_icon: displayName: "" formula.reading_time: displayName: "Est. Time"
views:
-
type: cards name: "Library" order:
- cover
- file.name
- author
- formula.status_icon
filters:
not:
- 'status == "dropped"'
-
type: table name: "Reading List" filters: and: - 'status == "to-read"' order:
- file.name
- author
- pages
- formula.reading_time
Project Notes Base
filters: and: - file.inFolder("Projects") - 'file.ext == "md"'
formulas: last_updated: 'file.mtime.relative()' link_count: 'file.links.length'
summaries: avgLinks: 'values.filter(value.isType("number")).mean().round(1)'
properties: formula.last_updated: displayName: "Updated" formula.link_count: displayName: "Links"
views:
-
type: table name: "All Projects" order:
- file.name
- status
- formula.last_updated
- formula.link_count summaries: formula.link_count: avgLinks groupBy: property: status direction: ASC
-
type: list name: "Quick List" order:
- file.name
- status
Daily Notes Index
filters: and: - file.inFolder("Daily Notes") - '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'
formulas: word_estimate: '(file.size / 5).round(0)' day_of_week: 'date(file.basename).format("dddd")'
properties: formula.day_of_week: displayName: "Day" formula.word_estimate: displayName: "~Words"
views:
- type: table
name: "Recent Notes"
limit: 30
order:
- file.name
- formula.day_of_week
- formula.word_estimate
- file.mtime
Embedding Bases
Embed in Markdown files:
![[MyBase.base]]
<!-- Specific view --> ![[MyBase.base#View Name]]
YAML Quoting Rules
-
Use single quotes for formulas containing double quotes: 'if(done, "Yes", "No")'
-
Use double quotes for simple strings: "My View Name"
-
Escape nested quotes properly in complex expressions
Common Patterns
Filter by Tag
filters: and: - file.hasTag("project")
Filter by Folder
filters: and: - file.inFolder("Notes")
Filter by Date Range
filters: and: - 'file.mtime > now() - "7d"'
Filter by Property Value
filters: and: - 'status == "active"' - 'priority >= 3'
Combine Multiple Conditions
filters: or: - and: - file.hasTag("important") - 'status != "done"' - and: - 'priority == 1' - 'due != ""'
References
-
Bases Syntax
-
Functions
-
Views
-
Formulas