# Template Field Types ## Overview Templates support explicit type declarations for frontmatter fields. This ensures correct formatting and enables proper LLM schema generation. ## Syntax ```json { "fieldname": "strategy|strategy:type" } ``` The type is specified after a colon `:` at the end of the strategy chain. ## Supported Types | Type | Description | YAML Output | Example | |------|-------------|-------------|---------| | `text` | String value (default) | `field: value` | Title, description | | `number` | Integer or float | `field: 42` | Count, score | | `checkbox` | Boolean value | `field: true` | Published, active | | `date` | Date only (YAML ISO date) | `field: '2025-10-23'` | Birth date, deadline | | `datetime` | Date and time (YAML ISO 8601) | `field: '2025-10-23T19:54:00+02:00'` | Created, modified | | `list` | Array of strings | `field: [item1, item2]` | Tags, keywords, authors | If no type is specified, `text` is assumed. ## Examples ### Basic Template with Types ```json { "title": "heur|orig:text", "created": "heur|orig:datetime", "changed": "heur|orig:datetime", "authors": "heur|orig:list", "version": "heur|orig:text", "tags": "heur|orig|ai default:list", "published": "orig|lit:false:checkbox", "word_count": "heur:number" } ``` ### Text Fields **Template:** ```json { "title": "heur|orig:text", "summary": "orig|ai default:text", "author_name": "heur|lit:Anonymous:text" } ``` **Output:** ```yaml --- title: My Document summary: This is a summary author_name: Anonymous --- ``` ### Number Fields **Template:** ```json { "priority": "orig|lit:5:number", "version_number": "heur:number", "word_count": "heur:number" } ``` **Output:** ```yaml --- priority: 5 version_number: 2 word_count: 1532 --- ``` **Literal conversion:** - `lit:42:number` → `42` (integer) - `lit:3.14:number` → `3.14` (float) - Invalid numbers default to string ### Checkbox Fields **Template:** ```json { "published": "orig|lit:false:checkbox", "draft": "lit:true:checkbox", "featured": "orig|lit:false:checkbox" } ``` **Output:** ```yaml --- published: false draft: true featured: false --- ``` **Literal conversion:** - `true`, `1`, `yes`, `on` → `true` - Anything else → `false` ### Date Fields **Template:** ```json { "birth_date": "orig:date", "deadline": "heur:date" } ``` **Output:** ```yaml --- birth_date: '2025-10-23' deadline: '2025-12-31' --- ``` **Format:** ISO 8601 date (`YYYY-MM-DD`) ### Datetime Fields **Template:** ```json { "created": "heur:datetime", "modified": "heur:datetime", "published_at": "orig:datetime" } ``` **Output:** ```yaml --- created: '2025-10-23T19:54:00+02:00' modified: '2025-10-23T20:15:30+02:00' published_at: '2025-10-23T18:00:00+00:00' --- ``` **Format:** ISO 8601 with timezone ### List Fields **Template:** ```json { "tags": "heur|orig|ai default:list", "authors": "heur|orig:list", "keywords": "orig|lit:[]:list", "categories": "ai categorize:list" } ``` **Output:** ```yaml --- tags: - machine_learning - python - tutorial authors: - John Doe - Jane Smith keywords: [] categories: - technology - programming --- ``` **Literal list:** ```json { "reviewers": "lit:[]:list" } ``` Creates empty list: `reviewers: []` ## Type with Strategies ### Literal Values ```json { "status": "lit:draft:text", "priority": "lit:3:number", "urgent": "lit:false:checkbox", "default_tags": "lit:[]:list" } ``` ### Heuristic Values Heuristics automatically infer appropriate types: ```json { "created": "heur:datetime", // From git (ISO 8601) "changed": "heur:datetime", // From git (ISO 8601) "authors": "heur:list", // From git (list of names) "version": "heur:text", // From git (tag or hash) "title": "heur:text", // From # heading "tags": "heur:list" // From normalized tags } ``` ### Original Values Preserves the original type if it matches: ```json { "tags": "orig:list", // Keep original tags list "published": "orig:checkbox", // Keep original boolean "score": "orig:number" // Keep original number } ``` ### AI Values LLM generates values conforming to the specified type: ```json { "summary": "ai summarize:text", "tags": "ai default:list", "relevance_score": "ai evaluate:number", "needs_review": "ai check:checkbox" } ``` The type determines the JSON schema sent to the LLM. ## Complex Templates ### Blog Post ```json { "title": "heur|orig:text", "date": "heur:datetime", "author": "heur|lit:Blog Team:text", "category": "orig|ai categorize:text", "tags": "orig|ai default:list", "published": "orig|lit:false:checkbox", "featured": "orig|lit:false:checkbox", "word_count": "heur:number", "reading_time": "heur:number", "excerpt": "orig|ai excerpt:text" } ``` ### Documentation ```json { "title": "heur|orig:text", "version": "heur:text", "created": "heur:datetime", "updated": "heur:datetime", "authors": "heur:list", "reviewers": "orig|lit:[]:list", "status": "orig|lit:draft:text", "tags": "heur|orig|ai default:list", "api_version": "orig:text", "deprecated": "orig|lit:false:checkbox" } ``` ### Task/Todo ```json { "title": "heur|orig:text", "created": "heur:datetime", "due_date": "orig:date", "priority": "orig|lit:3:number", "completed": "orig|lit:false:checkbox", "assigned_to": "orig|lit:[]:list", "tags": "orig:list", "estimated_hours": "orig:number" } ``` ## Type Validation ### Automatic Conversion When using literal values, types are automatically converted: ```json { "published": "lit:true:checkbox" // String "true" → boolean true } ``` ### Invalid Values If conversion fails, value is kept as string: ```json { "count": "lit:invalid:number" // "invalid" → "invalid" (string) } ``` ## LLM Schema Generation Types control the JSON schema sent to LLMs: **Template:** ```json { "title": "ai generate:text", "tags": "ai generate:list", "relevance": "ai score:number", "approved": "ai check:checkbox" } ``` **Generated Schema:** ```json { "type": "object", "properties": { "title": {"type": "string"}, "tags": {"type": "array", "items": {"type": "string"}}, "relevance": {"type": "number"}, "approved": {"type": "boolean"} } } ``` This ensures LLM returns correctly typed values. ## Best Practices ### 1. Always Specify Types for Lists ```json { "tags": "heur|orig:list", // ✅ Explicit "tags": "heur|orig" // ❌ Ambiguous } ``` ### 2. Use Checkbox for Booleans ```json { "published": "orig|lit:false:checkbox", // ✅ Boolean "published": "orig|lit:no:text" // ❌ String } ``` ### 3. Datetime for Timestamps ```json { "created": "heur:datetime", // ✅ Full timestamp "created": "heur:text" // ❌ Generic } ``` ### 4. Number for Numeric Data ```json { "priority": "orig|lit:5:number", // ✅ Number "priority": "orig|lit:5:text" // ❌ String "5" } ``` ### 5. List Default Values ```json { "keywords": "orig|lit:[]:list", // ✅ Empty list "keywords": "orig:list" // ⚠️ May be null } ``` ## Migration from Untyped Templates ### Before (Untyped) ```json { "title": "heur|orig", "tags": "heur|orig|ai default", "published": "lit:false" } ``` ### After (Typed) ```json { "title": "heur|orig:text", "tags": "heur|orig|ai default:list", "published": "lit:false:checkbox" } ``` **Note:** Untyped templates still work (default to `text`), but typed templates are recommended for clarity and correctness. ## Troubleshooting ### List Shows as String **Problem:** `tags: "tag1, tag2"` instead of `tags: [tag1, tag2]` **Solution:** Specify `:list` type and ensure rules split comma-separated values: ```json { "tags": "heur|orig:list" } ``` ### Boolean Shows as String **Problem:** `published: "true"` instead of `published: true` **Solution:** Use `:checkbox` type: ```json { "published": "orig|lit:false:checkbox" } ``` ### Number Shows as String **Problem:** `priority: "5"` instead of `priority: 5` **Solution:** Use `:number` type: ```json { "priority": "orig|lit:5:number" } ``` ### Date Format Wrong **Problem:** `date: "10/23/2025"` instead of `date: '2025-10-23'` **Solution:** Use `:date` or `:datetime` type and ensure source provides ISO 8601 format. ## See Also - [LITERAL_VALUES.md](LITERAL_VALUES.md) - Literal value syntax - [CONFIGURATION.md](CONFIGURATION.md) - Template configuration - [USAGE.md](USAGE.md) - Template usage examples - [RULES_GUIDE.md](RULES_GUIDE.md) - Rule writing guide