Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge of geddy core master branch w/ CLI rewrite

Conflicts:
	bin/cli.js
	lib/controller/base_controller.js
  • Loading branch information...
commit 7440d5127427a775a3e8b156c0c4c12c1e808df8 2 parents 243591c + 1ddb995
Ken Goldfarb kengoldfarb authored
5 .travis.yml
View
@@ -1,6 +1,5 @@
language: node_js
node_js:
+ - "0.10"
- "0.8"
- - "0.6"
-
-install: jake utilities handlebars jade
+ - "0.6"
2  README.md
View
@@ -191,7 +191,7 @@ router.match('/farewells/:farewelltype/kings/:kingid').to(
//Can also match specific HTTP methods only
router.match('/xandadu', 'get').to(
- {controller: 'Xandadu', action: 'specialHandler'});
+ {controller: 'Xanadu', action: 'specialHandler'});
```
***Resource routes***
426 bin/cli.js
View
@@ -1,322 +1,122 @@
#!/usr/bin/env node
-// Dependencies
var geddy = require('../lib/geddy')
+ , fs = require('fs')
, path = require('path')
, utils = require('utilities')
- , parseopts = require('../lib/parseopts');
-
-// Variables
-var cwd = process.cwd()
- , args = process.argv.slice(2)
- , parser
- , optsMap
- , cmds
- , opts
- , usage
- , cmd
- , engineCmd
- , rtCmd
- , modelCmd
- , dirpath
- , filepath
- , die
- , jake
- , jakeArgs
- , jakeProgram
- , jakeLoader
- , start;
-
-// Usage dialog
-usage = [
- 'Geddy web framework for Node.js'
- , ''
- , 'Usage:'
- , ' geddy [options/commands] [arguments]'
- , ''
- , 'Options:'
- , ' --environment, -e Environment to use'
- , ' --hostname, -b Host name or IP to bind the server to (default: localhost)'
- , ' --port, -p Port to bind the server to (default: 4000)'
- , ' --geddy-root, -g /path/to/approot The path to the root for the app you want'
- , ' to run (default is current working directory)'
- , ' --workers, -w Number of worker processes to start (default: 1)'
- , ' --debug, -d Sets the log level to output debug messages to'
- , ' the console'
- , ' --realtime, -rt When generating or scaffolding, take realtime into account'
- , ' --jade, -j When generating views this will create Jade'
- , ' templates(Default: EJS)'
- , ' --handle, -H When generating views this will create Handlebars'
- , ' templates(Default: EJS)'
- , ' --mustache, -m When generating views this will create Mustache'
- , ' templates(Default: EJS)'
- , ' --swig, -s When generating views this will create Swig'
- , ' templates(Default: EJS)'
- , ' --help, -h Output this usage dialog'
- , ' --version, -v Output the version of Geddy that\'s installed'
- , ''
- , 'Commands:'
- , ' console Start up the Geddy REPL'
- , ' app <name> Create a new Geddy application'
- , ' resource <name> [attrs] Create a new resource. A resource includes'
- , ' a model, controller and route'
- , ' scaffold <name> [attrs] Create a new scaffolding. Scaffolding includes'
- , ' the views, a model, controller and route'
- , ' secret Generate a new application secret in'
- , ' `config/secret`'
- , ' controller <name> Generate a new controller including an index view'
- , ' and and a route'
- , ' model <name> [attrs] Generate a new model'
- , ' routes [query] Shows routes for a given resource route or all '
- , ' routes if empty'
- , ' auth[:update] Creates user authentication for you, using Passport.'
- , ''
- , 'Examples:'
- , ' geddy Start Geddy on localhost:4000 in development mode'
- , ' or if the directory isn\'t a Geddy app it\'ll'
- , ' display a prompt to use "geddy -h"'
- , ' geddy -p 3000 Start Geddy on port 3000'
- , ' geddy -e production Start Geddy in production mode'
- , ' geddy -j scaffold user Generate a users scaffolding using Jade templates'
- , ' geddy resource user name admin:boolean'
- , ' Generate a users resource with the model properties'
- , ' name as a string and admin as a boolean'
- , ' geddy scaffold user name:string:default'
- , ' Generate a users scaffolding user name as the default'
- , ' value to display data with'
- , ' geddy routes user Show all routes for the user resource'
- , ' geddy routes user.index Show the index route for the user resource'
- , ''
-].join('\n');
-
-// Options available
-optsMap = [
- { full: 'origins'
- , abbr: 'o'
- , args: true
- , canon: 'origins'
- }
-, { full: ['hostname', 'bind']
- , abbr: 'b'
- , args: true
- , canon: 'hostname'
- }
-, { full: 'port'
- , abbr: 'p'
- , args: true
- , canon: 'port'
- }
-, { full: 'workers'
- , abbr: ['n', 'w']
- , args: true
- , canon: 'workers'
- }
-, { full: 'version'
- , abbr: ['v', 'V']
- , args: false
- , canon: 'version'
- }
-, { full: 'help'
- , abbr: 'h'
- , args: false
- , canon: 'help'
- }
-, { full: 'debug'
- , abbr: 'd'
- , args: true
- , canon: 'debug'
- }
-, { full: 'loglevel'
- , abbr: 'l'
- , args: true
- , canon: 'loglevel'
- }
-, { full: 'environment'
- , abbr: 'e'
- , args: true
- , canon: 'environment'
- }
-, { full: 'geddy-root'
- , abbr: 'g'
- , args: true
- , canon: 'geddyRoot'
- }
-, { full: 'spawned'
- , abbr: ['s', 'q', 'Q']
- , args: true
- , canon: 'spawned'
- }
-, { full: 'jade'
- , abbr: 'j'
- , args: false
- , canon: 'jade'
- }
-, { full: ['handle', 'handlebars']
- , abbr: 'H'
- , args: false
- , canon: 'handlebars'
- }
-, { full: ['handle', 'swig']
- , abbr: 'S'
- , args: false
- , canon: 'swig'
- }
-, { full: 'mustache'
- , abbr: 'm'
- , args: false
- , canon: 'mustache'
- }
-, { full: 'realtime'
- , abbr: 'rt'
- , args: false
- , canon: 'realtime'
- }
-];
-
-// Parse optsMap and generate options and cmd commands
-parser = new parseopts.Parser(optsMap);
-parser.parse(args);
-cmds = parser.cmds;
-opts = parser.opts;
-
-// Set handlebars option to handle option
-opts.handle = opts.handlebars || opts.handle;
-
-// Exit the process with a message
-die = function (str) {
- console.log(str);
- process.exit();
-};
-
-// Start Geddy with options
-start = function () {
- geddy.startCluster(opts);
-};
-
-if (opts.help) {
- die(usage);
-}
-if (opts.version) {
- die(geddy.version);
+ , parseopts = require('../lib/parseopts')
+ , cmd = require('../lib/cmd');
+
+var args = process.argv.slice(2);
+args = cmd.parseArgs(args);
+
+// Jake commands -- hand off to Jake to load up env
+// and run whatever command. Jake parses all the CLI
+// args itself
+if (args[0] == 'jake') {
+ args.shift();
+ var c = new cmd.JakeCmd(args);
+ c.run();
}
-
-// `geddy app foo` or `geddy resource bar` etc. -- run generators
-if (cmds.length) {
- // Get Jake file and jakelibdir for generators
- dirpath = path.normalize(path.join(__dirname, '..', 'gen'));
- filepath = path.normalize(path.join(dirpath, 'Jakefile'));
-
- cmd = '';
-
- // Some commands take only one arg
- if (!(cmds[0] == 'jake' ||
- cmds[0] == 'secret' ||
- cmds[0] == 'auth' ||
- cmds[0] == 'auth:update' ||
- cmds[0] == 'console' ||
- cmds[0] == 'routes')
- && !cmds[1]) {
- throw new Error(cmds[0] + ' command requires another argument.');
- }
-
- // Add engines to command
- if (opts.jade) {
- engineCmd = ',' + 'jade';
- } else if (opts.handle) {
- engineCmd = ',' + 'handlebars';
- } else if (opts.mustache) {
- engineCmd = ',' + 'mustache';
- } else if (opts.swig) {
- engineCmd = ',' + 'swig';
- } else engineCmd = ',default';
-
- if (opts.realtime) {
- rtCmd = ',' + 'realtime';
- }
- else {
- rtCmd = ',default';
- }
-
- // Get the model properties
- if (cmds.slice(2).length > 0) {
- modelCmd = ',' + cmds.slice(2).join('%');
- } else modelCmd = '';
-
- // Add Jake argument based on commands
- switch (cmds[0]) {
- case 'jake':
- cmd = 'jake';
- jakeArgs = cmds.slice(1);
- break;
- case 'console':
- // Start console
- cmd += 'console:start[' + (cmds[1] || 'development') + ']';
- break;
- case 'auth':
- // Create authentication
- cmd += 'auth:init[' + engineCmd.substr(1) + ']';
- break;
- case 'auth:update':
- // Update authentication
- cmd += 'auth:update';
- break;
- case 'app':
- // Generating application
- cmd += 'gen:app[' + cmds[1] + engineCmd + rtCmd + ']';
- break;
- case 'resource':
- // Generating resource
- cmd += 'gen:resource[' + cmds[1] + modelCmd + ']';
- break;
- case 'scaffold':
- // Generating application
- cmd += 'gen:scaffold[' + cmds[1] + rtCmd + engineCmd + modelCmd + ']';
- break;
- case 'controller':
- // Generating controller
- cmd += 'gen:bareController[' + cmds[1] + engineCmd + ']';
- break;
- case 'model':
- // Generating model
- cmd += 'gen:model[' + cmds[1] + modelCmd + ']';
- break;
- case 'secret':
- // Generating new app secret
- cmd += 'gen:secret';
- break;
- case 'routes':
- // Show routes(Optionally empty)
- cmd += 'routes:show[' + (cmds[1] || '') + ']';
- break;
- default:
- die(cmds[0] + ' is not a Geddy command.');
- }
-
- jake = require('jake');
- jakeProgram = jake.program;
- jakeLoader = jake.loader;
- // Load Geddy's bundled Jakefile
- jakeLoader.loadDirectory(path.join(dirpath, 'jakelib'));
- jakeLoader.loadFile(filepath);
- if (cmd == 'jake') {
- jakeProgram.parseArgs(jakeArgs);
- // Load Jakefile and jakelibdir files for app
- jakeLoader.loadFile(jakeProgram.opts.jakefile);
- jakeLoader.loadDirectory(jakeProgram.opts.jakelibdir);
- // Prepend env:init to load Geddy env
- jakeProgram.taskNames.unshift('env:init');
- jakeProgram.init();
- }
- else {
- jakeProgram.init({
- quiet: !opts.debug
- , trace: true
- });
- jakeProgram.setTaskNames([cmd]);
- }
- jakeProgram.run();
+// Generator commands -- the Cmd object will parse
+// the args into commands and opts
+else if (args[0] == 'gen') {
+ args.shift();
+ var c = new cmd.Cmd(args);
+ c.run();
}
-// Just `geddy` -- start the server
+// Run the server
else {
- start();
+ (function () {
+ var parser
+ , optsMap
+ , cmds
+ , opts
+ , usage
+ , die;
+
+ // Server options
+ optsMap = [
+ { full: 'origins'
+ , abbr: 'o'
+ , args: true
+ , canon: 'origins'
+ }
+ , { full: ['hostname', 'bind']
+ , abbr: 'b'
+ , args: true
+ , canon: 'hostname'
+ }
+ , { full: 'port'
+ , abbr: 'p'
+ , args: true
+ , canon: 'port'
+ }
+ , { full: 'workers'
+ , abbr: ['n', 'w']
+ , args: true
+ , canon: 'workers'
+ }
+ , { full: 'version'
+ , abbr: ['v', 'V']
+ , args: false
+ , canon: 'version'
+ }
+ , { full: 'help'
+ , abbr: 'h'
+ , args: false
+ , canon: 'help'
+ }
+ , { full: 'debug'
+ , abbr: 'd'
+ , args: true
+ , canon: 'debug'
+ }
+ , { full: 'loglevel'
+ , abbr: 'l'
+ , args: true
+ , canon: 'loglevel'
+ }
+ , { full: 'environment'
+ , abbr: 'e'
+ , args: true
+ , canon: 'environment'
+ }
+ , { full: 'geddy-root'
+ , abbr: 'g'
+ , args: true
+ , canon: 'geddyRoot'
+ }
+ , { full: 'spawned'
+ , abbr: ['s', 'q', 'Q']
+ , args: true
+ , canon: 'spawned'
+ }
+ ];
+
+ // Parse optsMap and generate options and cmd commands
+ parser = new parseopts.Parser(optsMap)
+ parser.parse(args);
+ cmds = parser.cmds;
+ opts = parser.opts;
+
+ // Exit the process with a message
+ die = function (str) {
+ console.log(str);
+ process.exit();
+ };
+
+ if (opts.help) {
+ var usage = fs.readFileSync(path.join(__dirname, '..',
+ 'usage.txt')).toString();
+ return die(usage);
+ }
+
+ if (opts.version) {
+ return die(geddy.version);
+ }
+
+ geddy.startCluster(opts);
+ })();
}
+
2  examples/related_models/config/router.js
View
@@ -27,7 +27,7 @@ router.match('/').to({controller: 'Main', action: 'index'});
// {controller: 'Farewells', action: 'kings'});
// Can also match specific HTTP methods only
// router.match('/xandadu', 'get').to(
-// {controller: 'Xandadu', action: 'specialHandler'});
+// {controller: 'Xanadu', action: 'specialHandler'});
//
// Resource-based routes
// router.resource('hemispheres');
2  examples/socket_io/config/router.js
View
@@ -27,7 +27,7 @@ router.match('/').to({controller: 'Main', action: 'index'});
// {controller: 'Farewells', action: 'kings'});
// Can also match specific HTTP methods only
// router.match('/xandadu', 'get').to(
-// {controller: 'Xandadu', action: 'specialHandler'});
+// {controller: 'Xanadu', action: 'specialHandler'});
//
// Resource-based routes
// router.resource('hemispheres');
2  examples/todo_app/config/router.js
View
@@ -27,7 +27,7 @@ router.match('/').to({controller: 'Todos', action: 'index'});
// {controller: 'Farewells', action: 'kings'});
// Can also match specific HTTP methods only
// router.match('/xandadu', 'get').to(
-// {controller: 'Xandadu', action: 'specialHandler'});
+// {controller: 'Xanadu', action: 'specialHandler'});
//
// Resource-based routes
// router.resource('hemispheres');
40 examples/todo_app_coffee/app/controllers/todos.coffee
View
@@ -2,55 +2,49 @@ class Todos
respondsWith: ['html', 'json', 'js', 'txt']
index: (req, resp, params) ->
- self = this
- geddy.model.Todo.all (err, todos) ->
- self.respond params: params, todos: todos
+ geddy.model.Todo.all (err, todos) =>
+ @respond params: params, todos: todos
add: (req, resp, params) ->
- this.respond params: params
+ @respond params: params
create: (req, resp, params) ->
- self = this
todo = geddy.model.Todo.create
title: params.title
status: 'open'
- todo.save (err, data) ->
+ todo.save (err, data) =>
if err
params.errors = err
- self.transfer 'add'
+ @transfer 'add'
else
- self.redirect controller: self.name
+ @redirect controller: @name
show: (req, resp, params) ->
- self = this
- geddy.model.Todo.first params.id, (err, todo) ->
- self.respond params: params, todo: todo
+ geddy.model.Todo.first params.id, (err, todo) =>
+ @respond params: params, todo: todo
edit: (req, resp, params) ->
- self = this
- geddy.model.Todo.first params.id, (err, todo) ->
- self.respond params: params, todo: todo
+ geddy.model.Todo.first params.id, (err, todo) =>
+ @respond params: params, todo: todo
update: (req, resp, params) ->
- self = this
- geddy.model.Todo.first params.id, (err, todo) ->
+ geddy.model.Todo.first params.id, (err, todo) =>
todo.updateAttributes params
- todo.save (err, data) ->
+ todo.save (err, data) =>
if err
params.errors = err
- self.transfer 'edit'
+ @transfer 'edit'
else
- self.redirect controller: self.name
+ @redirect controller: @name
remove: (req, resp, params) ->
- self = this
- geddy.model.Todo.remove params.id, (err) ->
+ geddy.model.Todo.remove params.id, (err) =>
if err
params.errors = err
- self.transfer 'edit'
+ @transfer 'edit'
else
- self.redirect controller: self.name
+ @redirect controller: @name
exports.Todos = Todos
100 gen/jakelib/console.jake
View
@@ -1,64 +1,62 @@
-namespace('console', function () {
- task('start', ['env:init'], {async: true}, function () {
- var t = jake.Task['env:init'];
+task('console', {async: true}, function () {
+ var t = jake.Task['env:init'];
- t.addListener('complete', function () {
- var repl = require('repl')
- , rl;
+ t.addListener('complete', function () {
+ var repl = require('repl')
+ , rl;
- rl = repl.start({
- prompt: '>>> '
- , input: process.stdin
- , output: process.stdout
- });
+ rl = repl.start({
+ prompt: '>>> '
+ , input: process.stdin
+ , output: process.stdout
+ });
- rl.on('close', function () {
- console.log('Exiting...');
- return complete();
- })
+ rl.on('close', function () {
+ console.log('Exiting...');
+ return complete();
+ })
- rl.context.capture = function (err, data) {
- return rl.context.results = {
- err: err
- , data: data
- };
+ rl.context.capture = function (err, data) {
+ return rl.context.results = {
+ err: err
+ , data: data
};
-
- rl.context.echo = function (err, data) {
- rl.context.capture(err, data);
- if (err) {
- console.log('Error: ', err);
- }
-
- if (data) {
- if (data.length) {
- for (var i in data) {
- if (data[i] && data[i].toData) {
- console.log(data[i].toData());
- } else {
- console.log(data[i]);
- }
- }
- }
- else {
- if (data && data.toData) {
- console.log(data.toData());
+ };
+
+ rl.context.echo = function (err, data) {
+ rl.context.capture(err, data);
+ if (err) {
+ console.log('Error: ', err);
+ }
+
+ if (data) {
+ if (data.length) {
+ for (var i in data) {
+ if (data[i] && data[i].toData) {
+ console.log(data[i].toData());
} else {
- console.log(data);
+ console.log(data[i]);
}
}
- } else {
- console.log('No data');
}
- };
-
- rl.context.routes = function (resource) {
- console.log(getRoutes(resource));
- };
- });
-
- t.invoke();
+ else {
+ if (data && data.toData) {
+ console.log(data.toData());
+ } else {
+ console.log(data);
+ }
+ }
+ } else {
+ console.log('No data');
+ }
+ };
+
+ rl.context.routes = function (resource) {
+ console.log(getRoutes(resource));
+ };
});
+
+ t.invoke();
});
50 gen/jakelib/gen.jake
View
@@ -222,7 +222,7 @@ namespace('gen', function () {
}
modelTask.on('complete', function () {
- jake.Task['gen:controller'].invoke(name);
+ jake.Task['gen:controllerMin'].invoke(name);
jake.Task['gen:route'].invoke(name);
jake.Task['gen:test'].invoke(name,
{properties: modelProperties});
@@ -237,7 +237,7 @@ namespace('gen', function () {
}, {async: true});
// Creates a full scaffold with views, a model, controller and a resource route
- task('scaffold', function (name, realtime, engine, modelProperties) {
+ task('scaffold', function (name, modelProperties, engine, realtime) {
var modelTask = jake.Task['gen:model'];
if (!name) {
@@ -289,33 +289,33 @@ namespace('gen', function () {
}, {async: true});
- task('controller', function (name) {
- if (!name) {
- throw new Error('No controller name specified.');
- }
-
-
- _writeTemplate(name, 'resource/controller', path.join('app', 'controllers'),
- {inflection: 'plural', bare: false});
- });
-
task('test', function (name) {
if (!name) {
throw new Error('No test name specified.');
}
-
_writeTemplate(name, 'resource/test_model', 'test/models',
{inflection: 'singular'});
_writeTemplate(name, 'resource/test_controller', 'test/controllers',
{inflection: 'plural'});
});
+ // Called by gen:resource
+ task('controllerMin', function (name) {
+ if (!name) {
+ throw new Error('No controller name specified.');
+ }
+ _writeTemplate(name, 'resource/controller', path.join('app', 'controllers'), {
+ inflection: 'plural'
+ , bare: false
+ });
+ });
+
+ // Called by gen:scaffold
task('controllerScaffold', function (name, options) {
if (!name) {
throw new Error('No controller name specified.');
}
options = options || {};
-
_writeTemplate(name, 'scaffold/controller', path.join('app', 'controllers'), {
inflection: 'plural'
, bare: false
@@ -323,14 +323,14 @@ namespace('gen', function () {
});
});
- task('bareController', function (name, engine) {
+ // Called by `geddy gen controller <controller_name>`
+ task('controller', function (name, engine) {
if (!name) {
throw new Error('No controller name specified.');
}
if (!engine || engine == 'default') {
engine = 'ejs';
}
-
_writeTemplate(name, 'resource/controller', path.join('app', 'controllers'),
{inflection: 'plural', bare: true});
jake.Task['gen:route'].invoke(name, {bare: true});
@@ -574,5 +574,23 @@ namespace('gen', function () {
'DO make a backup of it, keep it someplace safe.');
});
+ task('auth', {async: true}, function () {
+ var t = jake.Task['auth:init'];
+ t.on('complete', function () {
+ complete();
+ });
+ t.invoke.apply(t, arguments);
+ });
+
+ namespace('auth', function () {
+ task('update', function () {
+ var t = jake.Task['auth:update'];
+ t.on('complete', function () {
+ complete();
+ });
+ t.invoke.apply(t, arguments);
+ });
+ });
+
});
11 gen/jakelib/routes.jake
View
@@ -5,13 +5,12 @@ var helpers = require('./helpers')
, addRoute = helpers.addRoute;
-namespace('routes', function () {
- task('show', ['env:init'], {async: true}, function (resource) {
- console.log('Showing route results for "' + resource + '"');
- console.log(getRoutes(resource));
- });
-
+task('routes', ['env:init'], {async: true}, function (resource) {
+ console.log('Showing route results for "' + resource + '"');
+ console.log(getRoutes(resource));
+ complete();
});
+
269 lib/cmd.js
View
@@ -0,0 +1,269 @@
+var path = require('path')
+ , utils = require('utilities')
+ , parseopts = require('./parseopts')
+ , cmd = {}
+ , engineCmd
+ , rtCmd
+ , modelCmd
+ , die
+ , jakeArgs
+ , jakeProgram
+ , jakeLoader
+
+var _taskArgsMap = {
+ 'app': ['primary', 'template', 'rt']
+, 'model': ['primary', 'model']
+, 'resource': ['primary', 'model']
+, 'scaffold': ['primary', 'model', 'template', 'rt']
+, 'controller': ['primary', 'template']
+, 'secret': []
+, 'auth': ['template']
+, 'auth:update': []
+};
+
+cmd = new (function () {
+ var genCmds
+ , jakeCmds;
+
+ genCmds = {
+ 'app': true
+ , 'auth': true
+ , 'auth:update': true
+ , 'secret': true
+ , 'resource': true
+ , 'scaffold': true
+ , 'controller': true
+ , 'model': true
+ , 'migration': true
+ };
+
+ jakeCmds = {
+ 'console': true
+ , 'routes': true
+ , 'db:init': true
+ };
+
+ this.parseArgs = function (args) {
+ var initArg = args[0]
+ , ret;
+ // No args, or first arg is an option -- assume no commands,
+ // running server. Bail out with current args
+ if (!args.length || initArg.indexOf('-') === 0) {
+ return args;
+ }
+ else {
+ ret = args.slice();
+ }
+
+ // Gen commands
+ if (genCmds[initArg]) {
+ console.log('=======================');
+ console.log(' NOTE: `' + ret[0] + '` command is ' +
+ 'deprecated.\n Please use `geddy gen ' + ret[0] + '`');
+ console.log('=======================');
+ ret.unshift('gen');
+ }
+ // Jake commands
+ else if (jakeCmds[initArg]) {
+ console.log('=======================');
+ console.log(' NOTE: `' + ret[0] + '` command is ' +
+ 'deprecated.\n Please use `geddy jake ' + ret[0] + '`');
+ console.log('=======================');
+ ret.unshift('jake');
+ }
+ else {
+ if (initArg == 'gen') {
+ if (!genCmds[ret[1]]) {
+ throw new Error(initArg + ' ' + ret[1] +
+ ' is not a valid geddy command.');
+ }
+ }
+ else {
+ if (initArg != 'jake') {
+ throw new Error(initArg + ' is not a valid geddy command.');
+ }
+ }
+ }
+ return ret;
+ };
+
+})();
+
+
+var Cmd = function (args) {
+ this.cmds = null;
+ this.opts = null;
+ this.namedArgs = {
+ primary: ''
+ , model: ''
+ , template: ''
+ , rt: ''
+ };
+ this.baseTaskName = args[0];
+ this.jakeTaskName = '';
+ this.jakeProgram = null;
+ this.jakeLoader = null;
+
+ this.createJake();
+ this.parseArgs(args);
+ this.createJakeTaskName();
+};
+
+Cmd.prototype = new (function () {
+
+ // Options available -- probably should have gone with
+ // '--template=jade' instead of a flag for each template type
+ var _optsMap = [
+ { full: 'jade'
+ , abbr: 'j'
+ , args: false
+ , canon: 'jade'
+ }
+ , { full: ['handle', 'handlebars']
+ , abbr: 'H'
+ , args: false
+ , canon: 'handlebars'
+ }
+ , { full: 'mustache'
+ , abbr: 'm'
+ , args: false
+ , canon: 'mustache'
+ }
+ , { full: 'realtime'
+ , abbr: 'rt'
+ , args: false
+ , canon: 'realtime'
+ }
+ ];
+
+ this.run = function () {
+ this.initJake();
+ this.runJake();
+ };
+
+ this.parseArgs = function (args) {
+ var parser
+ , cmds
+ , opts
+ , namedArgs = this.namedArgs
+ , model = ''
+ , template = 'default'
+ , rt = 'default';
+
+ parser = new parseopts.Parser(_optsMap);
+ parser.parse(args);
+ cmds = parser.cmds;
+ opts = parser.opts;
+ // Set handlebars option to handle option
+ opts.handle = opts.handlebars || opts.handle;
+
+ this.cmds = cmds;
+ this.opts = opts;
+
+ // Parse the primary arg out of the args
+ // This is the main arg passed to each Jake task
+ // e.g., the app name, model name, etc.
+ // ------
+ namedArgs.primary = cmds[1];
+
+ // Get the model properties
+ // ------
+ if (cmds.slice(2).length) {
+ // Use percents to delimit, since this gets passed to Jake
+ model = cmds.slice(2).join('%');
+ }
+ namedArgs.model = model;
+
+ // Template-language options
+ // ------
+ if (opts.jade) {
+ template = 'jade';
+ }
+ else if (opts.handle) {
+ template = 'handlebars';
+ }
+ else if (opts.mustache) {
+ template = 'mustache';
+ }
+ namedArgs.template = template;
+
+ // Set up RT?
+ // ------
+ if (opts.realtime) {
+ rt = 'realtime';
+ }
+ namedArgs.rt = rt;
+ };
+
+ this.createJakeTaskName = function () {
+ var name = this.baseTaskName
+ , namedArgs = this.namedArgs
+ , argNames = _taskArgsMap[name]
+ , args = [];
+ name = 'gen:' + name;
+ // Get any value parsed out for each of the specified named args
+ // for this particular task
+ argNames.forEach(function (n) {
+ args.push(namedArgs[n]);
+ });
+ name += '[' + args.join(',') + ']';
+ this.jakeTaskName = name;
+ };
+
+ this.createJake = function () {
+ var jake = require('jake')
+ , dirpath = path.normalize(path.join(__dirname, '..', 'gen'))
+ , filepath = path.normalize(path.join(dirpath, 'Jakefile'));
+ this.jakeProgram = jake.program;
+ this.jakeLoader = jake.loader;
+ // Load Geddy's bundled Jakefile
+ this.jakeLoader.loadDirectory(path.join(dirpath, 'jakelib'));
+ this.jakeLoader.loadFile(filepath);
+ };
+
+ this.initJake = function () {
+ this.jakeProgram.init({
+ quiet: !this.opts.debug
+ , trace: this.opts.debug
+ });
+ this.jakeProgram.setTaskNames([this.jakeTaskName]);
+ };
+
+ this.runJake = function () {
+ this.jakeProgram.run();
+ };
+})();
+
+var JakeCmd = function (cmd, opts) {
+ Cmd.apply(this, arguments);
+};
+
+JakeCmd.prototype = Object.create(Cmd.prototype);
+JakeCmd.prototype.constructor = JakeCmd;
+
+// Override a couple of methods
+utils.mixin(JakeCmd.prototype, new (function () {
+ this.parseArgs = function (args) {
+ // Let Jake parse the raw args directly
+ this.jakeProgram.parseArgs(args);
+ };
+
+ this.initJake = function () {
+ // Load Jakefile and jakelibdir files for app
+ this.jakeLoader.loadFile(this.jakeProgram.opts.jakefile);
+ this.jakeLoader.loadDirectory(this.jakeProgram.opts.jakelibdir);
+ // Prepend env:init to load Geddy env
+ this.jakeProgram.taskNames.unshift('env:init');
+ this.jakeProgram.init();
+ };
+
+ // Override, no-op -- don't need a task-name with
+ // bracket params -- setting directly
+ this.createJakeTaskName = function () {};
+
+})());
+
+cmd.Cmd = Cmd;
+cmd.JakeCmd = JakeCmd;
+
+module.exports = cmd;
111 lib/controller/base_controller.js
View
@@ -597,90 +597,85 @@ controller.BaseController.prototype = new (function () {
return;
}
+ // Hand content off to formatting along with callback for writing out
+ // the formatted respnse
+ response.formatContent(format, content, this, opts, callback);
+ };
+
+ this.renderTemplate = function (d, opts, callback) {
+ var self = this
+ , data = utils.mixin({}, d) // Prevent mixin-polution
+ , templater
+ , content = '';
+
+ this.setTemplateAndLayout(opts);
+
+ // Mix in controller instance-vars (props only, no methods)
+ // Don't overwrite existing same-name properties
+ for (var p in this) {
+ if (!(data[p] || typeof this[p] == 'function')) {
+ data[p] = this[p];
+ }
+ };
+
+ templater = new Templater(this.layout, this.template, data);
+ templater.render(callback);
+ };
+
+ this.setTemplateAndLayout = function (opts) {
+ var controllerFilename =
+ utils.string.getInflection(this.name, 'filename', 'plural')
+ , actionFilename = utils.string.snakeize(this.params.action);
+
// Set template and layout paths
if (opts.template) {
+ // If template includes full views path just use it
if (opts.template.match('app/views/')) {
- // If template includes full views path just use it
this.template = opts.template;
}
else if (opts.template.match('/')) {
// If it includes a '/' and it isn't the full path
// Assume they are using the `controller/action` style
+ // and prepend views dir
this.template = 'app/views/' + opts.template;
}
+ // Assume they only included the action, so add the controller path
else {
- // Assume they only included the action, so add the controller path
- this.template = 'app/views/' + utils.string.decapitalize(this.params.controller) +
- '/' + opts.template;
+ this.template = 'app/views/' + controllerFilename + '/' + opts.template;
}
}
+ else {
+ this.template = 'app/views/' + controllerFilename + '/' + actionFilename;
+ }
if (opts.layout) {
+ // If layout includes `app/views` just return it
if (opts.layout.match('app/views')) {
- // If layout includes `app/views` just return it
- self.layout = opts.layout;
+ this.layout = opts.layout;
}
+ // If it includes a '/' and it isn't the full path
+ // Assume they are using the `controller/action` style
+ // and prepend views dir
else if (opts.layout.match('/')) {
- // If it includes a '/' and it isn't the full path
- // Assume they are using the `controller/action` style
- self.layout = 'app/views/' + opts.layout;
+ this.layout = 'app/views/' + opts.layout;
}
+ // Assume they only included the controller, so append it to
+ // the layouts path
else {
- // Assume they only included the action, so add the controller path
- self.layout = 'app/views/layouts/' + opts.layout;
+ this.layout = 'app/views/layouts/' + opts.layout;
}
}
-
- // If options.layout is set to `false` just set it
- if (typeof opts.layout === 'boolean' && !opts.layout) {
- self.layout = opts.layout;
- }
-
- // Hand content off to formatting along with callback for writing out
- // the formatted respnse
- response.formatContent(format, content, self, callback);
- };
- this.render = this.respond; // Keep backwards compat
-
- this.renderTemplate = function (d, callback) {
-
- var self = this
- , data = utils.mixin({}, d) // Prevent mixin-polution
- , templater = new Templater()
- , content = '';
-
- if (!this.template || !this.layout) {
- // Format directory names
- var dirName = utils.inflection.pluralize(this.name);
- dirName = utils.string.snakeize(dirName);
- }
-
- // Get template if not set
- this.template = this.template || 'app/views/' + dirName + '/' + this.params.action;
-
- // Get layout if not set or set empty layout if `false`
- if (typeof self.layout === 'boolean' && !self.layout) {
- // Use custom Geddy empty template in `lib/template/templates`
- self.layout = 'geddy/empty';
- }
else {
- self.layout = self.layout || 'app/views/layouts/' + dirName;
- }
-
- // Mix in controller instance-vars (props only, no methods)
- // Don't overwrite existing same-name properties
- for (var p in self) {
- if (!(data[p] || typeof self[p] == 'function')) {
- data[p] = self[p];
+ // If options.layout is explicitly set to false, use custom
+ // Geddy empty template in `lib/template/templates`
+ if (opts.layout === false) {
+ this.layout = 'geddy/empty';
+ }
+ else {
+ this.layout = 'app/views/layouts/' + controllerFilename;
}
}
- templater.render(data, {
- layout: self.layout
- , template: self.template
- , controller: self.name
- , action: self.params.action
- }, callback);
};
})();
12 lib/response/format.js
View
@@ -6,7 +6,7 @@ var utils = require('utilities')
builtInFormats = {
'txt': {
contentType: 'text/plain'
- , handler: function (content, controller, callback) {
+ , handler: function (content, controller, opts, callback) {
var res;
if (content) {
if (typeof content.toString == 'function') {
@@ -25,14 +25,14 @@ builtInFormats = {
, 'html': {
contentType: 'text/html'
- , handler: function (content, controller, callback) {
- controller.renderTemplate(content, callback);
+ , handler: function (content, controller, opts, callback) {
+ controller.renderTemplate(content, opts, callback);
}
}
, 'json': {
contentType: ['application/json', 'text/json']
- , handler: function (content, controller, callback) {
+ , handler: function (content, controller, opts, callback) {
var res
, toJson;
if (content) {
@@ -53,7 +53,7 @@ builtInFormats = {
, 'xml': {
contentType: ['application/xml', 'text/xml']
- , handler: function (content, controller, callback) {
+ , handler: function (content, controller, opts, callback) {
var res
, name = ''
, toXml;
@@ -86,7 +86,7 @@ builtInFormats = {
, 'js': {
contentType: ['application/javascript', 'text/javascript']
- , handler: function (content, controller, callback) {
+ , handler: function (content, controller, opts, callback) {
var params = controller.params
, res;
4 lib/response/index.js
View
@@ -55,9 +55,9 @@ var response = new function () {
}
};
- this.formatContent = function (f, content, controller, callback) {
+ this.formatContent = function (f, content, controller, opts, callback) {
var formatObj = format.formats[f];
- return formatObj.handler(content, controller, callback);
+ return formatObj.handler(content, controller, opts, callback);
};
}();
192 lib/template/index.js
View
@@ -15,196 +15,26 @@
* limitations under the License.
*
*/
-var path = require('path')
- , fs = require('fs')
- , utils = require('utilities')
- , Adapter = require('./adapters').Adapter
+var Adapter = require('./adapters').Adapter
, Templater
- , Partial
- , Layout
- , cache = {};
+ , Partial = require('./partial').Partial
+ , Layout = require('./layout').Layout;
-Templater = function () {};
+Templater = function (layout, template, data) {
+ this.layout = layout;
+ this.template = template;
+ this.data = data;
+};
Templater.prototype = new (function () {
- this.render = function (data, config, cb) {
+ this.render = function (cb) {
// Register data to helpers, and register the helpers to the adapter
- geddy.viewHelpers.registerData(data);
+ geddy.viewHelpers.registerData(this.data);
Adapter.registerHelpers(geddy.viewHelpers);
- var layout = new Layout(config.layout, config.template, data);
+ var layout = new Layout(this.layout, this.template, this.data);
layout.render(cb);
};
})();
exports.Templater = Templater;
-Partial = function (templatePath, data, parent) {
- var self = this;
- this.id = utils.string.uuid();
- this.templatePath = templatePath
- this.data = data;
- this.parent = parent;
- this.children = [];
- this.content = '';
-
- // Hang a `partial` method on the execution-context for the
- // template rendering (e.g., will be the EJS global `partial`
- // function to add sub-templates
- this.data.partial = function (templatePath, data) {
- var child = new Partial(templatePath, data, self);
- self.addChild(child);
- return '###partial###' + child.id
- };
-};
-
-Partial.prototype = new (function () {
-
- this.render = function (cb) {
- var self = this
- , templateData = this.getTemplateData()
- , file = templateData.file
- , ext = templateData.ext
- , handleData = function (data) {
- self.renderSelf(data, ext);
- self.renderChildren(cb);
- };
-
- // Use cached template content if possible
- if (cache[file]) {
- handleData(cache[file]);
- }
- // Otherwise fetch off disk
- else {
- // Get the template from the FS then cache it for subsequent requests
- fs.readFile(file, 'utf8', function (err, data) {
- if (err) {
- throw err;
- }
- if (geddy.config.environment != 'development') {
- cache[file] = data;
- }
- handleData(data);
- });
- }
- };
-
- this.renderSelf = function (templateContent, ext) {
- var adapter = new Adapter();
- // Render with appropriate engine
- adapter.set({engine: ext, template: templateContent});
- this.content = adapter.render(this.data);
- };
-
- this.renderChildren = function (cb) {
- var self = this
- , children = this.children
- , incr = children.length;
-
- if (children.length) {
- children.forEach(function (child) {
- child.render(function (content) {
- self.content = self.content.replace(
- '###partial###' + child.id, content);
- incr--;
- if (!incr) {
- cb(self.content);
- }
- });
- });
- }
- else {
- cb(this.content);
- }
-
- };
-
- this.getTemplateData = function () {
- var dirs = []
- , dir
- , key
- , templatePath = this.templatePath
- , templateData;
-
- // Look for an exact match
- templateData = geddy.templateRegistry[templatePath];
-
- // No exact match, try with some directory prefixes
- if (!templateData) {
- // Loop through dirs until a registered template path is found
- // Note: Template paths are gathered at init so we don't have to
- // touch the FS when looking for templates
-
- // If this is a child partial, then look in the parent's directory
- if (this.parent) {
- dirs.unshift(path.dirname(this.parent.templatePath));
- }
-
- // Any local template directory
- dirs.unshift(path.dirname(templatePath));
-
- // Last resort; look in the base views directory
- dirs.unshift(path.normalize('app/views'));
-
-
- for (var i = 0, ii = dirs.length; i < ii; i++) {
- dir = dirs[i];
- // Not full path (No extension(s))
- key = path.normalize(path.join(dir, templatePath));
-
- templateData = geddy.templateRegistry[key];
- if (templateData) {
- break;
- }
- }
- }
-
- // Still no joy
- if (!templateData) {
- // Is this a Layout?
- if (this instanceof Layout) {
- // Try to use the default application layout
- key = path.normalize('app/views/layouts/application');
- templateData = geddy.templateRegistry[key];
- // If they've removed the default layout for some reason
- if (!templateData) {
- throw new geddy.errors.InternalServerError('Layout template "' +
- templatePath + '" not found in ' +
- geddy.utils.array.humanize(dirs));
- }
- }
- // If it's a normal Partial then it doesn't exist, boom
- else {
- throw new geddy.errors.InternalServerError('Partial template "' +
- templatePath + '" not found in ' +
- geddy.utils.array.humanize(dirs));
- }
- }
-
- return templateData || null;
- };
-
- this.addChild = function (child) {
- this.children.push(child);
- };
-
-})();
-
-// Subclass of Partial
-Layout = function (layoutPath, templatePath, data) {
- var self = this;
- // Call the ctor on 'this' -- the the layoutPath will be our
- // templatePath
- Partial.call(this, layoutPath, data, null);
-
- // `yield` is just a special case of `partial` using the template-path
- // that the layout wraps -- just hard-code the path and pass along
- // the same data
- this.data.yield = function () {
- return self.data.partial(templatePath, data);
- };
-};
-
-Layout.prototype = Object.create(Partial.prototype);
-Layout.prototype.constructor = Layout;
-
-exports.Templater = Templater;
22 lib/template/layout.js
View
@@ -0,0 +1,22 @@
+var Layout
+ , Partial = require('./partial').Partial;
+
+// Subclass of Partial
+Layout = function (layoutPath, templatePath, data) {
+ var self = this;
+ // Call the ctor on 'this' -- the the layoutPath will be our
+ // templatePath
+ Partial.call(this, layoutPath, data, null);
+
+ // `yield` is just a special case of `partial` using the template-path
+ // that the layout wraps -- just hard-code the path and pass along
+ // the same data
+ this.data.yield = function () {
+ return self.data.partial(templatePath, data);
+ };
+};
+
+Layout.prototype = Object.create(Partial.prototype);
+Layout.prototype.constructor = Layout;
+
+exports.Layout = Layout;
163 lib/template/partial.js
View
@@ -0,0 +1,163 @@
+var Partial
+ , Layout
+ , Adapter = require('./adapters').Adapter
+ , path = require('path')
+ , fs = require('fs')
+ , utils = require('utilities')
+ , cache = {};
+
+Partial = function (templatePath, data, parent) {
+ var self = this;
+ this.id = utils.string.uuid();
+ this.templatePath = templatePath
+ this.data = data || {};
+ this.parent = parent;
+ this.children = [];
+ this.content = '';
+
+ // Hang a `partial` method on the execution-context for the
+ // template rendering (e.g., will be the EJS global `partial`
+ // function to add sub-templates
+ this.data.partial = function (templatePath, data) {
+ var child = new Partial(templatePath, data, self);
+ self.addChild(child);
+ return '###partial###' + child.id
+ };
+};
+
+Partial.prototype = new (function () {
+
+ this.getTemplateData = function () {
+ var dirs = []
+ , dir
+ , key
+ , templatePath = this.templatePath
+ , templateData;
+
+ // Look for an exact match
+ templateData = geddy.templateRegistry[templatePath];
+
+ // No exact match, try with some directory prefixes
+ if (!templateData) {
+ // Loop through dirs until a registered template path is found
+ // Note: Template paths are gathered at init so we don't have to
+ // touch the FS when looking for templates
+
+ // If this is a child partial, then look in the parent's directory
+ if (this.parent) {
+ dirs.unshift(path.dirname(this.parent.templatePath));
+ }
+
+ // Any local template directory
+ dirs.unshift(path.dirname(templatePath));
+
+ // Last resort; look in the base views directory
+ dirs.unshift(path.normalize('app/views'));
+
+
+ for (var i = 0, ii = dirs.length; i < ii; i++) {
+ dir = dirs[i];
+ // Not full path (No extension(s))
+ key = path.normalize(path.join(dir, templatePath));
+
+ templateData = geddy.templateRegistry[key];
+ if (templateData) {
+ break;
+ }
+ }
+ }
+
+ // Still no joy
+ if (!templateData) {
+ // Is this a Layout?
+ if (this instanceof Layout) {
+ // Try to use the default application layout
+ key = path.normalize('app/views/layouts/application');
+ templateData = geddy.templateRegistry[key];
+ // If they've removed the default layout for some reason
+ if (!templateData) {
+ throw new Error('Layout template "' + templatePath + '" not found in ' +
+ utils.array.humanize(dirs));
+ }
+ }
+ // If it's a normal Partial then it doesn't exist, boom
+ else {
+ throw new Error('Partial template "' + templatePath + '" not found in ' +
+ utils.array.humanize(dirs));
+ }
+ }
+
+ return templateData || null;
+ };
+
+ this.render = function (cb) {
+ var self = this
+ , templateData = this.getTemplateData()
+ , file = templateData.file
+ , ext = templateData.ext
+ , handleData = function (data) {
+ self.renderSelf(data, ext);
+ self.renderChildren(cb);
+ };
+
+ // Use cached template content if possible
+ if (cache[file]) {
+ handleData(cache[file]);
+ }
+ // Otherwise fetch off disk
+ else {
+ // Get the template from the FS then cache it for subsequent requests
+ fs.readFile(file, 'utf8', function (err, data) {
+ if (err) {
+ throw err;
+ }
+ if (geddy.config.environment != 'development') {
+ cache[file] = data;
+ }
+ handleData(data);
+ });
+ }
+ };
+
+ this.renderSelf = function (templateContent, ext) {
+ var adapter = new Adapter();
+ // Render with appropriate engine
+ adapter.set({engine: ext, template: templateContent});
+ this.content = adapter.render(this.data);
+ };
+
+ this.renderChildren = function (cb) {
+ var self = this
+ , children = this.children
+ , incr = children.length;
+
+ if (children.length) {
+ children.forEach(function (child) {
+ child.render(function (content) {
+ self.content = self.content.replace(
+ '###partial###' + child.id, content);
+ incr--;
+ if (!incr) {
+ cb(self.content);
+ }
+ });
+ });
+ }
+ else {
+ cb(this.content);
+ }
+
+ };
+
+ this.addChild = function (child) {
+ this.children.push(child);
+ };
+
+})();
+
+exports.Partial = Partial;
+
+// Layout is a subclass of Partial, depends on it
+// being defined
+Layout = require('./layout').Layout;
+
2  package.json
View
@@ -8,7 +8,7 @@
"MVC",
"realtime"
],
- "version": "0.8.1",
+ "version": "0.8.3",
"author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",
"dependencies": {
"jake": "0.5.x",
26 test/cmd.js
View
@@ -0,0 +1,26 @@
+var assert = require('assert')
+ , cmd = require('../lib/cmd')
+ , Cmd = cmd.Cmd
+ , tests;
+
+tests = {
+ 'Cmd parseArgs gen app defaults': function () {
+ var c = new Cmd(['app', 'foo'], {});
+ assert.equal('gen:app[foo,default,default]', c.jakeTaskName);
+ }
+
+, 'Cmd parseArgs gen app --jade': function () {
+ var c = new Cmd(['app', 'foo', '--jade']);
+ assert.equal('gen:app[foo,jade,default]', c.jakeTaskName);
+ }
+
+, 'Cmd parseArgs gen scaffold zooby foo bar --realtime': function () {
+ var c = new Cmd(['scaffold', 'zooby', 'foo:int', 'bar:string',
+ '--realtime']);
+ assert.equal('gen:scaffold[zooby,foo:int%bar:string,default,realtime]',
+ c.jakeTaskName);
+ }
+
+};
+
+module.exports = tests;
2  test/templates/engines/ejs.js
View
@@ -16,7 +16,7 @@
*
*/
-var Adapter = require('../../../lib/template/adapters')
+var Adapter = require('../../../lib/template/adapters').Adapter
, assert = require('assert')
, tests
, render = function (str, data) {
2  test/templates/engines/handlebars_mustache.js
View
@@ -24,7 +24,7 @@ try {
events.emit('error', err);
}
-var Adapter = require('../../../lib/template/adapters')
+var Adapter = require('../../../lib/template/adapters').Adapter
, assert = require('assert')
, tests
, render = function (str, data) {
2  test/templates/engines/jade.js
View
@@ -24,7 +24,7 @@ try {
events.emit('error', err);
}
-var Adapter = require('../../../lib/template/adapters')
+var Adapter = require('../../../lib/template/adapters').Adapter
, assert = require('assert')
, tests
, render = function (str, data) {
40 test/templates/partial.js
View
@@ -0,0 +1,40 @@
+require('../../lib/geddy');
+
+var assert = require('assert')
+ , Partial = require('../../lib/template/partial').Partial
+ , tests;
+
+geddy.templateRegistry = {
+ 'app/views/foo/baz': {
+ file: 'app/views/foo/baz.html.ejs'
+ , ext: '.ejs'
+ , baseName: 'baz'
+ , baseNamePath: 'app/views/foo/baz'
+ }
+
+, 'app/views/foo/bar': {
+ file: 'app/views/foo/bar.html.ejs'
+ , ext: '.ejs'
+ , baseName: 'bar'
+ , baseNamePath: 'app/views/foo/bar'
+ }
+};
+
+tests = {
+
+ 'relative template path, top-level partial': function () {
+ var p = new Partial('foo/bar', {})
+ , data = p.getTemplateData();
+ assert.ok(data);
+ }
+
+, 'relative template path, sub-partial': function () {
+ var pParent = new Partial('app/views/foo/baz', {})
+ var pSub = new Partial('bar', {}, pParent)
+ , data = pSub.getTemplateData();
+ assert.ok(data);
+ }
+
+};
+
+module.exports = tests;
79 usage.txt
View
@@ -0,0 +1,79 @@
+=======================================================
+ Geddy web framework for Node.js
+=======================================================
+ Server usage:
+ geddy [options] Runs a Geddy server for the current app directory
+
+ Server options:
+ --environment, -e Environment to use
+ --hostname, -b Host name or IP to bind the server to
+ (default: localhost)
+ --port, -p Port to bind the server to (default: 4000)
+ --geddy-root, -g /path/to/approot The path to the root for the app you want
+ to run (default is current working directory)
+ --workers, -w Number of worker processes to start (default: 1)
+ --debug, -d Sets the log level to output debug messages to
+ the console
+ --help, -h Output this usage dialog
+ --version, -v Output the version of Geddy that\'s installed
+
+ Server examples:
+ geddy Start Geddy on localhost:4000 in development mode
+ or if the directory isn\'t a Geddy app it\'ll
+ display a prompt to use "geddy -h"
+ geddy -p 3000 Start Geddy on port 3000
+ geddy -e production Start Geddy in production mode
+ geddy -j scaffold user Generate a users scaffolding using Jade templates
+
+-------------------------------------------------------
+ Jake usage:
+ geddy jake [task] [options] [env vars]
+ Runs a Jake task in the context of the current app
+
+ Jake options:
+ (See https://github.com/mde/jake for full documentation)
+
+ Jake examples:
+ geddy jake console Run a REPL in your app environment
+ geddy jake test Run your application's tests in the app environment
+ geddy jake db:init environment=development
+ Initialize the development database for your app
+ geddy jake routes Show all routes
+ geddy jake routes[user] Show all routes for the user resource
+ geddy jake routes[user.index] Show the index route for the user resource
+
+-------------------------------------------------------
+ Generator usage:
+ geddy gen [command] [options] [arguments]
+
+ Generator commands:
+ gen app <name> Create a new Geddy application
+ gen resource <name> [attrs] Create a new resource. A resource includes
+ a model, controller and route
+ gen scaffold <name> [attrs] Create a new scaffolding. Scaffolding includes
+ the views, a model, controller and route
+ gen secret Generate a new application secret in
+ `config/secret`
+ gen controller <name> Generate a new controller including an index view
+ and and a route
+ gen model <name> [attrs] Generate a new model
+ gen auth[:update] Creates user authentication for you, using Passport.
+
+ Generator options:
+ --realtime, -rt When generating or scaffolding, take realtime into account
+ --jade, -j When generating views this will create Jade
+ templates(Default: EJS)
+ --handle, -H When generating views this will create Handlebars
+ templates(Default: EJS)
+ --mustache, -m When generating views this will create Mustache
+ templates(Default: EJS)
+ Generator examples:
+ geddy gen app foo Generate an app in a directory named 'foo'
+ geddy gen resource user name admin:boolean
+ Generate a users resource with the model properties
+ name as a string and admin as a boolean
+ geddy gen scaffold user name:string:default
+ Generate a users scaffolding user name as the default
+ value to display data with
+
+
Please sign in to comment.
Something went wrong with that request. Please try again.