# 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, // Tags status: NodeStatus, // draft, active, superseded, archived content: String, // Markdown content relates_to: Vec, // Related node IDs depends_on: Vec, // Dependency node IDs implements: Vec, // Pattern/guideline node IDs extends: Vec, // Extension node IDs project: Option, // Project identifier } ``` ### Type-Specific Variables **Decision (ADR):** ```rust { context: String, // Problem context decision: String, // Decision made consequences: Vec, // Impacts alternatives: Vec<{ // Alternatives considered name: String, description: String, pros: Vec, cons: Vec, }>, } ``` **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, } ``` **Pattern:** ```rust { problem: String, // Problem statement solution: String, // Solution description forces: Vec, // 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, drawbacks: Vec, }, } ``` **Journal:** ```rust { date: String, // Date (YYYY-MM-DD) tasks: Vec<{ // Tasks for the day description: String, completed: bool, }>, highlights: Vec, // Daily highlights learnings: Vec, // Things learned links: Vec, // 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, nodes_by_status: HashMap, top_tags: Vec<(String, usize)>, }, nodes: Vec, } ``` **JSON Export:** ```rust { graph: Graph, nodes: Vec, edges: Vec, 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`