Files
madomeda/TEMPLATE_TYPES.md
2025-10-23 20:14:21 +02:00

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:number42 (integer)
  • lit:3.14:number3.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, ontrue
  • 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