obsidian-templater
Help with templates/snippets for the Obsidian Templater plugin. Use to help generate Obsidian templates from natural language, understand and debug existing tp.* snippets, and adapt vault notes and workflows to Templater when users mention Templater, tp.*, or <% %>.
What this skill does
# Templater template generation
Templater is an Obsidian plugin for dynamic note templates. Commands embedded in a template file run when the template is applied to a note, outputting results inline.
## Core template syntax
| Tag | Behavior |
| ------------------- | ------------------------------------------------ |
| `<% expression %>` | Outputs the result of the expression |
| `<%* code %>` | Executes JS code; no output by default |
| `<%+ expression %>` | Re-evaluated in preview mode (deprecated, avoid) |
| `<%-` / `-%>` | Trims one newline before/after the tag |
| `<%_` / `_%>` | Trims all whitespace before/after the tag |
To output from a `<%* %>` execution block, append to the special `tR` string:
```
<%* tR += "some output" %>
```
To discard everything generated up to a point (e.g., strip template-only frontmatter):
```
<%* tR = "" -%>
```
All `tp.*` functions are available in both tag types.
---
## Built-in Templater modules
### tp.date
```
tp.date.now(format?, offset?, reference?, reference_format?)
```
Returns a formatted date string. `format` uses moment.js tokens (`"YYYY-MM-DD"` is the default). `offset` is a number of days (`7`, `-1`) or a duration string (`"P1W"`). `reference` is a date string parsed with `reference_format`.
```
tp.date.tomorrow(format?) // today + 1 day
tp.date.yesterday(format?) // today - 1 day
tp.date.weekday(format, weekday, reference?, reference_format?)
// weekday: 0=Sun … 6=Sat
moment // full moment.js object, accessible globally
```
Common format strings: `"YYYY-MM-DD"`, `"YYYY-MM-DD HH:mm"`, `"dddd Do MMMM YYYY"`, `"HH:mm"`, `"ddd"`, `"MMM D"`.
---
### tp.file
Dynamic properties (not function calls — no parentheses):
```
tp.file.title // basename without extension
tp.file.content // full text of the file
tp.file.tags // string[] of all tags on the file
```
Functions:
```
tp.file.creation_date(format?) // default "YYYY-MM-DD HH:mm"
tp.file.last_modified_date(format?) // default "YYYY-MM-DD HH:mm"
tp.file.folder(absolute?) // folder name; full path if absolute=true
tp.file.path(relative?) // absolute path; vault-relative if relative=true
tp.file.cursor(order?) // place cursor here after template runs; order = tab index
tp.file.cursor_append(content) // insert content at the current cursor
tp.file.selection() // currently selected text in the editor
tp.file.exists(filepath) // async → boolean
tp.file.find_tfile(filename) // → TFile | null (for use with create_new / include)
tp.file.include("[[NoteLink]]") // async; embeds another note's content (also processed)
tp.file.create_new(template, filename, open_new?, folder?) // async; create note from template
tp.file.move(path, file?) // async; move file (path has no extension)
tp.file.rename(new_title) // async; rename the current file
```
---
### tp.system
All are async — use `await` inside `<%* %>` blocks:
```
await tp.system.clipboard()
await tp.system.prompt(prompt_text, default_value?, throw_on_cancel?, multi_line?)
await tp.system.suggester(text_items, items, throw_on_cancel?, placeholder?, limit?)
await tp.system.multi_suggester(text_items, items, throw_on_cancel?, title?, limit?)
```
`suggester` takes two parallel arrays: display labels and return values. They can be the same array.
```javascript
<%* const type = await tp.system.suggester(["Meeting", "Decision", "Reference"], ["meeting", "decision", "ref"]) %>
```
---
### tp.frontmatter
Direct property access — not a function:
```
<% tp.frontmatter.status %>
<% tp.frontmatter.project %>
```
Returns `undefined` if the property doesn't exist.
---
### tp.web
All are async:
```
await tp.web.daily_quote() // Obsidian callout block with a random quote
await tp.web.random_picture(size, query?, include_size?)
// size: "800" or "800x600"; returns markdown image syntax
await tp.web.request(url, path?)
// HTTP GET returning JSON; path is dot-notation like "data.title"
```
---
### tp.config
Read-only context about the current run:
```
tp.config.template_file // TFile of the template being applied
tp.config.target_file // TFile of the note being created/modified
tp.config.active_file // TFile of the currently active file
tp.config.run_mode // 0=CreateNewFromTemplate 1=AppendActiveFile 2=OverwriteFile
// 3=OverwriteActiveFile 4=DynamicProcessor
```
---
### App and Obsidian API modules
`tp.app` is the Obsidian `App` object. `tp.obsidian` exposes the Obsidian API module. Used in advanced JS execution blocks for vault traversal, metadata cache queries, etc.
---
### tp.hooks
```
tp.hooks.on_all_templates_executed(callback)
```
Callback fires after all nested templates (e.g., from `tp.file.create_new`) have finished.
---
### User-defined functions (tp.user)
Scripts placed in the folder configured in Templater settings are callable as `tp.user.<filename>(args...)`. Scripts use CommonJS format:
```javascript
// Scripts/slugify.js
module.exports = function (text) {
return text.toLowerCase().replace(/\s+/g, "-");
};
```
```
<% tp.user.slugify(tp.file.title) %>
```
Scripts can also export an object of named functions. Pass `tp` as an argument to access Templater context inside a script. Note: user functions are unavailable on mobile.
---
## Whitespace control in templates
Control flow tags (`<%* if (...) { %>`, `<%* } %>`) leave blank lines by default. Use `-%>` to trim the newline that follows a tag:
```
<%* if (tp.file.folder() === "Work") { -%>
**Project:** <% tp.frontmatter.project %>
<%* } else { -%>
General note
<%* } -%>
```
---
## Common implementation patterns
### Daily note
```
---
date: <% tp.date.now() %>
---
<< [[<% tp.date.yesterday() %>]] | [[<% tp.date.tomorrow() %>]] >>
# <% tp.file.title %>
<%* tR += await tp.web.daily_quote() %>
<% tp.file.cursor() %>
```
### Prompted metadata + file rename
```
<%*
const title = await tp.system.prompt("Note title", tp.file.title)
const status = await tp.system.suggester(["Draft", "In progress", "Done"], ["draft", "in-progress", "done"])
await tp.file.rename(title)
-%>
---
title: <% title %>
status: <% status %>
created: <% tp.file.creation_date() %>
---
# <% title %>
<% tp.file.cursor() %>
```
### Strip template-file frontmatter from output
```
---
type: template
description: This is a person template.
---
<%* tR = "" -%>
---
type: person
created: <% tp.file.creation_date() %>
---
# <% tp.file.cursor() %>
```
### Conditional content by folder
```
<%* if (tp.file.folder() === "Work") { -%>
**Project:** <% tp.frontmatter.project ?? "unassigned" %>
<%* } else { -%>
**Topic:**
<%* } -%>
```
For subfolder matching: `tp.file.folder(true).startsWith("Work/")` — `folder(true)` returns the full vault-relative path.
### Include another note
```
<% await tp.file.include("[[Shared Header]]") %>
```
---
## Date formatting with Moment.js
See [momentjs.md](references/momentjs.md) for a comprehensive formatting cheatsheet and JS manipulation reference. Use this when defining `format` strings for `tp.date.now()` or when manipulating dates inside `<%* %>` blocks using the `moment` global.
---
## Optional vault integration via obsidian-clis
If the obsidian-clis skill is available and Obsidian is running, vault context can improve output:
```bash
obsidian properties counts # what frontmatter properties exist across the vault
obsidian tags counts sort=count # most-used tags
obsidian read file="Daily Note" # read an existing template for style reference
```
Ask the user before running any CLRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.