diff --git a/lib/index.js b/lib/index.js index 9103e25..69fec9b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,6 +3,9 @@ // Main module file // -------------------- +// modules +var ejs = require('ejs'); + // imports var Errors = require('./errors'), Utils = require('./utils'), @@ -26,10 +29,14 @@ Overlook.Errors = Overlook.prototype.Errors = Errors; Overlook.Plugin = Overlook.prototype.Plugin = Plugin; Overlook.Routes = Overlook.prototype.Routes = Routes; Overlook.log = Overlook.prototype.log = log; +Overlook.viewEngines = Overlook.prototype.viewEngines = {ejs: ejs}; // add Overlook to Overlook.prototype Overlook.prototype.Overlook = Overlook; +// view paths +Overlook.viewsPaths = []; + // plugins Overlook.plugins = Overlook.prototype.plugins = {}; Overlook.plugin = pluginMethod; diff --git a/lib/overlook.js b/lib/overlook.js index aa91286..6e745cd 100644 --- a/lib/overlook.js +++ b/lib/overlook.js @@ -10,7 +10,8 @@ var pathModule = require('path'), expressor = require('expressor'), fs = require('fs-extra-promise'), promisifyAny = require('promisify-any'), - requireFolderTree = require('require-folder-tree'); + requireFolderTree = require('require-folder-tree'), + walkFolderTree = require('walk-folder-tree'); // imports var Utils = require('./utils'), @@ -48,14 +49,16 @@ module.exports = { // load config this.initConfig(); - // init views - this.views = []; - // conform paths options this.getPaths().forEach(function(pathType) { if (!options.paths[pathType]) options.paths[pathType] = pathModule.join(options.paths.root, pathType); }); + // init viewsPaths + this.viewsPaths = _.clone(this.Overlook.viewsPaths); + if (options.paths.views) this.viewsPaths.unshift(options.paths.views); + this.viewsPaths.push(pathModule.join(__dirname, '../views')); + // return overlook object return this; }, @@ -84,7 +87,7 @@ module.exports = { }, getPaths: function() { - return ['controllers', 'public']; + return ['controllers', 'views', 'public']; }, start: function*() { @@ -103,6 +106,10 @@ module.exports = { }).bind(this)); this.log('Initialized plugins'); + // init views + this.log('Loading views from ' + this.options.paths.views); + yield this.viewsInit(); + this.log('Loaded views'); // init controllers this.log('Loading controllers from ' + this.options.paths.controllers); @@ -121,6 +128,24 @@ module.exports = { return this; }, + viewsInit: function*() { + var views = this.views = {}, + viewEngines = this.viewEngines; + + yield this.viewsPaths.map(coSeries(function*(path) { + if (!(yield fs.existsAsync(path))) return; + + yield walkFolderTree(path, function*(params) { + if (params.directory) return; + var ext = pathModule.extname(params.name).slice(1); + if (ext && viewEngines[ext]) { + var pathWithoutExt = params.path.slice(0, -ext.length - 1); + if (!views[pathWithoutExt]) views[pathWithoutExt] = ext; + } + }); + })); + }, + controllersInit: function*() { var overlook = this, app = this.app, @@ -213,6 +238,11 @@ module.exports = { // static files if (this.options.paths.public) app.use(express.static(this.options.paths.public)); + + // add all view folders + app.set('view engine', 'ejs'); + app.set('views', this.viewsPaths); + return app; }, diff --git a/lib/pluginMethod.js b/lib/pluginMethod.js index 0a1aa27..8e16b1a 100644 --- a/lib/pluginMethod.js +++ b/lib/pluginMethod.js @@ -23,6 +23,9 @@ module.exports = function(plugin, options) { // run init action if (plugin.init) plugin.init(this); + // save views to Overlook + if (plugin.viewsPath) this.viewsPaths.push(plugin.viewsPath); + // done return this; }; diff --git a/lib/routes.js b/lib/routes.js index 01719c0..62bc251 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -37,15 +37,15 @@ BaseAction.prototype.init = function() { // set default view if not defined if (!this.view) { var treePath = this.treePath.slice(1); - if (this.overlook.views.indexOf(treePath) != -1) { + if (this.overlook.views[treePath]) { this.view = treePath; } else { - this.view = '_default/all'; + this.view = '_default/default'; } } // check view exists - if (this.overlook.views.indexOf(this.view) == -1) throw new Errors.Base("View '" + this.view + "' specified for " + this.treePath + ' does not exist'); + if (!this.overlook.views[this.view]) throw new Errors.Base("View '" + this.view + "' specified for " + this.treePath + ' does not exist'); return Promise.resolve(); }; @@ -54,7 +54,7 @@ BaseAction.prototype.all = function() { }; BaseAction.prototype.render = function(locals) { var res = this.res; - return Promise.promisify(res.render, res)(this.view, locals || {}) + return Promise.promisify(res.render, res)(this.view + '.' + this.overlook.views[this.view], locals || {}) .then(function(html) { res.send(html); }); diff --git a/package.json b/package.json index 88b907c..752036b 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,15 @@ "bluebird": "^2.9.31", "co-bluebird": "0.0.2", "co-series": "0.0.2", + "ejs": "^2.3.2", "express": "^4.13.0", "expressor": "^2.1.1", "fs-extra-promise": "^0.1.3", "is-generator": "^1.0.2", "lodash": "^3.10.0", "promisify-any": "^1.0.0", - "require-folder-tree": "^1.4.5" + "require-folder-tree": "^1.4.5", + "walk-folder-tree": "^0.1.2" }, "devDependencies": { "mocha": "^2.2.4", diff --git a/views/_default/default.ejs b/views/_default/default.ejs new file mode 100644 index 0000000..6476a52 --- /dev/null +++ b/views/_default/default.ejs @@ -0,0 +1 @@ +

Hello! <%= title %>