Permalink
Browse files

Initial Import

  • Loading branch information...
0 parents commit d9d9c8d159fe3200364cda8b27d3b2f3aa0eadd4 @davglass committed Mar 7, 2011
Showing with 320 additions and 0 deletions.
  1. +30 −0 LICENSE
  2. +72 −0 README.md
  3. +27 −0 examples/server.js
  4. +11 −0 examples/views/index.dust
  5. +14 −0 examples/views/layouts/main.dust
  6. +5 −0 examples/views/partials/nav.dust
  7. +133 −0 lib/dust.js
  8. +28 −0 package.json
30 LICENSE
@@ -0,0 +1,30 @@
+Software License Agreement (BSD License)
+
+Copyright (c) 2011, Dav Glass <davglass@gmail.com>.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+* The name of Dav Glass may not be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of Dav Glass.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
@@ -0,0 +1,72 @@
+# Dust Template Engine for ExpressJS
+
+This express module allows you to use [Dust]:(http://akdubya.github.com/dustjs/) as your template engine.
+
+## Install
+
+ npm install express-dust
+
+## Async Rendering
+
+Express does not support async rendering, so with this module installed you will only be able
+to use Dust as your renderer in your app. We have to override the render/partial methods on the
+prototype of the ServerResponse object in order to support the async nature of Dust.
+
+If the callback is ommitted to render/partial the response will automatically be passed to res.send
+when the Dust operation is completed.
+
+## Usage
+
+There is a simple example included in this repo under `./examples`.
+
+
+### server.js
+
+ var app = require('express').createServer();
+ var dust = require('../lib/dust');
+
+ //Sets up Global Variables to be used in all views
+ dust.makeBase({
+ copy: '&copy; 2011 Nobody LLC'
+ });
+
+ app.get('/', function(req, res, next) {
+ res.render('index', {
+ //Local Variables for this view
+ title: 'This is a test'
+ });
+ });
+
+ app.listen(8000);
+
+
+### views/layouts/main.dust
+
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <title>{+title}My Site{/title}</title>
+ </head>
+ <body>
+ {>"partials/nav"/}
+
+ {+html_body}
+ {/html_body}
+ <div id="footer">{+copy}Copyright{/copy}</footer>
+ </body>
+ </html>
+
+### views/index.dust
+
+ {>"layouts/main"/}
+
+ {<title}Foo {title}{/title}
+
+
+ {<html_body}
+ <p>This is my index.dust main body {title}</p>
+ {/html_body}
+
+ {<copy}{copy|s}{/copy}
+
@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+
+var app = require('express').createServer();
+var dust = require('../lib/dust');
+
+dust.makeBase({
+ copy: '&copy; 2011 Nobody LLC'
+});
+
+app.get('/', function(req, res, next) {
+ res.render('index', {
+ title: 'This is a test'
+ });
+});
+
+app.get('/partial', function(req, res, next) {
+ res.partial('nav');
+});
+
+app.get('/partial_html', function(req, res, next) {
+ res.partial('nav', function(err, html) {
+ res.send(html);
+ });
+});
+
+app.listen(8000);
+console.log('App listening at: http://localhost:8000/');
@@ -0,0 +1,11 @@
+{>"layouts/main"/}
+
+{<title}Foo {title}{/title}
+
+
+{<html_body}
+ <p>This is my index.dust main body {title}</p>
+{/html_body}
+
+{<copy}{copy|s}{/copy}
+
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>{+title}My Site{/title}</title>
+</head>
+<body>
+{>"partials/nav"/}
+
+{+html_body}
+{/html_body}
+<div id="footer">{+copy}Copyright{/copy}</footer>
+</body>
+</html>
@@ -0,0 +1,5 @@
+<ul>
+ <li><a href="/one">One</a></li>
+ <li><a href="/two">Two</a></li>
+ <li><a href="/three">Three</a></li>
+</ul>
@@ -0,0 +1,133 @@
+var fs = require('fs'),
+ fsPath = require('path'),
+ http = require('http'),
+
+ dust = require('dust'),
+
+ baseContext = dust.makeBase({});
+
+var mix = function(s, d) {
+ for (var i in s) {
+ d[i] = s[i]
+ }
+ return d;
+}
+
+module.exports = {
+ makeBase: function(obj) {
+ baseContext = dust.makeBase(mix(baseContext.global, obj));
+ return baseContext;
+ }
+}
+
+
+// Loads the named template the first time it's used (it will be cached for
+// later calls).
+function getView(name, callback) {
+ name = name.replace(/\.dust$/, '') + '.dust';
+ fs.readFile(fsPath.join(process.cwd(), 'views', name), 'utf8', callback);
+}
+
+dust.onLoad = getView;
+
+// This needs a setter TODO
+// Disable whitespace compression.
+dust.optimizers.format = function (context, node) {
+ return node;
+};
+
+// Duckpunch Express's res.render() method to use Dust. This is necessary
+// because Express doesn't support async template engines by default.
+http.ServerResponse.prototype.render = function (view, options, callback) {
+ var res = this;
+
+ // Support callback as second arg.
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+
+ callback || (callback = function (err, html) {
+ if (err) { res.req.next(err); return; }
+ res.send(html);
+ });
+
+ options = options ? baseContext.push(options) : baseContext;
+
+ if (res.locals) {
+ options = options.push(res.locals);
+ }
+
+ // TODO: Figure out a good way to catch parser errors. Currently Dust's
+ // parser just throws them instead of passing them to the callback.
+ // See https://github.com/akdubya/dustjs/issues#issue/12
+ if (res.app.settings.env === 'development') {
+ dust.cache = {}; // Reflect template changes without a restart.
+
+ getView(view, function (err, content) {
+ if (err) { res.req.next(err); return; }
+ dust.renderSource(content, options, callback);
+ });
+ } else {
+ dust.render(view, options, callback);
+ }
+};
+
+http.ServerResponse.prototype.partial = function (view, options, callback) {
+ var res = this,
+ req = this.req,
+ header = '',
+ ct = req.headers['content-type'],
+ setHeader = false;
+
+ // Support callback as second arg.
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+ if (!callback) {
+ setHeader = true;
+ }
+
+ var part = fsPath.join(process.cwd(), 'views', 'partials', view + '.dust');
+
+ callback || (callback = function (err, html) {
+ if (err) { res.req.next(err); return; }
+ res.send(html);
+ });
+ fsPath.exists(part, function(x) {
+ if (x) {
+ res.render('partials/' + view, function(err, html) {
+ if (err) {
+ callback(err);
+ return;
+ }
+ var data = html;
+ if (setHeader) {
+ if (ct && ct.indexOf(';') > 0) {
+ ct = ct.split(';')[0];
+ }
+ switch (ct) {
+ case 'application/json':
+ case 'text/javascript':
+ header = '.json';
+ data = { html: html };
+ break;
+ case 'text/plain':
+ header = '.txt';
+ break;
+ default:
+ header = '.html';
+ break;
+ }
+ res.contentType(header);
+ }
+ callback(null, data);
+ });
+
+ } else {
+ callback({ error: 'Not Found' });
+ }
+ });
+
+}
@@ -0,0 +1,28 @@
+{
+ "name": "express-dust",
+ "version": "0.1.0",
+ "description": "ExpressJS DustJS View Renderer",
+ "author": "Dav Glass <davglass@gmail.com> @davglass",
+ "contributors":[
+ "Ryan Grove <ryan@wonko.com> @yaypie"
+ ],
+ "bugs": { "web" : "http://github.com/davglass/express-dust/issues" },
+ "os": ["darwin", "linux"],
+ "engines": {
+ "node" : ">=0.4.0"
+ },
+ "main": "./lib/dust",
+ "dependencies": {
+ "express": ">=1.0.7"
+ },
+ "licenses":[
+ {
+ "type" : "BSD",
+ "url" : "http://github.com/davglass/express-dust/blob/master/LICENSE"
+ }
+ ],
+ "repository": {
+ "type":"git",
+ "url":"http://github.com/davglass/express-dust.git"
+ }
+}

0 comments on commit d9d9c8d

Please sign in to comment.