MACHIN
This commit is contained in:
		
							
								
								
									
										331
									
								
								32/node_modules/hbs/lib/hbs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								32/node_modules/hbs/lib/hbs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,331 @@
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
var path = require('path');
 | 
			
		||||
var walk = require('walk').walk;
 | 
			
		||||
 | 
			
		||||
var async = require('./async');
 | 
			
		||||
 | 
			
		||||
function Instance(handlebars) {
 | 
			
		||||
  if (!(this instanceof Instance)) {
 | 
			
		||||
    return new Instance(handlebars);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // expose handlebars, allows users to use their versions
 | 
			
		||||
  // by overriding this early in their apps
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  self.handlebars = handlebars || require('handlebars').create();
 | 
			
		||||
 | 
			
		||||
  // cache for templates, express 3.x doesn't do this for us
 | 
			
		||||
  self.cache = {};
 | 
			
		||||
 | 
			
		||||
  self.__express = middleware.bind(this);
 | 
			
		||||
 | 
			
		||||
  // queue for partials registration
 | 
			
		||||
  self._queue = null
 | 
			
		||||
 | 
			
		||||
  // DEPRECATED, kept for backwards compatibility
 | 
			
		||||
  self.SafeString = this.handlebars.SafeString;
 | 
			
		||||
  self.Utils = this.handlebars.Utils;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// express 3.x template engine compliance
 | 
			
		||||
function middleware(filename, options, cb) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  if (self._queue) {
 | 
			
		||||
    self._queue.push(middleware.bind.apply(middleware, [this].concat(Array.prototype.slice.call(arguments))))
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var cache = self.cache;
 | 
			
		||||
  var handlebars = self.handlebars;
 | 
			
		||||
 | 
			
		||||
  self.async = async();
 | 
			
		||||
 | 
			
		||||
  // grab extension from filename
 | 
			
		||||
  // if we need a layout, we will look for one matching out extension
 | 
			
		||||
  var extension = path.extname(filename);
 | 
			
		||||
 | 
			
		||||
  // Default handlebars runtime options
 | 
			
		||||
  var handlebarsOpts = {
 | 
			
		||||
    allowProtoMethodsByDefault: true,
 | 
			
		||||
    allowProtoPropertiesByDefault: true
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If passing the locals as data, create the handlebars options object now
 | 
			
		||||
  if (self.__localsAsData) {
 | 
			
		||||
    handlebarsOpts.data = options._locals
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // render the original file
 | 
			
		||||
  // cb(err, str)
 | 
			
		||||
  function render_file(locals, cb) {
 | 
			
		||||
    // cached?
 | 
			
		||||
    var template = cache[filename];
 | 
			
		||||
    if (template) {
 | 
			
		||||
      try {
 | 
			
		||||
        var res = template(locals, handlebarsOpts)
 | 
			
		||||
        self.async.done(function (values) {
 | 
			
		||||
          Object.keys(values).forEach(function (id) {
 | 
			
		||||
            res = res.replace(id, values[id])
 | 
			
		||||
          })
 | 
			
		||||
 | 
			
		||||
          cb(null, res)
 | 
			
		||||
        })
 | 
			
		||||
      } catch (err) {
 | 
			
		||||
        cb(prependFilenameToError(filename, err))
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fs.readFile(filename, 'utf8', function(err, str){
 | 
			
		||||
      if (err) {
 | 
			
		||||
        return cb(err);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var template = handlebars.compile(str);
 | 
			
		||||
      if (locals.cache) {
 | 
			
		||||
        cache[filename] = template;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        var res = template(locals, handlebarsOpts);
 | 
			
		||||
        self.async.done(function(values) {
 | 
			
		||||
          Object.keys(values).forEach(function(id) {
 | 
			
		||||
            res = res.replace(id, values[id]);
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          cb(null, res);
 | 
			
		||||
        });
 | 
			
		||||
      } catch (err) {
 | 
			
		||||
        cb(prependFilenameToError(filename, err))
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // render with a layout
 | 
			
		||||
  function render_with_layout (filename, template, locals, cb) {
 | 
			
		||||
    render_file(locals, function(err, str) {
 | 
			
		||||
      if (err) {
 | 
			
		||||
        return cb(err);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      locals.body = str;
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        var res = template(locals, handlebarsOpts)
 | 
			
		||||
        self.async.done(function (values) {
 | 
			
		||||
          Object.keys(values).forEach(function (id) {
 | 
			
		||||
            res = res.replace(id, values[id])
 | 
			
		||||
          })
 | 
			
		||||
 | 
			
		||||
          cb(null, res)
 | 
			
		||||
        })
 | 
			
		||||
      } catch (err) {
 | 
			
		||||
        cb(prependFilenameToError(filename, err))
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var layout = options.layout;
 | 
			
		||||
 | 
			
		||||
  // user did not specify a layout in the locals
 | 
			
		||||
  // check global layout state
 | 
			
		||||
  if (layout === undefined && options.settings && options.settings['view options']) {
 | 
			
		||||
    layout = options.settings['view options'].layout;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // user explicitly request no layout
 | 
			
		||||
  // either by specifying false for layout: false in locals
 | 
			
		||||
  // or by settings the false view options
 | 
			
		||||
  if (layout !== undefined && !layout) {
 | 
			
		||||
    return render_file(options, cb);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var view_dirs = options.settings.views;
 | 
			
		||||
 | 
			
		||||
  var layout_filename = [].concat(view_dirs).map(function (view_dir) {
 | 
			
		||||
    var view_path = path.join(view_dir, layout || 'layout');
 | 
			
		||||
 | 
			
		||||
    if (!path.extname(view_path)) {
 | 
			
		||||
      view_path += extension;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return view_path;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  for (var i = 0; i < layout_filename.length; i++) {
 | 
			
		||||
    var layout_template = cache[layout_filename[i]]
 | 
			
		||||
 | 
			
		||||
    if (layout_template) {
 | 
			
		||||
      return render_with_layout(layout_filename[i], layout_template, options, cb)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO check if layout path has .hbs extension
 | 
			
		||||
 | 
			
		||||
  function prependFilenameToError (filename, err) {
 | 
			
		||||
    // prepend to the message
 | 
			
		||||
    if (typeof err.message === 'string') {
 | 
			
		||||
      err.message = filename + ': ' + err.message
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return err
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function cacheAndCompile(filename, str) {
 | 
			
		||||
    var layout_template = handlebars.compile(str);
 | 
			
		||||
    if (options.cache) {
 | 
			
		||||
      cache[filename] = layout_template;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render_with_layout(filename, layout_template, options, cb)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function tryReadFileAndCache(templates) {
 | 
			
		||||
    var template = templates.shift();
 | 
			
		||||
 | 
			
		||||
    fs.readFile(template, 'utf8', function(err, str) {
 | 
			
		||||
      if (err) {
 | 
			
		||||
        if (layout && templates.length === 0) {
 | 
			
		||||
          // Only return error if user explicitly asked for layout.
 | 
			
		||||
          return cb(err);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (templates.length > 0) {
 | 
			
		||||
          return tryReadFileAndCache(templates);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return render_file(options, cb);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      cacheAndCompile(template, str);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  tryReadFileAndCache(layout_filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// express 2.x template engine compliance
 | 
			
		||||
Instance.prototype.compile = function (str) {
 | 
			
		||||
  if (typeof str !== 'string') {
 | 
			
		||||
    return str;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var template = this.handlebars.compile(str);
 | 
			
		||||
  return function (locals) {
 | 
			
		||||
    return template(locals, {
 | 
			
		||||
      helpers: locals.blockHelpers,
 | 
			
		||||
      partials: null,
 | 
			
		||||
      data: null
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Instance.prototype.registerHelper = function () {
 | 
			
		||||
  this.handlebars.registerHelper.apply(this.handlebars, arguments);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Instance.prototype.registerPartial = function () {
 | 
			
		||||
  this.handlebars.registerPartial.apply(this.handlebars, arguments);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Instance.prototype.registerPartials = function (directory, options, done) {
 | 
			
		||||
  var self = this
 | 
			
		||||
 | 
			
		||||
  if (this._queue) {
 | 
			
		||||
    self._queue.unshift(self.registerPartials.bind.apply(self.registerPartials,
 | 
			
		||||
      [this].concat(Array.prototype.slice.call(arguments))))
 | 
			
		||||
    return
 | 
			
		||||
  } else {
 | 
			
		||||
    self._queue = []
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var callback
 | 
			
		||||
  var handlebars = self.handlebars
 | 
			
		||||
  var opts = options || {}
 | 
			
		||||
 | 
			
		||||
  if (done || typeof options !== 'function') {
 | 
			
		||||
    callback = done
 | 
			
		||||
  } else {
 | 
			
		||||
    callback = options
 | 
			
		||||
    opts = {}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var rename = opts.rename !== undefined ? opts.rename : function (name) {
 | 
			
		||||
    return name.replace(/\-/g, '_')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var w = walk(directory)
 | 
			
		||||
  w.on('file', function (root, stat, done) {
 | 
			
		||||
    var filepath = path.join(root, stat.name)
 | 
			
		||||
    var isValidTemplate = /\.(html|hbs)$/.test(filepath);
 | 
			
		||||
 | 
			
		||||
    if (!isValidTemplate) {
 | 
			
		||||
      return done(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fs.readFile(filepath, 'utf8', function(err, data) {
 | 
			
		||||
      if (!err) {
 | 
			
		||||
        var extname = path.extname(filepath)
 | 
			
		||||
        var name = path.relative(directory, filepath)
 | 
			
		||||
          .slice(0, -(extname.length))
 | 
			
		||||
          .replace(/\\/g, '/')
 | 
			
		||||
 | 
			
		||||
        handlebars.registerPartial(rename(name).replace(/ /g, '_'), data)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      done(err);
 | 
			
		||||
    });
 | 
			
		||||
  })
 | 
			
		||||
  w.on('end', function () {
 | 
			
		||||
    if (self._queue) {
 | 
			
		||||
      var q = self._queue
 | 
			
		||||
 | 
			
		||||
      self._queue = null
 | 
			
		||||
 | 
			
		||||
      for (var i = 0; i < q.length; i++) {
 | 
			
		||||
        q[i]()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  if (callback) {
 | 
			
		||||
    w.on('end', callback)
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Instance.prototype.registerAsyncHelper = function(name, fn) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  self.handlebars.registerHelper(name, function() {
 | 
			
		||||
    return self.async.resolve(fn.bind(this), arguments)
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Instance.prototype.localsAsTemplateData = function(app) {
 | 
			
		||||
  // Set a flag to indicate we should pass locals as data
 | 
			
		||||
  this.__localsAsData = true;
 | 
			
		||||
 | 
			
		||||
  app.render = (function(render) {
 | 
			
		||||
    return function(view, options, callback) {
 | 
			
		||||
      if (typeof options === "function") {
 | 
			
		||||
        callback = options;
 | 
			
		||||
        options = {};
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Mix response.locals (options._locals) with app.locals (this.locals)
 | 
			
		||||
      options._locals = options._locals || {};
 | 
			
		||||
      for (var key in this.locals) {
 | 
			
		||||
        options._locals[key] = this.locals[key];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return render.call(this, view, options, callback);
 | 
			
		||||
    };
 | 
			
		||||
  })(app.render);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = new Instance();
 | 
			
		||||
module.exports.create = function(handlebars) {
 | 
			
		||||
  return new Instance(handlebars);
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user