@bernierllc/template-engine
v0.4.0
Published
A core utility for template rendering and variable substitution with support for Liquid and Handlebars engines
Readme
@bernierllc/template-engine
A core utility for template rendering and variable substitution with support for Liquid and Handlebars engines. Features email-safe and documentation-safe preprocessing, template validation, and syntax checking.
Installation
npm install @bernierllc/template-engineUsage
Basic Template Rendering
import { TemplateEngine } from '@bernierllc/template-engine';
// Create engine instance
const engine = new TemplateEngine({
defaultEngine: 'liquid' // or 'handlebars' or 'auto'
});
// Render a template
const template = 'Hello {{name}}, welcome to {{company}}!';
const context = { name: 'John', company: 'BernierLLC' };
const result = engine.render(template, context);
console.log(result); // "Hello John, welcome to BernierLLC!"Engine-Specific Usage
import { LiquidEngine, HandlebarsEngine } from '@bernierllc/template-engine';
// Liquid engine
const liquidEngine = new LiquidEngine();
const liquidResult = liquidEngine.render(
'Hello {{ name | upcase }}!',
{ name: 'world' }
);
// Handlebars engine
const hbsEngine = new HandlebarsEngine();
const hbsResult = hbsEngine.render(
'Hello {{name}}!',
{ name: 'world' }
);Email-Safe Preprocessing
const emailTemplate = `
<script>alert('xss')</script>
<p>Hello {{name}}</p>
<a href="javascript:void(0)">Click</a>
`;
const safe = engine.preprocess(emailTemplate, {
emailSafe: true,
removeScripts: true,
sanitizeHTML: true
});
const result = engine.render(safe, { name: 'John' });
// Scripts and unsafe content removedDocumentation-Safe Templates
const docsTemplate = `
# Documentation for {{project}}
## Features
- Feature 1
- Feature 2
`;
const processed = engine.preprocess(docsTemplate, {
docsSafe: true,
engine: 'liquid'
});
const result = engine.render(processed, { project: 'MyApp' });Template Validation
import { TemplateValidator } from '@bernierllc/template-engine';
const validator = new TemplateValidator();
const template = '{{name}} - {{#if active}}Active{{/if}}';
const validation = validator.validate(template, 'handlebars');
if (!validation.isValid) {
console.error('Validation errors:', validation.errors);
console.warn('Warnings:', validation.warnings);
}
console.log('Suggestions:', validation.suggestions);Custom Helpers and Filters
// Liquid filters
const liquidEngine = new LiquidEngine();
liquidEngine.registerFilter('reverse', (value: string) => {
return value.split('').reverse().join('');
});
const result = liquidEngine.render(
'{{ name | reverse }}',
{ name: 'hello' }
); // "olleh"
// Handlebars helpers
const hbsEngine = new HandlebarsEngine();
hbsEngine.registerHelper('loud', (value: string) => {
return value.toUpperCase() + '!!!';
});
const hbsResult = hbsEngine.render(
'{{loud greeting}}',
{ greeting: 'hello' }
); // "HELLO!!!"Auto-Detection
const engine = new TemplateEngine({
defaultEngine: 'auto' // Automatically detect engine from template syntax
});
// Detects Liquid syntax
const liquidResult = engine.render('{{ name | upcase }}', { name: 'test' });
// Detects Handlebars syntax
const hbsResult = engine.render('{{name}}', { name: 'test' });API Reference
TemplateEngine
Main class for template rendering with automatic engine detection.
Constructor Options
interface EngineConfig {
defaultEngine?: 'liquid' | 'handlebars' | 'auto';
cacheSize?: number; // Number of compiled templates to cache (default: 100)
strictFilters?: boolean; // Throw on undefined filters (default: false)
strictVariables?: boolean; // Throw on undefined variables (default: false)
}Methods
render(template: string, context: TemplateContext): string- Render a template with contextrenderAsync(template: string, context: TemplateContext): Promise<string>- Async renderingcompile(template: string): CompiledTemplate- Compile template for reusepreprocess(template: string, options: PreprocessOptions): string- Preprocess for safetyregisterHelper(name: string, fn: HelperFunction): void- Register custom helperregisterFilter(name: string, fn: FilterFunction): void- Register custom filter
LiquidEngine
Liquid template engine implementation with email and docs preprocessing.
Built-in Filters
upcase- Convert to uppercasedowncase- Convert to lowercasecapitalize- Capitalize first letterreverse- Reverse stringsize- Get length/sizedefault- Provide default valuestrip_html- Remove HTML tagsstrip_newlines- Remove newlinesdate- Format dates
HandlebarsEngine
Handlebars template engine implementation with email and docs preprocessing.
Built-in Helpers
if- Conditional renderingunless- Inverse conditionaleach- Loop over arrays/objectswith- Change contexteq- Equality comparisonne- Not equal comparisonlt,gt,lte,gte- Numeric comparisonsand,or,not- Logical operationsformatDate- Date formattinguppercase,lowercase- String transformationsdefault- Default values
TemplateValidator
Validates template syntax, security, and best practices.
Validation Types
syntax- Template syntax errorsvariable- Undefined variable warningssecurity- Security vulnerabilities (XSS, script injection)performance- Performance suggestionsbest-practice- Best practice recommendations
Methods
validate(template: string, engine: string): ValidationResult- Validate templatevalidateSyntax(template: string, engine: string): TemplateError[]- Syntax check onlycheckSecurity(template: string): TemplateWarning[]- Security check only
Configuration
Preprocessor Options
interface PreprocessOptions {
engine?: 'liquid' | 'handlebars' | 'auto';
emailSafe?: boolean; // Remove scripts, sanitize HTML
docsSafe?: boolean; // Preserve markdown, escape only when needed
removeScripts?: boolean; // Remove all script tags
sanitizeHTML?: boolean; // Sanitize HTML attributes
}Template Context
interface TemplateContext {
[key: string]: any;
_meta?: TemplateMetadata; // Optional metadata
_helpers?: Record<string, HelperFunction>; // Custom helpers
_filters?: Record<string, FilterFunction>; // Custom filters
}Integration Status
Logger Integration
- Status: Not applicable
- Reason: Core utility package with no logging requirements. Silent operation by design.
Docs-Suite Integration
- Status: Ready
- Format: TypeDoc + Markdown
- Documentation: Full API documentation with TypeScript types and usage examples
NeverHub Integration
- Status: Not applicable
- Reason: Pure utility package with no service discovery or event requirements. Operates independently without runtime dependencies.
Security Considerations
The template engine includes built-in security features:
- Script Removal: Automatically removes
<script>tags whenemailSafeis enabled - XSS Prevention: Detects potential XSS vulnerabilities in templates
- HTML Sanitization: Removes dangerous HTML attributes (onclick, onerror, etc.)
- Variable Escaping: Auto-escapes variables by default in both engines
- Validation: Syntax and security validation before rendering
Performance
- Template Caching: Compiled templates are cached (configurable size)
- Lazy Loading: Engines loaded only when needed
- Async Support: Non-blocking rendering with
renderAsync - Memory Efficient: LRU cache prevents memory leaks
Best Practices
- Always validate templates before rendering user-provided content
- Use email-safe preprocessing for email templates
- Enable strict mode in production for early error detection
- Cache compiled templates for frequently used templates
- Use async rendering for large templates or complex contexts
Examples
See the examples/ directory for complete working examples:
basic-usage.ts- Simple template renderingemail-templates.ts- Email-safe preprocessingcustom-helpers.ts- Custom helpers and filtersvalidation.ts- Template validationadvanced.ts- Advanced features and patterns
License
Copyright (c) 2025 Bernier LLC. All rights reserved.
