Created
April 5, 2011 06:52
-
-
Save laurie71/903142 to your computer and use it in GitHub Desktop.
proof-of-concept middleware to support content blocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var debug = require('util').debug; | |
// helper prototype for rendering block scripts, stylesheet links, etc | |
var blocktag = { | |
toString: function() { | |
var tag = this.tag, | |
html = '<'+tag, | |
that = this; | |
Object.getOwnPropertyNames(this).forEach(function(prop) { | |
if (prop !== 'tag') { | |
html += ' '+prop+'="'+that[prop]+'"'; | |
} | |
}); | |
if (tag === 'script') { | |
html += '></script>'; | |
} else { | |
html += ' />'; | |
} | |
return html; | |
} | |
} | |
module.exports = function(app) { | |
return function(req, res, next) { | |
// request-local hash of named blocks | |
var blocks = {}; | |
// dynamic helper for defining/rendering blocks | |
function block(name) { | |
var block, html; | |
if (arguments.length === 0) return next(new Error('unnamed block')); | |
block = blocks[name]; | |
if (arguments.length === 1) { | |
// render block contents | |
html = ''; | |
if (block) { | |
block.forEach(function(item) { | |
html = String(item) + html; | |
}); | |
} | |
debug('block: '+name+': '+JSON.stringify(block)); | |
debug('html: '+html); | |
return html; | |
} else { | |
// define/append block contents | |
if (! block) block = blocks[name] = []; | |
block.push(Array.prototype.slice.call(arguments, 1)); | |
debug('block: '+name+': '+JSON.stringify(block)); | |
return ''; | |
} | |
}; | |
// utility method for adding a script to a block | |
block.script = function(src) { | |
return Object.create(blocktag, { | |
src : { enumerable: true, value: src }, | |
tag : { enumerable: true, value: 'script' }, | |
type: { enumerable: true, value: 'text/javascript' } | |
}); | |
}; | |
// utility method for adding a stylesheet to a block | |
block.stylesheet = function(href, media) { | |
var tag = Object.create(blocktag, { | |
href: { enumerable: true, value: href }, | |
tag : { enumerable: true, value: 'link' }, | |
type: { enumerable: true, value: 'text/css' }, | |
rel : { enumerable: true, value: 'stylesheet' } | |
}); | |
if (media) { | |
tag.media = media; | |
} | |
return tag; | |
}; | |
debug('add helpers'); | |
// res.local('block', block); | |
// req.app.dynamicHelpers(block); | |
// req.app.helpers(block); | |
app.helpers({block:block}); | |
next(); | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- use blocks.js to inject content into layout --> | |
<!-- use new layout() helper to get nested layouts --> | |
<% layout('layout_main') %> | |
<% block('head', block.stylesheet('page.css')) %> | |
<% block('foot', block.script('page.js')) %> | |
<h2>Index Page</h2> | |
<p> | |
This is the main page content. | |
It is wrapped by the <t>layout_main</t> layout. | |
It adds the following blocks to the layout: | |
</p> | |
<ul><li>A page.css stylesheet in the document head</li> | |
<li>A page.js script at the document foot</li> | |
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- use blocks.js to inject content into *parent* layout --> | |
<!-- use new layout() helper to select parent layout --> | |
<% layout('layout_site') %> | |
<% block('head', block.stylesheet('layout.css')) %> | |
<% block('foot', block.script('layout.js')) %> | |
<h1>Main Layout</h1> | |
<p> | |
This is the main page layout. | |
It is wrapped by the <t>layout_site</t> layout. | |
It adds the following blocks to the layout: | |
</p> | |
<ul><li>A layout.css stylesheet in the document head</li> | |
<li>A layout.js script at the document foot</li> | |
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<head> | |
<meta charset=utf-8> | |
<title>Nested Layouts with Blocks Demo</title> | |
<!-- pull in the 'head' block content defined by our child layouts/pages --> | |
<%- block('head') %> | |
</head> | |
<body> | |
<h1>Site Layout</h1> | |
<p> | |
This is the master site layout. | |
It is not wrapped by a layout. | |
It includes the following dynamic blocks: | |
</p> | |
<ul><li><t>head</t>: a block whose content is rendered in the HTML 'head' section</li> | |
<li><t>foot</t>: a block whose content is rendered just before the closing 'body' tag</li> | |
</ul> | |
<!-- pull in the 'foot' block content defined by our child layouts/pages --> | |
<%- block('foot') %> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment