Permalink
Browse files

progress on refatoring

  • Loading branch information...
1 parent 0a554f6 commit 0293c144521c698f2b74d1f455296e11552ab6d2 @kadirpekel committed Oct 24, 2010
Showing with 130 additions and 136 deletions.
  1. +2 −4 examples/coffeescript-cgi/boot.js
  2. +2 −5 examples/standalone/boot.js
  3. +124 −126 lib/meryl.js
  4. +2 −1 lint.cfg
@@ -3,9 +3,7 @@
*/
module.exports = function (meryl) {
- meryl.options = {
- templateExt: '.coffee',
- templateFunc: require('coffeekup').adapters.meryl
- };
+ meryl.options.templateExt = '.coffee';
+ meryl.options.templateFunc = require('coffeekup').adapters.meryl;
};
@@ -5,10 +5,7 @@ var connect = require('connect');
// export a function accepting Meryl instance
module.exports = function (meryl) {
- meryl.plug(connect.staticProvider(), connect.logger());
+ meryl.options.templateExt = '.mt', // Default is '.jshtml'
- meryl.options = {
- templateExt: '.mt', // Default is '.jshtml'
- port: 3000 // Already the default one
- };
+ meryl.plug(connect.staticProvider(), connect.logger());
};
View
@@ -9,8 +9,25 @@
*/
var sys = require('sys'),
http = require('http'),
+ url = require('url'),
fs = require('fs'),
path = require('path');
+
+/**
+ * Default encoding
+ */
+var __encoding = 'utf-8';
+
+Object.merge = function (src, dest) {
+ if (src && dest) {
+ for (var key in src) {
+ if (src.hasOwnProperty(key)) {
+ dest[key] = src[key];
+ }
+ }
+ }
+ return dest;
+};
/*
* This function renders source string with given data which uses
@@ -31,32 +48,70 @@ var microtemplate = function (source, data) {
"');}return p.join('');")(data);
};
+
+/*
+ * Parses path expression and extract path variables
+ *
+ * @param {String} expr
+ * @param {String} path
+ * @return {Object}
+ * @api private
+ */
+var matchPathExpression = function (expr, path) {
+ var p1 = '{([^}]+)}',
+ p2 = '<([^>]+)>',
+ rA = new RegExp('(?:' + p1 + ')|(?:' + p2 + ')', 'gi'),
+ keys = [],
+ values = null,
+ capture = null;
+ while ((capture = rA.exec(expr))) {
+ keys.push(capture[1] || capture[2]);
+ }
+ var rB = new RegExp('^' + expr.replace(/\(/, '(?:', 'gi')
+ .replace(/\./, '\\.', 'gi')
+ .replace(/\*/, '.*', 'gi')
+ .replace(new RegExp(p1, 'gi'), '([^/\\.\\?]+)')
+ .replace(new RegExp(p2, 'gi'), '(.+)') + '$');
+
+ if ((values = rB.exec(path))) {
+ var result = {};
+ values.shift();
+ if (values.length === keys.length) {
+ for (var i = 0; i < keys.length; i++) {
+ result[keys[i]] = values[i];
+ }
+ } else {
+ throw new Error('Inconsistent path expression');
+ }
+ return result;
+ }
+ return null;
+};
+
/**
* Meryl core object
*/
-var Meryl = function () {
- // myself
- var self = this;
-
- // handler registry
+function Meryl() {
+ // Handler registry
this.handlers = [];
- // plugin registry
+ // Plugin registry
this.plugins = [];
+ // Option registry
+ this.options = {
+ port: 3000,
+ hostname: 'localhost',
+ templateDir: '',
+ templateExt: '.jshtml',
+ templateFunc: microtemplate
+ };
// Aliases
this.h = this.handle;
this.p = this.plug;
-
- // Options
- this.options = {};
-};
+}
Meryl.prototype = {
- /*
- * Default encoding
- */
- _encoding: 'utf-8',
-
+
/*
* Default not found handler definition
*
@@ -88,47 +143,6 @@ Meryl.prototype = {
},
/*
- * Parses path expression and extract path variables
- *
- * @param {String} expr
- * @param {String} path
- * @return {Object}
- * @api private
- */
- _parsePath: function (expr, path) {
- var p1 = '{([^}]+)}',
- p2 = '<([^>]+)>',
- rA = new RegExp('(?:' + p1 + ')|(?:' + p2 + ')', 'gi'),
- keys = [],
- values = null,
- capture = null;
- while ((capture = rA.exec(expr))) {
- keys.push(capture[1] || capture[2]);
- }
- var rB = new RegExp('^' + expr.replace(/\(/, '(?:', 'gi')
- .replace(/\./, '\\.', 'gi')
- .replace(/\*/, '.*', 'gi')
- .replace(new RegExp(p1, 'gi'), '([^/\\.\\?]+)')
- .replace(new RegExp(p2, 'gi'), '(.+)') + '$');
-
- if ((values = rB.exec(path))) {
- var result = {};
- values.shift();
- if (values.length === keys.length) {
- for (var key in keys) {
- if (keys.hasOwnProperty(key)) {
- result[keys[key]] = values[key];
- }
- }
- } else {
- throw new Error('Inconsistent path expression');
- }
- return result;
- }
- return null;
- },
-
- /*
* Process incoming requests and do main routing
* operations through handlers and plugins by chaining matched
* ones with each other
@@ -146,20 +160,12 @@ Meryl.prototype = {
var procunit = infra[i];
i += 1;
if (procunit && procunit.pattern) {
- var parts = self._parsePath(procunit.pattern, req.method +
+ var parts = matchPathExpression(procunit.pattern, req.method +
' ' + req.params.pathname);
if (parts) {
if (procunit.cb) {
- for (var part in parts) {
- if (parts.hasOwnProperty(part)) {
- req.params[part] = parts[part];
- }
- }
- for (var key in req.params.query) {
- if (req.params.query.hasOwnProperty(key)) {
- req.params[key] = req.params.query[key];
- }
- }
+ Object.merge(parts, req.params);
+ Object.merge(req.params.query, req.params);
procunit.cb.call(ctx, req, resp, next);
}
} else {
@@ -238,38 +244,6 @@ Meryl.prototype = {
},
/*
- * This function renders given template name using rendering options
- * with given data
- *
- * @param {String} templateName
- * @param {Object} data
- * @param {Boolean} suppressFsErr
- * @return {String}
- * @api private
- */
- _render: function (templateName, data, suppressFsErrors) {
- templateName = templateName || '';
- suppressFsErrors = suppressFsErrors || false;
- var templateDir = this.options.templateDir || '',
- templateExt = this.options.templateExt || '.jshtml',
- templateFunc = this.options.templateFunc || microtemplate;
- templateName = templateName.replace(/\.\./, '.', 'g');
- if (!templateName.length || templateName[templateName.length - 1] === '/') {
- templateName += 'index';
- }
- var templatePath = path.join('.', templateDir, templateName + templateExt),
- src = null;
- try {
- src = fs.readFileSync(templatePath, this._encoding);
- } catch (e) {
- if (!suppressFsErrors) {
- throw e;
- }
- }
- return src ? templateFunc(src, data) : null;
- },
-
- /*
* Main entry point of Meryl. It pushes some initial
* preperations for handling http requests.
*
@@ -281,53 +255,77 @@ Meryl.prototype = {
* @api public
*/
cgi: function (opts) {
- var self = this,
- infra = self.plugins.concat(self.handlers);
- for (var i in opts || {}) {
- if (opts.hasOwnProperty(i)) {
- self.options[i] = opts[i];
- }
- }
- infra.push({pattern: '* /(<templatename>)?', cb: function (req, resp, next) {
- if (!resp.render(req.params.templatename, null, true, true)) {
- next();
+ var self = this;
+
+ opts = Object.merge(opts || {}, self.options);
+
+ var infra = self.plugins.concat(self.handlers);
+ infra.push({pattern: '* <templatename>', cb: function (req, resp, next) {
+ try {
+ resp.render(req.params.templatename);
+ } catch (e) {
+ if (e === 'template not found') {
+ next();
+ } else {
+ throw e;
+ }
}
}});
infra.push({pattern: '*', cb: self._notFoundHandler});
+
return function (req, resp) {
- req.params = require('url').parse(req.url, true);
- resp.headers = {'content-type': 'text/html'};
resp.status = 200;
+ resp.headers = {'content-type': 'text/html'};
+
resp.send = function (data, encoding) {
+ if (!this.headers.hasOwnProperty('content-length')) {
+ this.headers['content-length'] = data ? data.length : 0;
+ }
this.writeHead(this.status, this.headers);
- this.end(data, encoding || self._encoding);
+ this.end(data, encoding || __encoding);
};
+
resp.redirect = function (location) {
- resp.status = 301;
- resp.headers.location = location;
- resp.send();
+ this.status = 301;
+ this.headers.location = location;
+ this.send();
};
- function render(templateName, data, suppressFsErrors) {
+
+ function render(templateName, data) {
+ templateName = templateName || '/';
+ templateName = templateName.replace(/\.\./, '.', 'g');
+
data = data || {};
data.request = req;
data.response = resp;
data.render = render;
- return self._render(templateName, data, suppressFsErrors);
- }
- resp.render = function (templateName, data, suppressFsErrors, noSend) {
- var output = render(templateName, data, suppressFsErrors);
- if (output !== null || !noSend) {
- resp.send(output);
+
+ if (templateName[templateName.length - 1] === '/') {
+ templateName += 'index';
}
- return output;
+ var templatePath = path.join(process.cwd(),
+ opts.templateDir, templateName + self.options.templateExt);
+ var src = null;
+ try {
+ src = fs.readFileSync(templatePath, __encoding);
+ } catch (e) {
+ throw 'template not found';
+ }
+ return src ? opts.templateFunc(src, data) : null;
+ }
+
+ resp.render = function (templateName, data) {
+ return this.send(render(templateName, data));
};
+
+ req.params = url.parse(req.url, true);
req.addListener('data', function (data) {
if (!req.postdata) {
req.postdata = data;
} else {
req.postdata += data;
}
- }).addListener('end', function () {
+ }).addListener('end', function () {
self._proc(infra, self, req, resp);
});
};
@@ -350,8 +348,8 @@ Meryl.prototype = {
*/
run: function (opts) {
var server = http.createServer(this.cgi(opts));
- server.listen(this.options.port || process.env.PORT || 3000,
- this.options.hostname || process.env.HOSTNAME || 'localhost');
+ server.listen(process.env.PORT || this.options.port,
+ process.env.HOSTNAME || this.options.hostname);
return server;
},
View
@@ -2,5 +2,6 @@ var options = {
indent: 2,
onevar: false,
evil: true,
- regexp: false
+ regexp: false,
+ plusplus: false
};

0 comments on commit 0293c14

Please sign in to comment.