templater
Templater Plugin Skill
This skill enables Claude Code to create valid Templater templates for dynamic content in Obsidian.
Overview
Templater extends Obsidian's template system with:
- Dynamic date/time insertion
- File manipulation and creation
- User prompts and selections
- System clipboard access
- Web requests
- Custom user scripts
Template Syntax
Basic Syntax
<% expression %> Output result
<%* statement %> Execute without output (for logic)
Examples
<% tp.date.now() %> Outputs: 2024-02-15
<%* await tp.file.rename("New Name") %> Renames file (no output)
Date Module (tp.date)
tp.date.now
Get current date with optional formatting and offset.
<% tp.date.now() %>
<% tp.date.now("YYYY-MM-DD") %>
<% tp.date.now("dddd, MMMM Do YYYY") %>
<% tp.date.now("YYYY-MM-DD", 7) %>
<% tp.date.now("YYYY-MM-DD", -7) %>
<% tp.date.now("YYYY-MM-DD", "P1M") %>
<% tp.date.now("YYYY-MM-DD", "P-1M") %>
<% tp.date.now("YYYY-MM-DD", 1, tp.file.title, "YYYY-MM-DD") %>
Parameters:
format- Date format string (default: "YYYY-MM-DD")offset- Days as number or ISO 8601 duration stringreference- Reference date stringreference_format- Format of reference date
tp.date.tomorrow
<% tp.date.tomorrow() %>
<% tp.date.tomorrow("YYYY-MM-DD") %>
tp.date.yesterday
<% tp.date.yesterday() %>
<% tp.date.yesterday("YYYY-MM-DD") %>
tp.date.weekday
Get a specific weekday relative to current/reference date.
<% tp.date.weekday("YYYY-MM-DD", 0) %>
<% tp.date.weekday("YYYY-MM-DD", 7) %>
<% tp.date.weekday("YYYY-MM-DD", -7) %>
<% tp.date.weekday("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD") %>
Parameters:
format- Date format stringweekday- 0 = Monday of current week, 7 = next Monday, -7 = last Mondayreference- Reference date stringreference_format- Format of reference date
Date Format Tokens (Moment.js)
| Token | Output | Description |
|---|---|---|
YYYY |
2024 | 4-digit year |
YY |
24 | 2-digit year |
MM |
01-12 | Month (padded) |
M |
1-12 | Month |
MMMM |
January | Full month name |
MMM |
Jan | Short month |
DD |
01-31 | Day (padded) |
D |
1-31 | Day |
Do |
1st-31st | Day with ordinal |
dddd |
Monday | Full weekday |
ddd |
Mon | Short weekday |
dd |
Mo | Min weekday |
HH |
00-23 | Hour 24h (padded) |
H |
0-23 | Hour 24h |
hh |
01-12 | Hour 12h (padded) |
h |
1-12 | Hour 12h |
mm |
00-59 | Minutes (padded) |
ss |
00-59 | Seconds (padded) |
a |
am/pm | AM/PM lowercase |
A |
AM/PM | AM/PM uppercase |
W |
1-53 | ISO week number |
Q |
1-4 | Quarter |
Moment.js Direct Usage
<% moment(tp.file.title, "YYYY-MM-DD").format("MMMM Do, YYYY") %>
<% moment(tp.file.title, "YYYY-MM-DD").startOf("month").format("YYYY-MM-DD") %>
<% moment(tp.file.title, "YYYY-MM-DD").endOf("month").format("YYYY-MM-DD") %>
<% moment(tp.file.title, "YYYY-MM-DD").add(1, "week").format("YYYY-MM-DD") %>
<% moment(tp.file.title, "YYYY-MM-DD").subtract(1, "month").format("YYYY-MM-DD") %>
File Module (tp.file)
Properties
<% tp.file.title %> File name without extension
<% tp.file.path(true) %> Relative path from vault root
<% tp.file.path(false) %> Absolute system path
<% tp.file.folder(true) %> Folder path from vault root
<% tp.file.folder(false) %> Folder name only
<% tp.file.tags %> Array of tags in file
<% tp.file.content %> Full file content as string
tp.file.creation_date
<% tp.file.creation_date() %>
<% tp.file.creation_date("YYYY-MM-DD HH:mm") %>
<% tp.file.creation_date("dddd, MMMM Do YYYY") %>
tp.file.last_modified_date
<% tp.file.last_modified_date() %>
<% tp.file.last_modified_date("YYYY-MM-DD HH:mm") %>
tp.file.cursor
Place cursor after template insertion.
<% tp.file.cursor() %>
<% tp.file.cursor(1) %>
<% tp.file.cursor(2) %>
Multiple cursors with same number create multi-cursor selection.
tp.file.cursor_append
Append text at cursor position.
<%* tp.file.cursor_append("Text to append") %>
tp.file.selection
Get currently selected text.
<% tp.file.selection() %>
tp.file.include
Include another file's content.
<% await tp.file.include("[[Template]]") %>
<% await tp.file.include("[[Note#Section]]") %>
<% await tp.file.include("[[Note#^blockid]]") %>
<% await tp.file.include(tp.file.find_tfile("TemplateName")) %>
tp.file.exists
Check if file exists.
<% await tp.file.exists("folder/file.md") %>
<% await tp.file.exists(tp.file.folder(true) + "/" + tp.file.title + ".md") %>
tp.file.find_tfile
Get TFile object by name.
<% tp.file.find_tfile("MyFile").basename %>
<% tp.file.find_tfile("MyTemplate") %>
tp.file.create_new
Create a new file.
<%* await tp.file.create_new("File content", "NewFileName") %>
<%* await tp.file.create_new(tp.file.find_tfile("MyTemplate"), "NewFileName") %>
<%* await tp.file.create_new("Content", "Name", true) %>
<%* await tp.file.create_new("Content", "Name", false, "Path/To/Folder") %>
Parameters:
template- Content string or TFile templatefilename- Name for new file (default: "Untitled")open_new- Open file after creation (default: false)folder- Target folder path or TFolder
tp.file.rename
Rename current file.
<%* await tp.file.rename("New Name") %>
<%* await tp.file.rename(tp.file.title + " - Copy") %>
tp.file.move
Move current file.
<%* await tp.file.move("/New/Path/" + tp.file.title) %>
<%* await tp.file.move("/Archive/" + tp.file.title) %>
System Module (tp.system)
tp.system.clipboard
Get clipboard content.
<% await tp.system.clipboard() %>
tp.system.prompt
Show input prompt to user.
<% await tp.system.prompt("Enter a value") %>
<% await tp.system.prompt("Enter title", "Default Value") %>
<% await tp.system.prompt("Enter notes", "", false, true) %>
Parameters:
prompt_text- Text shown above inputdefault_value- Default value in inputthrow_on_cancel- Throw error if cancelled (default: false)multiline- Use multiline textarea (default: false)
tp.system.suggester
Show selection list to user.
<% await tp.system.suggester(["Option 1", "Option 2", "Option 3"], ["value1", "value2", "value3"]) %>
<% await tp.system.suggester((item) => item, ["Apple", "Banana", "Cherry"]) %>
<% await tp.system.suggester((item) => item.basename, tp.app.vault.getMarkdownFiles()) %>
Parameters:
text_items- Array of display text or mapping functionitems- Array of values to returnthrow_on_cancel- Throw error if cancelled (default: false)placeholder- Placeholder textlimit- Max items to render
tp.system.multi_suggester
Select multiple items.
<% await tp.system.multi_suggester(["A", "B", "C"], ["A", "B", "C"]) %>
<% (await tp.system.multi_suggester((f) => f.basename, tp.app.vault.getMarkdownFiles())).map(f => `[[${f.basename}]]`) %>
Web Module (tp.web)
tp.web.request
Make HTTP request.
<% await tp.web.request("https://api.example.com/data") %>
<% await tp.web.request("https://jsonplaceholder.typicode.com/todos/1") %>
<% await tp.web.request("https://api.example.com/data", "items.0.name") %>
Parameters:
url- URL to fetchpath- JSON path to extract specific data
tp.web.daily_quote
Get daily quote.
<% await tp.web.daily_quote() %>
tp.web.random_picture
Get random Unsplash image.
<% await tp.web.random_picture() %>
<% await tp.web.random_picture("200x200") %>
<% await tp.web.random_picture("200x200", "nature,water") %>
Config Module (tp.config)
Access Templater context information.
<% tp.config.template_file %> Template TFile
<% tp.config.target_file %> Target TFile
<% tp.config.run_mode %> How Templater was triggered
<% tp.config.active_file %> Active file when triggered
Frontmatter Module (tp.frontmatter)
Access current file's frontmatter.
<% tp.frontmatter.title %>
<% tp.frontmatter.tags %>
<% tp.frontmatter.author %>
<% tp.frontmatter["custom-field"] %>
Hooks Module (tp.hooks)
Execute code after all templates complete.
<%*
tp.hooks.on_all_templates_executed(() => {
// Code to run after template execution
console.log("Template execution complete");
});
%>
Obsidian Module (tp.obsidian)
Access Obsidian API.
<%* new tp.obsidian.Notice("Hello!") %>
<%* tp.obsidian.moment().format("YYYY-MM-DD") %>
User Scripts (tp.user)
Call custom scripts from configured folder.
<% await tp.user.myFunction() %>
<% await tp.user.myFunction("arg1", "arg2") %>
Complete Template Examples
Daily Note Template
---
created: <% tp.date.now("YYYY-MM-DD") %>
tags: daily
---
# <% tp.date.now("dddd, MMMM Do YYYY") %>
## Morning Review
- [ ] Review calendar
- [ ] Check email
- [ ] Set top 3 priorities
## Today's Tasks
- [ ] <% tp.file.cursor() %>
## Notes
## Evening Review
### What went well?
### What could improve?
---
[[<% tp.date.yesterday("YYYY-MM-DD") %>|Yesterday]] | [[<% tp.date.tomorrow("YYYY-MM-DD") %>|Tomorrow]]
Meeting Note Template
---
type: meeting
date: <% tp.date.now("YYYY-MM-DD") %>
attendees:
---
# Meeting: <% await tp.system.prompt("Meeting Title") %>
**Date:** <% tp.date.now("MMMM Do YYYY, h:mm A") %>
**Attendees:** <% await tp.system.prompt("Attendees (comma separated)") %>
## Agenda
1. <% tp.file.cursor(1) %>
## Discussion Notes
## Action Items
- [ ]
## Next Steps
Weekly Review Template
---
type: weekly-review
week: <% tp.date.now("YYYY-[W]WW") %>
---
# Weekly Review: <% tp.date.weekday("MMMM Do", 0) %> - <% tp.date.weekday("MMMM Do", 6) %>
## This Week's Accomplishments
## Incomplete Items
## Lessons Learned
## Next Week's Priorities
1.
2.
3.
## Notes
Project Note Template
---
type: project
status: <% await tp.system.suggester(["Active", "Planning", "On Hold", "Complete"], ["active", "planning", "on-hold", "complete"]) %>
created: <% tp.date.now("YYYY-MM-DD") %>
due:
tags: project
---
# <% await tp.system.prompt("Project Name") %>
## Overview
<% tp.file.cursor() %>
## Goals
-
## Tasks
- [ ]
## Resources
## Notes
## Log
### <% tp.date.now("YYYY-MM-DD") %>
- Created project note
Literature Note Template
---
type: literature
title: <% await tp.system.prompt("Title") %>
author: <% await tp.system.prompt("Author") %>
year: <% await tp.system.prompt("Year") %>
status: queue
created: <% tp.date.now("YYYY-MM-DD") %>
---
# <% tp.frontmatter.title %>
**Author:** <% tp.frontmatter.author %>
**Year:** <% tp.frontmatter.year %>
## Summary
## Key Points
-
## Quotes
## My Thoughts
## Connections
-
Quick Capture Template
---
type: capture
created: <% tp.date.now("YYYY-MM-DD HH:mm") %>
---
# Quick Capture
<% await tp.system.clipboard() %>
---
*Captured on <% tp.date.now("MMMM Do YYYY [at] h:mm A") %>*
File from Clipboard
<%*
const content = await tp.system.clipboard();
const title = await tp.system.prompt("Note title", content.split('\n')[0].substring(0, 50));
await tp.file.rename(title);
%>
# <% tp.file.title %>
<% await tp.system.clipboard() %>
Dynamic File Creation
<%*
const type = await tp.system.suggester(
["Meeting", "Project", "Daily"],
["meeting", "project", "daily"]
);
let template;
switch(type) {
case "meeting":
template = tp.file.find_tfile("Meeting Template");
break;
case "project":
template = tp.file.find_tfile("Project Template");
break;
case "daily":
template = tp.file.find_tfile("Daily Template");
break;
}
await tp.file.create_new(template, tp.date.now("YYYY-MM-DD") + " - " + type, true);
%>
Conditional Content
<%*
const includeSection = await tp.system.suggester(["Yes", "No"], [true, false]);
%>
<% includeSection ? "## Optional Section\n\nThis section was included." : "" %>
Common Patterns
Reference File Title as Date
<% tp.date.now("YYYY-MM-DD", 1, tp.file.title, "YYYY-MM-DD") %>
Navigate Between Daily Notes
[[<% tp.date.now("YYYY-MM-DD", -1, tp.file.title, "YYYY-MM-DD") %>|Previous]] | [[<% tp.date.now("YYYY-MM-DD", 1, tp.file.title, "YYYY-MM-DD") %>|Next]]
Week Navigation
[[<% tp.date.weekday("YYYY-[W]WW", -7, tp.file.title, "YYYY-[W]WW") %>|Previous Week]] | [[<% tp.date.weekday("YYYY-[W]WW", 7, tp.file.title, "YYYY-[W]WW") %>|Next Week]]
Month Range from Title
Start: <% moment(tp.file.title, "YYYY-MM").startOf("month").format("YYYY-MM-DD") %>
End: <% moment(tp.file.title, "YYYY-MM").endOf("month").format("YYYY-MM-DD") %>
Store and Reuse Values
<%*
const projectName = await tp.system.prompt("Project name");
const priority = await tp.system.suggester(["High", "Medium", "Low"], ["high", "medium", "low"]);
-%>
---
project: <% projectName %>
priority: <% priority %>
---
# <% projectName %>
Priority: <% priority %>
Append to Existing File
<%*
const targetFile = tp.file.find_tfile("Log");
await tp.app.vault.append(targetFile, "\n- " + tp.date.now() + ": " + await tp.system.prompt("Log entry"));
%>
References
More from zpankz/obsidian-skills
viva-llm
Use VIVA LLM for multi-provider chat, voice calls, terminal integration, assistants, skills, MCP tools, and agent mode inside Obsidian. Trigger when the user mentions VIVA LLM, voice chat, realtime voice, LLM providers in Obsidian, or vault-integrated AI chat.
1obsidian-plugin-accessibility
Use this skill when building or reviewing Obsidian plugin UI for keyboard access, ARIA labels, screen reader support, focus handling, or mobile touch targets. Accessibility is treated as mandatory, not optional.
1tasks
Create and query tasks using the Tasks plugin syntax including due dates, recurrence, priorities, and task queries. Use when the user mentions Tasks plugin, recurring tasks, task queries, or advanced task management in Obsidian.
1dataview
Create Dataview queries using DQL (Dataview Query Language), inline queries, and DataviewJS. Use when the user mentions Dataview, DQL, querying notes, listing notes by metadata, or creating dynamic views of vault content.
1defuddle
Extract clean markdown from web pages using Defuddle CLI, removing clutter to save tokens. Use when the user provides a URL to read or analyze.
1datacore
Create Datacore views using JSX/React syntax and the dc.* API. Use when the user mentions Datacore, dc.useQuery, JSX views, or React-based vault queries. Datacore is the successor to Dataview with better performance and interactive views.
1