Comparing version 2.2.0 to 2.2.1
2.2.1 / 2011-04-04 | ||
================== | ||
* Added `layout(path)` helper to change the layout within a view. Closes #610 | ||
* Fixed `partial()` collection object support. | ||
Previously only anything with `.length` would work. | ||
When `.length` is present one must still be aware of holes, | ||
however now `{ collection: {foo: 'bar'}}` is valid, exposes | ||
`keyInCollection` and `keysInCollection`. | ||
* Performance improved with better view caching | ||
* Removed `request` and `response` locals | ||
* Changed; errorHandler page title is now `Express` instead of `Connect` | ||
2.2.0 / 2011-03-30 | ||
@@ -3,0 +17,0 @@ ================== |
@@ -30,3 +30,3 @@ | ||
exports.version = '2.2.0'; | ||
exports.version = '2.2.1'; | ||
@@ -73,1 +73,6 @@ /** | ||
require('./request'); | ||
// Error handler title | ||
exports.errorHandler.title = 'Express'; | ||
@@ -94,8 +94,2 @@ | ||
// default dynamic locals | ||
this.dynamicHelpers({ | ||
request: function(req, res){ return req; } | ||
, response: function(req, res){ return res; } | ||
}); | ||
// default development configuration | ||
@@ -102,0 +96,0 @@ this.configure('development', function(){ |
123
lib/view.js
@@ -116,12 +116,35 @@ | ||
var len = collection.length | ||
, buf = ''; | ||
, buf = '' | ||
, keys | ||
, key | ||
, val; | ||
options.collectionLength = len; | ||
for (var i = 0; i < len; ++i) { | ||
var val = collection[i]; | ||
options.firstInCollection = i === 0; | ||
options.indexInCollection = i; | ||
options.lastInCollection = i === len - 1; | ||
object = val; | ||
buf += render(); | ||
if ('number' == typeof len || Array.isArray(collection)) { | ||
for (var i = 0; i < len; ++i) { | ||
val = collection[i]; | ||
options.firstInCollection = i == 0; | ||
options.indexInCollection = i; | ||
options.lastInCollection = i == len - 1; | ||
object = val; | ||
buf += render(); | ||
} | ||
} else { | ||
keys = Object.keys(collection); | ||
len = keys.length; | ||
options.collectionLength = len; | ||
options.collectionKeys = keys; | ||
for (var i = 0; i < len; ++i) { | ||
key = keys[i]; | ||
val = collection[key]; | ||
options.keyInCollection = key; | ||
options.firstInCollection = i == 0; | ||
options.indexInCollection = i; | ||
options.lastInCollection = i == len - 1; | ||
object = val; | ||
buf += render(); | ||
} | ||
} | ||
return buf; | ||
@@ -245,3 +268,4 @@ } else { | ||
, viewOptions = app.set('view options') | ||
, cacheTemplates = app.set('cache views'); | ||
, cacheViews = app.set('cache views') | ||
, root = app.set('views') || process.cwd() + '/views'; | ||
@@ -263,6 +287,3 @@ // merge "view options" | ||
// Defaults | ||
var self = this | ||
, root = app.set('views') || process.cwd() + '/views' | ||
, partial = options.renderPartial | ||
var partial = options.renderPartial | ||
, layout = options.layout; | ||
@@ -290,29 +311,2 @@ | ||
// Populate view | ||
var orig = view = new View(view, options); | ||
// Try _ prefix ex: ./views/_<name>.jade | ||
if (!view.exists) view = new View(orig.prefixPath, options); | ||
// Try index ex: ./views/user/index.jade | ||
if (!view.exists) view = new View(orig.indexPath, options); | ||
// Try ../<name>/index ex: ../user/index.jade | ||
// when calling partial('user') within the same dir | ||
if (!view.exists && !options.isLayout) view = new View(orig.upIndexPath, options); | ||
// Try root ex: <root>/user.jade | ||
if (!view.exists) view = new View(orig.rootPath, options); | ||
// Try root _ prefix ex: <root>/_user.jade | ||
if (!view.exists && partial) view = new View(view.prefixPath, options); | ||
// Does not exist | ||
if (!view.exists) { | ||
if (app.enabled('hints')) hintAtViewPaths(orig, options); | ||
var err = new Error('failed to locate view "' + orig.view + '"'); | ||
err.view = orig; | ||
throw err; | ||
} | ||
// Dynamic helper support | ||
@@ -346,9 +340,46 @@ if (false !== options.dynamicHelpers) { | ||
// Attempt render | ||
var engine = view.templateEngine | ||
, template = cacheTemplates | ||
? cache[view.path] || (cache[view.path] = engine.compile(view.contents, options)) | ||
: engine.compile(view.contents, options) | ||
, str = template.call(options.scope, options); | ||
// cached view | ||
if (cache[view]) { | ||
view = cache[view]; | ||
// resolve view | ||
} else { | ||
var orig = view = new View(view, options); | ||
// Try _ prefix ex: ./views/_<name>.jade | ||
if (!view.exists) view = new View(orig.prefixPath, options); | ||
// Try index ex: ./views/user/index.jade | ||
if (!view.exists) view = new View(orig.indexPath, options); | ||
// Try ../<name>/index ex: ../user/index.jade | ||
// when calling partial('user') within the same dir | ||
if (!view.exists && !options.isLayout) view = new View(orig.upIndexPath, options); | ||
// Try root ex: <root>/user.jade | ||
if (!view.exists) view = new View(orig.rootPath, options); | ||
// Try root _ prefix ex: <root>/_user.jade | ||
if (!view.exists && partial) view = new View(view.prefixPath, options); | ||
// Does not exist | ||
if (!view.exists) { | ||
if (app.enabled('hints')) hintAtViewPaths(orig, options); | ||
var err = new Error('failed to locate view "' + orig.view + '"'); | ||
err.view = orig; | ||
throw err; | ||
} | ||
var engine = view.templateEngine; | ||
view.fn = engine.compile(view.contents, options) | ||
if (cacheViews) cache[orig.view] = view; | ||
} | ||
// layout helper | ||
options.layout = function(path){ | ||
layout = path; | ||
}; | ||
// render | ||
var str = view.fn.call(options.scope, options); | ||
// layout expected | ||
@@ -355,0 +386,0 @@ if (layout) { |
@@ -20,3 +20,3 @@ | ||
/** | ||
* Memory cache. | ||
* Require cache. | ||
*/ | ||
@@ -27,8 +27,2 @@ | ||
/** | ||
* Existance cache. | ||
*/ | ||
var exists = {}; | ||
/** | ||
* Initialize a new `View` with the given `view` path and `options`. | ||
@@ -43,3 +37,2 @@ * | ||
options = options || {}; | ||
// TODO: more caching | ||
this.view = view; | ||
@@ -66,12 +59,7 @@ this.root = options.root; | ||
View.prototype.__defineGetter__('exists', function(){ | ||
var path = this.path; | ||
if (null != exists[path]) { | ||
return exists[path]; | ||
} else { | ||
try { | ||
stat(path); | ||
return exists[path] = true; | ||
} catch (err) { | ||
return exists[path] = false; | ||
} | ||
try { | ||
stat(this.path); | ||
return true; | ||
} catch (err) { | ||
return false; | ||
} | ||
@@ -78,0 +66,0 @@ }); |
{ | ||
"name": "express", | ||
"description": "Sinatra inspired web development framework", | ||
"version": "2.2.0", | ||
"version": "2.2.1", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
@@ -6,0 +6,0 @@ "contributors": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
86694
1829