471 lines
8.5 KiB
Markdown
471 lines
8.5 KiB
Markdown
|
|
# 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
|