description and source-codeejs-locals = function (file, options, fn){
// Express used to set options.locals for us, but now we do it ourselves
// (EJS does some __proto__ magic to expose these funcs/values in the template)
if (!options.locals) {
options.locals = {};
}
if (!options.locals.blocks) {
// one set of blocks no matter how often we recurse
var blocks = { scripts: new Block(), stylesheets: new Block() };
options.locals.blocks = blocks;
options.locals.scripts = blocks.scripts;
options.locals.stylesheets = blocks.stylesheets;
options.locals.block = block.bind(blocks);
options.locals.stylesheet = stylesheet.bind(blocks.stylesheets);
options.locals.script = script.bind(blocks.scripts);
}
// override locals for layout/partial bound to current options
options.locals.layout = layout.bind(options);
options.locals.partial = partial.bind(options);
ejs.renderFile(file, options, function(err, html) {
if (err) {
return fn(err,html);
}
var layout = options.locals._layoutFile;
// for backward-compatibility, allow options to
// set a default layout file for the view or the app
// (NB:- not called `layout` any more so it doesn't
// conflict with the layout() function)
if (layout === undefined) {
layout = options._layoutFile;
}
if (layout) {
// use default extension
var engine = options.settings['view engine'] || 'ejs',
desiredExt = '.'+engine;
// apply default layout if only "true" was set
if (layout === true) {
layout = path.sep + 'layout' + desiredExt;
}
if (extname(layout) !== desiredExt) {
layout += desiredExt;
}
// clear to make sure we don't recurse forever (layouts can be nested)
delete options.locals._layoutFile;
delete options._layoutFile;
// make sure caching works inside ejs.renderFile/render
delete options.filename;
if (layout.length > 0 && layout[0] === path.sep) {
// if layout is an absolute path, find it relative to view options:
layout = join(options.settings.views, layout.slice(1));
} else {
// otherwise, find layout path relative to current template:
layout = resolve(dirname(file), layout);
}
// now recurse and use the current result as `body` in the layout:
options.locals.body = html;
renderFile(layout, options, fn);
} else {
// no layout, just do the default:
fn(null, html);
}
});
}