UNPKG

cody

Version:
388 lines (315 loc) 10.4 kB
// // Johan Coppieters - jan 2013 - Cody // // console.log("loading " + module.id); var cody = require("../index.js"); // // Context // // Created by Application in buildContext as results of servePage for every request, // containing all the context info for that request. // // Accessible through the controller of the request. // All its properties are accessible as globals for the view rendered for that request. // // Additionally provides some helpers (formatting/utitlities), thus accessible by the views. function Context(path, page, app, req, res) { this.version = (app) ? app.version : "v0.0"; this.page = page; this.app = app; this.req = req; this.res = res; this.path = path; // copy query params and body params into this.params and .param this.params = {}; for(var q in req.query) { if (Object.prototype.hasOwnProperty.call(req.query, q)) { this.params[q] = req.query[q]; } } for(var b in req.body) { if (Object.prototype.hasOwnProperty.call(req.body, b)) { this.params[b] = req.body[b]; } } this.request = this.params.request || path.request || page.item.defaultrequest || ""; this.status = "success"; this.message = ""; this.host = req.headers.host; this.dateFormat = "dd-mm-yyyy"; this.min = ""; // ".min" this.static = (app.prefix) ? "/" + app.prefix + "/static" : "/static"; this.dynamic = (app.prefix) ? "/" + app.prefix + "/data" : "/data"; this.cstatic = "/cody/static"; this.gPrefix = (app.prefix) ? "/" + app.prefix : ""; var stringPage = app.getPage(page.language, "strings"); this.strings = []; this.addStrings(stringPage); this.fn = (page) ? page.getView() : "index.ejs"; this.session = req.session; this.setLogin((typeof this.session === "undefined") ? {} : this.session.login); // make global cody lib available this.cody = cody; } module.exports = Context; // // mini contexts for saving in between login requests // Context.prototype.getMini = function() { var mini = {}; mini.params = {}; for(var x in this.params) { if (Object.prototype.hasOwnProperty(this.params, x)) { mini.params[x] = this.params[x]; } } //mini.params = this.params; mini.path = this.path; mini.request = this.request; mini.context = this.context; mini.static = this.static; mini.dynamic = this.dynamic; mini.fn = this.fn; return mini; }; Context.prototype.copyFromMini = function(mini) { this.params = {}; for(var x in mini.params) { if (Object.prototype.hasOwnProperty(mini.params, x)) { this.params[x] = mini.params[x]; } } this.path = mini.path; this.request = mini.request; this.context = mini.context; this.static = mini.static; this.dynamic = mini.dynamic; this.fn = mini.fn; this.page = this.app.findPage(this.path); }; // // Strings - translations - etc... // Context.prototype.addStrings = function(page, kind) { var self = this; if (typeof page !== "undefined") { page.content.forEach( function (C) { if ((typeof kind === "undefined") || (kind === C.kind)) { self.strings[C.name] = C.data; } }); } }; // // Render content queried by name or kind. // // { kind: String, // not_kind: String, // name: String, // not_name: String, // intro: Y/N, Show intro part? // page: Page } Optional Page to get the content from instead of current Context.prototype.render = function(params) { var html = ""; var content = this.page.content; if (typeof params === "undefined") { params = {}; } if (typeof params.page !== "undefined") { content = params.page.content; } if (typeof content === "undefined") { return ""; } for (var ic in content) { var C = content[ic]; if (params.name && (C.name != params.name)) continue; if (params.not_name && (C.name == params.not_name)) continue; if (params.kind && (C.kind != params.kind)) continue; if (params.not_kind && (C.kind == params.not_kind)) continue; if (params.intro && (C.intro != params.intro)) continue; html += C.render(this.controller); } return html; }; // // login stuff // Context.prototype.setLogin = function(login) { if (typeof this.session !== "undefined") this.session.login = login; this.login = new cody.User(login); }; Context.prototype.isLoggedIn = function() { return (this.login) && (typeof this.login !== "undefined") && (this.login.active === "Y"); }; Context.prototype.getLogin = function() { return this.login || new cody.User({}); }; // // General utilities // Context.prototype.getValueByIndex = function(object, index) { var nr = 0; for (var iO in object) { if (nr === index) { return object[iO]; } nr++; } return undefined; } Context.prototype.getKeyByIndex = function(object, index) { var nr = 0; for (var iO in object) { if (nr === index) { return iO; } nr++; } return undefined; } Context.prototype.val = function(value) { return (typeof value === "undefined") ? "" : value; }; Context.prototype.getUnique = function() { return new Date().getTime(); }; // returns 'checked' if true, for option lists. Context.prototype.checked = function( bool ) { return (bool) ? 'checked' : ''; }; // // Creates html options from a given list // // 1. optionList([String], String) // Creates an option for each string and marks theId as string. // 2. optionList([Object], String, String, String) // Creates an option for each object, using theIdName and theNameName properties // of each object to set the id and html resp. // Context.prototype.optionList = function(theList, theId, theIdName, theNameName) { var x = ""; var first = cody.Application.findFirst(theList); if (typeof first === "string") { for (var j=0; j < theList.length; j++) { var S = theList[j]; x += "<option value=\"" + S + "\"" + ((S == theId) ? "selected" : "") + ">" + S + "</option>\n"; } } else { var idName = theIdName || "id"; var nameName = theNameName || "name"; for (var i in theList) { if (theList.hasOwnProperty(i)) { var O = theList[i]; x += "<option value=\"" + O[idName] + "\"" + ((O[idName] == theId) ? "selected" : "") + ">" + O[nameName] + "</option>\n"; } } } return x; }; // // optionListF([Any], String, (Any) -> String, (Any) -> String) -> String // // Uses two functions that take an element from the list as argument and return // an id/name to create the options. Marks the option that has the id theId as "selected". // Context.prototype.optionListF = function (theList, theId, getId, getName) { var options = ""; theList.forEach(function (item) { var id = getId(item); console.log(id); var name = getName(item); options += "<option value=\"" + id + "\"" + ((id == theId) ? "selected" : "") + ">" + name + "</option>\n"; }); return options; }; Context.prototype.find = function(theList, theId, theIdName) { var idName = theIdName || "id"; for (var i=0; i < theList.length; i++) { var R = theList[i]; if (R[idName] == theId) { return R; } } return {}; }; // // Session handlers // Context.prototype.fromSession = function(paramName, defaultValue) { var x = this.session[paramName]; return (typeof x === "undefined") ? defaultValue : x; }; Context.prototype.toSession = function(paramName, value) { this.session[paramName] = value; }; // // Request Parameter handlers // Context.prototype.getParam = function(paramName, defaultValue) { var x = this.params[paramName]; if (typeof defaultValue === "boolean") { x = (x === "true") || (x === "Y") || (x === "1") || (x === 1); }; if (typeof defaultValue === "number") { if ((typeof x === "undefined") || (x === "")) return defaultValue; var tmp = parseFloat(x); x = (tmp % 1 === 0) ? parseInt(x) : tmp; }; if ((typeof defaultValue !== "undefined") && (defaultValue instanceof Date)) { x = this.makeDate(x, defaultValue); } return (typeof x === "undefined") ? defaultValue : x; }; Context.prototype.setParam = function(paramName, value) { this.params[paramName] = value; }; // Adds a leading "0" when the number < 10. function two(n) { return (n < 10) ? ("0" + n) : n; } Context.prototype.formatTime = function(aDate) { return two(aDate.getHours()) + ":" + two(aDate.getMinutes()) + ":" + two(aDate.getSeconds()); }; Context.prototype.formatShortTime = function(aDate) { return two(aDate.getHours()) + ":" + two(aDate.getMinutes()); }; // should look at the current locale of the user page // for now we depend on the dateFormat field of this context Context.prototype.formatDate = function(aDate) { if ((typeof aDate === "undefined") || (!aDate)) { console.log("formatDate called without date parameter..."); aDate = new Date(); } if (this.dateFormat === "dd-mm-yyyy") { return two(aDate.getDate()) + "-" + two(aDate.getMonth()+1) + "-" + aDate.getFullYear(); } else if (this.dateFormat === "mm-dd-yyyy") { return two(aDate.getMonth()+1) + "-" + two(aDate.getDate()) + "-" + aDate.getFullYear(); } else { // "yyyy-mm-dd" return aDate.getFullYear() + "-" + two(aDate.getMonth()+1) + "-" + two(aDate.getDate()); } }; Context.prototype.makeDate = function(value, defaultValue) { if (typeof value === "undefined") { return defaultValue; } var parts = (value.indexOf("-") > 0) ? value.split("-") : value.split("/"); if (this.dateFormat === "dd-mm-yyyy") { return (parts.length < 3) ? defaultValue : new Date(parts[2], parseInt(parts[1], 10)-1, parts[0]); } else if (this.dateFormat === "mm-dd-yyyy") { return (parts.length < 3) ? defaultValue : new Date(parts[2], parseInt(parts[0], 10)-1, parts[1]); } else { // "yyyy-mm-dd" return (parts.length < 3) ? defaultValue : new Date(parts[0], parseInt(parts[1], 10)-1, parts[0]); } } Context.prototype.makeInt = function(value, defaultValue) { if (typeof value !== "number") { value = parseInt(value, 10); } return isNaN(value) ? defaultValue : value; } Context.prototype.makeNum = function(value, defaultValue, precision) { if (typeof value !== "number") { value = parseFloat(value); } if (isNaN(value)) { value = defaultValue; } if (typeof precision !== "undefined") { value = value.toFixed(precision); } return value; }