Package Exports
- motley
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (motley) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme

an alternative rapid web development framework
Idea
Motley is an "alternative" framework whose goal is to bundle independently usable modules into a cohesive workflow for rapid website development. You won't see any monolithic implementations going on here. Think of it as a starter kit for your app, and a plugin-centric pattern of development.
Featured modules
- middler - http router and middleware runner
- buffet - static asset server
- templ - renderer for handlebars-based templates
- expres - Express.js compatibility layer
- sess - session handler
- haredis - high-availability redis client
- modeler - schemaless db-agnostic entity system (redis store used by default)
Several useful utilities are also packaged including dish, formidable, glob and request.
Bootstrap
When you initially require('motley') from your app, you get three things:
app: Motley exports a global (singleton) app object, so there's no need to create it. It's also anEventEmitterif you like sort kind of thing.app.boot(cb): Reads./conf.ymlor./conf.json(if exists) and puts the parsed result onapp.conf. Also reads./package.json(if exists) and puts that onapp.pkg. Callscbafter, with anerrif anything went wrong.app.motley(): Synchronously loads all of Motley's built-in plugins, middleware and your app's plugins and middleware onapp, in that order.
Example server.js:
var app = require('motley');
app.boot(function (err) {
if (err) throw err;
// (if we have any core overrides, they go here)
app.motley();
// (this is where we call app.server.listen(), if this is a web app)
});Note that unlike other frameworks, Motley will NOT call listen() on the server
for you. Your app MUST call app.server.listen() to serve requests! This allows
you to
- use port registries such as amino or seaport
- handle the
listeningevent however you want - re-use your plugins/models in CLI/cron situations when activating the server would be undesirable
- use an app as a plugin inside another app - "appception"!
Middleware
Middleware are a simple way of incrementally handling an HTTP request, by defining a
function that interacts with server req and res streams, and calling
next() to continue to the next handler, or next(err) if something went wrong.
To control ordering, you may export an optional weight property, with -1000
being equivalent to middler().first(), 0 being neutral, and 1000 being
equivalent to middler().last().
Auto loading: Any paths in your project matching ./middleware/**.js will be automatically
required when app.motley() is called, and the exports of those files are expected
to be functions that take req, res, next as arguments.
Example
var app = require('motley');
module.exports = function (req, res, next) {
// do something with request or response...
next();
};
// "heavy" weights run after other middleware
module.exports.weight = 1000;Controllers
Controllers are where routes are defined, logic is performed for requests, and templates are rendered.
A Motley controller is simply a node module which exports an unattached instance of
middler. For convenience, a new
instance of middler can be acquired by calling app.controller().
Auto loading: Any paths in your project matching ./controllers/**.js will
be automatically required when app.motley() is called, and the exports of
those files are expected to be middler
instances OR middleware handlers.
Example
var app = require('motley')
, marked = require('marked')
require('../models/posts');
function requireAuth (req, res, next) {
if (req.user) next();
else res.renderStatus(403);
}
module.exports = app.controller()
.get('/', function (req, res, next) {
var posts = [];
app.posts.tail({load: true}, function (err, chunk, next) {
if (err) return next(err);
posts = posts.concat(chunk);
if (chunk.length && next) next();
else res.render('index', {
title: 'motley example',
user: req.user,
posts: posts
});
});
})
.get('/posts/:id', function (req, res, next) {
app.posts.load(req.params.id, function (err, post) {
if (err) return next(err);
if (post) res.render('post', post);
else res.renderStatus(404);
});
})
.post('/posts', requireAuth, function (req, res, next) {
req.body.content = marked(req.body.body);
req.body.author_id = req.user.id;
app.posts.create(req.body, function (err, post) {
if (err) return next(err);
res.redirect('/posts/' + post.id);
});
})Plugins
Plugins in Motley are a simple way of bolting on functionality to app by
modifying the global state when the plugin is required. Use it to expose APIs
for your controllers or middleware to use.
Auto loading: Any paths in your project matching ./plugins/**.js will
be automatically required when app.motley() is called, and those files are
expected to start with var app = require('motley') and then modify app in
some way.
Example
var app = require('motley');
app.hello = function () {
console.log('hello world!');
};External plugins
Plugins can easily be packaged as npm modules, or developed in different repos. Creating an external plugin is as easy as:
- create a
package.jsonand addmotleyto peerDependencies - use
var app = require('motley')and expose an API onapp require('my-plugin')from your app
Overriding core
If you don't like some core plugin or middleware, you can usually override it by
loading a plugin with the same API between when you call app.boot() and
app.motley():
var app = require('motley')
, https = require('https')
, modeler = require('modeler')
app.boot(function (err) {
if (err) throw err;
app.collection = modeler; // memory store version of modeler
app.server = https.createServer(app.conf.https);
app.motley();
// now we're using https instead of http, and memory store instead of redis!
});For a minimal (or highly customized) setup, you also don't even have to call
app.motley(), just require the parts you want and run with it:
var app = require('motley');
app.boot(function (err) {
if (err) throw err;
require('motley/plugins/load');
app.load('./plugins');
// etc
});Examples
See ./example for detailed usage.
Developed by Terra Eclipse
Terra Eclipse, Inc. is a nationally recognized political technology and strategy firm located in Aptos, CA and Washington, D.C.
License: MIT
- Copyright (C) 2013 Carlos Rodriguez (http://s8f.org/)
- Copyright (C) 2013 Terra Eclipse, Inc. (http://www.terraeclipse.com/)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

