monapdx_obsidian-skeletal/docs/adding-templates.md
Ashly e1f533342d Add local deploy script, docs, and UI tweaks
Add local deployment workflow and docs: .env.local.example, scripts/deploy-local.mjs, deploy:local npm script, screenshots, and CHANGELOG.md. Update README with deployment, screenshots, usage, and development instructions. Update .gitignore to exclude local env, logs, and build outputs. Polish UI and layout: refactor TemplateBrowserModal structure and update styles.css for responsive modal/pane scrolling. Small metadata changes: manifest/package.json author/description and LICENSE copyright.
2026-07-17 02:18:18 -07:00

2.1 KiB

Adding a template

Templates are data-driven. You rarely need a new modal—define controls and a pure generate function.

1. Choose a category file

Add the template to the matching module under src/templates/ (for example lists.ts, tasks.ts). Export it in that file's array; src/templates/index.ts already concatenates every category.

2. Define the template

import type { MarkdownTemplate } from "../types/templates";
import { asNumber, commonPlaceholderControl, listItem, resolvePlaceholder, repeatLines, itemLabel } from "../generators/shared";

export const myTemplate: MarkdownTemplate = {
  id: "lists-my-template", // unique, stable id
  name: "My template",
  description: "Short description shown in the browser.",
  category: "lists",
  tags: ["example"],
  controls: [
    { id: "count", type: "number", label: "Items", default: 3, min: 1, max: 20, step: 1 },
    commonPlaceholderControl(),
  ],
  generate(values) {
    const count = asNumber(values.count, 3);
    const ph = resolvePlaceholder(values);
    return repeatLines(count, (i) => listItem(itemLabel(i, ph, { prefix: "Item" })));
  },
};

Push myTemplate into the category's exported array (or spread it in).

3. Control types

Use the discriminated union in src/types/templates.ts:

type Purpose
text Single-line text
number Numeric (min / max / step)
toggle Boolean
select Dropdown (options)
multiline Textarea
character Single character (progress bar glyphs)
list List of labels (one per line in the UI)

Avoid any. Read values with helpers from src/generators/shared.ts (asNumber, asBoolean, asString, asStringList).

4. Shared generators

Reuse heading, listItem, taskItem, buildTable, linkify, and progress helpers in src/generators/progress.ts (createManagedProgressBlock) when you need updatable progress markers.

5. Verify

npm run typecheck
npm test
npm run build
# optional: copy into your vault (requires .env.local — see README)
npm run deploy:local

Open the template browser in Obsidian and confirm search, controls, preview, and insert.