Skip to content

Commit

Permalink
Added express middleware for pre-rendering layouts as well as support…
Browse files Browse the repository at this point in the history
… for UA based partials
  • Loading branch information
davglass committed Nov 1, 2010
1 parent c5bf734 commit 0af0592
Showing 1 changed file with 99 additions and 10 deletions.
109 changes: 99 additions & 10 deletions lib/express.js
Expand Up @@ -4,11 +4,75 @@
*/
YUI.add('express', function(Y) {

if (YUI.express) {
//Catch double loading of YUI().use('*');
return;
}

var path = YUI.require('path'),
fs = YUI.require('fs'),
sys = YUI.require('sys'),
DEBUG = false;
/**
* The default content holder for partials, if one is not given this one is used.
* @property defaultContent
* @static
*/
YUI.defaultContent = '#content';

/**
* Express middleware to "pre-parse" the layout and add it to a YUI instance
* that is then bound to the req as req.Y. Calling res.send() will automatically call
* Y.config.doc.outerHTML and echo to the response.
* The middleware can be used like this: http://gist.github.com/657453
* @static
* @method express
*/
YUI.express = function(req, res, next) {
var fn = function(req, res, next, yConfig) {
if (!req.Y) {
var ua = req.headers['user-agent'];
YUI({ debug: DEBUG, UA: ua }).use('*', function(Y) {
Y.config.win.location.href = req.originalUrl;
Y.express = yConfig;
req.Y = res.Y = Y;
if (yConfig.render) {
res._ySend = res.send;
res.sub = function(sub) {
var html = this.Y.config.doc.outerHTML;
html = this.Y.substitute(html, sub);
this.Y.config.doc.innerHTML = html;
};
res.send = function(str) {
Y.config.doc.innerHTML = str;
this.send = function() {
this._ySend.call(this, Y.config.doc.outerHTML);
req.Y = res.Y = null;
YUI._express[Y.id] = Y;
YUI.cleanExpress();
};
next();
};
var c = {};
if (yConfig.locals) {
c.locals = yConfig.locals;
}
res.render(yConfig.render, c);
}
});
} else {
next();
}
};
if (req && res && next) {
return fn.call(this, req, res, next);
} else {
return function(req2, res2, next2) {
fn.call(this, req2, res2, next2, req);
};
}
};

/**
* Hash of all YUI instances uses in the course of rendering the pages.
* So they can be blown away after they are used.
Expand Down Expand Up @@ -64,9 +128,11 @@ YUI.add('express', function(Y) {
* {
* name: 'header', //Name of the /views/partial/{name}.html file to load
* method: 'append', //append,prepend,appendChild
* node: '#conent', //Any valid selector
* node: '#content', //Any valid selector
* enum: 'one', //one,all
* fn: function //The callback function to run after the action.
* fn: function, //The callback function to run after the action.
* ua: 'webkit', //Any truthy value from Y.UA
* test: function(Y, options) //Test function passed Y instance and render options. Return true to include this partial.
* }
* @property partials
* @static
Expand Down Expand Up @@ -141,7 +207,10 @@ YUI.add('express', function(Y) {
YUI.render = function(content, options) {
var eY, locals = options.locals,
ua = options.scope.headers['user-agent'];


if (options.scope.res.Y && !options.partial) {
locals.instance = options.scope.res.Y;
}
if (locals.instance) {
eY = locals.instance;
eY.UA = YUI.Env.parseUA(ua);
Expand Down Expand Up @@ -185,16 +254,34 @@ YUI.add('express', function(Y) {
}
if (parts && parts.length) {
eY.each(parts, function(p) {
var str = locals.partial(p.name);
var enum = p.enum || 'one';
var method = p.method || 'append';
eY[enum](p.node)[method](str);
if (p.fn) {
p.fn(eY, options, p);
var run = true;
if (p.test && eY.Lang.isFunction(p.test)) {
run = false;
if (p.test(eY, options)) {
run = true;
}
}
if (p.ua) {
run = false;
if (eY.UA[p.ua]) {
run = true;
}
}
if (run) {
var str = locals.partial(p.name);
var enum = p.enum || 'one';
var method = p.method || 'append';
eY[enum](p.node)[method](str);
if (p.fn) {
p.fn(eY, options, p);
}
}
});
}
var html = docType + "\n";
if (!locals.content) {
locals.content = YUI.defaultContent;
}
var content = eY.one(locals.content);
if (content && locals.body) {
content.prepend(locals.body);
Expand All @@ -209,7 +296,9 @@ YUI.add('express', function(Y) {
if (locals.sub) {
html = eY.substitute(html, locals.sub);
}
YUI._express[eY.id] = eY;
if (!options.scope.res.Y) {
YUI._express[eY.id] = eY;
}
YUI.cleanExpress();
return html;
} else {
Expand Down

0 comments on commit 0af0592

Please sign in to comment.