arnaucube
arnaucube/socketioMEANseedPublic Self-hosted repository
socketioMEANseed/server/node_modules/express/lib/view.js
server/node_modules/express/lib/view.jsRaw
  1/**
  2 * Module dependencies.
  3 */
  4
  5var debug = require('debug')('express:view');
  6var path = require('path');
  7var fs = require('fs');
  8var utils = require('./utils');
  9
 10/**
 11 * Module variables.
 12 * @private
 13 */
 14
 15var dirname = path.dirname;
 16var basename = path.basename;
 17var extname = path.extname;
 18var join = path.join;
 19var resolve = path.resolve;
 20
 21/**
 22 * Expose `View`.
 23 */
 24
 25module.exports = View;
 26
 27/**
 28 * Initialize a new `View` with the given `name`.
 29 *
 30 * Options:
 31 *
 32 *   - `defaultEngine` the default template engine name
 33 *   - `engines` template engine require() cache
 34 *   - `root` root path for view lookup
 35 *
 36 * @param {String} name
 37 * @param {Object} options
 38 * @api private
 39 */
 40
 41function View(name, options) {
 42  options = options || {};
 43  this.name = name;
 44  this.root = options.root;
 45  var engines = options.engines;
 46  this.defaultEngine = options.defaultEngine;
 47  var ext = this.ext = extname(name);
 48  if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
 49  if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
 50  this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
 51  this.path = this.lookup(name);
 52}
 53
 54/**
 55 * Lookup view by the given `name`
 56 *
 57 * @param {String} name
 58 * @return {String}
 59 * @api private
 60 */
 61
 62View.prototype.lookup = function lookup(name) {
 63  var path;
 64  var roots = [].concat(this.root);
 65
 66  debug('lookup "%s"', name);
 67
 68  for (var i = 0; i < roots.length && !path; i++) {
 69    var root = roots[i];
 70
 71    // resolve the path
 72    var loc = resolve(root, name);
 73    var dir = dirname(loc);
 74    var file = basename(loc);
 75
 76    // resolve the file
 77    path = this.resolve(dir, file);
 78  }
 79
 80  return path;
 81};
 82
 83/**
 84 * Render with the given `options` and callback `fn(err, str)`.
 85 *
 86 * @param {Object} options
 87 * @param {Function} fn
 88 * @api private
 89 */
 90
 91View.prototype.render = function render(options, fn) {
 92  debug('render "%s"', this.path);
 93  this.engine(this.path, options, fn);
 94};
 95
 96/**
 97 * Resolve the file within the given directory.
 98 *
 99 * @param {string} dir
100 * @param {string} file
101 * @private
102 */
103
104View.prototype.resolve = function resolve(dir, file) {
105  var ext = this.ext;
106  var path;
107  var stat;
108
109  // <path>.<ext>
110  path = join(dir, file);
111  stat = tryStat(path);
112
113  if (stat && stat.isFile()) {
114    return path;
115  }
116
117  // <path>/index.<ext>
118  path = join(dir, basename(file, ext), 'index' + ext);
119  stat = tryStat(path);
120
121  if (stat && stat.isFile()) {
122    return path;
123  }
124};
125
126/**
127 * Return a stat, maybe.
128 *
129 * @param {string} path
130 * @return {fs.Stats}
131 * @private
132 */
133
134function tryStat(path) {
135  debug('stat "%s"', path);
136
137  try {
138    return fs.statSync(path);
139  } catch (e) {
140    return undefined;
141  }
142}