kogral/templates/README.md

400 lines
8.5 KiB
Markdown
Raw Normal View History

2026-01-23 16:12:50 +00:00
# Knowledge Base Templates
This directory contains Tera templates for generating and exporting knowledge base documents.
## Overview
Templates are divided into two categories:
1. **Document Templates** - Generate new KOGRAL documents with proper frontmatter
2. **Export Templates** - Export KOGRAL data to various formats (Logseq, JSON, reports)
## Document Templates
Located in the root `templates/` directory. Used to create new knowledge base entries.
### Available Templates
| Template | Purpose | Node Type |
|----------|---------|-----------|
| `note.md.tera` | General notes and observations | note |
| `decision.md.tera` | Architectural Decision Records (ADR) | decision |
| `guideline.md.tera` | Code guidelines and best practices | guideline |
| `pattern.md.tera` | Design patterns and solutions | pattern |
| `journal.md.tera` | Daily notes and journal entries | journal |
| `execution.md.tera` | Agent execution records (from Vapora) | execution |
### Template Variables
All document templates receive these common variables:
```rust
{
id: String, // UUID
title: String, // Node title
created: DateTime, // ISO 8601 timestamp
modified: DateTime, // ISO 8601 timestamp
tags: Vec<String>, // Tags
status: NodeStatus, // draft, active, superseded, archived
content: String, // Markdown content
relates_to: Vec<String>, // Related node IDs
depends_on: Vec<String>, // Dependency node IDs
implements: Vec<String>, // Pattern/guideline node IDs
extends: Vec<String>, // Extension node IDs
project: Option<String>, // Project identifier
}
```
### Type-Specific Variables
**Decision (ADR):**
```rust
{
context: String, // Problem context
decision: String, // Decision made
consequences: Vec<String>, // Impacts
alternatives: Vec<{ // Alternatives considered
name: String,
description: String,
pros: Vec<String>,
cons: Vec<String>,
}>,
}
```
**Guideline:**
```rust
{
language: String, // Programming language
category: String, // Category (error-handling, testing, etc.)
overview: String, // Brief overview
rules: Vec<{ // Guideline rules
title: String,
description: String,
rationale: String,
}>,
examples: Vec<{ // Code examples
title: String,
good: String, // Good practice
bad: String, // Bad practice
explanation: String,
}>,
exceptions: Vec<String>,
}
```
**Pattern:**
```rust
{
problem: String, // Problem statement
solution: String, // Solution description
forces: Vec<String>, // Constraints/forces
context: String, // When to use
structure: String, // Pattern structure
implementation: Vec<{ // Implementation steps
title: String,
description: String,
code: String,
language: String,
}>,
consequences: {
benefits: Vec<String>,
drawbacks: Vec<String>,
},
}
```
**Journal:**
```rust
{
date: String, // Date (YYYY-MM-DD)
tasks: Vec<{ // Tasks for the day
description: String,
completed: bool,
}>,
highlights: Vec<String>, // Daily highlights
learnings: Vec<String>, // Things learned
links: Vec<String>, // Related node IDs
}
```
**Execution:**
```rust
{
task_type: String, // Type of task
agent: String, // Agent name
outcome: String, // success, failure, etc.
duration_ms: u64, // Execution time
steps: Vec<{ // Execution steps
description: String,
duration_ms: u64,
result: String,
}>,
errors: Vec<{ // Errors encountered
type: String,
message: String,
details: String,
}>,
metrics: Vec<{ // Performance metrics
name: String,
value: f64,
unit: String,
}>,
}
```
## Export Templates
Located in `templates/export/`. Used to export KOGRAL data to external formats.
### Available Export Templates
| Template | Format | Purpose |
|----------|--------|---------|
| `logseq-page.md.tera` | Logseq Markdown | Export single node to Logseq page |
| `logseq-journal.md.tera` | Logseq Markdown | Export journal to Logseq daily note |
| `summary.md.tera` | Markdown Report | Generate KOGRAL summary report |
| `graph.json.tera` | JSON | Export entire graph to JSON |
### Export Template Variables
**Logseq Export:**
```rust
{
node: Node, // Full node object
}
```
**Summary Export:**
```rust
{
graph: {
name: String,
version: String,
description: String,
},
timestamp: DateTime,
stats: {
total_nodes: usize,
total_edges: usize,
nodes_by_type: HashMap<NodeType, usize>,
nodes_by_status: HashMap<NodeStatus, usize>,
top_tags: Vec<(String, usize)>,
},
nodes: Vec<Node>,
}
```
**JSON Export:**
```rust
{
graph: Graph,
nodes: Vec<Node>,
edges: Vec<Edge>,
stats: Statistics,
}
```
## Usage Examples
### Generate a New Note
```rust
use kb_core::export::tera::TeraEngine;
use kb_core::models::{Node, NodeType};
let tera = TeraEngine::new(Path::new("templates"))?;
let mut node = Node::new(NodeType::Note, "My Note".to_string());
node.content = "This is my note content".to_string();
node.tags = vec!["rust".to_string(), "kogral".to_string()];
let markdown = tera.render_node(&node)?;
```
### Export to Logseq
```rust
let logseq_md = tera.export_logseq(&node)?;
std::fs::write(".logseq/pages/my-note.md", logseq_md)?;
```
### Generate Summary Report
```rust
use tera::Context;
let mut context = Context::new();
context.insert("graph", &graph);
context.insert("timestamp", &Utc::now());
context.insert("stats", &statistics);
context.insert("nodes", &nodes);
let summary = tera.render_custom("export/summary.md.tera", &context)?;
```
## Customization
### Override Default Templates
Copy a template and modify it:
```bash
cp templates/note.md.tera my-templates/custom-note.md.tera
# Edit my-templates/custom-note.md.tera
```
Update configuration:
```nickel
{
templates = {
templates_dir = "my-templates",
templates = {
note = "custom-note.md.tera",
},
},
}
```
### Create Custom Templates
Add to `templates/custom/`:
```jinja2
---
id: {{ id }}
title: {{ title }}
custom_field: {{ my_custom_field }}
---
# {{ title }}
Custom template content here.
```
Register in config:
```nickel
{
templates = {
custom = {
my-template = "custom/my-template.md.tera",
},
},
}
```
## Template Syntax
Templates use Tera syntax (similar to Jinja2):
### Variables
```jinja2
{{ variable }}
{{ object.field }}
{{ array.0 }}
```
### Filters
```jinja2
{{ text | upper }}
{{ date | date(format="%Y-%m-%d") }}
{{ content | truncate(length=100) }}
{{ json_data | json_encode | safe }}
```
### Conditionals
```jinja2
{% if condition %}
...
{% elif other_condition %}
...
{% else %}
...
{% endif %}
```
### Loops
```jinja2
{% for item in items %}
{{ item }}
{% endfor %}
{% for key, value in map %}
{{ key }}: {{ value }}
{% endfor %}
```
### Comments
```jinja2
{# This is a comment #}
```
## YAML Frontmatter
All document templates generate YAML frontmatter compatible with:
- **Logseq** - Wikilinks, properties
- **kogral-core parser** - Full schema validation
- **Git** - Human-readable diffs
Example:
```yaml
---
id: abc-123
type: note
title: My Note
created: 2026-01-17T10:30:00Z
modified: 2026-01-17T10:30:00Z
tags: ["rust", "kogral"]
status: draft
relates_to:
- other-note-id
---
```
## Best Practices
1. **Keep Templates Simple** - Focus on structure, not complex logic
2. **Use Defaults** - Provide sensible defaults with `| default(value="...")`
3. **Indent Consistently** - Use `| indent(width=2)` for nested content
4. **Escape User Content** - Use `| escape` for user-provided text in HTML/JSON
5. **Document Custom Fields** - Add comments explaining custom template variables
## Troubleshooting
### Template Not Found
Ensure `templates_dir` in config points to the correct directory:
```nickel
templates = {
templates_dir = "templates", // Relative to project root
}
```
### Variable Not Found
Check that the variable is provided in the template context. Add a default:
```jinja2
{{ variable | default(value="") }}
```
### Rendering Errors
Enable debug mode to see detailed error messages:
```rust
let tera = Tera::new("templates/**/*.tera")?;
tera.autoescape_on(vec![]); // Disable autoescaping for markdown
```
## References
- [Tera Documentation](https://keats.github.io/tera/)
- [Logseq Markdown Format](https://docs.logseq.com/)
- kogral-core models: `crates/kogral-core/src/models.rs`
- Template engine: `crates/kogral-core/src/export/tera.rs`