github.com/solo-io/unik@v0.0.0-20190717152701-a58d3e8e33b7/docs/examples/example-nodejs-fileserver/node_modules/express/lib/view.js (about)

     1  /*!
     2   * express
     3   * Copyright(c) 2009-2013 TJ Holowaychuk
     4   * Copyright(c) 2013 Roman Shtylman
     5   * Copyright(c) 2014-2015 Douglas Christopher Wilson
     6   * MIT Licensed
     7   */
     8  
     9  'use strict';
    10  
    11  /**
    12   * Module dependencies.
    13   * @private
    14   */
    15  
    16  var debug = require('debug')('express:view');
    17  var path = require('path');
    18  var fs = require('fs');
    19  var utils = require('./utils');
    20  
    21  /**
    22   * Module variables.
    23   * @private
    24   */
    25  
    26  var dirname = path.dirname;
    27  var basename = path.basename;
    28  var extname = path.extname;
    29  var join = path.join;
    30  var resolve = path.resolve;
    31  
    32  /**
    33   * Module exports.
    34   * @public
    35   */
    36  
    37  module.exports = View;
    38  
    39  /**
    40   * Initialize a new `View` with the given `name`.
    41   *
    42   * Options:
    43   *
    44   *   - `defaultEngine` the default template engine name
    45   *   - `engines` template engine require() cache
    46   *   - `root` root path for view lookup
    47   *
    48   * @param {string} name
    49   * @param {object} options
    50   * @public
    51   */
    52  
    53  function View(name, options) {
    54    var opts = options || {};
    55  
    56    this.defaultEngine = opts.defaultEngine;
    57    this.ext = extname(name);
    58    this.name = name;
    59    this.root = opts.root;
    60  
    61    if (!this.ext && !this.defaultEngine) {
    62      throw new Error('No default engine was specified and no extension was provided.');
    63    }
    64  
    65    var fileName = name;
    66  
    67    if (!this.ext) {
    68      // get extension from default engine name
    69      this.ext = this.defaultEngine[0] !== '.'
    70        ? '.' + this.defaultEngine
    71        : this.defaultEngine;
    72  
    73      fileName += this.ext;
    74    }
    75  
    76    if (!opts.engines[this.ext]) {
    77      // load engine
    78      opts.engines[this.ext] = require(this.ext.substr(1)).__express;
    79    }
    80  
    81    // store loaded engine
    82    this.engine = opts.engines[this.ext];
    83  
    84    // lookup path
    85    this.path = this.lookup(fileName);
    86  }
    87  
    88  /**
    89   * Lookup view by the given `name`
    90   *
    91   * @param {string} name
    92   * @private
    93   */
    94  
    95  View.prototype.lookup = function lookup(name) {
    96    var path;
    97    var roots = [].concat(this.root);
    98  
    99    debug('lookup "%s"', name);
   100  
   101    for (var i = 0; i < roots.length && !path; i++) {
   102      var root = roots[i];
   103  
   104      // resolve the path
   105      var loc = resolve(root, name);
   106      var dir = dirname(loc);
   107      var file = basename(loc);
   108  
   109      // resolve the file
   110      path = this.resolve(dir, file);
   111    }
   112  
   113    return path;
   114  };
   115  
   116  /**
   117   * Render with the given options.
   118   *
   119   * @param {object} options
   120   * @param {function} callback
   121   * @private
   122   */
   123  
   124  View.prototype.render = function render(options, callback) {
   125    debug('render "%s"', this.path);
   126    this.engine(this.path, options, callback);
   127  };
   128  
   129  /**
   130   * Resolve the file within the given directory.
   131   *
   132   * @param {string} dir
   133   * @param {string} file
   134   * @private
   135   */
   136  
   137  View.prototype.resolve = function resolve(dir, file) {
   138    var ext = this.ext;
   139  
   140    // <path>.<ext>
   141    var path = join(dir, file);
   142    var stat = tryStat(path);
   143  
   144    if (stat && stat.isFile()) {
   145      return path;
   146    }
   147  
   148    // <path>/index.<ext>
   149    path = join(dir, basename(file, ext), 'index' + ext);
   150    stat = tryStat(path);
   151  
   152    if (stat && stat.isFile()) {
   153      return path;
   154    }
   155  };
   156  
   157  /**
   158   * Return a stat, maybe.
   159   *
   160   * @param {string} path
   161   * @return {fs.Stats}
   162   * @private
   163   */
   164  
   165  function tryStat(path) {
   166    debug('stat "%s"', path);
   167  
   168    try {
   169      return fs.statSync(path);
   170    } catch (e) {
   171      return undefined;
   172    }
   173  }