CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
view.js206 linesDownload Raw Back to lib
1/*!2 * express3 * Copyright(c) 2009-2013 TJ Holowaychuk4 * Copyright(c) 2013 Roman Shtylman5 * Copyright(c) 2014-2015 Douglas Christopher Wilson6 * MIT Licensed7 */8 9'use strict';10 11/**12 * Module dependencies.13 * @private14 */15 16var debug = require('debug')('express:view');17var path = require('node:path');18var fs = require('node:fs');19 20/**21 * Module variables.22 * @private23 */24 25var dirname = path.dirname;26var basename = path.basename;27var extname = path.extname;28var join = path.join;29var resolve = path.resolve;30 31/**32 * Module exports.33 * @public34 */35 36module.exports = View;37 38/**39 * Initialize a new `View` with the given `name`.40 *41 * Options:42 *43 *   - `defaultEngine` the default template engine name44 *   - `engines` template engine require() cache45 *   - `root` root path for view lookup46 *47 * @param {string} name48 * @param {object} options49 * @public50 */51 52function View(name, options) {53  var opts = options || {};54 55  this.defaultEngine = opts.defaultEngine;56  this.ext = extname(name);57  this.name = name;58  this.root = opts.root;59 60  if (!this.ext && !this.defaultEngine) {61    throw new Error('No default engine was specified and no extension was provided.');62  }63 64  var fileName = name;65 66  if (!this.ext) {67    // get extension from default engine name68    this.ext = this.defaultEngine[0] !== '.'69      ? '.' + this.defaultEngine70      : this.defaultEngine;71 72    fileName += this.ext;73  }74 75  if (!opts.engines[this.ext]) {76    // load engine77    var mod = this.ext.slice(1)78    debug('require "%s"', mod)79 80    // default engine export81    var fn = require(mod).__express82 83    if (typeof fn !== 'function') {84      throw new Error('Module "' + mod + '" does not provide a view engine.')85    }86 87    opts.engines[this.ext] = fn88  }89 90  // store loaded engine91  this.engine = opts.engines[this.ext];92 93  // lookup path94  this.path = this.lookup(fileName);95}96 97/**98 * Lookup view by the given `name`99 *100 * @param {string} name101 * @private102 */103 104View.prototype.lookup = function lookup(name) {105  var path;106  var roots = [].concat(this.root);107 108  debug('lookup "%s"', name);109 110  for (var i = 0; i < roots.length && !path; i++) {111    var root = roots[i];112 113    // resolve the path114    var loc = resolve(root, name);115    var dir = dirname(loc);116    var file = basename(loc);117 118    // resolve the file119    path = this.resolve(dir, file);120  }121 122  return path;123};124 125/**126 * Render with the given options.127 *128 * @param {object} options129 * @param {function} callback130 * @private131 */132 133View.prototype.render = function render(options, callback) {134  var sync = true;135 136  debug('render "%s"', this.path);137 138  // render, normalizing sync callbacks139  this.engine(this.path, options, function onRender() {140    if (!sync) {141      return callback.apply(this, arguments);142    }143 144    // copy arguments145    var args = new Array(arguments.length);146    var cntx = this;147 148    for (var i = 0; i < arguments.length; i++) {149      args[i] = arguments[i];150    }151 152    // force callback to be async153    return process.nextTick(function renderTick() {154      return callback.apply(cntx, args);155    });156  });157 158  sync = false;159};160 161/**162 * Resolve the file within the given directory.163 *164 * @param {string} dir165 * @param {string} file166 * @private167 */168 169View.prototype.resolve = function resolve(dir, file) {170  var ext = this.ext;171 172  // <path>.<ext>173  var path = join(dir, file);174  var stat = tryStat(path);175 176  if (stat && stat.isFile()) {177    return path;178  }179 180  // <path>/index.<ext>181  path = join(dir, basename(file, ext), 'index' + ext);182  stat = tryStat(path);183 184  if (stat && stat.isFile()) {185    return path;186  }187};188 189/**190 * Return a stat, maybe.191 *192 * @param {string} path193 * @return {fs.Stats}194 * @private195 */196 197function tryStat(path) {198  debug('stat "%s"', path);199 200  try {201    return fs.statSync(path);202  } catch (e) {203    return undefined;204  }205}206