MD Butler
approvedby Peter Petschownik
Automatically manages YAML frontmatter fields for all notes. A reliable alternative to Templater formulas for consistent metadata. - This plugin has not been manually reviewed by Obsidian staff.
MD Butler
MD Butler is an Obsidian plugin that automatically manages YAML frontmatter fields for all your notes. Event-driven, configurable, and a reliable alternative to Templater formulas for consistent metadata.
Features
- Event-driven metadata: Automatically update metadata on file open, modify, rename, or bulk operations
- Configurable fields: 8 built-in fields (FileName, FilePath, DateCreated, NoteType, LastModified, LastMoved, Source, Tags) plus unlimited custom fields
- Template system: Powerful
{{template}}expressions with pipe-chain functions ({{title | upper | replace:a,b}})- Date formatting:
{{date:YYYY-MM-DD}},{{now+7d}} - Frontmatter access:
{{frontmatter:key}} - File properties:
{{title}},{{fileName}},{{fileFolder}}(alias{{folder}}),{{filePath}},{{oldPath}},{{oldName}},{{oldFolder}} - Pipe functions:
upper,lower,trim,replace:X,Y,default:VAL,substr:S,E,date:FMT
- Date formatting:
- Conditional fields: Apply fields only when conditions are met (frontmatter, path, filename, or folder rules). Auto-removes the YAML key when the condition no longer matches
- Event binding: Per-field event checkboxes (open, modify, rename, bulk)
- Folder filtering: Include or exclude entire folder trees
- Processing scope: "New notes only" (skip files with DateCreated) or "All files"
- Force apply: Overwrite all metadata across the vault
- Full repair: Force-apply → cleanup orphaned keys → consistency check — all in one command
- Do-Not-Touch list: Protect specific YAML keys from being deleted or overwritten
- YAML key migration: Automatically migrate old YAML keys to new ones when you rename a field
- Orphaned key cleanup: Remove leftover YAML keys from deleted fields
- Consistency check: Scans your vault and reports files with missing fields
- Field requirement modes:
required(default) orif-exists—if-existsonly flags a field when the YAML key exists but is empty (useful for fields like LastMoved that are only set under certain circumstances) - Drag-and-drop UI: Reorder fields easily in settings
Installation
From Obsidian Community Plugins
- Open Obsidian → Settings → Community Plugins
- Browse and search for MD Butler
- Install and enable it — future updates arrive automatically
Manual installation
- Download the latest release from GitHub
- Copy
main.js,manifest.json, andstyles.csstoVaultFolder/.obsidian/plugins/md-butler/ - Reload Obsidian and enable the plugin
Commands
| Command | ID | Description |
|---|---|---|
| Apply Metadata to all Notes | md-butler:apply-all | Update metadata for all notes respecting scope & filters |
| Force-apply metadata to all notes | md-butler:force-apply | Overwrite all metadata fields (ignores scope) |
| Full repair | md-butler:full-repair | Force-apply → cleanup → consistency check |
| Vault Consistency Check | md-butler:check-consistency | Scan vault for missing fields |
| Clean up old YAML keys | md-butler:cleanup-keys | Remove orphaned YAML keys from deleted fields |
Settings
| Setting | Description |
|---|---|
| Date Format | Moment.js format string for all date values |
| Processing Mode | "New notes only" or "All files" |
| Metadata Fields | Drag-and-drop list of enabled fields with templates, events, and conditions |
| Excluded Folders | Folders to skip (when in exclude mode) |
| Included Folders | Folders to process (when in include mode) |
| Protected YAML Keys | Keys the plugin must never delete or overwrite |
Field Types
Built-in fields
| Field ID | YAML Key | Default Events | Description |
|---|---|---|---|
| fileName | FileName | open, rename, bulk | Current file name without extension |
| filePath | FilePath | open, rename, bulk | Full vault path to the file |
| dateCreated | DateCreated | open, rename, bulk | Date the file was first created |
| noteType | NoteType | open, rename, bulk | Select field: Project, Note (default), Task, Person, Meeting, Reference |
| lastModified | LastModified | modify, rename, bulk | Date the file was last modified |
| lastMoved | LastMoved | rename | Date the file was last renamed/moved (requirement: if-exists) |
| source | Source | open, rename, bulk | Custom field (disabled by default) |
| tags | Tags | modify, bulk | Custom field (disabled by default) |
Select fields
Fields can be type: "text" (default) or type: "select". Select fields have:
- Configurable
options[]— the allowed values (one per line in settings) defaultValue— set once for new notes if no template is active- Template dropdown — pick one option to always overwrite with that value
- Smart default: when template is "(none)", the writer sets
defaultValue ?? options[0]for new notes
Built-in NoteType is a select field. Create your own (Status, Priority, Area, etc.).
Custom fields
Create unlimited custom fields with:
- Custom YAML key name
- Type selection (text or select)
- Template expression or default value
- Event binding (open/modify/rename/bulk)
- Conditions for selective application
- Drag-and-drop reordering
Requirement modes
Each field has a requirement mode that controls how the Vault Consistency Check flags it:
| Mode | Behavior |
|---|---|
required (default) | Field must exist — reported as missing if the YAML key is absent |
if-exists | Field is only flagged if the YAML key exists but is empty (null, "", or {}) |
Use if-exists for fields that are only set under certain circumstances and should not be flagged when simply absent — e.g. LastMoved (only set when a file has been moved) or optional metadata that is added later.
Template Reference
{{date:YYYY-MM-DD}} → 2026-06-17
{{now+7d}} → 2026-06-24 (relative date)
{{now-1w}} → 2026-06-10 (relative date, supports d/w/M/y)
{{title}} → File name without extension
{{fileName}} → File name with extension
{{fileFolder}} → Parent folder path (alias: {{folder}})
{{filePath}} → Full vault path
{{oldPath}} → Previous path (rename events only)
{{oldFolder}} → Previous folder (rename events only)
{{oldName}} → Previous file name (rename events only)
{{frontmatter:key}} → Value of any frontmatter key
{{title | upper}} → UPPERCASE
{{title | lower}} → lowercase
{{title | trim}} → trimmed
{{title | replace:a,b}} → Replace all 'a' with 'b'
{{title | default:Untitled}} → Fallback if empty
{{title | substr:0,5}} → First 5 characters
{{date:YYYY | upper}} → Chained: format then uppercase
Conditions Reference
| Type | Operators | Description |
|---|---|---|
| always | — | Always apply (default) |
| frontmatter | exists, equals, matches, contains | Check a frontmatter key value |
| path | equals, matches, contains | Check file path |
| filename | equals, matches, contains | Check file name |
| folder | equals, matches, contains | Check parent folder |
Fields with conditions are auto-removed from frontmatter when their condition no longer matches — the YAML key is deleted on the next event that triggers a write.
Development
# Clone the repo
git clone https://github.com/PPeapps/MD-Butler
cd md-butler
# Install dependencies
npm install
# Development (watch mode)
npm run dev
# Production build
npm run build
# Lint
npm run lint
Requirements
- Obsidian v1.8.0 or later
- No external dependencies (uses Obsidian API only)
License
MIT
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.