RenderHtmlCommand
Overview
The RenderHtmlCommand renders HTML content from templates with dynamic data binding. Use this for generating HTML emails, web page previews, and reports.
Key Features:
- ✅ Inline HTML template rendering
- ✅ Pre-registered template loading via
templateId - ✅ Handlebars syntax support (
{{variable}}) - ✅ Dynamic data binding
- ✅ Conditional rendering and loops
Syntax
Option 1: Using Inline Template
var result = doCmd('RenderHtmlCommand', {
Data: {
template: '<h1>Hello {{name}}</h1>',
data: { name: 'John Doe' }
}
});
Option 2: Using Template ID (Recommended)
var result = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'welcome-email-template',
data: { name: 'John Doe', accountNumber: '1234567890' }
}
});
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Data.template | string | Yes* | HTML template string with placeholders |
Data.templateId | string | Yes* | Name of pre-registered HTML template in database |
Data.data | object | Yes | Data object to populate template placeholders |
*Note: Either template OR templateId must be provided (not both).
Return Value
{
"isSuccessful": true,
"message": "HTML template rendered successfully.",
"data": {
"html": "<h1>Hello John Doe</h1>",
"templateLength": 25,
"renderedLength": 26
}
}
Template Syntax
RenderHtmlCommand supports Handlebars-style syntax:
Variables
<p>Hello {{customerName}}</p>
<p>Account: {{accountNumber}}</p>
Conditional Rendering
{{#if approved}}
<p style="color: green;">Your loan is approved!</p>
{{/if}}
{{#if rejected}}
<p style="color: red;">Application rejected.</p>
{{/if}}
Loops/Iterations
<ul>
{{#each transactions}}
<li>{{date}}: {{amount}}</li>
{{/each}}
</ul>
Nested Properties
<p>{{customer.firstName}} {{customer.lastName}}</p>
<p>{{address.street}}, {{address.city}}</p>
Common Use Cases
1. Render Welcome Email
var htmlContent = doCmd('RenderHtmlCommand', {
Data: {
template: `
<div style="font-family: Arial, sans-serif; padding: 20px;">
<h2>Welcome {{customerName}}</h2>
<p>Your account <strong>{{accountNumber}}</strong> has been created.</p>
<p>Initial balance: <strong>₦{{balance}}</strong></p>
</div>
`,
data: {
customerName: context.customerName,
accountNumber: context.accountNumber,
balance: $.format.currency(context.initialBalance)
}
}
});
// Send as HTML email
doCmd('SendMailCommand', {
Data: {
email: [context.email],
subject: 'Welcome to BankLingo',
message: htmlContent.data.html
}
});
2. Using Pre-Registered Template
// Use existing template
var htmlContent = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'loan-approval-email',
data: {
customerName: context.customerName,
approved: context.loanStatus === 'approved',
loanAmount: $.format.currency(context.loanAmount),
interestRate: context.interestRate,
tenure: context.tenure
}
}
});
// Send email
doCmd('SendMailCommand', {
Data: {
email: [context.customerEmail],
subject: 'Loan Application Update',
message: htmlContent.data.html
}
});
3. Generate Transaction Report
var reportHtml = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'monthly-transaction-report',
data: {
month: context.month,
year: context.year,
customerName: context.customerName,
transactions: context.transactions.map(t => ({
date: $.format.date(t.date),
description: t.description,
amount: $.format.currency(t.amount)
}))
}
}
});
context.reportPreview = reportHtml.data.html;
Best Practices
✅ Do's
- Use
templateIdfor production templates (reusable and maintainable) - Validate data before rendering
- Format currency and dates before passing to template
- Use inline CSS for email templates (better compatibility)
❌ Don'ts
- Don't include JavaScript in email templates
- Don't use complex CSS for emails (limited support)
- Don't forget to sanitize user input to prevent XSS
Error Handling
Template Not Found
{
"isSuccessful": false,
"message": "HTML template with ID 'welcome-email' not found.",
"data": {
"error": "Template not found",
"templateId": "welcome-email"
}
}
Missing Parameter
{
"isSuccessful": false,
"message": "Either 'template' or 'templateId' is required.",
"data": {
"error": "Missing template or templateId"
}
}
Template Limits
| Limit | Value |
|---|---|
| Maximum Template Size | 1 MB (1,048,576 bytes) |
| Maximum Recursion Depth | 50 levels |
| Supported Syntax | Handlebars ({{variable}}) |
Related Commands
- SendMailCommand - Send HTML emails
- DocumentRenderV2Command - Generate Word/PDF documents
- SendSMSCommand - Send SMS messages
<p>{{customer.firstName}} {{customer.lastName}}</p>
<p>{{address.street}}, {{address.city}}</p>
Examples
Example 1: Render Email Template (Inline)
var htmlContent = doCmd('RenderHtmlCommand', {
Data: {
template: `
<div style="font-family: Arial, sans-serif; padding: 20px;">
<h2>Welcome {{customerName}}</h2>
<p>Your account <strong>{{accountNumber}}</strong> has been created successfully.</p>
<p>Your initial balance is: <strong>₦{{balance}}</strong></p>
{{#if bonusEligible}}
<div style="background: #e8f5e9; padding: 10px; border-radius: 5px;">
<p>🎉 Congratulations! You're eligible for a ₦{{bonusAmount}} signup bonus!</p>
</div>
{{/if}}
<hr/>
<p style="color: #666; font-size: 12px;">
If you have questions, contact us at support@banklingo.app
</p>
</div>
`,
data: {
customerName: context.customerName,
accountNumber: context.accountNumber,
balance: $.format.currency(context.initialBalance),
bonusEligible: context.initialBalance >= 10000,
bonusAmount: 500
}
}
});
// Send as HTML email
doCmd('SendMailCommand', {
Data: {
email: [context.email],
subject: 'Welcome to BankLingo',
message: htmlContent.data.html
}
});
Example 2: Using Pre-Registered Template (templateId)
Step 1: Create HTML template in database:
doCmd('CreateHtmlTemplateDefinitiionCommand', {
Data: {
name: 'loan-approval-email',
template: `
<div style="font-family: Arial;">
<h2>Loan Application Status</h2>
<p>Dear {{customerName}},</p>
{{#if approved}}
<div style="background: #4caf50; color: white; padding: 15px;">
<h3>✅ Loan Approved!</h3>
<p>Amount: ₦{{loanAmount}}</p>
<p>Interest Rate: {{interestRate}}%</p>
<p>Tenure: {{tenure}} months</p>
</div>
{{/if}}
{{#if rejected}}
<div style="background: #f44336; color: white; padding: 15px;">
<h3>❌ Loan Rejected</h3>
<p>Reason: {{rejectionReason}}</p>
</div>
{{/if}}
</div>
`,
description: 'Template for loan approval/rejection emails'
}
});
Step 2: Use template in process:
var htmlContent = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'loan-approval-email', // ⭐ Use templateId instead of inline template
data: {
customerName: context.customerName,
approved: context.loanStatus === 'approved',
rejected: context.loanStatus === 'rejected',
loanAmount: $.format.currency(context.loanAmount),
interestRate: context.interestRate,
tenure: context.tenure,
rejectionReason: context.rejectionReason
}
}
});
// Send email
doCmd('SendMailCommand', {
Data: {
email: [context.customerEmail],
subject: 'Loan Application Update',
message: htmlContent.data.html
}
});
Example 3: Generate Report Preview with Loops
var reportHtml = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'monthly-transaction-report',
data: {
month: context.month,
year: context.year,
customerName: context.customerName,
totalTransactions: context.transactions.length,
totalAmount: $.format.currency(context.totalAmount),
transactions: context.transactions.map(t => ({
date: $.format.date(t.date),
description: t.description,
amount: $.format.currency(t.amount),
type: t.type,
balance: $.format.currency(t.balance)
}))
}
}
});
// Store for display
context.reportPreview = reportHtml.data.html;
Example 4: Conditional Content
var emailHtml = doCmd('RenderHtmlCommand', {
Data: {
template: `
<div>
<h2>Account Alert</h2>
{{#if lowBalance}}
<div style="background: #fff3cd; padding: 10px;">
⚠️ Your balance is low: ₦{{balance}}
</div>
{{/if}}
{{#if overdraft}}
<div style="background: #f8d7da; padding: 10px;">
❌ Your account is overdrawn by ₦{{overdraftAmount}}
</div>
{{/if}}
{{#if recentDeposit}}
<div style="background: #d4edda; padding: 10px;">
✅ Recent deposit of ₦{{depositAmount}} received
</div>
{{/if}}
<p>Current Balance: <strong>₦{{balance}}</strong></p>
</div>
`,
data: {
balance: context.accountBalance,
lowBalance: context.accountBalance < 1000,
overdraft: context.accountBalance < 0,
overdraftAmount: Math.abs(context.accountBalance),
recentDeposit: context.lastTransactionType === 'credit',
depositAmount: context.lastTransactionAmount
}
}
});
Benefits of Using templateId
✅ Reusability: Define template once, use in multiple processes
✅ Maintainability: Update template in one place
✅ Version Control: Track template changes over time
✅ Cleaner Code: Separates presentation from logic
✅ Centralized Management: All templates in database
Error Handling
Template Not Found
{
"isSuccessful": false,
"message": "HTML template with ID 'welcome-email' not found.",
"data": {
"error": "Template not found",
"templateId": "welcome-email"
}
}
Missing Parameter
{
"isSuccessful": false,
"message": "Either 'template' or 'templateId' is required and must be a non-empty string.",
"data": {
"error": "Missing template or templateId"
}
}
Template Too Large
{
"isSuccessful": false,
"message": "Template size exceeds maximum allowed size of 1048576 bytes.",
"data": {
"error": "Template too large",
"maxSize": 1048576
}
}
Best Practices
1. Use templateId for Production
// ✅ Good: Use templateId for production templates
doCmd('RenderHtmlCommand', {
Data: {
templateId: 'customer-welcome-email',
data: context
}
});
// ⚠️ Avoid: Inline templates for complex HTML (hard to maintain)
doCmd('RenderHtmlCommand', {
Data: {
template: '<div>...500 lines of HTML...</div>',
data: context
}
});
2. Validate Data Before Rendering
// Ensure all required fields exist
if (!context.customerName || !context.email) {
throw new Error('Missing required customer data');
}
var html = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'welcome-email',
data: context
}
});
3. Format Data Appropriately
// Format data before passing to template
var html = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'loan-summary',
data: {
customerName: context.customerName,
loanAmount: $.format.currency(context.loanAmount), // ✅ Formatted
date: $.format.date(context.applicationDate), // ✅ Formatted
status: context.status.toUpperCase() // ✅ Formatted
}
}
});
4. Test Templates Before Deployment
// Test template rendering with sample data
var testHtml = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'new-template',
data: {
name: 'Test User',
email: 'test@example.com',
amount: 10000
}
}
});
if (!testHtml.isSuccessful) {
throw new Error('Template test failed: ' + testHtml.message);
}
Template Limits
| Limit | Value |
|---|---|
| Maximum Template Size | 1 MB (1,048,576 bytes) |
| Maximum Recursion Depth | 50 levels |
| Supported Syntax | Handlebars-style ({{variable}}) |
Related Commands
- SendMailCommand - Send HTML emails
- SendSMSCommand - Send SMS messages
- DocumentRenderV2Command - Generate Word/PDF documents
- CreateHtmlTemplateDefinitiionCommand - Create HTML templates
See Also
Best Practices
✅ Do's
- Use template variables for dynamic content
- Sanitize user input to prevent XSS
- Test HTML across different browsers/email clients
- Use inline CSS for email templates
❌ Don'ts
- Don't include JavaScript in email templates
- Don't forget to escape special characters
- Don't use complex CSS for emails
Version History
- v1.0 - Initial release
- v1.1 - Added template caching
- v1.2 - Improved variable binding