obsidian-bases ยท diff

git:20260702.cfc9a75 to git:20260906.9af3950

8 added, 493 removed. Audit A to A.

---
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.
+ description: "Create or edit Obsidian .base files, including database views, filters, formulas, cards, and summaries."
---
- # Obsidian Bases Skill
-
- ## Workflow
-
- 1. **Create the file**: Create a `.base` file in the vault with valid YAML content
- 2. **Define scope**: Add `filters` to select which notes appear (by tag, folder, property, or date)
- 3. **Add formulas** (optional): Define computed properties in the `formulas` section
- 4. **Configure views**: Add one or more views (`table`, `cards`, `list`, or `map`) with `order` specifying which properties to display
- 5. **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`
- 6. **Test in Obsidian**: Open the `.base` file 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 |
- | <code>!</code> | logical not |
-
- ## Properties
-
- ### Three Types of Properties
-
- 1. **Note properties** - From frontmatter: `note.author` or just `author`
- 2. **File properties** - File metadata: `file.name`, `file.mtime`, etc.
- 3. **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.
-
- ```yaml
- formulas:
- # 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](references/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
-
- ```yaml
- views:
- - type: table
- name: "My Table"
- order:
- - file.name
- - status
- - due_date
- summaries:
- price: Sum
- count: Average
- ```
-
- ### Cards View
-
- ```yaml
- views:
- - type: cards
- name: "Gallery"
- order:
- - file.name
- - cover_image
- - description
- ```
-
- ### List View
-
- ```yaml
- views:
- - type: list
- name: "Simple List"
- order:
- - file.name
- - status
- ```
-
- ### Map View
-
- Requires latitude/longitude properties and the Maps community plugin.
-
- ```yaml
- views:
- - 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
-
- ```yaml
- 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: 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
-
- ```yaml
- 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: 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
-
- ```yaml
- 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:
-
- ```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"
- ```
+ # Obsidian Bases
- ## References
+ Use for .base artifacts in Obsidian. Read the [preserved syntax guidance](UPSTREAM.md)
+ for the requested view or formula. Consult the
+ [function reference](references/FUNCTIONS_REFERENCE.md) only when a needed
+ function is not covered there. Preserve unrelated vault content.
- - [Bases Syntax](https://help.obsidian.md/bases/syntax)
- - [Functions](https://help.obsidian.md/bases/functions)
- - [Views](https://help.obsidian.md/bases/views)
- - [Formulas](https://help.obsidian.md/formulas)
- - [Complete Functions Reference](references/FUNCTIONS_REFERENCE.md)
+ [Preservation provenance](references/provenance.json). Resolve original relative
+ paths from this skill directory; the preserved file stays here to retain its links.