Express Template Helpers
Introduction
Template helpers are functions that you can use within your template files to transform data or perform operations that make your views more dynamic. They act as a bridge between your controllers and views, allowing you to keep your templates clean and your logic organized.
In Express applications, different templating engines (like EJS, Handlebars, Pug) provide different ways to implement these helpers. They're particularly useful when you need to:
- Format data (dates, currency, text)
- Perform conditional logic that's too complex for template syntax
- Create reusable blocks of template code
- Implement functionality that would otherwise clutter your templates
In this lesson, we'll explore how to create and use template helpers in Express applications with various templating engines.
Understanding Template Helpers
Template helpers are essentially JavaScript functions that you can call from within your template files. They can take parameters, perform operations, and return values that get rendered in the final HTML.
Why Use Template Helpers?
- Separation of concerns: Keep complex logic out of your templates
- Code reusability: Define a function once and use it across multiple templates
- Cleaner templates: Make your templates more readable by abstracting away complex operations
- Maintainable code: Easier to update functionality in a central location
Template Helpers in Different Engines
Let's look at how to implement helpers in three popular templating engines: Handlebars, EJS, and Pug.
Handlebars Helpers
Handlebars is particularly good at using helpers, as they're a core part of its design.
Basic Setup
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
// Initialize Handlebars
const hbs = exphbs.create({
// Define your helpers here
helpers: {
// Format a date
formatDate: function(date) {
return new Date(date).toLocaleDateString();
},
// Capitalize a string
capitalize: function(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
}
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
Using Helpers in Templates
Input Data:
{
title: "learning express templates",
publishDate: "2023-05-15",
content: "This is an article about Express templates."
}
Output HTML:
<div class="article">
<h2>Learning express templates</h2>
<p>Published on: 5/15/2023</p>
<div class="content">This is an article about Express templates.</div>
</div>
EJS Helpers
EJS doesn't have built-in support for helpers like Handlebars, but you can pass helper functions to your templates through the render method.
Basic Setup
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
// Create helper functions
const helpers = {
formatDate: function(date) {
return new Date(date).toLocaleDateString();
},
capitalize: function(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
};
// Use middleware to make helpers available to all templates
app.use((req, res, next) => {
res.locals.helpers = helpers;
next();
});
Using Helpers in Templates
<div class="article">
<h2><%= helpers.capitalize(title) %></h2>
<p>Published on: <%= helpers.formatDate(publishDate) %></p>
<div class="content"><%= content %></div>
</div>
Pug Helpers
Like EJS, Pug doesn't have a built-in helper system, but you can pass helper functions through locals.
Basic Setup
const express = require('express');
const app = express();
app.set('view engine', 'pug');
// Create helper functions
const helpers = {
formatDate: function(date) {
return new Date(date).toLocaleDateString();
},
capitalize: function(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
};
// Make helpers available to all templates
app.use((req, res, next) => {
res.locals.helpers = helpers;
next();
});
Using Helpers in Templates
div.article
h2= helpers.capitalize(title)
p Published on: #{helpers.formatDate(publishDate)}
div.content= content
Creating Advanced Helpers
Let's create some more useful template helpers for real-world applications.
Currency Formatter
helpers.formatCurrency = function(amount, currency = 'USD') {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency
}).format(amount);
};
Usage in template:
Truncate Text
helpers.truncate = function(text, length = 100) {
if (text.length <= length) return text;
return text.substring(0, length) + '...';
};
Usage:
Conditional Class Helper
helpers.ifEqual = function(a, b, options) {
if (a === b) {
return options.fn(this);
}
return options.inverse(this);
};
Usage in Handlebars:
List Iterator Helper
helpers.list = function(items, options) {
let html = '<ul>';
for (let i = 0; i < items.length; i++) {
html += '<li>' + options.fn(items[i]) + '</li>';
}
html += '</ul>';
return html;
};
Usage:
Real-world Example: Blog Template
Let's see a more comprehensive example of using template helpers in a blog application:
Setup the Helpers
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
// Initialize Handlebars with custom helpers
const hbs = exphbs.create({
helpers: {
formatDate: function(date) {
const options = { year: 'numeric', month: 'long', day: 'numeric' };
return new Date(date).toLocaleDateString('en-US', options);
},
excerpt: function(content, length = 150) {
if (content.length <= length) return content;
return content.substring(0, length) + '...';
},
timeToRead: function(content) {
// Average reading speed: 200 words per minute
const wordsPerMinute = 200;
const words = content.trim().split(/\s+/).length;
const minutes = Math.ceil(words / wordsPerMinute);
return minutes + ' min read';
},
toLowerCase: function(text) {
return text.toLowerCase();
},
tagBadgeClass: function(tag) {
// Return different badge classes based on tag
const classes = {
javascript: 'badge-warning',
node: 'badge-success',
express: 'badge-info',
default: 'badge-secondary'
};
return classes[tag.toLowerCase()] || classes.default;
}
}
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
Using in Blog Post Template
Example Data:
const post = {
title: "Getting Started with Express Template Helpers",
publishDate: "2023-09-15",
author: "Jane Developer",
tags: ["JavaScript", "Express", "Node"],
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam euismod, nisl eget aliquam ultricies, nunc nisl ultricies nunc, quis ultricies nisl nisl eget aliquam ultricies, nunc nisl ultricies nunc, quis ultricies nisl..."
// (imagine this is much longer)
};
res.render('blog/post', { post, summary: true });
Best Practices
- Keep helpers simple and focused: Each helper should do one thing well.
- Document your helpers: Add comments to explain what each helper does, its parameters, and return values.
- Organize helpers by category: As your application grows, consider organizing helpers into categories.
- Test helpers separately: Write unit tests for your helper functions.
- Handle errors gracefully: Make sure your helpers don't throw errors that could break the template rendering.
- Be mindful of performance: Complex operations in helpers can slow down rendering.
Creating Organized Helper Files
For larger applications, it's good practice to organize your helpers into separate files:
// helpers/dateHelpers.js
module.exports = {
formatDate: function(date) {
return new Date(date).toLocaleDateString();
},
timeAgo: function(date) {
// Implementation for relative time
}
};
// helpers/textHelpers.js
module.exports = {
capitalize: function(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
},
truncate: function(text, length) {
// Implementation for text truncation
}
};
// index.js (combine all helpers)
const dateHelpers = require('./dateHelpers');
const textHelpers = require('./textHelpers');
module.exports = {
...dateHelpers,
...textHelpers
};
Then register them with your templating engine:
const allHelpers = require('./helpers');
const hbs = exphbs.create({
helpers: allHelpers
});
app.engine('handlebars', hbs.engine);
Summary
Template helpers are powerful tools for enhancing your Express templates. They allow you to:
- Keep your templates clean and focused on presentation
- Reuse formatting and logic across multiple views
- Handle complex operations outside of your templates
- Create a more maintainable codebase
Different templating engines have different approaches to implementing helpers, but the core concept remains the same: move complex logic into functions that can be called from your templates.
By mastering template helpers, you'll build more maintainable, readable, and flexible Express applications.
Additional Resources
Exercises
- Create a helper function that formats phone numbers (e.g., from "1234567890" to "(123) 456-7890").
- Build a pagination helper that generates pagination links based on the current page and total pages.
- Implement a "highlightSearch" helper that wraps search terms in HTML
<mark>
tags within a body of text. - Create a helper that generates a random placeholder image URL based on dimensions.
- Build a set of helpers for a e-commerce site that handle product pricing, discounts, and availability messages.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)