Skip to content
Browse files

Major update, added features for reloading files/html/js and design o…

…verlay. Also bundled socket.io
  • Loading branch information...
1 parent 91ad88a commit 69b999ab3ff997b97ebe01e47a7422fc3a2d9f48 @mape committed Nov 13, 2010
View
12 README.md
@@ -1,10 +1,20 @@
# node-express-boilerplate
-A boilerplate used to quickly get minor projects going. With less configuration.
+## What does node-express-boilerplate do?
+
+node-express-boilerplate is a collection of neat things that makes prototyping dummy frontend fast and streamlined. No more tab+refreshing to see css, javascript eller markup.
+
+* Auto updates the CSS without pageload when CSS files change.
+* Auto refreshes the page when markup or javascript files change.
+* Auto matches urls to templates without server changes. Visiting /file-name/ tries to serve file-name.ejs and has fallback to index.ejs.
+* Use the Sync button to redirect all browsers to the current page. This is handy when you want to test the design on multiple browsers and don't want to navigate to the page with each browser.
+* The Validate button shows the current validation status of the current page. If it is green the page validates, if it is red it shows how many errors there are and if you click it you get a list of what errors are present and where they are.
+* Overlay images to have a design reference.
## Requires
npm install connect
npm install connect-assetmanager
npm install connect-assetmanager-handlers
npm install express
npm install ejs
+ npm install socket.io
View
160 lib/dummy-helper.js
@@ -0,0 +1,160 @@
+var fs = require('fs');
+
+module.exports = function(app, timestamps) {
+ var timestamps = {
+ 'content': 0
+ , 'css': 0
+ };
+
+ var path = false;
+ app.get('/reload-content/', function(req, res) {
+ var timeoutCss;
+ var timeoutContent;
+ var timeoutPath;
+ var reloadCss = timestamps.css;
+ var reloadContent = timestamps.content;
+
+ (function reload () {
+ timeoutContent = setTimeout(function () {
+ if (reloadContent < timestamps.content) {
+ reloadContent = timestamps.content;
+ res.send('content');
+ reset();
+ } else {
+ reload();
+ }
+ }, 100);
+ })();
+
+ (function reload () {
+ timeoutCss = setTimeout(function () {
+ if (reloadCss < timestamps.css) {
+ reloadCss = timestamps.css;
+ res.send('css');
+ reset();
+ } else {
+ reload();
+ }
+ }, 100);
+ })();
+
+ (function reload () {
+ timeoutPath = setTimeout(function () {
+ if (path) {
+ res.send(path);
+ reset();
+ } else {
+ reload();
+ }
+ }, 100);
+ })();
+
+ function reset() {
+ if (timeoutCss) {
+ clearTimeout(timeoutCss);
+ }
+ if (timeoutCss) {
+ clearTimeout(timeoutPath);
+ }
+ if (timeoutContent) {
+ clearTimeout(timeoutContent);
+ }
+ }
+ });
+
+ app.post('/reload-content/', function(req, res) {
+ if (req.body.path) {
+ path = req.body.path;
+ setTimeout(function() {
+ path = null;
+ }, 1000);
+ }
+ res.send('');
+ });
+
+ var exec = require('child_process').exec;
+ var crypto = require('crypto');
+ var validateCache = {};
+ function getValidationSource(filePath, source, res, cacheKey) {
+ fs.writeFile(filePath, source, function (err) {
+ exec('curl -F "content=<'+filePath+';type=text/html" -F "showsource=no" http://validator.mape.me', function (error, stdout, stderr) {
+ if (stdout.indexOf('There were errors') === -1) {
+ validateCache[cacheKey] = 'ok';
+ res.send('ok');
+ } else {
+ validateCache[cacheKey] = stdout;
+ res.send(stdout);
+ }
+ fs.unlink(filePath, function() {});
+ });
+ });
+ }
+ app.post('/validate-content/', function(req, res) {
+ if (req.body.source) {
+ var cacheKey = crypto.createHash('md5').update(req.body.source).digest('hex');
+
+ if (validateCache[cacheKey] === undefined) {
+ var filePath = '/tmp/'+Date.now()+'.tmp';
+ getValidationSource(filePath, req.body.source, res, cacheKey);
+ } else {
+ res.send(validateCache[cacheKey]);
+ }
+ } else {
+ res.send('nope');
+ }
+ });
+
+ fs.readdir(app.settings.views, function(err, files) {
+ files.forEach(function(file) {
+ fs.watchFile(app.settings.views+'/'+file, function (old, newFile) {
+ if (old.mtime.toString() != newFile.mtime.toString()) {
+ timestamps.content = Date.now();
+ }
+ });
+ });
+ });
+
+ app.get(/.*/, function(req, res) {
+ var file = 'index';
+ var urlMatch = req.url.match(/\/([^\/]+)/);
+
+ if (urlMatch && urlMatch[1]) {
+ urlMatch = urlMatch[1];
+ file = urlMatch;
+ } else {
+ urlMatch = '';
+ }
+
+ fs.stat(app.settings.views+'/'+file+'.ejs', function (err, stats) {
+ if (err) {
+ file = 'index';
+ }
+ var overlayPath = 'public/img/overlays/'+file+'.png';
+ var overlayCenteredPath = 'public/img/overlays/'+file+'-center.png';
+ fs.stat(overlayPath, function (err, stats) {
+ if (err) {
+ fs.stat(overlayCenteredPath, function (err, stats) {
+ if (err) {
+ render(null);
+ } else {
+ render(file+'-center.png');
+ }
+ });
+ } else {
+ render(file+'.png');
+ }
+ });
+ });
+ function render(overlay) {
+ res.render(file, {
+ locals: {
+ 'page': (urlMatch) ? '/'+urlMatch+'/' : '/'
+ , 'date': new Date().toString()
+ , 'dummyHelperHtml': overlay ? '<div id="dummy-overlay" style="background-image: url(/img/overlays/'+overlay+');"></div>' : ''
+ }
+ });
+ }
+ });
+
+ return timestamps;
+};
View
17 lib/socket-server.js
@@ -0,0 +1,17 @@
+var io = require('socket.io');
+module.exports = function Server(server) {
+ var socket = io.listen(server);
+ socket.on('connection', function (client) {
+ client.send('welcome');
+ //setInterval(function() {
+ // client.send(Date.now());
+ //}, 100);
+ client.on('message', function (msg) {
+ console.log(msg);
+ });
+ client.on('disconnect', function () {
+ console.log('disconnect');
+ });
+ });
+ return this;
+};
View
2 nodemon-ignore
@@ -0,0 +1,2 @@
+/public/*
+/views/*
View
7 package.json
@@ -6,10 +6,11 @@
"engines" : ["node"],
"repository" : { "type":"git", "url":"http://github.com/mape/node-express-boilerplate" },
"dependencies" : {
- "connect" : ">=0.2.4",
- "connect-assetmanager" : ">=0.0.4",
- "connect-assetmanager-handlers" : ">=0.0.6",
+ "connect" : ">=0.2.7",
+ "connect-assetmanager" : ">=0.0.12",
+ "connect-assetmanager-handlers" : ">=0.0.12",
"ejs" : ">=0.2.0",
"express" : ">=1.0.0"
+ "socket.io" : ">=0.6.0"
}
}
View
11 public/css/client.css
@@ -8,13 +8,13 @@
html
{
height: 100%;
- gradient: #222_#555;
+ gradient: purple_yellow;
}
body
{
height: 100%;
-vendor-box-sizing: border-box;
- background: url(/img/bg.png);
+ background: data-url(/img/bg.png);
color: #000;
margin: 0;
font: 12px 'helvetica neue', helvetica, arial, sans-serif;
@@ -36,7 +36,7 @@ h1,h2
h1
{
color: #111;
- font-size: 25px;
+ font-size: 27px;
}
h2
{
@@ -81,14 +81,15 @@ li
{
list-style: outside;
padding: 5px 0;
+ line-height: 1.4;
}
#page-container
{
width: 550px;
position: absolute;
top: 50%;
left: 50%;
- margin: -75px 0 0 -290px;
+ margin: -165px 0 0 -315px;
border: 1px rgba(255,255,255,0.3) solid;
gradient: rgba(255,255,255,0.5)_rgba(255,255,255,0.1);
-vendor-box-shadow: 0px 0px 15px rgba(0,0,0,0.3), 0px 0px 10px rgba(0,0,0,0.2) inset;
@@ -112,5 +113,5 @@ li
padding: 0px 10px;
display: inline-block;
position: relative;
- margin: 0 0 0 11px;
+ margin: 0 0 0 14px;
}
View
22 public/css/frontend-development.css
@@ -1,6 +1,7 @@
body
{
margin-right: 40px;
+ position: relative;
}
#frontend-development
{
@@ -34,8 +35,8 @@ body
#frontend-development > div.ok
{
color: #fff;
- gradient: #029b02_#027402;
- border: 1px solid #026302;
+ gradient: #46c93c_#3cae33;
+ border: 1px solid #1c5d17;
}
#frontend-development > div.bad
{
@@ -51,7 +52,7 @@ body
top: 50%;
left: 50%;
margin: -8px 0 0 -8px;
- background: data-url(/img/frontend-development/ajax-loading.gif);
+ background:url(data:image/gif;base64,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);
}
#frontend-development-validation-errors
{
@@ -139,4 +140,17 @@ body
text-align: center;
cursor: pointer;
margin: -9px -4px 0 0;
-}
+}
+#dummy-overlay
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ bottom: 0;
+ background-repeat: no-repeat;
+}
+#dummy-overlay.center
+{
+ background-position: top center;
+}
View
BIN public/img/bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
36 public/js/jquery.client.js
@@ -1,3 +1,5 @@
+WEB_SOCKET_SWF_LOCATION = '/swf/WebSocketMain.swf';
+
if (!window.console) {
var console = {
'log': function(){}
@@ -6,8 +8,38 @@ if (!window.console) {
, 'timeEnd': function(){}
, 'profile': function(){}
, 'profileEnd': function(){}
+ };
+}
+
+var domCache = {};
+function $$(selector) {
+ if (!domCache[selector]) {
+ domCache[selector] = $(selector);
}
+ return domCache[selector];
}
+
(function ($) {
- $('body').removeClass('nojs');
-})(jQuery.noConflict());
+ $$('body').removeClass('nojs');
+ var server = new io.Socket(null, {
+ 'port': '#socketIoPort#'
+ , 'rememberTransport': true
+ , 'transports': [
+ 'websocket'
+ , 'flashsocket'
+ , 'htmlfile'
+ , 'xhr-multipart'
+ , 'xhr-polling'
+ ]
+ });
+ server.on('connect', function() {
+ console.log('connect');
+ });
+ server.on('message', function(msg) {
+ console.log(msg);
+ });
+ server.on('disconnect', function() {
+ console.log('disconnect');
+ });
+ server.connect();
+})(jQuery);
View
31 public/js/jquery.frontend-development.js
@@ -15,7 +15,8 @@ var doReload = true;
}
});
}
- }(function reload($) {
+ }
+ (function reload($) {
$.ajax({
'url': '/reload-content/'
, 'cache': false
@@ -44,7 +45,7 @@ var doReload = true;
}
});
})($);
- var $toolbar = $('<div id="frontend-development"></div>').appendTo('html');
+ var $toolbar = $('<div id="frontend-development"></div>').appendTo('body');
var $refresh = $('<div title="Sync all browsers to this page" class="sync">S</div>').click(function (event) {
doMoveAjax(currentPath);
@@ -75,10 +76,13 @@ var doReload = true;
var $errorContainer = $('<ul id="frontend-development-validation-errors"/>').appendTo('html').hide();
var count;
$(html).find('li.error').each(function(index) {
- $errorContainer.append('<li>'+$(this).html()+'</li>')
+ $errorContainer.append('<li>'+$(this).html()+'</li>');
count = index+1;
});
- $validate.append('<div class="validation-errors">'+count+'</div>');
+ if (count === undefined) {
+ return;
+ }
+ $validate.append('<div class="validation-errors">'+(count || '')+'</div>');
$validate.stop().animate({'opacity': 0.3}, 500).animate({'opacity': 1}, 500);
pulseInterval = setInterval(function() {
$validate.stop().animate({'opacity': 0.3}, 500).animate({'opacity': 1}, 500);
@@ -98,6 +102,23 @@ var doReload = true;
});
}
});
- }).appendTo($toolbar)
+ }).appendTo($toolbar);
$validate.click();
+
+ var $overlay = $('#dummy-overlay');
+ if ($overlay.length) {
+ if ($overlay.attr('style').match(/-center/)) {
+ $overlay.addClass('center');
+ }
+ $('html').live('click', function(event) {
+ if (toggleAnimation) {
+ clearInterval(toggleAnimation);
+ }
+ $overlay.toggle();
+ });
+ $overlay.stop().fadeTo(500, 0).fadeTo(500, 1);
+ var toggleAnimation = setInterval(function() {
+ $overlay.stop().fadeTo(500, 0).fadeTo(500, 1);
+ }, 1000);
+ }
})(jQuery);
View
6,241 public/js/jquery.js
0 additions, 6,241 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
BIN public/swf/WebSocketMain.swf
Binary file not shown.
View
191 server.js
@@ -1,35 +1,44 @@
+process.title = 'node-dummy';
+process.addListener('uncaughtException', function (err, stack) {
+ console.log('Caught exception: ' + err);
+ console.log(err.stack.split('\n'));
+});
var connect = require('connect');
var assetManager = require('connect-assetmanager');
var assetHandler = require('connect-assetmanager-handlers');
var express = require('express');
+var DummyHelper = require('./lib/dummy-helper');
+var SocketServer = require('./lib/socket-server');
var fs = require('fs');
-
-process.title = 'node-express-boilerplate';
-process.addListener('uncaughtException', function (err, stack) {
- console.log('Caught exception: ' + err);
- console.log(err.stack.split('\n'));
-});
-
var assets = assetManager({
'js': {
'route': /\/static\/js\/[0-9]+\/.*\.js/
, 'path': './public/js/'
, 'dataType': 'js'
, 'files': [
- 'jquery.js'
+ 'http://cdn.socket.io/stable/socket.io.js'
+ , 'http://code.jquery.com/jquery-latest.js'
, '*'
, 'jquery.client.js'
, 'jquery.frontend-development.js'
]
, 'preManipulate': {
- '^': []
+ '^': [
+ function (file, path, index, isLast, callback) {
+ if (path.match(/jquery.client/)) {
+ callback(file.replace(/'#socketIoPort#'/, port));
+ } else {
+ callback(file);
+ }
+ }
+ ]
}
, 'postManipulate': {
'^': [
- function (file, path, index, isLast, callback) {
- // Enables live JS editing auto reload.
+ assetHandler.uglifyJsOptimize
+ , function (file, path, index, isLast, callback) {
callback(file);
- lastChangedContent = Date.now();
+ dummyTimestamps.content = Date.now();
}
]
}
@@ -40,28 +49,32 @@ var assets = assetManager({
, 'files': [
'reset.css'
, '*'
- , 'client.css'
, 'frontend-development.css'
]
, 'preManipulate': {
- '^': [
+ 'msie [6-7]': [
+ assetHandler.fixVendorPrefixes
+ , assetHandler.fixGradients
+ , assetHandler.stripDataUrlsPrefix
+ ]
+ , '^': [
assetHandler.fixVendorPrefixes
, assetHandler.fixGradients
, assetHandler.replaceImageRefToBase64(__dirname + '/public')
]
}
, 'postManipulate': {
'^': [
- function (file, path, index, isLast, callback) {
- // Enables live CSS editing without reload.
+ assetHandler.yuiCssOptimize
+ , function (file, path, index, isLast, callback) {
callback(file);
- lastChangedCss = Date.now();
+ dummyTimestamps.css = Date.now();
}
]
}
}
});
-
+var port = 666;
var app = module.exports = express.createServer();
app.configure(function() {
@@ -72,143 +85,29 @@ app.configure(function() {
app.configure(function() {
app.use(connect.conditionalGet());
app.use(connect.bodyDecoder());
- app.use(connect.logger());
+ app.use(connect.logger({ format: ':req[x-real-ip]\t:status\t:method\t:url\t' }));
app.use(assets);
app.use(connect.staticProvider(__dirname + '/public'));
});
app.dynamicHelpers({
- cacheTimeStamps: function(req, res) {
+ 'cacheTimeStamps': function(req, res) {
return assets.cacheTimestamps;
}
});
-app.configure('development', function() {
- app.use(connect.errorHandler({ dumpExceptions: true, showStack: true }));
-
- // Set as global to allow assetmaanger to change
- lastChangedContent = 0;
- lastChangedCss = 0;
- var path = false;
- app.get('/reload-content/', function(req, res) {
- var timeoutCss;
- var timeoutContent;
- var timeoutPath;
- var reloadCss = lastChangedCss;
- var reloadContent = lastChangedContent;
- (function reload () {
- timeoutContent = setTimeout(function () {
- if (reloadContent < lastChangedContent) {
- reloadContent = lastChangedContent;
- res.send('content');
- reset();
- } else {
- reload();
- }
- }, 100);
- })();
- (function reload () {
- timeoutCss = setTimeout(function () {
- if (reloadCss < lastChangedCss) {
- reloadCss = lastChangedCss;
- res.send('css');
- reset();
- } else {
- reload();
- }
- }, 100);
- })();
- (function reload () {
- timeoutPath = setTimeout(function () {
- if (path) {
- res.send(path);
- reset();
- } else {
- reload();
- }
- }, 100);
- })();
-
- function reset() {
- if (timeoutCss) {
- clearTimeout(timeoutCss);
- }
- if (timeoutCss) {
- clearTimeout(timeoutPath);
- }
- if (timeoutContent) {
- clearTimeout(timeoutContent);
- }
- }
- });
-
- app.post('/reload-content/', function(req, res) {
- if (req.body.path) {
- path = req.body.path;
- setTimeout(function() {
- path = null;
- }, 1000);
- }
- res.send('');
- });
-
- var exec = require('child_process').exec;
- var crypto = require('crypto');
- var validateCache = {};
- function getValidationSource(filePath, source, res, cacheKey) {
- fs.writeFile(filePath, source, function (err) {
- exec('curl -F "content=<'+filePath+';type=text/html" -F "showsource=no" http://validator.mape.me', function (error, stdout, stderr) {
- if (stdout.indexOf('There were errors') === -1) {
- validateCache[cacheKey] = 'ok';
- res.send('ok');
- } else {
- validateCache[cacheKey] = stdout;
- res.send(stdout);
- }
- fs.unlink(filePath, function() {});
- });
- });
- }
- app.post('/validate-content/', function(req, res) {
- if (req.body.source) {
- var cacheKey = crypto.createHash('md5').update(req.body.source).digest('hex');
-
- if (validateCache[cacheKey] === undefined) {
- var filePath = '/tmp/'+Date.now()+'.tmp';
- getValidationSource(filePath, req.body.source, res, cacheKey);
- } else {
- res.send(validateCache[cacheKey]);
- }
- } else {
- res.send('nope');
- }
- });
-
- fs.readdir(app.settings.views, function(err, files) {
- files.forEach(function(file) {
- fs.watchFile(app.settings.views+'/'+file, function (old, newFile) {
- if (old.mtime.toString() != newFile.mtime.toString()) {
- lastChangedContent = Date.now();
- }
- });
- });
- });
+// Examples
+app.get('/your-page/', function(req, res) {
+ res.render('index', { locals: { 'key': 'value' } });
});
-app.get('/', function(req, res) {
- res.render('index', {
- locals: {
- 'page': '/'
- , 'date': new Date().toString()
- }
- });
+
+app.post(/some-path/, function(req, res) {
+ console.log(req.body);
+ res.render('index', { locals: { 'key': 'value' } });
});
-app.get('/1/', function(req, res) {res.render('index', {locals:{'page': '/1/', 'date': new Date().toString()}});});
-app.get('/2/', function(req, res) {res.render('index', {locals:{'page': '/2/', 'date': new Date().toString()}});});
-app.get('/3/', function(req, res) {res.render('index', {locals:{'page': '/3/', 'date': new Date().toString()}});});
-app.get('/4/', function(req, res) {res.render('index', {locals:{'page': '/4/', 'date': new Date().toString()}});});
-app.get('/5/', function(req, res) {res.render('index', {locals:{'page': '/5/', 'date': new Date().toString()}});});
-app.get('/6/', function(req, res) {res.render('index', {locals:{'page': '/6/', 'date': new Date().toString()}});});
-app.get('/7/', function(req, res) {res.render('index', {locals:{'page': '/7/', 'date': new Date().toString()}});});
-app.get('/8/', function(req, res) {res.render('index', {locals:{'page': '/8/', 'date': new Date().toString()}});});
-app.listen(666);
+// Keep this just above .listen()
+var dummyTimestamps = new DummyHelper(app);
+
+app.listen(port, null);
+new SocketServer(app);
View
17 views/index.ejs
@@ -1,4 +1,4 @@
-<div title="test" id="page-container">
+<div id="page-container">
<h1><%= date %></h1>
<h2><%= page %></h2>
<hr>
@@ -12,17 +12,18 @@
<a class="button" href="/5/">5</a>
<a class="button" href="/6/">6</a>
<a class="button" href="/7/">7</a>
- <a class="button" href="/8/">8</b>
+ <a class="button" href="/8/">8</a>
</div>
<hr>
- <h3>What does node-dummy do?</h3>
+ <h3>What does node-express-boilerplate do?</h3>
<p>
- <a href="http://github.com/mape">node-dummy</a> is a collection of neat things that makes prototyping dummy frontend fast and streamlined. No more tab+refreshing to see css changes or when altering markup.
+ <a href="http://github.com/mape">node-express-boilerplate</a> is a collection of neat things that makes prototyping the frontend fast and streamlined. No more tab+refreshing to see css, javascript eller markup.
</p>
<ul>
- <li>Auto reload the CSS without pageload when CSS files change.</li>
- <li>Auto reload the page when markup or javascript files change.</li>
+ <li>Auto updates the CSS <strong>without pageload</strong> when CSS files change.</li>
+ <li>Auto refreshes the page when markup or javascript files change.</li>
+ <li>Auto matches urls to templates without server changes. Visiting /file-name/ tries to serve file-name.ejs and has fallback to index.ejs.</li>
<li>Use the <strong>Sync button</strong> to redirect all browsers to the current page. This is handy when you want to test the design on multiple browsers and don't want to navigate to the page with each browser.</li>
- <li>Use the <strong>Validate button</strong> to make sure the markup is valid.</li>
+ <li>The <strong>Validate button</strong> shows the current validation status of the current page. If it is green the page validates, if it is red it shows how many errors there are and if you click it you get a list of what errors are present and where they are.</li>
</ul>
-</div>
+</div>
View
16 views/layout.ejs
@@ -1,14 +1,18 @@
<!DOCTYPE html>
<html>
<head>
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <link rel="stylesheet" href="/static/css/1286786505000/style.css" type="text/css">
- <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">
- <title>node-dummy</title>
+ <link rel="stylesheet" href="/static/css/<%=cacheTimeStamps.css%>/style.css" type="text/css">
+ <title>node-express-boilerplate</title>
</head>
-<body class="nojs">
+<!--[if lt IE 7 ]> <body class="ie6 ie nojs"> <![endif]-->
+<!--[if IE 7 ]> <body class="ie7 ie nojs"> <![endif]-->
+<!--[if IE 8 ]> <body class="ie8 ie nojs"> <![endif]-->
+<!--[if IE 9 ]> <body class="ie9 ie nojs"> <![endif]-->
+<!--[if !IE]><!--> <body class="nojs"> <!--<![endif]-->
<%- body %>
- <script src="/static/js/1286966542000/client.js" type="text/javascript"></script>
+ <% if (locals.dummyHelperHtml) {%><%- dummyHelperHtml%><% } %>
+ <script src="/static/js/<%=cacheTimeStamps.js%>/client.js" type="text/javascript"></script>
</body>
</html>

0 comments on commit 69b999a

Please sign in to comment.
Something went wrong with that request. Please try again.