8.5 KiB
Template Field Types
Overview
Templates support explicit type declarations for frontmatter fields. This ensures correct formatting and enables proper LLM schema generation.
Syntax
{
"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
{
"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:
{
"title": "heur|orig:text",
"summary": "orig|ai default:text",
"author_name": "heur|lit:Anonymous:text"
}
Output:
---
title: My Document
summary: This is a summary
author_name: Anonymous
---
Number Fields
Template:
{
"priority": "orig|lit:5:number",
"version_number": "heur:number",
"word_count": "heur:number"
}
Output:
---
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:
{
"published": "orig|lit:false:checkbox",
"draft": "lit:true:checkbox",
"featured": "orig|lit:false:checkbox"
}
Output:
---
published: false
draft: true
featured: false
---
Literal conversion:
true,1,yes,on→true- Anything else →
false
Date Fields
Template:
{
"birth_date": "orig:date",
"deadline": "heur:date"
}
Output:
---
birth_date: '2025-10-23'
deadline: '2025-12-31'
---
Format: ISO 8601 date (YYYY-MM-DD)
Datetime Fields
Template:
{
"created": "heur:datetime",
"modified": "heur:datetime",
"published_at": "orig:datetime"
}
Output:
---
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:
{
"tags": "heur|orig|ai default:list",
"authors": "heur|orig:list",
"keywords": "orig|lit:[]:list",
"categories": "ai categorize:list"
}
Output:
---
tags:
- machine_learning
- python
- tutorial
authors:
- John Doe
- Jane Smith
keywords: []
categories:
- technology
- programming
---
Literal list:
{
"reviewers": "lit:[]:list"
}
Creates empty list: reviewers: []
Type with Strategies
Literal Values
{
"status": "lit:draft:text",
"priority": "lit:3:number",
"urgent": "lit:false:checkbox",
"default_tags": "lit:[]:list"
}
Heuristic Values
Heuristics automatically infer appropriate types:
{
"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:
{
"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:
{
"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
{
"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
{
"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
{
"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:
{
"published": "lit:true:checkbox" // String "true" → boolean true
}
Invalid Values
If conversion fails, value is kept as string:
{
"count": "lit:invalid:number" // "invalid" → "invalid" (string)
}
LLM Schema Generation
Types control the JSON schema sent to LLMs:
Template:
{
"title": "ai generate:text",
"tags": "ai generate:list",
"relevance": "ai score:number",
"approved": "ai check:checkbox"
}
Generated Schema:
{
"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
{
"tags": "heur|orig:list", // ✅ Explicit
"tags": "heur|orig" // ❌ Ambiguous
}
2. Use Checkbox for Booleans
{
"published": "orig|lit:false:checkbox", // ✅ Boolean
"published": "orig|lit:no:text" // ❌ String
}
3. Datetime for Timestamps
{
"created": "heur:datetime", // ✅ Full timestamp
"created": "heur:text" // ❌ Generic
}
4. Number for Numeric Data
{
"priority": "orig|lit:5:number", // ✅ Number
"priority": "orig|lit:5:text" // ❌ String "5"
}
5. List Default Values
{
"keywords": "orig|lit:[]:list", // ✅ Empty list
"keywords": "orig:list" // ⚠️ May be null
}
Migration from Untyped Templates
Before (Untyped)
{
"title": "heur|orig",
"tags": "heur|orig|ai default",
"published": "lit:false"
}
After (Typed)
{
"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:
{
"tags": "heur|orig:list"
}
Boolean Shows as String
Problem: published: "true" instead of published: true
Solution: Use :checkbox type:
{
"published": "orig|lit:false:checkbox"
}
Number Shows as String
Problem: priority: "5" instead of priority: 5
Solution: Use :number type:
{
"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 value syntax
- CONFIGURATION.md - Template configuration
- USAGE.md - Template usage examples
- RULES_GUIDE.md - Rule writing guide