/**
* MOST Web Framework
* A JavaScript Web Framework
* http://themost.io
*
* Copyright (c) 2014, Kyriakos Barbounakis k.barbounakis@gmail.com, Anthi Oikonomou anthioikonomou@gmail.com
*
* Released under the BSD3-Clause license
* Date: 2014-06-09
*/
/**
* @ignore
*/
var app = require('./index'),
async = require('async'),
util = require('util'),
path = require('path');
/**
* @class EjsEngine
* @param {HttpContext=} context
* @constructor
* @property {HttpContext} context Gets or sets an instance of HttpContext that represents the current HTTP context.
*/
function EjsEngine(context) {
/**
* @type {HttpContext}
*/
var ctx = context;
Object.defineProperty(this,'context', {
get: function() {
return ctx;
},
set: function(value) {
ctx = value;
},
configurable:false,
enumerable:false
});
}
/**
*
* @param {string} filename
* @param {*=} data
* @param {Function} callback
*/
EjsEngine.prototype.render = function(filename, data, callback) {
var self = this;
try {
var ejs = require('ejs'), fs = require('fs'), common = require('./common');
fs.readFile(filename,'utf-8', function(err, str) {
try {
if (err) {
if (err.code === 'ENOENT') {
//throw not found exception
return callback(new common.HttpNotFoundException('View layout cannot be found.'));
}
return callback(err);
}
else {
//get view header (if any)
var matcher = /^(\s*)<%#(.*?)%>/;
var properties = { layout:null };
if (matcher.test(str)) {
var matches = matcher.exec(str);
properties = JSON.parse(matches[2]);
//remove match
str = str.replace(matcher,'');
}
//create view context
var viewContext = app.views.createViewContext(self.context);
//extend view context with page properties
util._extend(viewContext, properties || {});
//set view context data
viewContext.data = data;
var partial = false;
if (self.context && self.context.request.route)
partial = common.parseBoolean(self.context.request.route['partial']);
if (properties.layout && !partial) {
var layout;
if (/^\//.test(properties.layout)) {
//relative to application folder e.g. /views/shared/master.html.ejs
layout = app.current.mapPath(properties.layout);
}
else {
//relative to view file path e.g. ./../master.html.html.ejs
layout = path.resolve(filename, properties.layout);
}
//set current view buffer (after rendering)
viewContext.body = ejs.render(str, viewContext);
//render master layout
fs.readFile(layout,'utf-8', function(err, layoutData) {
try {
if (err) {
if (err.code === 'ENOENT') {
return callback(new common.HttpNotFoundException('Master view layout cannot be found'));
}
return callback(err);
}
var result = ejs.render(layoutData, viewContext);
callback(null, result);
}
catch (e) {
callback(e);
}
});
}
else {
var result = ejs.render(str, viewContext);
callback(null, result);
}
}
}
catch (e) {
callback(e);
}
});
}
catch (e) {
callback.call(self, e);
}
}
/**
*
* @param {HttpContext=} context
* @returns {EjsEngine}
*/
EjsEngine.prototype.createInstance = function(context) {
return new EjsEngine(context);
};
if (typeof exports !== 'undefined') module.exports.createInstance = EjsEngine.prototype.createInstance;