Skip to content

Commit

Permalink
Merge pull request #369 from thelastshadow/master
Browse files Browse the repository at this point in the history
Handlesbars rebased
  • Loading branch information
Dennis Bartlett committed May 7, 2013
2 parents 5855de3 + 3a48221 commit a563a7b
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 5 deletions.
10 changes: 10 additions & 0 deletions bin/boilerplates/hbs/404.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Page not found</h1>

<h2>The view you were trying to reach does not exist.</h2>


<style type="text/css">
/* Styles included inline since you'll probably be deleting this page anyway */
body{font:14px Helvetica,Arial,sans-serif}html{background:#e0e0e0}p{margin:3% 1% 3% 0}a{color:#00b7ff}input{padding:.5em;width:50%}h1{font-size:28px;font-weight:bold;margin:20px 0 15px;color:#444;text-shadow:0 0 5px rgba(150,150,150,0.6)}h2{color:#444;text-shadow:0 0 5px rgba(150,150,150,0.6);font-size:18px;font-weight:bold;margin:10px 0 10px}h3{font-size:18px;font-weight:bold;margin:10px 0 10px;color:#eee;text-shadow:0 0 5px rgba(0,0,0,0.6)}#controllers li a{background:#eee;border-radius:8px;padding:.5em 1em;margin-bottom:.3em;display:block;width:50%}#topbar{width:100%;padding:0 2em;background:black;position:fixed;top:0;left:0;z-index:100;box-shadow:0 2px 2px rgba(100,100,100,0.5)}#branding{margin:0;text-shadow:none;padding:12px 0 0;height:35px;font-size:19px;font-weight:normal;color:white;width:100px;float:left}#branding a{color:white}#topbar{overflow:auto}#topbar li{float:left}#topbar li a{color:#aaa;font-size:.94em;height:30px;padding:17px 1.5em 0;display:block}#topbar li a:hover{color:#ccc}#topbar li a.selected{color:#ddd;background:#444;font-weight:bold;font-size:.94em;height:30px;padding:17px 1.5em 0;display:block}#topbar-dropdown{float:right;margin-top:15px;margin-right:45px}#content{background:#c0c0c0;padding:50px 20px 30px;box-shadow:0 3px 1px rgba(150,150,150,0.2)}img.spinner{padding:.5em;margin:0 auto;display:block}#footer{padding:1em 0 3em;color:#999;font-size:.85em}#footer .copyright{color:#777;margin-left:2em;opacity:.8}#footer .copyright:hover{opacity:1;text-decoration:underline}input.error{border-color:red}span.error{display:block;font-size:85%;color:red}.mobile-only{display:none}@media screen and (max-width:980px){input.ui-list-search{width:45%;padding-top:7px;padding-bottom:7px}}@media screen and (max-width:480px){.widescreen-nav{display:none}a.create-node{margin-bottom:1em}input.ui-list-search{width:auto;display:block;float:none!important;margin-left:0;margin-right:0;margin-top:1em;clear:both}.mobile-only{display:block}}
</style>
11 changes: 11 additions & 0 deletions bin/boilerplates/hbs/500.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<h1>Error</h1>

{{#error errors}}
<code>{{error}}</code>
{{/error}}

<style type="text/css">
/* Styles included inline since you'll probably be deleting this page anyway */
body{font:14px Helvetica,Arial,sans-serif}html{background:#e0e0e0}p{margin:3% 1% 3% 0}a{color:#00b7ff}input{padding:.5em;width:50%}h1{font-size:28px;font-weight:bold;margin:20px 0 15px;color:#444;text-shadow:0 0 5px rgba(150,150,150,0.6)}h2{color:#444;text-shadow:0 0 5px rgba(150,150,150,0.6);font-size:18px;font-weight:bold;margin:10px 0 10px}h3{font-size:18px;font-weight:bold;margin:10px 0 10px;color:#eee;text-shadow:0 0 5px rgba(0,0,0,0.6)}#controllers li a{background:#eee;border-radius:8px;padding:.5em 1em;margin-bottom:.3em;display:block;width:50%}#topbar{width:100%;padding:0 2em;background:black;position:fixed;top:0;left:0;z-index:100;box-shadow:0 2px 2px rgba(100,100,100,0.5)}#branding{margin:0;text-shadow:none;padding:12px 0 0;height:35px;font-size:19px;font-weight:normal;color:white;width:100px;float:left}#branding a{color:white}#topbar{overflow:auto}#topbar li{float:left}#topbar li a{color:#aaa;font-size:.94em;height:30px;padding:17px 1.5em 0;display:block}#topbar li a:hover{color:#ccc}#topbar li a.selected{color:#ddd;background:#444;font-weight:bold;font-size:.94em;height:30px;padding:17px 1.5em 0;display:block}#topbar-dropdown{float:right;margin-top:15px;margin-right:45px}#content{background:#c0c0c0;padding:50px 20px 30px;box-shadow:0 3px 1px rgba(150,150,150,0.2)}img.spinner{padding:.5em;margin:0 auto;display:block}#footer{padding:1em 0 3em;color:#999;font-size:.85em}#footer .copyright{color:#777;margin-left:2em;opacity:.8}#footer .copyright:hover{opacity:1;text-decoration:underline}input.error{border-color:red}span.error{display:block;font-size:85%;color:red}.mobile-only{display:none}@media screen and (max-width:980px){input.ui-list-search{width:45%;padding-top:7px;padding-bottom:7px}}@media screen and (max-width:480px){.widescreen-nav{display:none}a.create-node{margin-bottom:1em}input.ui-list-search{width:auto;display:block;float:none!important;margin-left:0;margin-right:0;margin-top:1em;clear:both}.mobile-only{display:block}}
</style>
3 changes: 3 additions & 0 deletions bin/boilerplates/hbs/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
viewEngine: 'hbs'
};
23 changes: 23 additions & 0 deletions bin/boilerplates/hbs/index.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<h1 id="header">
<a href="/">New Sails App</a>
</h1>
<div id="content">
<h2>It works!</h2>

<p>You've successfully installed the Sails Framework.</p>

<p>Sails is a modern, realtime MVC framework for the Node.js platform. <br/> <span class="highlight">It helps you build apps fast.</span></p>

<p>
<a href="https://github.com/balderdashy/sails/wiki" class="button"><span>Documentation</span></a>
<a href="https://github.com/balderdashy/sails/wiki/Changelog" class="button"><span>Changelog</span></a>
</p>
</div>

<div id="footer">
<a target="_blank" href="http://sailsjs.com" class="copyright">Built with Sails.js</a>
</div>

<style type="text/css">
body{font-size:1em;line-height:1.5;background:#e7e7e7;font-family:'Helvetica Neue',Helvetica,Arial,serif;text-shadow:0 1px 0 rgba(255,255,255,0.8);color:#6d6d6d}#header{width:100%;background:#fff;margin-bottom:25px}#header a{padding:25px 0;width:620px;margin:0 auto;color:#158ea1;display:block;font-weight:800}#content,#footer{width:620px;margin:0 auto}h2{font-size:32px}p{font-weight:300;margin-bottom:20px}a,a:hover{color:#c5000c}p a{font-weight:bold}a.button{-moz-border-radius:30px;-webkit-border-radius:30px;border-radius:30px;border-top:solid 1px #cbcbcb;border-left:solid 1px #b7b7b7;border-right:solid 1px #b7b7b7;border-bottom:solid 1px #b3b3b3;color:#303030;line-height:25px;font-weight:bold;font-size:15px;padding:12px 8px 12px 8px;display:inline-block;width:179px;margin-right:14px;background:#fdfdfd;background:-moz-linear-gradient(top,#fdfdfd 0,#f2f2f2 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fdfdfd),color-stop(100%,#f2f2f2));background:-webkit-linear-gradient(top,#fdfdfd 0,#f2f2f2 100%);background:-o-linear-gradient(top,#fdfdfd 0,#f2f2f2 100%);background:-ms-linear-gradient(top,#fdfdfd 0,#f2f2f2 100%);background:linear-gradient(top,#fdfdfd 0,#f2f2f2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdfdfd',endColorstr='#f2f2f2',GradientType=0);-webkit-box-shadow:10px 10px 5px #888;-moz-box-shadow:10px 10px 5px #888;box-shadow:0 1px 5px #e8e8e8}a.button:hover{border-top:solid 1px #b7b7b7;border-left:solid 1px #b3b3b3;border-right:solid 1px #b3b3b3;border-bottom:solid 1px #b3b3b3;background:#fafafa;background:-moz-linear-gradient(top,#fdfdfd 0,#f6f6f6 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fdfdfd),color-stop(100%,#f6f6f6));background:-webkit-linear-gradient(top,#fdfdfd 0,#f6f6f6 100%);background:-o-linear-gradient(top,#fdfdfd 0,#f6f6f6 100%);background:-ms-linear-gradient(top,#fdfdfd 0,#f6f6f6 100%);background:linear-gradient(top,#fdfdfd 0,#f6f6f6,100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdfdfd',endColorstr='#f6f6f6',GradientType=0)}a.button span{padding-left:30px;padding-right:30px;display:block;height:23px;text-align:center}.highlight{border-bottom:1px solid #158ea1}#footer{border-top:1px solid #cacaca;margin-top:40px;padding-top:20px;padding-bottom:30px;font-size:13px;color:#AAA}
</style>
20 changes: 20 additions & 0 deletions bin/boilerplates/hbs/layout.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>{{title}}></title>

<!-- Viewport mobile tag for sensible mobile support -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

<!-- JavaScript and stylesheets from your assets folder are included here -->
{{assets 'css'}}
{{assets 'js'}}
</head>

<body>
{{{body}}}

<!-- Templates from your view path are included here -->
{{assets 'tpl'}}
</body>
</html>
6 changes: 6 additions & 0 deletions bin/sails.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,12 @@ function createNewApp(appName, templateLang) {
generateFile('haml/404.haml', 'views/404.haml'); // Create 404, 500, and 422/403 pages
generateFile('haml/500.haml', 'views/500.haml');
generateFile('haml/config.js', 'config/views.js'); // Create views.js config
} else if (templateLang === 'handlebars' || templateLang === 'hbs') {
generateFile('hbs/index.hbs', 'views/home/index.hbs');
generateFile('hbs/404.hbs', 'views/404.hbs');
generateFile('hbs/500.hbs', 'views/500.hbs');
generateFile('hbs/layout.hbs', 'views/layout.hbs');
generateFile('hbs/config.js', 'config/views.js');
} else {
generateFile('ejs/index.ejs', 'views/home/index.ejs');
generateFile('ejs/404.ejs', 'views/404.ejs'); // Create 404, 500, and 422/403 pages
Expand Down
75 changes: 75 additions & 0 deletions lib/configuration/express.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,81 @@ exports.configure = function configure(cb) {
// Connect session to express
sails.express.app.use(express.session(sails.config.session));

/**
* Some handlebars specific methods.
*/
if (sails.config.viewEngine === 'hbs' && typeof sails.config.viewEngineModule !== 'undefined') {
var hbs = sails.config.viewEngineModule;

/**
* Allow handlebars templates (hbs) to access asset-stack in templates with {{assets 'css'}}
* also map {{assets 'tpl'}} to assets.templateLibrary()
*/
hbs.registerHelper('assets', function(type) {
type = (type === 'tpl') ? 'templateLibrary' : type;

/**
* Don't escape the html this outputs
*/
return new hbs.handlebars.SafeString(assets[type]());
});

/**
* Allow output of errors with {{error errors}}
*/
hbs.registerHelper('error', function(context, options) {
if (typeof context === 'array') {
var out = "";

for(var i=0, j=context.length; i<j; i++) {
out = out + options.fn(context[i]);
}

return out;
}
else if( typeof context === 'object') {
var out = "";

for(var i in context) {
out = out + options.fn(context[i]);
}

return out;
}
});

/**
* Allow handlebars partials in templates with {{> partialName}}
*
* Shamelessly stolen from Ben Williamson (http://stackoverflow.com/a/12700409/745190)
*/
var partialsDir = sails.config.paths.views + '/partials';


fs.stat(partialsDir, function(err){
if (!err) {
fs.readdir(partialsDir, function(err, filenames){
if (!err) {
filenames.forEach(function (filename) {
if (!err) {
var matches = /^([^.]+).hbs$/.exec(filename);
if (!matches) {
return;
}
var name = matches[1];
var template = fs.readFile(partialsDir + '/' + filename, 'utf8', function(err, template){
if (!err) {
hbs.registerPartial(name, template);
}
});
}
});
}
});
}
});
}

// Add annoying Sails header instead of annoying Express header
sails.express.app.use(function(req, res, next) {
res.header('X-Powered-By', 'Sails <sailsjs.org>');
Expand Down
11 changes: 8 additions & 3 deletions lib/configuration/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ module.exports = function (config, originalUserConfig) {
}
}

// View engines != ejs are not currently supported
if (config.viewEngine !== "ejs" && config.viewEngine !== "jade") {
throw new Error ("Sorry, only the ejs and jade view engines are supported at this time. You specified: "+config.viewEngine);
/**
* EJS, Jade and Moustache (hbs) are supported
*/
var allowedViewEngines = [
"ejs", "jade", "handlebars", "hbs"
];
if (allowedViewEngines.indexOf(config.viewEngine) === -1) {
throw new Error ("Sorry, only the ejs, jade and handlebars view engines are supported at this time. You specified: " + config.viewEngine);
}

// // Ignore invalid items in assets sequence
Expand Down
8 changes: 8 additions & 0 deletions lib/sails.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var CaptainsLogger = require('./util/logger');
// Templating
var ejs = require('ejs');
var jade = require('jade');
var hbs;
var handlebars = hbs = require('hbs');

// Sails ecosystem defaults
sails.waterline = require('./waterline');
Expand Down Expand Up @@ -125,6 +127,12 @@ function loadSails(configOverride, cb) {
// Validate user config
sails.config = configuration.validate(sails.config, userConfig);

/**
* Let's keep a copy of the templating engine in the config.
* We need this for handlebars so we can register some helper functions.
*/
sails.config.viewEngineModule = require(sails.config.viewEngine);

// Indicate that server is starting
sails.log("Starting server in " + sails.config.appPath + "...");

Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@
{
"name": "Colin Wren",
"email": "colin@cawren.com"
},
{
"name": "Robin Cafolla",
"email": "robin@zombiemongoose.com"
}
],
"version": "0.8.91",
"version": "0.8.91-hbs",
"description": "API-driven framework for building realtime apps, using MVC conventions (based on Express and Socket.io)",
"homepage": "http://sailsjs.com",
"keywords": [
Expand Down Expand Up @@ -107,7 +111,8 @@
"inflection": "~1.2.5",
"node-typescript": "0.1.3",
"coffee-script": "1.6.2",
"connect-redis": "1.4.5"
"connect-redis": "1.4.5",
"hbs": "2.1.0"
},
"devDependencies": {
"mocha": "*",
Expand Down

0 comments on commit a563a7b

Please sign in to comment.