UNPKG

wns-mvc-package

Version:

MVC package/bundle for WNS Middleware

287 lines (245 loc) 7.57 kB
/** * @WNS - The NodeJS Middleware and Framework * * @copyright: Copyright © 2012- YEPT ® * @page: http://wns.yept.net/ * @docs: http://wns.yept.net/docs/ * @license: http://wns.yept.net/license/ */ /** * No description yet. * * @author Pedro Nasser */ // Exports module.exports = { /** * Class dependencies */ extend: ['wnComponent'], /** * NPM dependencies */ dependencies: ['url'], /** * Private */ private: { _server: null, _controllers: [], _partials: {}, _config: { defaultController:"site", errorPage: "site/error", templateEngine: "Dust", path: { controllers: "controllers/", views: "views/", partials: "partials/" }, } }, /** * Public Variables */ public: { /** * @var object events to be preloaded. */ defaultEvents: { 'open': {}, 'handle': {}, 'error': {}, 'send': {} } }, /** * Methods */ methods: { /** * Initializer */ init: function () { this.app = this.getParent(); this.attachEvents(this.app); this.prepareEngines(this.app); }, /** * Attach events to the application */ attachEvents: function (app) { self.debug('Attaching events to the parent application',0); if (!_(app).isObject()) return false; if (!app.getEvent('readyRequest')) { self.warn('Failed to attach wnControllerServer. Requires to install `http` package on the parent server.'); self.warn('Learn how to easy install `http` package: http://github.com/pedronasser/wns-http-package'); return false; } app.addListener('readyRequest',function (e,req,resp) { req.parsedUrl=url.parse(req.url,true); req.route = self.app.getComponent('urlManager').parseRequest(req) || { translation: req.url, params: {}, template: '' }; req.template = self.route ? self.route.template : ''; self.next=e.next; self.processRequest(req,resp); }); }, /** * Prepare engines. */ prepareEngines: function (app) { var engineName = this.getConfig('templateEngine') || 'Dust'; var engineClass = 'wn'+engineName+'Template'; if (!app.c[engineClass]) { self.warn('Failed to attach '+engineClass+'. Requires to install `template` package on the application.'); self.warn('Learn how to easy install `template` package: http://github.com/pedronasser/wns-template-package'); return false; } app.template = app.createClass(engineClass,{}); app.template.parent = function () { return app; }; app.html = app.createClass('wnHtml',{}); app.html.setParent(app); app.html.encoder = app.createClass('wnHtmlEncoder',{}); }, /** * Process the request * @param {ServerRequest} req * @param {ServerResponse} resp */ processRequest: function (req,resp) { if (req.template.split("/").length>1 || req.template == '') { self.debug('Requesting for controller/action.',5); req.html = self.app.html; req.html.encoder = self.app.html.encoder; _.merge(req.query.GET, req.parsedUrl.query); _.merge(req.query.GET, req.route.params); resp.setHeader('Content-Type','text/html'); var _p=(req.route.translation).split('/'); var _plen = _p.length; var _controller=_plen>0&&_p[1]!=''?_p[1]:undefined; var _action=_plen>1&&_p[2]!=''?_p[2]:undefined; var ctrlName = (_controller !== undefined && _controller !== 'undefined') ? _controller : this.getConfig('defaultController'); var controller=this.getController(ctrlName,req,resp); if (!controller) { self.errorHandler(req,resp,404,'Controller not found'); return; } self.e.handle(controller); req.e = { error: controller.e.error }; resp.e = { error: controller.e.error }; controller.addListener('error',function (e,code,msg) { self.errorHandler(req,resp,code,msg); }); _action=req.action=(!_action?controller.defaultAction:_action); if (controller.resolveAction(_action)==false) { self.errorHandler(req,resp,404,'Action not found'); } } }, /** * Error handling */ errorHandler: function (req,resp,code,msg) { self.debug(code+': '+msg,1); if (code == 404 && self.getConfig('errorPage')!=undefined) { self.debug('Redirecting to ERROR PAGE...',2); req.route.translation = '/'+self.getConfig('errorPage'); req.error = 'Not found'; req.code = 404; self.processRequest(req,resp); } self.next(); }, /** * Flush all loaded application's controllers cache */ flushControllers: function () { for (c in _controllers) this.c['wn'+(c.substr(0,1).toUpperCase()+c.substr(1))+'Controller']=undefined; this.debug('All controllers has been flushed.',1); }, /** * Flush an application's controller cache * @param string $c controller's name */ flushController: function (c) { this.c['wn'+(c.substr(0,1).toUpperCase()+c.substr(1))+'Controller']=undefined; this.debug('Controller ´'+c+'´ has been flushed.',1); }, /** * Get a new or cached instance from a controller. * @param string $id controller's id * @return wnController */ getController: function (id,req,resp) { id = id.toLowerCase(); var controllerName = 'wn'+(id.substr(0,1).toUpperCase()+id.substr(1))+'Controller'; var classProto = this.app.c[controllerName]; if (_.isUndefined(classProto)) { self.debug('Looking up for the controller: '+id,1); var controllerFile = this.getConfig('path').controllers+id+'.js'; var builder = this.app.getComponent('classBuilder'); if (fs.existsSync(this.app.modulePath+controllerFile)) { builder.addSource(controllerName,this.app.modulePath+controllerFile); builder.classes[controllerName]=builder.buildClass(controllerName); if (!builder.classes[controllerName]) this.app.e.exception(new Error('Could not build the controller class.')); this.app.c[controllerName]=builder.classes[controllerName]; _controllers[id]=this.app.c[controllerName]; classProto = this.app.c[controllerName]; self.registerPartials(id); self.compilePartials(id); } else return false; } var config = { controllerName: id, verbosity: _verbosity, debug: _debug, path: this.getConfig('path') }; controller = new classProto(config,this.app.c,this.app,req,resp); return controller; }, /** * Register all partials from a controller * @param string $controllerName */ registerPartials: function (controllerName) { var partialPath = this.app.modulePath+this.getConfig('path').views+controllerName+'/'+this.getConfig('path').partials; if (_.isUndefined(this.getConfig('path').partials) || !fs.existsSync(partialPath)) return false; _partials[controllerName] = {}; var files = fs.readdirSync(partialPath); if (files) { for (f in files) { var name = files[f].split('.')[0]; _partials[controllerName][name]=partialPath+files[f]; } } }, /** * Compiled all partials * @param string $controllerName */ compilePartials: function (controllerName) { var partials = _partials[controllerName]; for (p in partials) { self.app.template.renderPartial(fs.readFileSync(partials[p]).toString('utf8'),controllerName+'-'+p); } }, } };