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 and/or/not26and: []27or: []28not: []2930# Define formula properties that can be used across all views31formulas:32formula_name: 'expression'3334# Configure display names and settings for properties35properties:36property_name:37displayName: "Display Name"38formula.formula_name:39displayName: "Formula Display Name"40file.ext:41displayName: "Extension"4243# Define custom summary formulas44summaries:45custom_summary_name: 'values.mean().round(3)'4647# Define one or more views48views:49- type: table | cards | list | map50name: "View Name"51limit: 10 # Optional: limit results52groupBy: # Optional: group results53property: property_name54direction: ASC | DESC55filters: # View-specific filters56and: []57order: # Properties to display in order58- file.name59- property_name60- formula.formula_name61summaries: # Map properties to summary formulas62property_name: Average63```6465## Filter Syntax6667Filters narrow down results. They can be applied globally or per-view.6869### Filter Structure7071```yaml72# Single filter73filters: 'status == "done"'7475# AND - all conditions must be true76filters:77and:78- 'status == "done"'79- 'priority > 3'8081# OR - any condition can be true82filters:83or:84- 'file.hasTag("book")'85- 'file.hasTag("article")'8687# NOT - exclude matching items88filters:89not:90- 'file.hasTag("archived")'9192# Nested filters93filters:94or:95- file.hasTag("tag")96- and:97- file.hasTag("book")98- file.hasLink("Textbook")99- not:100- file.hasTag("book")101- file.inFolder("Required Reading")102```103104### Filter Operators105106| Operator | Description |107|----------|-------------|108| `==` | equals |109| `!=` | not equal |110| `>` | greater than |111| `<` | less than |112| `>=` | greater than or equal |113| `<=` | less than or equal |114| `&&` | logical and |115| `\|\|` | logical or |116| <code>!</code> | logical not |117118## Properties119120### Three Types of Properties1211221. **Note properties** - From frontmatter: `note.author` or just `author`1232. **File properties** - File metadata: `file.name`, `file.mtime`, etc.1243. **Formula properties** - Computed values: `formula.my_formula`125126### File Properties Reference127128| Property | Type | Description |129|----------|------|-------------|130| `file.name` | String | File name |131| `file.basename` | String | File name without extension |132| `file.path` | String | Full path to file |133| `file.folder` | String | Parent folder path |134| `file.ext` | String | File extension |135| `file.size` | Number | File size in bytes |136| `file.ctime` | Date | Created time |137| `file.mtime` | Date | Modified time |138| `file.tags` | List | All tags in file |139| `file.links` | List | Internal links in file |140| `file.backlinks` | List | Files linking to this file |141| `file.embeds` | List | Embeds in the note |142| `file.properties` | Object | All frontmatter properties |143144### The `this` Keyword145146- In main content area: refers to the base file itself147- When embedded: refers to the embedding file148- In sidebar: refers to the active file in main content149150## Formula Syntax151152Formulas compute values from properties. Defined in the `formulas` section.153154```yaml155formulas:156# Simple arithmetic157total: "price * quantity"158159# Conditional logic160status_icon: 'if(done, "โ ", "โณ")'161162# String formatting163formatted_price: 'if(price, price.toFixed(2) + " dollars")'164165# Date formatting166created: 'file.ctime.format("YYYY-MM-DD")'167168# Calculate days since created (use .days for Duration)169days_old: '(now() - file.ctime).days'170171# Calculate days until due date172days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'173```174175## Key Functions176177Most 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).178179| Function | Signature | Description |180|----------|-----------|-------------|181| `date()` | `date(string): date` | Parse string to date (`YYYY-MM-DD HH:mm:ss`) |182| `now()` | `now(): date` | Current date and time |183| `today()` | `today(): date` | Current date (time = 00:00:00) |184| `if()` | `if(condition, trueResult, falseResult?)` | Conditional |185| `duration()` | `duration(string): duration` | Parse duration string |186| `file()` | `file(path): file` | Get file object |187| `link()` | `link(path, display?): Link` | Create a link |188189### Duration Type190191When subtracting two dates, the result is a **Duration** type (not a number).192193**Duration Fields:** `duration.days`, `duration.hours`, `duration.minutes`, `duration.seconds`, `duration.milliseconds`194195**IMPORTANT:** Duration does NOT support `.round()`, `.floor()`, `.ceil()` directly. Access a numeric field first (like `.days`), then apply number functions.196197```yaml198# CORRECT: Calculate days between dates199"(date(due_date) - today()).days" # Returns number of days200"(now() - file.ctime).days" # Days since created201"(date(due_date) - today()).days.round(0)" # Rounded days202203# WRONG - will cause error:204# "((date(due) - today()) / 86400000).round(0)" # Duration doesn't support division then round205```206207### Date Arithmetic208209```yaml210# Duration units: y/year/years, M/month/months, d/day/days,211# w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds212"now() + \"1 day\"" # Tomorrow213"today() + \"7d\"" # A week from today214"now() - file.ctime" # Returns Duration215"(now() - file.ctime).days" # Get days as number216```217218## View Types219220### Table View221222```yaml223views:224- type: table225name: "My Table"226order:227- file.name228- status229- due_date230summaries:231price: Sum232count: Average233```234235### Cards View236237```yaml238views:239- type: cards240name: "Gallery"241order:242- file.name243- cover_image244- description245```246247### List View248249```yaml250views:251- type: list252name: "Simple List"253order:254- file.name255- status256```257258### Map View259260Requires latitude/longitude properties and the Maps community plugin.261262```yaml263views:264- type: map265name: "Locations"266# Map-specific settings for lat/lng properties267```268269## Default Summary Formulas270271| Name | Input Type | Description |272|------|------------|-------------|273| `Average` | Number | Mathematical mean |274| `Min` | Number | Smallest number |275| `Max` | Number | Largest number |276| `Sum` | Number | Sum of all numbers |277| `Range` | Number | Max - Min |278| `Median` | Number | Mathematical median |279| `Stddev` | Number | Standard deviation |280| `Earliest` | Date | Earliest date |281| `Latest` | Date | Latest date |282| `Range` | Date | Latest - Earliest |283| `Checked` | Boolean | Count of true values |284| `Unchecked` | Boolean | Count of false values |285| `Empty` | Any | Count of empty values |286| `Filled` | Any | Count of non-empty values |287| `Unique` | Any | Count of unique values |288289## Complete Examples290291### Task Tracker Base292293```yaml294filters:295and:296- file.hasTag("task")297- 'file.ext == "md"'298299formulas:300days_until_due: 'if(due, (date(due) - today()).days, "")'301is_overdue: 'if(due, date(due) < today() && status != "done", false)'302priority_label: 'if(priority == 1, "๐ด High", if(priority == 2, "๐ก Medium", "๐ข Low"))'303304properties:305status:306displayName: Status307formula.days_until_due:308displayName: "Days Until Due"309formula.priority_label:310displayName: Priority311312views:313- type: table314name: "Active Tasks"315filters:316and:317- 'status != "done"'318order:319- file.name320- status321- formula.priority_label322- due323- formula.days_until_due324groupBy:325property: status326direction: ASC327summaries:328formula.days_until_due: Average329330- type: table331name: "Completed"332filters:333and:334- 'status == "done"'335order:336- file.name337- completed_date338```339340### Reading List Base341342```yaml343filters:344or:345- file.hasTag("book")346- file.hasTag("article")347348formulas:349reading_time: 'if(pages, (pages * 2).toString() + " min", "")'350status_icon: 'if(status == "reading", "๐", if(status == "done", "โ ", "๐"))'351year_read: 'if(finished_date, date(finished_date).year, "")'352353properties:354author:355displayName: Author356formula.status_icon:357displayName: ""358formula.reading_time:359displayName: "Est. Time"360361views:362- type: cards363name: "Library"364order:365- cover366- file.name367- author368- formula.status_icon369filters:370not:371- 'status == "dropped"'372373- type: table374name: "Reading List"375filters:376and:377- 'status == "to-read"'378order:379- file.name380- author381- pages382- formula.reading_time383```384385### Daily Notes Index386387```yaml388filters:389and:390- file.inFolder("Daily Notes")391- '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'392393formulas:394word_estimate: '(file.size / 5).round(0)'395day_of_week: 'date(file.basename).format("dddd")'396397properties:398formula.day_of_week:399displayName: "Day"400formula.word_estimate:401displayName: "~Words"402403views:404- type: table405name: "Recent Notes"406limit: 30407order:408- file.name409- formula.day_of_week410- formula.word_estimate411- file.mtime412```413414## Embedding Bases415416Embed in Markdown files:417418```markdown419![[MyBase.base]]420421<!-- Specific view -->422![[MyBase.base#View Name]]423```424425## YAML Quoting Rules426427- Use single quotes for formulas containing double quotes: `'if(done, "Yes", "No")'`428- Use double quotes for simple strings: `"My View Name"`429- Escape nested quotes properly in complex expressions430431## Troubleshooting432433### YAML Syntax Errors434435**Unquoted special characters**: Strings containing `:`, `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` `` must be quoted.436437```yaml438# WRONG - colon in unquoted string439displayName: Status: Active440441# CORRECT442displayName: "Status: Active"443```444445**Mismatched quotes in formulas**: When a formula contains double quotes, wrap the entire formula in single quotes.446447```yaml448# WRONG - double quotes inside double quotes449formulas:450label: "if(done, "Yes", "No")"451452# CORRECT - single quotes wrapping double quotes453formulas:454label: 'if(done, "Yes", "No")'455```456457### Common Formula Errors458459**Duration math without field access**: Subtracting dates returns a Duration, not a number. Always access `.days`, `.hours`, etc.460461```yaml462# WRONG - Duration is not a number463"(now() - file.ctime).round(0)"464465# CORRECT - access .days first, then round466"(now() - file.ctime).days.round(0)"467```468469**Missing null checks**: Properties may not exist on all notes. Use `if()` to guard.470471```yaml472# WRONG - crashes if due_date is empty473"(date(due_date) - today()).days"474475# CORRECT - guard with if()476'if(due_date, (date(due_date) - today()).days, "")'477```478479**Referencing undefined formulas**: Ensure every `formula.X` in `order` or `properties` has a matching entry in `formulas`.480481```yaml482# This will fail silently if 'total' is not defined in formulas483order:484- formula.total485486# Fix: define it487formulas:488total: "price * quantity"489```490491## References492493- [Bases Syntax](https://help.obsidian.md/bases/syntax)494- [Functions](https://help.obsidian.md/bases/functions)495- [Views](https://help.obsidian.md/bases/views)496- [Formulas](https://help.obsidian.md/formulas)497- [Complete Functions Reference](references/FUNCTIONS_REFERENCE.md)498