The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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