Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: obsidian-bases description: Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.
Obsidian Bases Skill
Workflow
- Create the file: Create a
.basefile in the vault with valid YAML content - Define scope: Add
filtersto select which notes appear (by tag, folder, property, or date) - Add formulas (optional): Define computed properties in the
formulassection - Configure views: Add one or more views (
table,cards,list, ormap) withorderspecifying which properties to display - Validate: Verify the file is valid YAML with no syntax errors. Check that all referenced properties and formulas exist. Common issues: unquoted strings containing special YAML characters, mismatched quotes in formula expressions, referencing
formula.Xwithout definingXinformulas - Test in Obsidian: Open the
.basefile in Obsidian to confirm the view renders correctly. If it shows a YAML error, check quoting rules below
Schema
Base files use the .base extension and contain valid YAML.
# Global filters apply to ALL views in the basefilters:# Can be a single filter string# OR a recursive filter object with and/or/notand: []or: []not: []# Define formula properties that can be used across all viewsformulas:formula_name: 'expression'# Configure display names and settings for propertiesproperties:property_name:displayName: "Display Name"formula.formula_name:displayName: "Formula Display Name"file.ext:displayName: "Extension"# Define custom summary formulassummaries:custom_summary_name: 'values.mean().round(3)'# Define one or more viewsviews:- type: table | cards | list | mapname: "View Name"limit: 10 # Optional: limit resultsgroupBy: # Optional: group resultsproperty: property_namedirection: ASC | DESCfilters: # View-specific filtersand: []order: # Properties to display in order- file.name- property_name- formula.formula_namesummaries: # Map properties to summary formulasproperty_name: Average
Filter Syntax
Filters narrow down results. They can be applied globally or per-view.
Filter Structure
# Single filterfilters: 'status == "done"'# AND - all conditions must be truefilters:and:- 'status == "done"'- 'priority > 3'# OR - any condition can be truefilters:or:- 'file.hasTag("book")'- 'file.hasTag("article")'# NOT - exclude matching itemsfilters:not:- 'file.hasTag("archived")'# Nested filtersfilters: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 | |
| <code>!</code> | logical not |
Properties
Three Types of Properties
- Note properties - From frontmatter:
note.authoror justauthor - 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 arithmetictotal: "price * quantity"# Conditional logicstatus_icon: 'if(done, "✅", "⏳")'# String formattingformatted_price: 'if(price, price.toFixed(2) + " dollars")'# Date formattingcreated: 'file.ctime.format("YYYY-MM-DD")'# Calculate days since created (use .days for Duration)days_old: '(now() - file.ctime).days'# Calculate days until due datedays_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
Key Functions
Most commonly used functions. For the complete reference of all types (Date, String, Number, List, File, Link, Object, RegExp), see FUNCTIONS_REFERENCE.md.
| Function | Signature | Description | |
|---|---|---|---|
date() | date(string): date | Parse string to date (YYYY-MM-DD HH:mm:ss) | |
now() | now(): date | Current date and time | |
today() | today(): date | Current date (time = 00:00:00) | |
if() | if(condition, trueResult, falseResult?) | Conditional | |
duration() | duration(string): duration | Parse duration string | |
file() | file(path): file | Get file object | |
link() | link(path, display?): Link | Create a link |
Duration Type
When subtracting two dates, the result is a Duration type (not a number).
Duration Fields: duration.days, duration.hours, duration.minutes, duration.seconds, duration.milliseconds
IMPORTANT: Duration does NOT support .round(), .floor(), .ceil() directly. Access a numeric field first (like .days), then apply number functions.
# CORRECT: Calculate days between dates"(date(due_date) - today()).days" # Returns number of days"(now() - file.ctime).days" # Days since created"(date(due_date) - today()).days.round(0)" # Rounded days# WRONG - will cause error:# "((date(due) - today()) / 86400000).round(0)" # Duration doesn't support division then round
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"now() + \"1 day\"" # Tomorrow"today() + \"7d\"" # A week from today"now() - file.ctime" # Returns Duration"(now() - file.ctime).days" # Get days as number
View Types
Table View
views:- type: tablename: "My Table"order:- file.name- status- due_datesummaries:price: Sumcount: Average
Cards View
views:- type: cardsname: "Gallery"order:- file.name- cover_image- description
List View
views:- type: listname: "Simple List"order:- file.name- status
Map View
Requires latitude/longitude properties and the Maps community plugin.
views:- type: mapname: "Locations"# Map-specific settings for lat/lng properties
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 | |
Range | Date | Latest - Earliest | |
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()).days, "")'is_overdue: 'if(due, date(due) < today() && status != "done", false)'priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))'properties:status:displayName: Statusformula.days_until_due:displayName: "Days Until Due"formula.priority_label:displayName: Priorityviews:- type: tablename: "Active Tasks"filters:and:- 'status != "done"'order:- file.name- status- formula.priority_label- due- formula.days_until_duegroupBy:property: statusdirection: ASCsummaries:formula.days_until_due: Average- type: tablename: "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", "📖", if(status == "done", "✅", "📚"))'year_read: 'if(finished_date, date(finished_date).year, "")'properties:author:displayName: Authorformula.status_icon:displayName: ""formula.reading_time:displayName: "Est. Time"views:- type: cardsname: "Library"order:- cover- file.name- author- formula.status_iconfilters:not:- 'status == "dropped"'- type: tablename: "Reading List"filters:and:- 'status == "to-read"'order:- file.name- author- pages- formula.reading_time
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: tablename: "Recent Notes"limit: 30order:- 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
Troubleshooting
YAML Syntax Errors
Unquoted special characters: Strings containing :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, ` `` must be quoted.
# WRONG - colon in unquoted stringdisplayName: Status: Active# CORRECTdisplayName: "Status: Active"
Mismatched quotes in formulas: When a formula contains double quotes, wrap the entire formula in single quotes.
# WRONG - double quotes inside double quotesformulas:label: "if(done, "Yes", "No")"# CORRECT - single quotes wrapping double quotesformulas:label: 'if(done, "Yes", "No")'
Common Formula Errors
Duration math without field access: Subtracting dates returns a Duration, not a number. Always access .days, .hours, etc.
# WRONG - Duration is not a number"(now() - file.ctime).round(0)"# CORRECT - access .days first, then round"(now() - file.ctime).days.round(0)"
Missing null checks: Properties may not exist on all notes. Use if() to guard.
# WRONG - crashes if due_date is empty"(date(due_date) - today()).days"# CORRECT - guard with if()'if(due_date, (date(due_date) - today()).days, "")'
Referencing undefined formulas: Ensure every formula.X in order or properties has a matching entry in formulas.
# This will fail silently if 'total' is not defined in formulasorder:- formula.total# Fix: define itformulas:total: "price * quantity"