Permalink
Browse files

Merge branch 'release/0.2.2'

  • Loading branch information...
2 parents ec9a73f + c039616 commit e92f09bbd63737f01ed05d030211a300bd442215 @aseemk committed Oct 10, 2011
Showing with 229 additions and 85 deletions.
  1. +1 −1 blocks.js
  2. +18 −0 example/app.js
  3. +39 −0 example/layout.html
  4. +19 −0 example/page.html
  5. +7 −2 package.json
  6. +11 −9 readme.md
  7. +7 −3 test/app.js
  8. +9 −0 test/child.html
  9. +0 −21 test/layout_main.html
  10. +0 −25 test/layout_site.html
  11. +23 −0 test/master.html
  12. +11 −0 test/parent.html
  13. +0 −24 test/test.html
  14. +84 −0 test/test.js
View
@@ -58,7 +58,7 @@ module.exports = function(req, res, next) {
return context.filename;
}
- req.app.helpers({
+ res.locals({
// block(name, html) adds the given HTML to the named block;
// block(name) returns the combined HTML for the named block
View
@@ -0,0 +1,18 @@
+var express = require('express');
+var app = express.createServer();
+
+app.configure(function () {
+ app.use(require('..'));
+ app.use(app.router);
+});
+
+app.set('views', __dirname);
+app.set('view engine', 'html');
+app.register('.html', require('ejs'));
+
+app.get('/', function (req, res) {
+ res.render('page');
+});
+
+app.listen(8080);
+console.log('listening on port 8080...');
View
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<head>
+
+ <meta charset=utf-8>
+ <title>Express-Blocks Example</title>
+
+ <% stylesheet('site.css') %>
+ <%- stylesheets %>
+
+</head>
+<body>
+
+ <h1>Express-Blocks Example</h1>
+
+ <h2>Site Content:</h2>
+
+ <p>
+ This content is specified by a site-wide layout. However, it can have
+ placeholders that individual pages can "fill in". The next paragraph
+ is an example:
+ </p>
+
+ <blockquote style="border-left: 4px solid silver; margin-left: 0; padding-left: 0.5em;">
+ <%- blocks.message %>
+ </blockquote>
+
+ <p>
+ In addition, this site-wide layout includes two resources:
+ <strong>site.css</strong> and <strong>site.js</strong>. View source;
+ they should preceed page-specific resources.
+ </p>
+
+ <%- body %>
+
+ <% script('site.js') %>
+ <%- scripts %>
+
+</body>
+</html>
View
@@ -0,0 +1,19 @@
+<% stylesheet('page.css') %>
+
+<% block('message', 'This paragraph is specified by the page. You can even\
+ use <em>arbitrary</em> <strong>HTML</strong>!') %>
+
+<h2>Page Content:</h2>
+
+<p>
+ This content is regular page-specific content. However, this page "filled
+ in" that paragraph above.
+</p>
+
+<p>
+ In addition, this page includes two resources: <strong>page.css</strong>
+ and <strong>page.js</strong>. View source; they should follow site-wide
+ resources.
+</p>
+
+<% script('page.js') %>
View
@@ -1,7 +1,7 @@
{
"name": "express-blocks",
"description": "Express middleware for blocks in views.",
- "version": "0.2.1",
+ "version": "0.2.2",
"repository": {
"type": "git",
"url": "git://github.com/aseemk/express-blocks.git"
@@ -17,6 +17,11 @@
"dependencies": {},
"devDependencies": {
"express": "2.2.x",
- "ejs": "0.3.x"
+ "ejs": "0.3.x",
+ "expresso": "0.7.x",
+ "jsdom": "0.2.x"
+ },
+ "scripts": {
+ "test": "expresso test/test.js"
}
}
View
@@ -50,21 +50,23 @@ Which are exposed to (top-level) layouts as blocks named `scripts` and
As Borat would say, niiice!
-Testing
+Example
-------
-Run the included Express test app:
+Run the included Express example:
+
+ node example/app.js
+
+Then open your browser to http://localhost:8080/ to see it in action.
- node test/app.js
+Testing
+-------
-Then open your browser to http://localhost:8080/ -- you should see:
+You can verify that everything works as expected via:
-* A page with three sections.
-* Three "Hello from ..." lines in the top section.
+ npm test
-And if you view source on the page, you should see three script references and
-three stylesheet references. Most importantly, both sets should be in order of
-'layout', 'page1' and 'page2'.
+If you want to submit a pull request, be sure to add a test case, too!
License
-------
View
@@ -11,8 +11,12 @@ app.set('view engine', 'html');
app.register('.html', require('ejs'));
app.get('/', function (req, res) {
- res.render('test', { foo: 'bar' });
+ // create an artificial delay to test concurrency
+ setTimeout(function () {
+ res.render('child');
+ }, 1000);
});
-app.listen(8080);
-console.log('listening on port 8080...');
+// since this is a test server, don't listen -- just return the server.
+// expresso will take care of listening.
+module.exports = app;
View
@@ -0,0 +1,9 @@
+<% layout('parent.html') %>
+
+<% stylesheet('child1.css') %>
+<% stylesheet('child2.css') %>
+
+<h3>Child</h3>
+
+<% script('child1.js') %>
+<% script('child2.js') %>
View
@@ -1,21 +0,0 @@
-<!-- use blocks.js to inject content into *parent* layout -->
-<!-- use new layout() helper to select parent layout -->
-
-<% layout('layout_site') %>
-<% stylesheet('layout.css') %>
-
-<h2>Main Layout</h2>
-<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</li>
- <li>A layout.js script</li>
- <li>A "hello" paragraph</li>
-</ul>
-
-<%- body %>
-
-<% block('foobar', '<p>Hello from layout <em>main</em>!</p>') %>
-<% script('layout.js') %>
View
@@ -1,25 +0,0 @@
-<!doctype html>
-<head>
- <meta charset=utf-8>
- <title>Nested Layouts with Blocks Demo</title>
- <!-- pull in the stylesheets defined by our child layouts/pages -->
- <%- stylesheets %>
-</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>stylesheets</t>: link rel="stylesheet" references placed before the closing 'head' tag</li>
- <li><t>scripts</t>: script references placed before the closing 'body' tag</li>
- <li><t>foobar</t>: this stuff right here: <%- blocks.foobar %>
- </ul>
-
- <%- body %>
-
- <!-- pull in the scripts defined by our child layouts/pages -->
- <%- scripts %>
-</body>
-</html>
View
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<head>
+
+ <meta charset=utf-8>
+ <title>Express-Blocks Test Site</title>
+
+ <% stylesheet('master1.css') %>
+ <% stylesheet('master2.css') %>
+ <%- stylesheets %>
+
+</head>
+<body>
+
+ <h1>Master</h1>
+
+ <%- body %>
+
+ <% script('master1.js') %>
+ <% script('master2.js') %>
+ <%- scripts %>
+
+</body>
+</html>
View
@@ -0,0 +1,11 @@
+<% layout('master.html') %>
+
+<% stylesheet('parent1.css') %>
+<% stylesheet('parent2.css') %>
+
+<h2>Parent</h2>
+
+<%- body %>
+
+<% script('parent1.js') %>
+<% script('parent2.js') %>
View
@@ -1,24 +0,0 @@
-<!-- use blocks.js to inject content into layout -->
-<!-- use new layout() helper to get nested layouts -->
-
-<% layout('layout_main') %>
-
-<% stylesheet('page1.css') %>
-<% stylesheet('page2.css') %>
-
-<h3>Index Page</h3>
-<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>Two page.css stylesheets</li>
- <li>Two page.js scripts</li>
- <li>Two "hello" lines.</li>
-</ul>
-
-<% block('foobar', '<p>Hello once from page <em>test</em>!<br/>') %>
-<% block('foobar', 'Hello again from page <em>test</em>!</p>') %>
-
-<% script('page1.js') %>
-<% script('page2.js') %>
View
@@ -0,0 +1,84 @@
+app = require('./app');
+assert = require('assert');
+jsdom = require('jsdom');
+
+function testRoot(exp) {
+ assert.response(app, {
+ url: '/'
+ }, exp);
+}
+
+exports["test basic not-broken-ness"] = function () {
+ testRoot({
+ status: 200,
+ body: /Express\-Blocks Test Site/
+ });
+};
+
+exports["test basic layout ordering"] = function () {
+ testRoot(function (res) {
+ var body = res.body;
+ var i1 = body.indexOf('<h1>Master</h1>');
+ var i2 = body.indexOf('<h2>Parent</h2>');
+ var i3 = body.indexOf('<h3>Child</h3>');
+ assert.ok(i1 < i2 && i2 < i3);
+ });
+};
+
+exports["test script ordering"] = function () {
+ testRoot(function (res) {
+ // between views, parent scripts should come before child scripts,
+ // but within a view, scripts should be in the original order.
+ jsdom.env(res.body, function (err, window) {
+ if (err) {
+ assert.fail('Unexpected: could not parse test site DOM');
+ }
+
+ scripts = window.document.getElementsByTagName('script');
+
+ // convert to node's ES5 array and map <script> tags to srcs:
+ scripts = Array.prototype.slice.call(scripts).map(function (script) {
+ return script.src;
+ })
+
+ // the srcs should match this order exactly:
+ assert.deepEqual(scripts, [
+ 'master1.js',
+ 'master2.js',
+ 'parent1.js',
+ 'parent2.js',
+ 'child1.js',
+ 'child2.js',
+ ]);
+ });
+ });
+};
+
+exports["test stylesheet ordering"] = function () {
+ testRoot(function (res) {
+ // between views, parent styles should come before child styles,
+ // but within a view, styles should be in the original order.
+ jsdom.env(res.body, function (err, window) {
+ if (err) {
+ assert.fail('Unexpected: could not parse test site DOM');
+ }
+
+ styles = window.document.getElementsByTagName('link');
+
+ // convert to node's ES5 array and map <link> tags to hrefs:
+ styles = Array.prototype.slice.call(styles).map(function (style) {
+ return style.href;
+ })
+
+ // the hrefs should match this order exactly:
+ assert.deepEqual(styles, [
+ 'master1.css',
+ 'master2.css',
+ 'parent1.css',
+ 'parent2.css',
+ 'child1.css',
+ 'child2.css',
+ ]);
+ });
+ });
+};

2 comments on commit e92f09b

gasi replied Oct 10, 2011

Nice job! :)

Owner

aseemk replied Oct 10, 2011

Thanks!

Please sign in to comment.