Templates & Note Creation
The Note Templates & Creation Workflow establishes a standardized, friction-free process for starting new markdown notes. It supports placeholder replacements, auto-discovers built-in/workspace templates, and acts as the front door for AI classification.
1. Overview
Entering high-quality notes into a personal knowledge vault requires consistent formatting. To avoid the blank-slate problem, this feature:
- Provides a quick, menu-driven way to create notes.
- Discovers built-in system templates as well as custom user templates placed in
.templates/. - Performs automatic token replacement for templates (such as
{{date}}and{{title}}). - Creates notes initially as unstructured drafts inside a unified
_drafts/directory so they do not clutter the organized directories before classification.
2. User Experience (UX) Flow
- Trigger: User runs the
AI Notes: New Notecommand from the Command Palette. - Selection: The user is presented with a QuickPick menu listing:
Blank note(empty slate)- Built-in templates (e.g.
meeting,daily) - Workspace templates (custom templates from
.templates/)
- Expansion & Generation:
If a template is selected, the extension reads the template file, automatically swaps template tokens (like
{{date}}for current date and{{title}}), generates a unique UUID-based filename (e.g.29-05-2026_df8s97a6.md), and writes it to_drafts/. - Editor Launch: The newly created markdown file is automatically loaded into the active editor, ready for writing.
3. VS Code Workspace Template Mockup
4. Under the Hood & Code Walkthrough
4.1 Gathering Active Templates
The discoverTemplates function scans both built-in resources and workspace configurations asynchronously. The workspace templates enable team collaboration on document standards directly inside a shared git repo:
export async function discoverTemplates(extensionPath: string, workspaceRoot: string): Promise<TemplateInfo[]> {
const templates: TemplateInfo[] = [];
// 1. Load built-in templates
const builtInDir = path.join(extensionPath, 'resources', 'templates');
try {
const entries = await fsp.readdir(builtInDir);
for (const entry of entries) {
if (entry.endsWith('.md')) {
templates.push({ name: path.basename(entry, '.md'), filePath: path.join(builtInDir, entry), source: 'built-in' });
}
}
} catch {}
// 2. Load workspace custom templates
const workspaceTemplateDir = path.join(workspaceRoot, '.templates');
try {
const entries = await fsp.readdir(workspaceTemplateDir);
for (const entry of entries) {
if (entry.endsWith('.md')) {
templates.push({ name: path.basename(entry, '.md'), filePath: path.join(workspaceTemplateDir, entry), source: 'workspace' });
}
}
} catch {}
return templates;
}
4.2 Variable Replacement Execution
Templates support double curly brace token matching. When triggered, the extension replaces placeholders using a global regular expression:
export function expandTemplateVariables(content: string, title?: string): string {
let result = content;
result = result.replace(/\{\{date\}\}/g, formatDateDDMMYYYY());
result = result.replace(/\{\{title\}\}/g, title || 'Untitled');
return result;
}