An Obsidian plugin that automatically applies templates to new notes based on their folder location. Create consistent note structures with dynamic variables like dates, times, and unique IDs.
- Automatic Templates: Assign templates to folders. New files get those templates automatically.
- Template Inheritance: Nested folders inherit templates from parent folders
- Dynamic Variables: Insert current date, time, note title, and unique IDs
- Smart Merging: Safely merges templates with existing content without data loss
- Manual Commands: Apply templates on-demand to existing notes
- Bulk Operations: Apply templates to all notes in a folder at once
- Create a templates folder (default: "Templates")
- Create template files in that folder (e.g.,
project-template.md,meeting-template.md) - Configure folder mappings in Settings → Snowflake
- Create new notes in mapped folders to see templates applied automatically
- Open Settings → Snowflake
- Click "Add folder mapping"
- Select a folder and its corresponding template
- Notes created in that folder will now use the template
Templates inherit from parent folders automatically:
Projects/ → uses: project-template.md
└── Web/ → uses: web-template.md
└── Frontend/ → inherits both templates with smart merging
Access via Command Palette (Ctrl/Cmd + P):
- Apply template to current note: Applies the appropriate template based on the note's location
- Apply specific template: Choose any template to apply to the current note
- Apply templates to folder: Bulk apply templates to all notes in a selected folder
- Create new note in folder: Creates a new note in the selected folder and applies all mapped templates
You can assign keyboard shortcuts to any Snowflake command:
- Go to Settings → Hotkeys
- Search for "Snowflake"
- Click the + icon next to any command
- Press your desired key combination
Tip: Replace Obsidian's default "New note" behavior:
Assign Cmd/Ctrl + N to "Snowflake: Create new note in folder." This gives you folder selection and automatic template application. The original Obsidian behavior can still be accessed via the Command Palette.
Snowflake supports the following dynamic variables that are replaced when templates are applied:
{{title}}- The filename without the .md extension- Example: "Meeting Notes.md" → "Meeting Notes"
{{date}}- Current date (format customizable in settings)- Default format: YYYY-MM-DD (e.g., "2024-01-15")
{{time}}- Current time (format customizable in settings)- Default format: HH:mm (e.g., "14:30")
{{snowflake_id}}- A unique 10-character alphanumeric ID- Format: Mix of letters and numbers (e.g., "x8K2n5pQ7A")
- Uses cryptographically secure random generation
- Multiple instances in the same template receive the same ID
Example template with variables:
---
id: {{snowflake_id}}
created: {{date}} {{time}}
modified: {{date}} {{time}}
---
# {{title}}
Created on {{date}} at {{time}}In settings, customize formats using moment.js syntax:
- Date:
DD/MM/YYYY,MMM DD, YYYY, etc. - Time:
h:mm A,HH:mm:ss, etc.
Templates can exclude properties from parent templates using the delete property. This is useful when you want to remove inherited properties that don't apply to specific note types.
Add a delete property to your template's frontmatter with an array of property names to exclude:
---
delete: [author, project]
category: personal
tags: [diary]
---- Properties listed in
deleteare removed from the inherited template - Child templates can re-add excluded properties by defining them explicitly
- The
deleteproperty itself is never included in the final note
Consider this template hierarchy:
base-template.md (parent):
---
author: Team
project: Default Project
status: draft
tags: [base]
---personal-template.md (child):
---
delete: [author, project]
category: personal
tags: [personal]
---journal-template.md (grandchild):
---
author: Me # Re-adds the author property
mood: neutral
tags: [journal]
---When a note uses the journal template:
projectis excluded (removed by personal-template)authoris included with value "Me" (re-added by journal-template)statusis included (never excluded)- All tags are concatenated:
[base, personal, journal]
Each folder mapping can have exclusion patterns to prevent templates from being applied to specific files or directories.
Exact filename:
README.md- excludes files named exactly "README.md"
Wildcard patterns:
*.tmp- excludes all files ending with .tmpdraft-*- excludes files starting with "draft-"test?.md- excludes files like "test1.md", "testA.md"
Directory patterns:
Archive/- excludes all files under the Archive directoryOld/Backups/- excludes all files under the nested Old/Backups directory
Recursive patterns:
**/README.md- excludes README.md files in any subdirectory**/draft-*- excludes draft files at any depth
To exclude an entire subdirectory and some specific files:
Archive/
*.tmp
draft-notes.md
This will ignore:
- Everything under
Projects/Archive/ - Any
.tmpfiles - Files named exactly
draft-notes.md
Built with TypeScript:
src/
├── main.ts # Plugin entry point
├── template-applicator.ts # Core template logic
├── template-loader.ts # Template file management
├── template-variables.ts # Variable replacement
├── frontmatter-merger.ts # YAML merging logic
├── commands.ts # Command registration
└── ui/ # Settings and modals
# Clone and install
git clone https://github.com/ali01/obsidian-snowflake.git
cd obsidian-snowflake
npm install
# Development (with watch)
npm run dev
# Production build
npm run build
# Run tests
npm test
# Quality checks
npm run check- Requires Obsidian v0.12.0 or higher
- Works with all themes and other plugins
- No external dependencies
- Issues: GitHub Issues
- Discussions: GitHub Discussions
MIT License - see LICENSE file
Ali Yahya