| name | obsidian-frontmatter |
| description | Lightweight plugin for managing Obsidian frontmatter properties using
functional shell operations. This skill should be used when working with
YAML frontmatter in Obsidian markdown files - adding, updating, removing,
or validating properties. Works with any Obsidian vault following standard
YAML conventions. Supports full YAML including nested structures, arrays,
and wikilinks. Uses composable shell functions for single-file or bulk
operations without external dependencies.
|
Obsidian Frontmatter Manager
A lightweight, dependency-free skill for managing YAML frontmatter in Obsidian markdown files. Built with functional programming principles using pure shell tools (awk, no Python/JS dependencies).
Overview
This skill provides a composable toolset for frontmatter operations in Obsidian vaults. It understands generic Obsidian YAML conventions and works across any vault configuration.
Key features:
- โ
No external dependencies (pure shell: bash, awk)
- โ
Composable functional design (single operations compose into bulk)
- โ
Full YAML support (scalars, arrays, nested objects)
- โ
Wikilink handling (automatic quoting)
- โ
Unicode support (Korean, emoji, international characters)
- โ
Parallel bulk operations (4 concurrent processes)
- โ
Vault-agnostic (works with any Obsidian vault)
Core Operations
The skill follows a functional programming approach with a single core function that composes for bulk operations:
fm-op <operation> <file> <property> [value] [options]
fm-bulk <operation> <property> [value] <file-pattern> [options]
Available Operations
- get - Extract property value
- set - Add or update property
- delete - Remove property
- validate - Check required properties exist
Usage Examples
Basic Operations
Get property value:
fm-op get "note.md" "tags"
fm-op get "note.md" "title"
Set simple property:
fm-op set "note.md" "title" "My Note"
fm-op set "note.md" "status" "published"
fm-op set "note.md" "rating" "4.5"
Set wikilink (automatically quoted):
fm-op set "note.md" "author" "[[John Doe]]" --quote
fm-op set "note.md" "parent" "[[Parent Page]]" --quote
Set array property:
fm-op set "note.md" "tags" "obsidian" --array
fm-op set "note.md" "tags" "tutorial" --array --append
fm-op set "note.md" "tags" "example" --array --append
Delete property:
fm-op delete "note.md" "old_field"
fm-op delete "note.md" "draft"
Validate required properties:
fm-op validate "note.md" title
fm-op validate "note.md" title tags author
List all properties:
fm-list "note.md"
Bulk Operations
Set property across multiple files:
fm-bulk set publish true "content/**/*.md"
fm-bulk set tags obsidian "**/*.md" --array --append
fm-bulk set status published "drafts/*.md"
Delete property from multiple files:
fm-bulk delete draft "content/**/*.md"
fm-bulk delete old_field "**/*.md"
Validate properties across files:
fm-bulk validate title "**/*.md" tags
fm-bulk validate title "content/**/*.md" author publish
Advanced Examples
Add author to literature notes:
fm-bulk set author "[[๊ณ ๋ฒ์]]" "30. Zettels/01. Literature Notes/*.md" --quote
Tag all meeting notes:
fm-bulk set tags meeting "10. Time/03. Meeting/**/*.md" --array --append
Publish digital garden articles:
fm-bulk set publish true "40. Digital Garden/Articles/*.md"
Validate project structure:
fm-bulk validate status "10. Time/02. Project/**/*.md" project_type
Obsidian YAML Conventions
This skill follows standard Obsidian YAML conventions:
Frontmatter Structure
- Enclosed by
--- delimiters on separate lines
- Must start at first line of document
- Blank line after closing
---
Important Conventions
Wikilinks must be quoted:
author: "[[Name]]"
author: [[Name]]
Standard indentation:
tags:
- tag1
- tag2
Common properties:
tags - Categorization (array or scalar)
aliases - Alternative names (array)
type - Note type
status - Progress status
author - Author (often wikilink)
date_created, date_modified - Timestamps
publish - Publishing flag
cssclass - Styling class
Full YAML Support
Scalars:
title: Simple Value
status: draft
published: true
rating: 4.5
Arrays (single-line):
tags: [obsidian, tutorial, example]
Arrays (multi-line):
tags:
- obsidian
- tutorial
- example
Nested objects:
metadata:
created: 2025-01-27
author: "[[Name]]"
Unicode support:
title: "ํ๊ธ ์ ๋ชฉ"
author: "[[๊ณ ๋ฒ์]]"
tags: [๐, ๐ฏ, โ
]
For complete conventions, see references/obsidian-yaml-conventions.md.
Advanced Operations
Complex YAML Structures
The skill handles complex YAML patterns:
Multi-line arrays:
fm-op set "note.md" "aliases" "Alt Name" --array --append
Nested properties:
fm-op get "note.md" "metadata"
Special characters:
fm-op set "note.md" "title" "Chapter 3: The Beginning" --quote
Formatting Preservation
The skill preserves existing formatting:
- Maintains 2-space indentation
- Keeps array format (single-line vs multi-line)
- Preserves property order
- Retains blank lines and structure
Error Handling
Graceful error handling:
- Creates frontmatter if missing
- Reports malformed YAML
- Validates operations before execution
- Clear error messages
Safe operations:
fm-op validate "note.md" title || echo "Missing title, skipping"
fm-op set "note.md" "status" "published"
Bulk Operations
Patterns for Mass Updates
Using find with fm-op:
find . -name "*.md" -type f -mtime -7 -exec \
fm-op set {} updated "$(date +%Y-%m-%d)" \;
find . -name "*.md" -type f | while read file; do
if fm-op validate "$file" title 2>/dev/null; then
fm-op set "$file" validated true
fi
done
Using fm-bulk wrapper:
fm-bulk set tags obsidian "**/*.md" --array --append
fm-bulk delete old_property "**/*.md"
fm-bulk validate title "**/*.md" tags
Performance
Bulk operations use parallel execution:
- 4 concurrent processes by default
- Efficient for large vaults (1000+ files)
- Progress visible during execution
Example timing:
- 100 files: ~2 seconds
- 1000 files: ~15 seconds
- 5000 files: ~60 seconds
Integration with Claude Code
Automatic Triggering
Claude Code automatically uses this skill when:
- Working with Obsidian markdown files
- Adding, updating, or removing frontmatter properties
- Validating note metadata
- Bulk updating vault properties
Complementary Tools
Works alongside:
- Obsidian Linter - For style enforcement
- Dataview - For property queries
- Templater - For template-based property insertion
- Custom plugins - Any plugin using standard YAML
Safe Operations
The skill ensures:
- No data loss during updates
- Preserves existing formatting
- Clear error messages
- Validation before bulk operations
Implementation Details
Technical Architecture
Core technology:
- AWK for YAML parsing (simple structures)
- Perl for complex updates (nested structures)
- Bash for orchestration and composition
Design principles:
- Single function for individual operations
- Composable for bulk operations
- No external dependencies
- Functional programming approach
Edge Cases Handled
- โ
Files without frontmatter (creates new)
- โ
Malformed YAML (reports error)
- โ
Missing properties (creates or returns empty)
- โ
Special characters (Korean, emoji, colons)
- โ
Wikilinks (automatic quoting)
- โ
Multi-line values (preserves format)
- โ
Nested structures (maintains hierarchy)
Parsing Patterns
For implementation details and parsing techniques, see:
Examples by Use Case
Literature Notes
fm-op set "lit-note.md" type "Literature Notes" --quote
fm-op set "lit-note.md" author "[[Paper Author]]" --quote
fm-op set "lit-note.md" source_url "https://example.com/paper.pdf"
fm-op set "lit-note.md" tags reading --array
Project Management
fm-op set "project.md" type project --quote
fm-op set "project.md" status todo --quote
fm-op set "project.md" project_type project --quote
fm-bulk set status inprogress "10. Time/02. Project/**/*.md"
Digital Garden
fm-bulk set publish true "40. Digital Garden/Articles/*.md"
fm-bulk set cssclass article "40. Digital Garden/Articles/*.md"
fm-bulk validate title "40. Digital Garden/Articles/*.md" tags author
Bible Study Notes
fm-bulk set tags sermon "60. Saint/01. Sermon/**/*.md" --array --append
fm-bulk set author "[[Pastor Name]]" "60. Saint/01. Sermon/**/*.md" --quote
Troubleshooting
Common Issues
Wikilink parsing errors:
fm-op set "note.md" "author" "[[Name]]" --quote
Array format:
fm-op set "note.md" "tags" "first" --array
fm-op set "note.md" "tags" "second" --array --append
Validation failures:
fm-op validate "note.md" title tags author || echo "Validation failed"
fm-list "note.md"
Debugging
Check property value:
fm-op get "note.md" "property_name"
List all properties:
fm-list "note.md"
Test on single file first:
fm-op set "test.md" "property" "value"
fm-list "test.md"
fm-bulk set "property" "value" "**/*.md"
Development and Extension
Custom Scripts
Build on core functions:
#!/bin/bash
for file in *.md; do
if ! fm-op get "$file" date_created >/dev/null 2>&1; then
fm-op set "$file" date_created "$(date +%Y-%m-%d)"
fi
done
Integration Examples
With git hooks:
find . -name "*.md" | while read file; do
fm-op validate "$file" title tags || exit 1
done
With automation:
find . -name "*.md" -mtime -1 | while read file; do
fm-op set "$file" date_modified "$(date +%Y-%m-%d)"
done
References
License
MIT License - Free to use and modify
Support
For issues or questions:
- Check references/ directory for detailed documentation
- Review examples in this file
- Test operations on single files before bulk updates
- Validate YAML syntax after updates