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.
yaml# Global filters apply to ALL views in the base filters: # Can be a single filter string # OR a recursive filter object with exactly ONE key: and, or, or not and: - 'status == "active"' - not: - 'file.hasTag("archived")' # 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 follow the same rules and: - 'status == "active"' 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
yaml# 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.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.
yamlformulas: # Simple arithmetic total: "price * quantity" # Conditional logic status_icon: 'if(done, "✅", "⏳")' # String formatting formatted_price: 'if(price, price.toFixed(2) + " dollars")' # Date formatting created: 'file.ctime.format("YYYY-MM-DD")' # Calculate days since created (use .days for Duration) days_old: '(now() - file.ctime).days' # Calculate days until due date days_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.
yaml# 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
yaml# 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
yamlviews: - type: table name: "My Table" order: - file.name - status - due_date summaries: price: Sum count: Average
Cards View
yamlviews: - type: cards name: "Gallery" order: - file.name - cover_image - description
List View
yamlviews: - type: list name: "Simple List" order: - file.name - status
Map View
Requires latitude/longitude properties and the Maps community plugin.
yamlviews: - type: map name: "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
yamlfilters: 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: 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
yamlfilters: 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: 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
Daily Notes Index
yamlfilters: 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:
markdown![[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.
yaml# WRONG - colon in unquoted string displayName: Status: Active # CORRECT displayName: "Status: Active"
Mismatched quotes in formulas: When a formula contains double quotes, wrap the entire formula in single quotes.
yaml# WRONG - double quotes inside double quotes formulas: label: "if(done, "Yes", "No")" # CORRECT - single quotes wrapping double quotes formulas: 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.
yaml# 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.
yaml# 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.
yaml# This will fail silently if 'total' is not defined in formulas order: - formula.total # Fix: define it formulas: total: "price * quantity"

