Skip to content

Instantly share code, notes, and snippets.

@crrobinson14
Created July 21, 2018 02:25
Show Gist options
  • Save crrobinson14/7a889498e8ca266fcdc98eff31488b5c to your computer and use it in GitHub Desktop.
Save crrobinson14/7a889498e8ca266fcdc98eff31488b5c to your computer and use it in GitHub Desktop.

EJS template rendering in ActionHero 19+

This example provides a proof of concept for simple EJS-based template rendering in ActionHero. Note that EJS is this author's favorite "simple" NodeJS template engine but it could easily be replaced with any other engine you wish.

Sample Usage

  1. Copy ejs.js to initializers/.
  2. Create a folder called templates/ and copy leaderboard.js there.
  3. Copy the sample 'getLeaderboard.js' action to actions/.

Once you do this, start or restart your local ActionHero service. Assuming you started it on port 3000, the following two URLs should now work:

http://localhost:3000/?action=getLeaderboard http://localhost:3000/?action=getLeaderboard&format=html

If format is not specified as HTML, standard JSON (API-style) is returned to the client as you would expect. If format is set to html, a template is rendered with the same data.

const { Initializer, api } = require('actionhero');
const ejs = require('ejs');
const ejsOptions = {
async: true,
};
const ejsMiddleware = {
name: 'EJS Template Renderer',
global: true,
priority: 1,
postProcessor: async data => {
const { template, templateData } = data.response;
if (template) {
data.toRender = false;
data.connection.setStatusCode(200);
data.connection.setHeader('Content-Type', 'text/html');
const rendered = await ejs.renderFile(`templates/${template}`, templateData || {}, ejsOptions);
data.connection.pipe(rendered);
}
}
};
module.exports = class Secrets extends Initializer {
constructor() {
super();
api.ejs = ejs;
this.name = 'EJS Template Rendering';
}
async initialize() {
api.actions.addMiddleware(ejsMiddleware);
}
};
const { Action } = require('actionhero');
const formatValidator = param => {
if (['html', 'json'].indexOf(param) === -1) {
throw new Error('Invalid format, must be "html" or "json".');
}
};
module.exports = class getLeaderboard extends Action {
constructor() {
super();
this.name = 'getLeaderboard';
this.description = 'Get the Leaderboard';
this.inputs = {
format: { required: false, validator: formatValidator, },
};
}
async run(data) {
const { format } = data.params;
const leaderboardData = [
{ id: 'abc123', name: 'Halle Berry', score: 45000 },
{ id: 'xyz123', name: 'Chuck Berry', score: 44999 },
{ id: '123xyz', name: 'Halley\'s Comet', score: 30000 },
{ id: '123abc', name: 'Halley\'s Comment', score: 20000 },
];
if (format === 'html') {
data.response.template = 'leaderboard.ejs';
data.response.templateData = { leaderboardData };
} else {
data.response.leaderboardData = leaderboardData;
}
}
};
<h1>Leaderboard</h1>
<% leaderboardData.forEach(function(leader){ %>
<div class="leader">
<span class="name"><%= leader.name %></span>
<span class="score"><%= leader.score %></span>
</div>
<% }); %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment