How to Create Custom Templates for AIOX: A Complete Guide to the Template Processing System
AIOX's template processing system is a standalone JavaScript engine that renders documents by replacing {{VARIABLE}} placeholders, conditionals, and loops with supplied data, requiring no external dependencies.
The SynkraAI/aiox-core repository ships a zero-dependency template processing system located in .aiox-core/infrastructure/scripts/template-engine.js. This engine transforms any plain-text file—whether Markdown, YAML, or custom formats—into a fully rendered document by processing Mustache-like syntax. You can use it to generate documentation, configuration files, or scaffolding within AIOX workflows.
Core Syntax and Features
The template engine implements four primary syntax constructs. Understanding these patterns is essential before creating custom templates for AIOX.
Simple Variables
Use double curly braces to inject scalar values directly into your template:
{{VAR_NAME}}
The engine substitutes this placeholder with the corresponding value from your variables object.
Conditional Blocks
Wrap content in {{#IF_CONDITION}} tags to include it only when the variable evaluates to truthy:
{{#IF_HAS_NOTES}}
## Notes
{{NOTES}}
{{/IF_HAS_NOTES}}
The closing tag must match the opening tag exactly, prefixed with a forward slash.
Loop Iteration
Repeat blocks for array elements using {{#EACH_ITEMS}}:
{{#EACH_TASKS}}
- {{ITEM.title}} (Priority: {{ITEM.priority}})
{{/EACH_TASKS}}
Inside loops, the engine exposes five automatic variables:
- {{ITEM}} - The current array element
- {{INDEX}} - The zero-based index
- {{FIRST}} - Boolean true for the first iteration
- {{LAST}} - Boolean true for the last iteration
- A shortcut variable based on the loop name (e.g.,
{{TASKS}}refers to the current item when iterating overEACH_TASKS)
Escape Sequences
Prevent processing by prefixing with a backslash:
\{{LITERAL}}
The engine temporarily swaps escaped braces during processing and restores them in the final output.
Processing Pipeline
The process() method executes transformations in a strict order to handle nested logic correctly:
- Escaped braces are temporarily replaced with placeholders
- Loops expand first (allowing inner conditionals to reference loop variables)
- Conditionals evaluate next
- Simple variables substitute
- Escaped braces restore to literal
{{...}}text
TemplateEngine API Reference
The engine exposes five primary methods in .aiox-core/infrastructure/scripts/template-engine.js:
process(template, variables)- Synchronously render a template string with a plain object of variablesloadAndProcess(templatePath, variables)- Asynchronously read a file from disk and render it (returns a Promise)validateTemplate(template, requiredVars)- Verify that every variable inrequiredVarsappears in the template; returns{ valid, missing, found }getTemplateVariables(template)- Extract all placeholders, categorized intosimple,conditionals, andloopsescapeInput(input)- Safely escape user-provided data to prevent injection before feeding it to the engine
Rendering Templates: Practical Examples
Inline String Rendering
For quick transformations, instantiate the engine and call process() directly:
const TemplateEngine = require('.aiox-core/infrastructure/scripts/template-engine');
const engine = new TemplateEngine();
const template = `
# {{TITLE}}
Created by {{AUTHOR}} on {{DATE}}
{{#IF_HAS_NOTES}}
## Notes
{{NOTES}}
{{/IF_HAS_NOTES}}
{{#EACH_TASKS}}
- {{ITEM.title}} ({{ITEM.priority}})
{{/EACH_TASKS}}
`;
const variables = {
TITLE: 'Sprint 42 Summary',
AUTHOR: 'Dex',
DATE: new Date().toISOString().split('T')[0],
HAS_NOTES: true,
NOTES: 'All stories delivered on time.',
TASKS: [
{ title: 'Write docs', priority: 'HIGH' },
{ title: 'Add tests', priority: 'MEDIUM' },
],
};
console.log(engine.process(template, variables));
This outputs a fully rendered Markdown document with conditional sections and iterated task lists.
Loading External Template Files
Use loadAndProcess() to render templates stored in the product catalogue:
const TemplateEngine = require('.aiox-core/infrastructure/scripts/template-engine');
const engine = new TemplateEngine();
async function generateStory() {
const templatePath = '.aiox-core/product/templates/story-tmpl.yaml';
const variables = {
STORY_ID: '3.12',
TITLE: 'User onboarding flow',
AUTHOR: 'Ana',
DATE: '2025-12-05',
};
const output = await engine.loadAndProcess(templatePath, variables);
console.log(output);
}
generateStory();
Validating Templates Before Rendering
Prevent runtime errors by verifying required variables exist:
const engine = new (require('.aiox-core/infrastructure/scripts/template-engine'))();
const customTemplate = `
# {{COMPONENT_NAME}}
{{#IF_HAS_PROPS}}
## Props
{{#EACH_PROPS}}
- {{ITEM.name}}: {{ITEM.type}}
{{/EACH_PROPS}}
{{/IF_HAS_PROPS}}
`;
const required = ['COMPONENT_NAME', 'HAS_PROPS'];
const validation = engine.validateTemplate(customTemplate, required);
if (!validation.valid) {
console.error('Missing variables:', validation.missing);
process.exit(1);
}
const result = engine.process(customTemplate, {
COMPONENT_NAME: 'Button',
HAS_PROPS: true,
PROPS: [{ name: 'variant', type: 'string' }],
});
console.log(result);
Escaping User Input
Sanitize untrusted data to prevent template injection:
const engine = new (require('.aiox-core/infrastructure/scripts/template-engine'))();
const userInput = '<script>alert("xss")</script> {{UNSAFE}}';
const safe = engine.escapeInput(userInput);
const template = 'User comment: {{COMMENT}}';
console.log(engine.process(template, { COMMENT: safe }));
The output displays literal HTML and escaped placeholders rather than executing them.
Creating Custom Templates for AIOX
Follow this workflow to build reusable templates for documentation generation or scaffolding.
Step 1: Create the Template File
Store your template under .aiox-core/product/templates/ or any project directory. For example, create .aiox-core/product/templates/component-tmpl.md:
# {{COMPONENT_NAME}}
**Type:** {{COMPONENT_TYPE}}
**Created:** {{DATE}}
**Author:** {{AUTHOR}}
## Description
{{DESCRIPTION}}
{{#IF_HAS_PROPS}}
## Props
| Name | Type | Default | Description |
| ---- | ---- | ------- | ----------- |
{{#EACH_PROPS}}
| {{ITEM.name}} | {{ITEM.type}} | {{ITEM.default}} | {{ITEM.description}} |
{{/EACH_PROPS}}
{{/IF_HAS_PROPS}}
Step 2: Define a Validation Schema
Add a YAML schema file alongside your template (e.g., component-tmpl.schema.yaml) to document required variables:
name: component-template
version: '1.0'
description: Template for component documentation
variables:
required:
- COMPONENT_NAME
- COMPONENT_TYPE
- DATE
- AUTHOR
- DESCRIPTION
optional:
- HAS_PROPS
- PROPS
validation:
COMPONENT_TYPE:
enum: [React, Vue, Angular, Vanilla]
DATE:
format: date
Feed the required array into validateTemplate() before rendering to ensure data completeness.
Step 3: Render from Your Script
Import the engine and process your custom template:
const engine = new (require('.aiox-core/infrastructure/scripts/template-engine'))();
const templatePath = '.aiox-core/product/templates/component-tmpl.md';
const variables = {
COMPONENT_NAME: 'PrimaryButton',
COMPONENT_TYPE: 'React',
DATE: '2025-01-15',
AUTHOR: 'DevTeam',
DESCRIPTION: 'Main action button with variants',
HAS_PROPS: true,
PROPS: [
{ name: 'variant', type: 'string', default: 'primary', description: 'Visual style' }
]
};
const output = await engine.loadAndProcess(templatePath, variables);
console.log(output);
Step 4: Integrate with AIOX Workflows
Call loadAndProcess() inside wizard steps, CLI commands, or custom tasks to automate documentation generation during your development pipeline.
Key Implementation Files
Understanding the source structure helps when debugging or extending the template processing system:
.aiox-core/infrastructure/scripts/template-engine.js- CoreTemplateEngineclass implementing theprocess(),loadAndProcess(), andvalidateTemplate()methods.aiox-core/docs/guides/template-engine-v2.md- Official syntax reference and advanced usage patterns.aiox-core/product/templates/- Built-in templates for PRDs, ADRs, and user storiespackages/installer/src/config/templates/env-template.js- Programmatic template generator used during project bootstrappingtests/template-engine/template-engine.test.js- Comprehensive test suite demonstrating edge cases and validation scenarios
Summary
- The AIOX template processing system resides in
.aiox-core/infrastructure/scripts/template-engine.jsand requires zero external dependencies - Templates use Mustache-like syntax with four constructs: simple variables (
{{VAR}}), conditionals ({{#IF}}), loops ({{#EACH}}), and escapes (\{{}}) - The TemplateEngine API provides
process()for strings,loadAndProcess()for files, andvalidateTemplate()for pre-flight checks - Custom templates belong in
.aiox-core/product/templates/and can include companion schema files for validation - Always use
escapeInput()to sanitize user data before passing it to the engine
Frequently Asked Questions
What file formats does the AIOX template processing system support?
The engine processes any plain-text format including Markdown, YAML, JSON, or custom text files. It performs pure string substitution, so the output format depends entirely on your template's content structure.
How do I validate that my template contains all required variables before rendering?
Call engine.validateTemplate(template, requiredVars) with an array of required variable names. The method returns an object with valid (boolean), missing (array), and found (array) properties, allowing you to abort execution or prompt for missing data before calling process().
Can I nest conditionals inside loops when creating custom templates?
Yes. The processing pipeline explicitly expands loops before evaluating conditionals, so inner {{#IF}} blocks can reference loop variables like {{ITEM}}, {{INDEX}}, {{FIRST}}, or {{LAST}}. This allows complex logic such as alternating row classes or conditional formatting within iterations.
Where should I store custom templates in an AIOX project?
While you can store templates anywhere, the conventional location is .aiox-core/product/templates/. Place companion schema files (.schema.yaml) in the same directory. This structure keeps templates organized alongside AIOX's built-in PRD, ADR, and Story templates for easy discovery and maintenance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →