Skip to main content

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' }
}
});
var result = doCmd('RenderHtmlCommand', {
Data: {
templateId: 'welcome-email-template',
data: { name: 'John Doe', accountNumber: '1234567890' }
}
});

Parameters

ParameterTypeRequiredDescription
Data.templatestringYes*HTML template string with placeholders
Data.templateIdstringYes*Name of pre-registered HTML template in database
Data.dataobjectYesData 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 templateId for 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

LimitValue
Maximum Template Size1 MB (1,048,576 bytes)
Maximum Recursion Depth50 levels
Supported SyntaxHandlebars ({{variable}})

<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

LimitValue
Maximum Template Size1 MB (1,048,576 bytes)
Maximum Recursion Depth50 levels
Supported SyntaxHandlebars-style ({{variable}})

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