最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I render a static HTML file with Handlebars on a Nodejs server? - Stack Overflow

programmeradmin2浏览0评论

I have e 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 piler 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.prepile(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);

I have e 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 piler 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.prepile(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);
Share Improve this question asked Feb 6, 2018 at 2:01 WaterlessStrawWaterlessStraw 6733 gold badges9 silver badges20 bronze badges 4
  • If I follow properly, what you are describing is to render the initial page on the server and send the HTML down to the client and then rerender the whole page in the client when data is updated. That seems overly plicated as you have to support two full render paths and pieces of code. I'd suggest you either render initially server-side and then insert updates/modifications surgically in the client (rather than rerendering the whole page) or always render in the client, both initially and when you get updates. – jfriend00 Commented Feb 6, 2018 at 2:47
  • You can save the initial ajax call by putting the data into the initial page as Javascript data in a <script> tag and your initial render can use the data from there. Then, there's only one type of rendering ever. When the page is first rendered, it is rendered from the Javascript data went with the page. When the page is re-rendered later, the same rendering mechanism is used, but it gets the data from another source (Ajax call or webSocket message presumably). – jfriend00 Commented Feb 6, 2018 at 2:50
  • Also, why would your server ever be writing test.html to the file system? You can't do that (render a hard-code filename as part of a request handler) for a server that handles more than one user. Multiple requests from multiple users will tromp on each other's data. Normally, you would render into a Javascript string (which you already do) and then send that string as the http response. No need to put the data into the file system. – jfriend00 Commented Feb 6, 2018 at 2:52
  • @jfriend00 I think I may have just worded this question poorly. I would like to generate a static HTML file from my handlebars template. Then the server would serve the static HTML file without any of the handlebars templating. It would generate this HTML file once, then serve this HTML file until it creates a new one. Hopefully this makes more sense? – WaterlessStraw Commented Feb 6, 2018 at 3:16
Add a ment  | 

1 Answer 1

Reset to default 13

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.pile(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 piled = _.template(source);
  return piled(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.

发布评论

评论列表(0)

  1. 暂无评论