You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.8 KiB

  1. /**
  2. * Module dependencies.
  3. */
  4. var path = require('path')
  5. , fs = require('fs')
  6. , utils = require('./utils')
  7. , dirname = path.dirname
  8. , basename = path.basename
  9. , extname = path.extname
  10. , exists = fs.existsSync || path.existsSync
  11. , join = path.join;
  12. /**
  13. * Expose `View`.
  14. */
  15. module.exports = View;
  16. /**
  17. * Initialize a new `View` with the given `name`.
  18. *
  19. * Options:
  20. *
  21. * - `defaultEngine` the default template engine name
  22. * - `engines` template engine require() cache
  23. * - `root` root path for view lookup
  24. *
  25. * @param {String} name
  26. * @param {Object} options
  27. * @api private
  28. */
  29. function View(name, options) {
  30. options = options || {};
  31. this.name = name;
  32. this.root = options.root;
  33. var engines = options.engines;
  34. this.defaultEngine = options.defaultEngine;
  35. var ext = this.ext = extname(name);
  36. if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
  37. if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
  38. this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
  39. this.path = this.lookup(name);
  40. }
  41. /**
  42. * Lookup view by the given `path`
  43. *
  44. * @param {String} path
  45. * @return {String}
  46. * @api private
  47. */
  48. View.prototype.lookup = function(path){
  49. var ext = this.ext;
  50. // <path>.<engine>
  51. if (!utils.isAbsolute(path)) path = join(this.root, path);
  52. if (exists(path)) return path;
  53. // <path>/index.<engine>
  54. path = join(dirname(path), basename(path, ext), 'index' + ext);
  55. if (exists(path)) return path;
  56. };
  57. /**
  58. * Render with the given `options` and callback `fn(err, str)`.
  59. *
  60. * @param {Object} options
  61. * @param {Function} fn
  62. * @api private
  63. */
  64. View.prototype.render = function(options, fn){
  65. this.engine(this.path, options, fn);
  66. };