Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Create and edit Obsidian .base files with table/card/list views, filters, formulas, and summaries.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: obsidian-bases3description: 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.4---56# Obsidian Bases Skill78## Workflow9101. **Create the file**: Create a `.base` file in the vault with valid YAML content112. **Define scope**: Add `filters` to select which notes appear (by tag, folder, property, or date)123. **Add formulas** (optional): Define computed properties in the `formulas` section134. **Configure views**: Add one or more views (`table`, `cards`, `list`, or `map`) with `order` specifying which properties to display145. **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.X` without defining `X` in `formulas`156. **Test in Obsidian**: Open the `.base` file in Obsidian to confirm the view renders correctly. If it shows a YAML error, check quoting rules below1617## Schema1819Base files use the `.base` extension and contain valid YAML.2021```yaml22# Global filters apply to ALL views in the base23filters:24# Can be a single filter string25# OR a recursive filter object with exactly ONE key: and, or, or not26and:27- 'status == "active"'28- not:29- 'file.hasTag("archived")'3031# Define formula properties that can be used across all views32formulas:33formula_name: 'expression'3435# Configure display names and settings for properties36properties:37property_name:38displayName: "Display Name"39formula.formula_name:40displayName: "Formula Display Name"41file.ext:42displayName: "Extension"4344# Define custom summary formulas45summaries:46custom_summary_name: 'values.mean().round(3)'4748# Define one or more views49views:50- type: table | cards | list | map51name: "View Name"52limit: 10 # Optional: limit results53groupBy: # Optional: group results54property: property_name55direction: ASC | DESC56filters: # View-specific filters follow the same rules57and:58- 'status == "active"'59order: # Properties to display in order60- file.name61- property_name62- formula.formula_name63summaries: # Map properties to summary formulas64property_name: Average65```6667## Filter Syntax6869Filters narrow down results. They can be applied globally or per-view.7071### Filter Structure7273```yaml74# Single filter75filters: 'status == "done"'7677# AND - all conditions must be true78filters:79and:80- 'status == "done"'81- 'priority > 3'8283# OR - any condition can be true84filters:85or:86- 'file.hasTag("book")'87- 'file.hasTag("article")'8889# NOT - exclude matching items90filters:91not:92- 'file.hasTag("archived")'9394# Nested filters95filters:96or:97- file.hasTag("tag")98- and:99- file.hasTag("book")100- file.hasLink("Textbook")101- not:102- file.hasTag("book")103- file.inFolder("Required Reading")104```105106### Filter Operators107108| Operator | Description |109|----------|-------------|110| `==` | equals |111| `!=` | not equal |112| `>` | greater than |113| `<` | less than |114| `>=` | greater than or equal |115| `<=` | less than or equal |116| `&&` | logical and |117| `\|\|` | logical or |118| <code>!</code> | logical not |119120## Properties121122### Three Types of Properties1231241. **Note properties** - From frontmatter: `note.author` or just `author`1252. **File properties** - File metadata: `file.name`, `file.mtime`, etc.1263. **Formula properties** - Computed values: `formula.my_formula`127128### File Properties Reference129130| Property | Type | Description |131|----------|------|-------------|132| `file.name` | String | File name |133| `file.basename` | String | File name without extension |134| `file.path` | String | Full path to file |135| `file.folder` | String | Parent folder path |136| `file.ext` | String | File extension |137| `file.size` | Number | File size in bytes |138| `file.ctime` | Date | Created time |139| `file.mtime` | Date | Modified time |140| `file.tags` | List | All tags in file |141| `file.links` | List | Internal links in file |142| `file.backlinks` | List | Files linking to this file |143| `file.embeds` | List | Embeds in the note |144| `file.properties` | Object | All frontmatter properties |145146### The `this` Keyword147148- In main content area: refers to the base file itself149- When embedded: refers to the embedding file150- In sidebar: refers to the active file in main content151152## Formula Syntax153154Formulas compute values from properties. Defined in the `formulas` section.155156```yaml157formulas:158# Simple arithmetic159total: "price * quantity"160161# Conditional logic162status_icon: 'if(done, "โ ", "โณ")'163164# String formatting165formatted_price: 'if(price, price.toFixed(2) + " dollars")'166167# Date formatting168created: 'file.ctime.format("YYYY-MM-DD")'169170# Calculate days since created (use .days for Duration)171days_old: '(now() - file.ctime).days'172173# Calculate days until due date174days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'175```176177## Key Functions178179Most commonly used functions. For the complete reference of all types (Date, String, Number, List, File, Link, Object, RegExp), see [FUNCTIONS_REFERENCE.md](references/FUNCTIONS_REFERENCE.md).180181| Function | Signature | Description |182|----------|-----------|-------------|183| `date()` | `date(string): date` | Parse string to date (`YYYY-MM-DD HH:mm:ss`) |184| `now()` | `now(): date` | Current date and time |185| `today()` | `today(): date` | Current date (time = 00:00:00) |186| `if()` | `if(condition, trueResult, falseResult?)` | Conditional |187| `duration()` | `duration(string): duration` | Parse duration string |188| `file()` | `file(path): file` | Get file object |189| `link()` | `link(path, display?): Link` | Create a link |190191### Duration Type192193When subtracting two dates, the result is a **Duration** type (not a number).194195**Duration Fields:** `duration.days`, `duration.hours`, `duration.minutes`, `duration.seconds`, `duration.milliseconds`196197**IMPORTANT:** Duration does NOT support `.round()`, `.floor()`, `.ceil()` directly. Access a numeric field first (like `.days`), then apply number functions.198199```yaml200# CORRECT: Calculate days between dates201"(date(due_date) - today()).days" # Returns number of days202"(now() - file.ctime).days" # Days since created203"(date(due_date) - today()).days.round(0)" # Rounded days204205# WRONG - will cause error:206# "((date(due) - today()) / 86400000).round(0)" # Duration doesn't support division then round207```208209### Date Arithmetic210211```yaml212# Duration units: y/year/years, M/month/months, d/day/days,213# w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds214"now() + \"1 day\"" # Tomorrow215"today() + \"7d\"" # A week from today216"now() - file.ctime" # Returns Duration217"(now() - file.ctime).days" # Get days as number218```219220## View Types221222### Table View223224```yaml225views:226- type: table227name: "My Table"228order:229- file.name230- status231- due_date232summaries:233price: Sum234count: Average235```236237### Cards View238239```yaml240views:241- type: cards242name: "Gallery"243order:244- file.name245- cover_image246- description247```248249### List View250251```yaml252views:253- type: list254name: "Simple List"255order:256- file.name257- status258```259260### Map View261262Requires latitude/longitude properties and the Maps community plugin.263264```yaml265views:266- type: map267name: "Locations"268# Map-specific settings for lat/lng properties269```270271## Default Summary Formulas272273| Name | Input Type | Description |274|------|------------|-------------|275| `Average` | Number | Mathematical mean |276| `Min` | Number | Smallest number |277| `Max` | Number | Largest number |278| `Sum` | Number | Sum of all numbers |279| `Range` | Number | Max - Min |280| `Median` | Number | Mathematical median |281| `Stddev` | Number | Standard deviation |282| `Earliest` | Date | Earliest date |283| `Latest` | Date | Latest date |284| `Range` | Date | Latest - Earliest |285| `Checked` | Boolean | Count of true values |286| `Unchecked` | Boolean | Count of false values |287| `Empty` | Any | Count of empty values |288| `Filled` | Any | Count of non-empty values |289| `Unique` | Any | Count of unique values |290291## Complete Examples292293### Task Tracker Base294295```yaml296filters:297and:298- file.hasTag("task")299- 'file.ext == "md"'300301formulas:302days_until_due: 'if(due, (date(due) - today()).days, "")'303is_overdue: 'if(due, date(due) < today() && status != "done", false)'304priority_label: 'if(priority == 1, "๐ด High", if(priority == 2, "๐ก Medium", "๐ข Low"))'305306properties:307status:308displayName: Status309formula.days_until_due:310displayName: "Days Until Due"311formula.priority_label:312displayName: Priority313314views:315- type: table316name: "Active Tasks"317filters:318and:319- 'status != "done"'320order:321- file.name322- status323- formula.priority_label324- due325- formula.days_until_due326groupBy:327property: status328direction: ASC329summaries:330formula.days_until_due: Average331332- type: table333name: "Completed"334filters:335and:336- 'status == "done"'337order:338- file.name339- completed_date340```341342### Reading List Base343344```yaml345filters:346or:347- file.hasTag("book")348- file.hasTag("article")349350formulas:351reading_time: 'if(pages, (pages * 2).toString() + " min", "")'352status_icon: 'if(status == "reading", "๐", if(status == "done", "โ ", "๐"))'353year_read: 'if(finished_date, date(finished_date).year, "")'354355properties:356author:357displayName: Author358formula.status_icon:359displayName: ""360formula.reading_time:361displayName: "Est. Time"362363views:364- type: cards365name: "Library"366order:367- cover368- file.name369- author370- formula.status_icon371filters:372not:373- 'status == "dropped"'374375- type: table376name: "Reading List"377filters:378and:379- 'status == "to-read"'380order:381- file.name382- author383- pages384- formula.reading_time385```386387### Daily Notes Index388389```yaml390filters:391and:392- file.inFolder("Daily Notes")393- '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'394395formulas:396word_estimate: '(file.size / 5).round(0)'397day_of_week: 'date(file.basename).format("dddd")'398399properties:400formula.day_of_week:401displayName: "Day"402formula.word_estimate:403displayName: "~Words"404405views:406- type: table407name: "Recent Notes"408limit: 30409order:410- file.name411- formula.day_of_week412- formula.word_estimate413- file.mtime414```415416## Embedding Bases417418Embed in Markdown files:419420```markdown421![[MyBase.base]]422423<!-- Specific view -->424![[MyBase.base#View Name]]425```426427## YAML Quoting Rules428429- Use single quotes for formulas containing double quotes: `'if(done, "Yes", "No")'`430- Use double quotes for simple strings: `"My View Name"`431- Escape nested quotes properly in complex expressions432433## Troubleshooting434435### YAML Syntax Errors436437**Unquoted special characters**: Strings containing `:`, `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` `` must be quoted.438439```yaml440# WRONG - colon in unquoted string441displayName: Status: Active442443# CORRECT444displayName: "Status: Active"445```446447**Mismatched quotes in formulas**: When a formula contains double quotes, wrap the entire formula in single quotes.448449```yaml450# WRONG - double quotes inside double quotes451formulas:452label: "if(done, "Yes", "No")"453454# CORRECT - single quotes wrapping double quotes455formulas:456label: 'if(done, "Yes", "No")'457```458459### Common Formula Errors460461**Duration math without field access**: Subtracting dates returns a Duration, not a number. Always access `.days`, `.hours`, etc.462463```yaml464# WRONG - Duration is not a number465"(now() - file.ctime).round(0)"466467# CORRECT - access .days first, then round468"(now() - file.ctime).days.round(0)"469```470471**Missing null checks**: Properties may not exist on all notes. Use `if()` to guard.472473```yaml474# WRONG - crashes if due_date is empty475"(date(due_date) - today()).days"476477# CORRECT - guard with if()478'if(due_date, (date(due_date) - today()).days, "")'479```480481**Referencing undefined formulas**: Ensure every `formula.X` in `order` or `properties` has a matching entry in `formulas`.482483```yaml484# This will fail silently if 'total' is not defined in formulas485order:486- formula.total487488# Fix: define it489formulas:490total: "price * quantity"491```492493## References494495- [Bases Syntax](https://help.obsidian.md/bases/syntax)496- [Functions](https://help.obsidian.md/bases/functions)497- [Views](https://help.obsidian.md/bases/views)498- [Formulas](https://help.obsidian.md/formulas)499- [Complete Functions Reference](references/FUNCTIONS_REFERENCE.md)500