WaterlessStraw
WaterlessStraw

Reputation: 673

How can I render a static HTML file with Handlebars on a Nodejs server?

I have come across plenty of resources online for this but haven't been able to find one that is straight forward enough for me to understand.

At the moment, I have multiple massive <script> tags in an HTML document that has handlebars content. The server sends this HTML document to the client where the client then renders the page with data from an AJAX call. I'd like to move this entire process server-side so that all the server has to do is send a static file and re-render the page when data is updated. Data changes a few times per day - which is why it isn't hard coded in and I would like to run the handlebars compiler on the HTML document when data is updated.

Is it possible to simply put the HTML document with handlebars templating in <script> tags through a function to generate a new HTML file with data filled in?

Here is the code I have within my app.js file that is runned the Node server that does not do what I want it to:

function registerHelpers(callback){
  Handlebars.registerHelper('equal', function(lvalue, rvalue, options) {
    if (arguments.length < 3)
        throw new Error("Handlebars Helper equal needs 2 parameters");
    if( lvalue!=rvalue ) {
        return options.inverse(this);
    } else {
        return options.fn(this);
    }

  });

  Handlebars.registerHelper('trim', function(text) {
    text = text.replace(/ /g, '');
    return new Handlebars.SafeString(text);
  });

  callback();
}

function buildHomePage() {
  var source = require(__dirname + '/public/home.handlebars');
  var template = Handlebars.precompile(source);
  var collection = db.get('datalist'); //Monk call to MongoDB
  collection.find({}, function (err, docs){
    var result = template(docs);
    console.log(result)
    var fs = require('fs');
        fs.writeFile("test.html", result, function(err) {
        if(err) {
          console.log(err);
        }
    });
  });
};

registerHelpers(buildHomePage);

Upvotes: 5

Views: 10177

Answers (1)

Alex M
Alex M

Reputation: 537

The following can render handlebars to static html. Run node example.js. You may need to run npm install --save handlebars prior.

var fs = require('fs');
var Handlebars = require('handlebars');

function render(filename, data)
{
  var source   = fs.readFileSync(filename,'utf8').toString();
  var template = Handlebars.compile(source);
  var output = template(data);
  return output;
}

var data = JSON.parse(fs.readFileSync("./data/strings.json", 'utf8'));

var result = render('./templates/somefile.html', data);

console.log(result);

If your handlebars templates are simple, with only string replacement, you can do this with underscore.js. Assume this example is named 'generate.js'

var fs = require('fs');
var _ = require('underscore');
_.templateSettings.interpolate = /\{\{(.+?)\}\}/g;

function render(filename, data)
{
  var source   = fs.readFileSync(filename,'utf8').toString();
  var compiled = _.template(source);
  return compiled(data);
}

var data = JSON.parse(fs.readFileSync("./data/strings.json", 'utf8'));

var result = render('./templates/somefile.html', data);

console.log(result);

Then run node generate.js to output the rendered template to the console. You may need to do npm install --save underscore prior.

Upvotes: 13

Related Questions