Repository: cliftonc/express-mvc-bootstrap Branch: master Commit: 4a6308d7da9e Files: 50 Total size: 127.0 KB Directory structure: gitextract_1e56a2is/ ├── .npmignore ├── .project ├── README.md ├── app-cluster.js ├── app.js ├── conf/ │ ├── configuration.js │ ├── development.js │ ├── production.js │ └── test.js ├── controllers/ │ └── AppController.js ├── eb ├── lib/ │ ├── AppController.js │ ├── ExamplesController.js │ ├── README │ └── inflection.js ├── models/ │ └── README ├── package.json ├── public/ │ └── css/ │ ├── Aristo/ │ │ └── jquery-ui-1.8.7.custom.css │ └── style.css ├── scripts/ │ ├── create-controller.js │ ├── create-model.js │ ├── create-test.js │ ├── create-view.js │ ├── generate-all.js │ ├── help.js │ └── templates/ │ ├── create-controller.help.ejs │ ├── create-controller.template.ejs │ ├── create-model.help.ejs │ ├── create-model.template.ejs │ ├── create-test.help.ejs │ ├── create-test.template.functional.ejs │ ├── create-test.template.integration.ejs │ ├── create-test.template.unit.ejs │ ├── create-view.help.ejs │ ├── create-view.template.edit.ejs │ ├── create-view.template.index.ejs │ ├── create-view.template.show.ejs │ └── help.ejs ├── tests/ │ ├── functional/ │ │ ├── README │ │ └── SampleTests.js │ ├── integration/ │ │ └── AppControllerTests.js │ └── unit/ │ ├── README │ └── SampleTests.js ├── utils/ │ ├── pager.js │ └── socketio.js └── views/ ├── 404.html ├── 500.html ├── app/ │ └── index.html ├── layout.html └── messages.html ================================================ FILE CONTENTS ================================================ ================================================ FILE: .npmignore ================================================ *.sock logs/* pids/* ================================================ FILE: .project ================================================ express-mvc-bootstrap ================================================ FILE: README.md ================================================ # THIS PROJECT IS NO LONGER MAINTAINED, TRY THIS ONE: https://github.com/niftylettuce/eskimo # Express MVC Bootstrap A MVC boilerplate for Express.js ## Description I built this application to create a template MVC `style` app that I could then use as the start point for further development. I used the excellent examples in the main [Express github repository](https://github.com/visionmedia/express), specifically the MVC example, as the starting point. I have however changed it quite substantially to make it clearer and remove some of the `magic` that confused me at first when learning. If you are familiar with other MVC frameworks hopefully my file structure makes some sense. ## Requires ### You need to manually install: - [Node.js](http://nodejs.org/): Amazing javascript asynchronous IO library, install manually. - [MongoDB](http://www.mongodb.org): NoSQL Database, install manually. - [NPM](http://npmjs.org/): Node package manager, used to install the remaining. ### And then install via NPM: - [Express](http://expressjs.com/): Application Framework for Node.js - [Mongoose](http://mongoosejs.com/): Node.JS ORM for Mongo - [ejs](http://embeddedjs.com/): EmbeddedJS Templating - [cluster](http://learnboost.github.com/cluster): extensible multi-core server manager - log: Tiny logger with streaming reader - [connect](https://github.com/senchalabs/connect): High performance middleware framework - mime: A comprehensive library for mime-type mapping - qs: querystring parser - [expresso](https://github.com/visionmedia/expresso): TDD framework, light-weight, fast, CI-friendly - should: test framework agnostic BDD-style assertions - [socket.io](https://github.com/learnboost/Socket.IO-node): The cross-browser WebSocket ### But I've included in this project: - [jQuery](http://jquery.com/): Javascript Library - [jQuery UI](http://jqueryui.com/): UI Library - [jQuery Aristo Template](http://taitems.tumblr.com/post/482577430/introducing-aristo-a-jquery-ui-theme): Fantastic looking jQuery UI Template. ## Installation - Install node.js // on osx with brew brew update brew install node // build from source git clone git://github.com/joyent/node.git ./configure make make install - Ininstall mongodb // on osx with brew brew update brew install mongodb // create db folder mkdir -p /usr/local/db/ > For more installation detail please see [this](http://www.mongodb.org/display/DOCS/Quickstart) - Install npm curl http://npmjs.org/install.sh | clean=no sh - Install required packages // install executable package globally npm install express-mvc-bootstrap -g // make project folder and go to that folder mkdir /path/to/project cd /path/to/project // install packages locally to be `require();` npm install socket.io should mongoose log cluster expresso qs mime ejs connect express express-mvc-bootstrap ## Setup - In you project folder run // create app eb create-app // running mongodb mongod --dbpath /usr/local/db/ // running server eb - Browse to http://localhost:3000 ## Commands: // Shows help eb script // Wrapper for 3 commands below eb script generate-all HelloWorld // Creates a model eb script create-model HelloWorld // Creates a controller eb script create-controller HelloWorld // Creates views eb script create-view HelloWorld // Creates tests eb script create-test HelloWorld // Runs server on different port eb server server.port=3000 // Creates a new app eb create-app ## TODO: Build some amazing apps! ================================================ FILE: app-cluster.js ================================================ /** * Module dependencies. */ var cluster = require('cluster'); var app; /** * Initial bootstrapping */ exports.boot = function(port,path){ //Create our express instance app = require('./app').boot(); // TODO : ENABLE Reload /** * var watchFolders = [path + '/models', path + '/controllers', path + '/views', path + '/utils'] .use(cluster.reload(watchFolders,{ signal: 'SIGQUIT', interval: 60000 })) */ cluster(app) .set('working directory', path) .set('socket path',path) .in('development') .set('workers', 1) .use(cluster.logger(path + '/logs', 'debug')) .use(cluster.debug()) .use(cluster.pidfiles(path + '/pids')) .in('test') .set('workers', 1) .use(cluster.logger(path + '/logs', 'warning')) .use(cluster.pidfiles(path + '/pids')) .in('production') .set('workers', 2) .use(cluster.logger(path + '/logs')) .use(cluster.pidfiles(path + '/pids')) .in('all') .listen(parseInt(port)); }; ================================================ FILE: app.js ================================================ /** * Module dependencies. */ var fs = require('fs'),express = require('express'), mongoose = require('mongoose'), nodepath = require('path'); var path = __dirname; var app; /** * Initial bootstrapping */ exports.boot = function(params){ //Create our express instance app = express.createServer(); // Import configuration require(path + '/conf/configuration.js')(app,express); // Bootstrap application bootApplication(app); bootModels(app); bootControllers(app); return app; }; /** * App settings and middleware * Any of these can be added into the by environment configuration files to * enable modification by env. */ function bootApplication(app) { // launch // app.use(express.logger({ format: ':method :url :status' })); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.cookieParser()); app.use(express.session({ secret: 'helloworld' })); app.use(express.static(path + '/public')); // Before router to enable dynamic routing app.use(app.router); // Example 500 page app['error'](function(err, req, res){ console.log('Internal Server Error: ' + err.message); res.render('500'); }); // Example 404 page via simple Connect middleware app.use(function(req, res){ res.render('404'); }); // Setup ejs views as default, with .html as the extension app.set('views', path + '/views'); app.register('.html', require('ejs')); app.set('view engine', 'html'); // Some dynamic view helpers app.dynamicHelpers({ request: function(req){ return req; }, hasMessages: function(req){ return Object.keys(req.session.flash || {}).length; }, messages: function(req){ return function(){ var msgs = req.flash(); console.log(msgs); return Object.keys(msgs).reduce(function(arr, type){ return arr.concat(msgs[type]); }, []); } } }); } //Bootstrap models function bootModels(app) { fs.readdir(path + '/models', function(err, files){ if (err) throw err; files.forEach(function(file){ bootModel(app, file); }); }); // Connect to mongoose mongoose.connect(app.set('db-uri')); } // Bootstrap controllers function bootControllers(app) { fs.readdir(path + '/controllers', function(err, files){ if (err) throw err; files.forEach(function(file){ // bootController(app, file); }); }); require(path + '/controllers/AppController')(app); // Include } // simplistic model support function bootModel(app, file) { var name = file.replace('.js', ''), schema = require(path + '/models/'+ name); // Include the mongoose file } // Load the controller, link to its view file from here function bootController(app, file) { var name = file.replace('.js', ''), controller = path + '/controllers/' + name, // full controller to include template = name.replace('Controller','').toLowerCase(); // template folder for html - remove the ...Controller part. // Include the controller // require(controller)(app,template); // Include } // allow normal node loading if appropriate if (!module.parent) { exports.boot().listen(3000); console.log("Express server %s listening on port %d", express.version, app.address().port) } ================================================ FILE: conf/configuration.js ================================================ /** * Default configuration manager * Inject app and express reference */ module.exports = function(app,express) { // DEVELOPMENT app.configure('development', function() { require("./development.js")(app,express); }); // TEST app.configure('test', function() { require("./test.js")(app,express); }); // PRODUCTION app.configure('production', function() { require("./production.js")(app,express); }); } ================================================ FILE: conf/development.js ================================================ /** * DEVELOPMENT Environment settings */ module.exports = function(app,express) { app.set('db-uri', 'mongodb://localhost/mvc-development'); app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); } ================================================ FILE: conf/production.js ================================================ /** * TEST Environment settings */ module.exports = function(app,express) { app.set('db-uri', 'mongodb://localhost/mvc-production'); app.use(express.errorHandler({ dumpExceptions: true, showStack: false })); } ================================================ FILE: conf/test.js ================================================ /** * PRODUCTION Environment settings */ module.exports = function(app,express) { app.set('db-uri', 'mongodb://localhost/mvc-production'); app.use(express.errorHandler({ dumpExceptions: false, showStack: false })); } ================================================ FILE: controllers/AppController.js ================================================ var fs = require('fs') , inflection = require('../lib/inflection'); module.exports = function(app) { // app.get("/favicon.ico", function() {}); // Required if you delete the favicon.ico from public // Plural app.get("/:controller?", router); // Index app.get("/:controller.:format?", router); // Index app.get("/:controller/:from-:to.:format?", router); // Index // Plural Create & Delete app.post("/:controller", router); // Create app.del("/:controller", router); // Delete all // Singular - different variable to clarify routing app.get("/:controller/:id.:format?", router); // To support controller/index app.get("/:controller/:id/:action", router); // Show edit app.put("/:controller/:id", router); // Update app.del("/:controller/:id", router); // Delete } /// function router(req, res, next) { var controller = req.params.controller ? req.params.controller : ''; var action = req.params.action ? req.params.action : ''; var id = req.params.id ? req.params.id : ''; var method = req.method.toLowerCase(); var fn = 'index'; // Default route if(controller.length == 0) { index(req,res,next); return; } // Determine the function to call based on controller / model and method if(id.length == 0) { // We are plural switch(method) { case 'get': fn = 'index'; break; case 'post': fn = 'create'; break; case 'delete': fn = 'destroyAll'; break; } } else { // Controller name is now singular, need to switch it back controller = controller.pluralize(); switch(method) { case 'get': if(action.length > 0) { fn = action; } else { fn = 'show'; } break; case 'put': fn = 'update'; break; case 'delete': fn = 'destroy'; break; } } try { var controllerLibrary = require('./' + controller.capitalize() + 'Controller'); if(typeof controllerLibrary[fn] === 'function') { controllerLibrary[fn](req,res,next); } else { res.render('404'); } } catch (e) { res.render('404'); } }; /** * Default Application index - shows a list of the controllers. * Redirect here if you prefer another controller to be your index. * @param req * @param res */ function index(req, res, next) { /** * If you want to redirect to another controller, uncomment */ // res.redirect('/controllerName'); var controllers = []; fs.readdir(__dirname + '/', function(err, files){ if (err) throw err; files.forEach(function(file){ if(file != "AppController.js") { controllers.push(file.replace('Controller.js','').toLowerCase()); } }); res.render('app',{controllers:controllers}); }); }; ================================================ FILE: eb ================================================ #!/usr/bin/env node /** * ExpressJs MVC Bootstrap * @Params - cmd - serve r | script | params */ /** * Framework version. */ var version = '0.1.2'; /** * Require everything in the library folder */ require.paths.unshift(__dirname + '/lib'); /** * Explicit module dependencies */ var fs = require('fs'), nodepath = require('path'), exec = require('child_process').exec; /** * Paths **/ var path = fs.realpathSync('.'); var bootstrapPath = __dirname; /** * Main Command router */ var appLauncher = { command:'cluster', server: { port:3000 }, script: { name:'help', params: [] } }; for(var i in process.argv) { // Skip the first two - Node and app.js path if(i>1) { processParam(process.argv[i],i); } } runLauncher(appLauncher); /** * Run the launcher * @param appLauncher */ function runLauncher(appLauncher) { // Always use current directory? console.log('\r\n\x1b[36mLaunching bootstrap from: \x1b[0m ' + path); console.log('\x1b[36mScript directory: \x1b[0m ' + bootstrapPath + '/scripts'); // Check if this is a bootstrap application? if(isLibrary()) { console.log('\x1b[1mDo not run this from the bootstrap library folder, please run from an empty directory or a bootstrapped app, or please run "npm install"\x1b[0m\r\n'); return; } // Check if this is a bootstrap application? if(!isBootstrap() && appLauncher.command != 'create-app') { console.log('\x1b[1mApplication not bootstrapped - you must run:\x1b[0m eb create-app\r\n'); return; } switch(appLauncher.command) { case 'test': runTests(appLauncher.script); break; case 'cluster': runCluster(appLauncher.server.port); break; case 'server': runServer(appLauncher.server.port); break; case 'script': runScript(appLauncher.script); break; case 'create-app': createApplication(path); break; default: appLauncher.command = 'script'; runScript(appLauncher.script); } } /** * Check if express app.js exists **/ function isLibrary() { return nodepath.existsSync(path + '/eb'); } /** * Check if .bootstrap exists **/ function isBootstrap() { return nodepath.existsSync(path + '/.eb-status'); } /** * Run a script * @param appLauncher * Runs by default from path where bootstrap runs via __dirname. */ function runScript(scriptLauncher) { var script = require(bootstrapPath + '/scripts/'+ scriptLauncher.name); script.execute(scriptLauncher.params,path); } /** * Process params into array to enable launch * @param param * @param params */ function processParam(param,depth) { var paramArray = param.split("="); // Run command - must always come after the app if(i == 2) { appLauncher.command = param; } // Server.port if(paramArray[0] == "server.port" && paramArray[1] != undefined) { appLauncher.server.port = paramArray[1]; } // if((appLauncher.command == "script" || appLauncher.command == "test") && i == 3) { appLauncher.script.name = param; } // Script params if(appLauncher.command == 'script' && i > 3) { appLauncher.script.params.push(param); } } /** * Run expresso tests */ function runTests(appLauncher) { var test = appLauncher.name ? appLauncher.name : 'all'; if(test == 'help') { // This is the default - ugly I know! test = ['unit','integration','functional']; } else { test = [test]; } test.forEach(function (item, index) { exec('expresso -I . -s tests/' + item + '/* ', { timeout: 60000, cwd:path }, function (error, stdout, stderr) { console.log("Finished test: " + item); console.log(stdout); console.log(stderr); }); }); } /** * Launch a server */ function runServer(port) { // Ensure we run in the local folder of the application process.chdir(path); var app = require(path + '/app').boot(); app.listen(port); console.log('\r\n\x1b[36mApplication started on port:\x1b[0m ' + port); } /** * Launch a cluster */ function runCluster(port) { // Ensure we run in the local folder of the application process.chdir(path); require(path + '/app-cluster').boot(port,path); console.log('\r\n\x1b[36mLaunching cluster mode on port: \x1b[0m' + port); } /** * Application Creation - Borrowed from Express scripts **/ /** * Create application at the given directory `path`. * * @param {String} path */ function createApplicationAt(path) { mkdir(path + '/models',function() { // Disabled as no default models // copy(bootstrapPath + '/models/*',path + '/models'); }); mkdir(path + '/controllers',function() { copy(bootstrapPath + '/controllers/*',path + '/controllers'); }); mkdir(path + '/conf',function() { copy(bootstrapPath + '/conf/*',path + '/conf'); }); mkdir(path + '/utils',function() { copy(bootstrapPath + '/utils/*',path + '/utils'); }); mkdir(path + '/views',function() { copy(bootstrapPath + '/views/*',path + '/views'); }); mkdir(path + '/public',function() { copy(bootstrapPath + '/public/*',path + '/public'); }); mkdir(path + '/lib',function() { copy(bootstrapPath + '/lib/*',path + '/lib'); }); mkdir(path + '/tests',function() { mkdir(path + '/tests/unit',function() { copy(bootstrapPath + '/tests/unit/*',path + '/tests/unit'); }); mkdir(path + '/tests/integration',function() { copy(bootstrapPath + '/tests/integration/*',path + '/tests/integration'); }); mkdir(path + '/tests/functional',function() { copy(bootstrapPath + '/tests/functional/*',path + '/tests/functional'); }); }); mkdir(path + '/logs'); mkdir(path + '/pids'); copy(bootstrapPath + '/app-cluster.js',path + '/'); copy(bootstrapPath + '/app.js',path + '/'); write(path + '/.eb-status','Created @ ' + new Date()); } function createApplication(path) { emptyDirectory(path, function(empty){ if (empty) { createApplicationAt(path); } else { confirm('This will over-write the existing application, continue? ', function(ok){ if (ok) { process.stdin.destroy(); createApplicationAt(path); } else { abort('aborting'); } }); } }); }; /** * Check if the given directory `path` is empty. * * @param {String} path * @param {Function} fn */ function emptyDirectory(path, fn) { fs.readdir(path, function(err, files){ if (err && 'ENOENT' != err.code) throw err; fn(!files || !files.length); }); } /** * echo str > path. * * @param {String} path * @param {String} str */ function write(path, str) { fs.writeFile(path, str); console.log(' \x1b[36mcreate\x1b[0m : ' + path); } /** * Prompt confirmation with the given `msg`. * * @param {String} msg * @param {Function} fn */ function confirm(msg, fn) { prompt(msg, function(val){ fn(/^ *y(es)?/i.test(val)); }); } /** * Prompt input with the given `msg` and callback `fn`. * * @param {String} msg * @param {Function} fn */ function prompt(msg, fn) { // prompt if (' ' == msg[msg.length - 1]) { process.stdout.write(msg); } else { console.log(msg); } // stdin process.stdin.setEncoding('ascii'); process.stdin.once('data', function(data){ fn(data); }).resume(); } /** * Mkdir -p. * * @param {String} path * @param {Function} fn */ function mkdir(path, fn) { exec('mkdir -p ' + path, function(err){ if (err) throw err; console.log(' \x1b[36mcreate\x1b[0m : ' + path); fn && fn(); }); } /** * cp -r * * @param {String} path * @param {Function} fn */ function copy(from, to, fn) { exec('cp -R ' + from + ' ' + to, function(err){ if (err) throw err; console.log(' \x1b[36mCopied\x1b[0m : ' + from + ' to ' + to); fn && fn(); }); } /** * Exit with the given `str`. * * @param {String} str */ function abort(str) { console.error(str); process.exit(1); } ================================================ FILE: lib/AppController.js ================================================ var fs = require('fs') , inflection = require('../lib/inflection'); module.exports = function(app) { // app.get("/favicon.ico", function() {}); // Required if you delete the favicon.ico from public // Plural app.get("/:controller?", router); // Index app.get("/:controller.:format?", router); // Index app.get("/:controller/:from-:to.:format?", router); // Index // Plural Create & Delete app.post("/:controller", router); // Create app.del("/:controller", router); // Delete all // Singular - different variable to clarify routing app.get("/:controller/:id.:format?", router); // To support controller/index app.get("/:controller/:id/:action", router); // Show edit app.put("/:controller/:id", router); // Update app.del("/:controller/:id", router); // Delete } /// function router(req, res, next) { var controller = req.params.controller ? req.params.controller : ''; var action = req.params.action ? req.params.action : ''; var id = req.params.id ? req.params.id : ''; var method = req.method.toLowerCase(); var fn = 'index'; // Default route if(controller.length == 0) { index(req,res,next); return; } // Determine the function to call based on controller / model and method if(id.length == 0) { // We are plural switch(method) { case 'get': fn = 'index'; break; case 'post': fn = 'create'; break; case 'delete': fn = 'destroyAll'; break; } } else { // Controller name is now singular, need to switch it back controller = controller.pluralize(); switch(method) { case 'get': if(action.length > 0) { fn = action; } else { fn = 'show'; } break; case 'put': fn = 'update'; break; case 'delete': fn = 'destroy'; break; } } var controllerLibrary = require('./' + controller.capitalize() + 'Controller'); if(typeof controllerLibrary[fn] === 'function') { controllerLibrary[fn](req,res,next); } else { res.render('404'); } }; /** * Default Application index - shows a list of the controllers. * Redirect here if you prefer another controller to be your index. * @param req * @param res */ function index(req, res, next) { /** * If you want to redirect to another controller, uncomment */ // res.redirect('/controllerName'); var controllers = []; fs.readdir(__dirname + '/', function(err, files){ if (err) throw err; files.forEach(function(file){ if(file != "AppController.js") { controllers.push(file.replace('Controller.js','').toLowerCase()); } }); res.render('app',{controllers:controllers}); }); }; ================================================ FILE: lib/ExamplesController.js ================================================ /** * Examples Controller * Created by create-controller script @ Fri Mar 11 2011 21:16:50 GMT+0000 (GMT) **/ var mongoose = require('mongoose'), Example = mongoose.model('Example'), pager = require('../utils/pager.js'), ViewTemplatePath = 'examples'; module.exports = { init: function(params) { ViewTemplatePath = params.viewPath // Enable over-ride of view path for testing }, /** * Index action, returns a list either via the views/examples/index.html view or via json * Default mapping to GET '/examples' * For JSON use '/examples.json' **/ index: function(req, res, next) { var from = req.params.from ? parseInt(req.params.from) - 1 : 0; var to = req.params.to ? parseInt(req.params.to) : 10; var total = 0; Example.count({}, function (err, count) { total = count; var pagerHtml = pager.render(from,to,total,'/examples'); Example.find({}) .sort('name', 1) .skip(from).limit(to) .find(function (err, examples) { if(err) return next(err); switch (req.params.format) { case 'json': res.send(examples.map(function(u) { return u.toObject(); })); break; default: res.render(ViewTemplatePath,{examples:examples,pagerHtml:pagerHtml}); } }); }); }, /** * Show action, returns shows a single item via views/examples/show.html view or via json * Default mapping to GET '/example/:id' * For JSON use '/example/:id.json' **/ show: function(req, res, next) { Example.findById(req.params.id, function(err, example) { if(err) return next(err); switch (req.params.format) { case 'json': res.send(example.toObject()); break; default: res.render(ViewTemplatePath + "/show",{example:example}); } }); }, /** * Edit action, returns a form via views/examples/edit.html view no JSON view. * Default mapping to GET '/example/:id/edit' **/ edit: function(req, res, next){ Example.findById(req.params.id, function(err, example) { if(err) return next(err); res.render(ViewTemplatePath + "/edit",{example:example}); }); }, /** * Update action, updates a single item and redirects to Show or returns the object as json * Default mapping to PUT '/example/:id', no GET mapping **/ update: function(req, res, next){ Example.findById(req.params.id, function(err, example) { if (!example) return next(err); example.name = req.body.example.name; example.save(function(err) { if (err) { console.log(err); req.flash('error','Could not update example: ' + err); res.redirect('/examples'); return; } switch (req.params.format) { case 'json': res.send(example.toObject()); break; default: req.flash('info', 'Example updated'); res.redirect('/example/' + req.params.id); } }); }); }, /** * Create action, creates a single item and redirects to Show or returns the object as json * Default mapping to POST '/examples', no GET mapping **/ create: function(req, res, next){ var example = new Example(req.body.example); example.save(function(err) { if (err) { req.flash('error','Could not create example: ' + err); res.redirect('/examples'); return; } switch (req.params.format) { case 'json': res.send(example.toObject()); break; default: req.flash('info','Example created'); res.redirect('/example/' + example.id); } }); }, /** * Delete action, deletes a single item and redirects to index * Default mapping to DEL '/example/:id', no GET mapping **/ destroy: function(req, res, next){ Example.findById(req.params.id, function(err, example) { if (!example) { req.flash('error','Unable to locate the example to delete!'); res.render('404'); return false; }; example.remove(function(err) { if(err) { req.flash('error','There was an error deleting the example!'); res.send('false'); } else { req.flash('info','Example deleted'); res.send('true'); } }); }); } }; ================================================ FILE: lib/README ================================================ Place any dependent libraries in here * inflection.js : http://code.google.com/p/inflection-js/ Modified to remove the link to window. ================================================ FILE: lib/inflection.js ================================================ /* Copyright (c) 2010 Ryan Schuft (ryan.schuft@gmail.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. */ /* This code is based in part on the work done in Ruby to support infection as part of Ruby on Rails in the ActiveSupport's Inflector and Inflections classes. It was initally ported to Javascript by Ryan Schuft (ryan.schuft@gmail.com) in 2007. The code is available at http://code.google.com/p/inflection-js/ The basic usage is: 1. Include this script on your web page. 2. Call functions on any String object in Javascript Currently implemented functions: String.pluralize(plural) == String renders a singular English language noun into its plural form normal results can be overridden by passing in an alternative String.singularize(singular) == String renders a plural English language noun into its singular form normal results can be overridden by passing in an alterative String.camelize(lowFirstLetter) == String renders a lower case underscored word into camel case the first letter of the result will be upper case unless you pass true also translates "/" into "::" (underscore does the opposite) String.underscore() == String renders a camel cased word into words seperated by underscores also translates "::" back into "/" (camelize does the opposite) String.humanize(lowFirstLetter) == String renders a lower case and underscored word into human readable form defaults to making the first letter capitalized unless you pass true String.capitalize() == String renders all characters to lower case and then makes the first upper String.dasherize() == String renders all underbars and spaces as dashes String.titleize() == String renders words into title casing (as for book titles) String.demodulize() == String renders class names that are prepended by modules into just the class String.tableize() == String renders camel cased singular words into their underscored plural form String.classify() == String renders an underscored plural word into its camel cased singular form String.foreign_key(dropIdUbar) == String renders a class name (camel cased singular noun) into a foreign key defaults to seperating the class from the id with an underbar unless you pass true String.ordinalize() == String renders all numbers found in the string into their sequence like "22nd" */ /* This sets up a container for some constants in its own namespace We use the window (if available) to enable dynamic loading of this script Window won't necessarily exist for non-browsers. if (window && !window.InflectionJS) { window.InflectionJS = null; } */ /* This sets up some constants for later use This should use the window namespace variable if available */ InflectionJS = { /* This is a list of nouns that use the same form for both singular and plural. This list should remain entirely in lower case to correctly match Strings. */ uncountable_words: [ 'equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'moose', 'deer', 'news' ], /* These rules translate from the singular form of a noun to its plural form. */ plural_rules: [ [new RegExp('(m)an$', 'gi'), '$1en'], [new RegExp('(pe)rson$', 'gi'), '$1ople'], [new RegExp('(child)$', 'gi'), '$1ren'], [new RegExp('^(ox)$', 'gi'), '$1en'], [new RegExp('(ax|test)is$', 'gi'), '$1es'], [new RegExp('(octop|vir)us$', 'gi'), '$1i'], [new RegExp('(alias|status)$', 'gi'), '$1es'], [new RegExp('(bu)s$', 'gi'), '$1ses'], [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'], [new RegExp('([ti])um$', 'gi'), '$1a'], [new RegExp('sis$', 'gi'), 'ses'], [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'], [new RegExp('(hive)$', 'gi'), '$1s'], [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'], [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'], [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'], [new RegExp('([m|l])ouse$', 'gi'), '$1ice'], [new RegExp('(quiz)$', 'gi'), '$1zes'], [new RegExp('s$', 'gi'), 's'], [new RegExp('$', 'gi'), 's'] ], /* These rules translate from the plural form of a noun to its singular form. */ singular_rules: [ [new RegExp('(m)en$', 'gi'), '$1an'], [new RegExp('(pe)ople$', 'gi'), '$1rson'], [new RegExp('(child)ren$', 'gi'), '$1'], [new RegExp('([ti])a$', 'gi'), '$1um'], [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'], [new RegExp('(hive)s$', 'gi'), '$1'], [new RegExp('(tive)s$', 'gi'), '$1'], [new RegExp('(curve)s$', 'gi'), '$1'], [new RegExp('([lr])ves$', 'gi'), '$1f'], [new RegExp('([^fo])ves$', 'gi'), '$1fe'], [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'], [new RegExp('(s)eries$', 'gi'), '$1eries'], [new RegExp('(m)ovies$', 'gi'), '$1ovie'], [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'], [new RegExp('([m|l])ice$', 'gi'), '$1ouse'], [new RegExp('(bus)es$', 'gi'), '$1'], [new RegExp('(o)es$', 'gi'), '$1'], [new RegExp('(shoe)s$', 'gi'), '$1'], [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'], [new RegExp('(octop|vir)i$', 'gi'), '$1us'], [new RegExp('(alias|status)es$', 'gi'), '$1'], [new RegExp('^(ox)en', 'gi'), '$1'], [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'], [new RegExp('(matr)ices$', 'gi'), '$1ix'], [new RegExp('(quiz)zes$', 'gi'), '$1'], [new RegExp('s$', 'gi'), ''] ], /* This is a list of words that should not be capitalized for title case */ non_titlecased_words: [ 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at', 'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over', 'with', 'for' ], /* These are regular expressions used for converting between String formats */ id_suffix: new RegExp('(_ids|_id)$', 'g'), underbar: new RegExp('_', 'g'), space_or_underbar: new RegExp('[\ _]', 'g'), uppercase: new RegExp('([A-Z])', 'g'), underbar_prefix: new RegExp('^_'), /* This is a helper method that applies rules based replacement to a String Signature: InflectionJS.apply_rules(str, rules, skip, override) == String Arguments: str - String - String to modify and return based on the passed rules rules - Array: [RegExp, String] - Regexp to match paired with String to use for replacement skip - Array: [String] - Strings to skip if they match override - String (optional) - String to return as though this method succeeded (used to conform to APIs) Returns: String - passed String modified by passed rules Examples: InflectionJS.apply_rules("cows", InflectionJs.singular_rules) === 'cow' */ apply_rules: function(str, rules, skip, override) { if (override) { str = override; } else { var ignore = (skip.indexOf(str.toLowerCase()) > -1); if (!ignore) { for (var x = 0; x < rules.length; x++) { if (str.match(rules[x][0])) { str = str.replace(rules[x][0], rules[x][1]); break; } } } } return str; } }; /* This lets us detect if an Array contains a given element Signature: Array.indexOf(item, fromIndex, compareFunc) == Integer Arguments: item - Object - object to locate in the Array fromIndex - Integer (optional) - starts checking from this position in the Array compareFunc - Function (optional) - function used to compare Array item vs passed item Returns: Integer - index position in the Array of the passed item Examples: ['hi','there'].indexOf("guys") === -1 ['hi','there'].indexOf("hi") === 0 */ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(item, fromIndex, compareFunc) { if (!fromIndex) { fromIndex = -1; } var index = -1; for (var i = fromIndex; i < this.length; i++) { if (this[i] === item || compareFunc && compareFunc(this[i], item)) { index = i; break; } } return index; }; } /* You can override this list for all Strings or just one depending on if you set the new values on prototype or on a given String instance. */ if (!String.prototype._uncountable_words) { String.prototype._uncountable_words = InflectionJS.uncountable_words; } /* You can override this list for all Strings or just one depending on if you set the new values on prototype or on a given String instance. */ if (!String.prototype._plural_rules) { String.prototype._plural_rules = InflectionJS.plural_rules; } /* You can override this list for all Strings or just one depending on if you set the new values on prototype or on a given String instance. */ if (!String.prototype._singular_rules) { String.prototype._singular_rules = InflectionJS.singular_rules; } /* You can override this list for all Strings or just one depending on if you set the new values on prototype or on a given String instance. */ if (!String.prototype._non_titlecased_words) { String.prototype._non_titlecased_words = InflectionJS.non_titlecased_words; } /* This function adds plurilization support to every String object Signature: String.pluralize(plural) == String Arguments: plural - String (optional) - overrides normal output with said String Returns: String - singular English language nouns are returned in plural form Examples: "person".pluralize() == "people" "octopus".pluralize() == "octopi" "Hat".pluralize() == "Hats" "person".pluralize("guys") == "guys" */ if (!String.prototype.pluralize) { String.prototype.pluralize = function(plural) { return InflectionJS.apply_rules( this, this._plural_rules, this._uncountable_words, plural ); }; } /* This function adds singularization support to every String object Signature: String.singularize(singular) == String Arguments: singular - String (optional) - overrides normal output with said String Returns: String - plural English language nouns are returned in singular form Examples: "people".singularize() == "person" "octopi".singularize() == "octopus" "Hats".singularize() == "Hat" "guys".singularize("person") == "person" */ if (!String.prototype.singularize) { String.prototype.singularize = function(singular) { return InflectionJS.apply_rules( this, this._singular_rules, this._uncountable_words, singular ); }; } /* This function adds camelization support to every String object Signature: String.camelize(lowFirstLetter) == String Arguments: lowFirstLetter - boolean (optional) - default is to capitalize the first letter of the results... passing true will lowercase it Returns: String - lower case underscored words will be returned in camel case additionally '/' is translated to '::' Examples: "message_properties".camelize() == "MessageProperties" "message_properties".camelize(true) == "messageProperties" */ if (!String.prototype.camelize) { String.prototype.camelize = function(lowFirstLetter) { var str = this.toLowerCase(); var str_path = str.split('/'); for (var i = 0; i < str_path.length; i++) { var str_arr = str_path[i].split('_'); var initX = ((lowFirstLetter && i + 1 === str_path.length) ? (1) : (0)); for (var x = initX; x < str_arr.length; x++) { str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1); } str_path[i] = str_arr.join(''); } str = str_path.join('::'); return str; }; } /* This function adds underscore support to every String object Signature: String.underscore() == String Arguments: N/A Returns: String - camel cased words are returned as lower cased and underscored additionally '::' is translated to '/' Examples: "MessageProperties".camelize() == "message_properties" "messageProperties".underscore() == "message_properties" */ if (!String.prototype.underscore) { String.prototype.underscore = function() { var str = this; var str_path = str.split('::'); for (var i = 0; i < str_path.length; i++) { str_path[i] = str_path[i].replace(InflectionJS.uppercase, '_$1'); str_path[i] = str_path[i].replace(InflectionJS.underbar_prefix, ''); } str = str_path.join('/').toLowerCase(); return str; }; } /* This function adds humanize support to every String object Signature: String.humanize(lowFirstLetter) == String Arguments: lowFirstLetter - boolean (optional) - default is to capitalize the first letter of the results... passing true will lowercase it Returns: String - lower case underscored words will be returned in humanized form Examples: "message_properties".humanize() == "Message properties" "message_properties".humanize(true) == "message properties" */ if (!String.prototype.humanize) { String.prototype.humanize = function(lowFirstLetter) { var str = this.toLowerCase(); str = str.replace(InflectionJS.id_suffix, ''); str = str.replace(InflectionJS.underbar, ' '); if (!lowFirstLetter) { str = str.capitalize(); } return str; }; } /* This function adds capitalization support to every String object Signature: String.capitalize() == String Arguments: N/A Returns: String - all characters will be lower case and the first will be upper Examples: "message_properties".capitalize() == "Message_properties" "message properties".capitalize() == "Message properties" */ if (!String.prototype.capitalize) { String.prototype.capitalize = function() { var str = this.toLowerCase(); str = str.substring(0, 1).toUpperCase() + str.substring(1); return str; }; } /* This function adds dasherization support to every String object Signature: String.dasherize() == String Arguments: N/A Returns: String - replaces all spaces or underbars with dashes Examples: "message_properties".capitalize() == "message-properties" "Message Properties".capitalize() == "Message-Properties" */ if (!String.prototype.dasherize) { String.prototype.dasherize = function() { var str = this; str = str.replace(InflectionJS.space_or_underbar, '-'); return str; }; } /* This function adds titleize support to every String object Signature: String.titleize() == String Arguments: N/A Returns: String - capitalizes words as you would for a book title Examples: "message_properties".titleize() == "Message Properties" "message properties to keep".titleize() == "Message Properties to Keep" */ if (!String.prototype.titleize) { String.prototype.titleize = function() { var str = this.toLowerCase(); str = str.replace(InflectionJS.underbar, ' '); var str_arr = str.split(' '); for (var x = 0; x < str_arr.length; x++) { var d = str_arr[x].split('-'); for (var i = 0; i < d.length; i++) { if (this._non_titlecased_words.indexOf(d[i].toLowerCase()) < 0) { d[i] = d[i].capitalize(); } } str_arr[x] = d.join('-'); } str = str_arr.join(' '); str = str.substring(0, 1).toUpperCase() + str.substring(1); return str; }; } /* This function adds demodulize support to every String object Signature: String.demodulize() == String Arguments: N/A Returns: String - removes module names leaving only class names (Ruby style) Examples: "Message::Bus::Properties".demodulize() == "Properties" */ if (!String.prototype.demodulize) { String.prototype.demodulize = function() { var str = this; var str_arr = str.split('::'); str = str_arr[str_arr.length - 1]; return str; }; } /* This function adds tableize support to every String object Signature: String.tableize() == String Arguments: N/A Returns: String - renders camel cased words into their underscored plural form Examples: "MessageBusProperty".tableize() == "message_bus_properties" */ if (!String.prototype.tableize) { String.prototype.tableize = function() { var str = this; str = str.underscore().pluralize(); return str; }; } /* This function adds classification support to every String object Signature: String.classify() == String Arguments: N/A Returns: String - underscored plural nouns become the camel cased singular form Examples: "message_bus_properties".classify() == "MessageBusProperty" */ if (!String.prototype.classify) { String.prototype.classify = function() { var str = this; str = str.camelize().singularize(); return str; }; } /* This function adds foreign key support to every String object Signature: String.foreign_key(dropIdUbar) == String Arguments: dropIdUbar - boolean (optional) - default is to seperate id with an underbar at the end of the class name, you can pass true to skip it Returns: String - camel cased singular class names become underscored with id Examples: "MessageBusProperty".foreign_key() == "message_bus_property_id" "MessageBusProperty".foreign_key(true) == "message_bus_propertyid" */ if (!String.prototype.foreign_key) { String.prototype.foreign_key = function(dropIdUbar) { var str = this; str = str.demodulize().underscore() + ((dropIdUbar) ? ('') : ('_')) + 'id'; return str; }; } /* This function adds ordinalize support to every String object Signature: String.ordinalize() == String Arguments: N/A Returns: String - renders all found numbers their sequence like "22nd" Examples: "the 1 pitch".ordinalize() == "the 1st pitch" */ if (!String.prototype.ordinalize) { String.prototype.ordinalize = function() { var str = this; var str_arr = str.split(' '); for (var x = 0; x < str_arr.length; x++) { var i = parseInt(str_arr[x]); if (i === NaN) { var ltd = str_arr[x].substring(str_arr[x].length - 2); var ld = str_arr[x].substring(str_arr[x].length - 1); var suf = "th"; if (ltd != "11" && ltd != "12" && ltd != "13") { if (ld === "1") { suf = "st"; } else if (ld === "2") { suf = "nd"; } else if (ld === "3") { suf = "rd"; } } str_arr[x] += suf; } } str = str_arr.join(' '); return str; }; } ================================================ FILE: models/README ================================================ ================================================ FILE: package.json ================================================ { "name": "express-mvc-bootstrap", "description": "Express MVC Application Accelerator", "version": "0.1.2", "homepage": "http://cliftonc.github.com/express-mvc-bootstrap", "repository": { "type": "git", "url": "git://github.com/cliftonc/express-mvc-bootstrap.git" }, "main":"bootstrap", "author": "Clifton Cunningham (cliftoncunningham.co.uk)", "directories": { "lib": "./lib", "conf": "./conf", "models": "./models", "controllers": "./controllers", "views": "./views", "public": "./public", "scripts": "./scripts", "utils": "./utils", "tests": "./tests" }, "repository" : { "type" : "git" , "url" : "https://github.com/cliftonc/express-mvc-bootstrap.git" }, "engines" : { "node" : "0.4 || 0.5" }, "dependencies" : { "express" : ">=2.0.0beta3", "connect" : ">=1.0.3", "cluster" : ">=0.4.0", "ejs" : ">=0.3.1", "socket.io" : ">=0.6.16", "mongoose" : ">=1.1.3", "expresso" : ">=0.7.3", "should" : ">=0.0.4" }, "bin": { "eb": "./eb" } } ================================================ FILE: public/css/Aristo/jquery-ui-1.8.7.custom.css ================================================ /* * jQuery UI CSS Framework 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Theming/API */ /* Layout helpers ----------------------------------*/ .ui-helper-hidden { display: none; } .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .ui-helper-clearfix { display: inline-block; } /* required comment for clearfix to work in Opera \*/ * html .ui-helper-clearfix { height:1%; } .ui-helper-clearfix { display:block; } /* end clearfix */ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } /* Interaction Cues ----------------------------------*/ .ui-state-disabled { cursor: default !important; } /* Icons ----------------------------------*/ /* states and images */ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } /* Misc visuals ----------------------------------*/ /* Overlays */ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } /* * jQuery UI CSS Framework 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Theming/API * * To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller */ /* Component containers ----------------------------------*/ .ui-widget { font-family: Helvetica,Arial,sans-serif; font-size: 1.1em; } .ui-widget .ui-widget { font-size: 1em; } .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Helvetica,Arial,sans-serif; font-size: 1em; } .ui-widget-content { border: 1px solid #B6B6B6; background: #ffffff; color: #4F4F4F; } .ui-widget-content a { color: #4F4F4F; } .ui-widget-header { border: 1px solid #B6B6B6; color: #4F4F4F; font-weight: bold; } .ui-widget-header { background: url(images/bg_fallback.png) 0 0 repeat-x; background: -webkit-gradient( linear, left bottom, left top, color-stop(1, rgb(237,237,237)), color-stop(0, rgb(196,196,196)) ); background: -moz-linear-gradient( center top, rgb(237,237,237), rgb(196,196,196) ); } .ui-widget-header a { color: #4F4F4F; } /* Interaction states ----------------------------------*/ .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #B6B6B6; font-weight: normal; color: #4F4F4F; } .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { background: url(images/bg_fallback.png) 0 0 repeat-x; background: -webkit-gradient( linear, left bottom, left top, color-stop(1, rgb(237,237,237)), color-stop(0, rgb(196,196,196)) ); background: -moz-linear-gradient( center top, rgb(237,237,237), rgb(196,196,196) ); -webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset; -moz-box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset; } .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #4F4F4F; text-decoration: none; } .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #9D9D9D; font-weight: normal; color: #313131; } .ui-state-hover a, .ui-state-hover a:hover { color: #313131; text-decoration: none; } .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { outline: none; color: #1c4257; border: 1px solid #7096ab; background: url(images/bg_fallback.png) 0 -50px repeat-x; background: -webkit-gradient( linear, left bottom, left top, color-stop(1, rgb(185,224,245)), color-stop(0, rgb(146,189,214)) ); background: -moz-linear-gradient( center top, rgb(185,224,245), rgb(146,189,214) ); -webkit-box-shadow: none; -moz-box-shadow: none; } .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #313131; text-decoration: none; } .ui-widget :active { outline: none; } /* Interaction Cues ----------------------------------*/ .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight { border: 1px solid #d2dbf4; background: #f4f8fd; color: #0d2054; -moz-border-radius: 0 !important; -webkit-border-radius: 0 !important; border-radius: 0 !important; } .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { border: 1px solid #e2d0d0; background: #fcf0f0; color: #280b0b; -moz-border-radius: 0 !important; -webkit-border-radius: 0 !important; border-radius: 0 !important; } .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } /* Icons ----------------------------------*/ /* states and images */ .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } .ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } .ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } .ui-state-default .ui-icon { background-image: url(images/ui-icons_454545_256x240.png); } .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } .ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } .ui-state-error .ui-icon, .ui-state-error-text .ui-icon { background: url(images/icon_sprite.png) -16px 0 no-repeat !important; } .ui-state-highlight .ui-icon, .ui-state-error .ui-icon { margin-top: -1px; } /* positioning */ .ui-icon-carat-1-n { background-position: 0 0; } .ui-icon-carat-1-ne { background-position: -16px 0; } .ui-icon-carat-1-e { background-position: -32px 0; } .ui-icon-carat-1-se { background-position: -48px 0; } .ui-icon-carat-1-s { background-position: -64px 0; } .ui-icon-carat-1-sw { background-position: -80px 0; } .ui-icon-carat-1-w { background-position: -96px 0; } .ui-icon-carat-1-nw { background-position: -112px 0; } .ui-icon-carat-2-n-s { background-position: -128px 0; } .ui-icon-carat-2-e-w { background-position: -144px 0; } .ui-icon-triangle-1-n { background-position: 0 -16px; } .ui-icon-triangle-1-ne { background-position: -16px -16px; } .ui-icon-triangle-1-e { background-position: -32px -16px; } .ui-icon-triangle-1-se { background-position: -48px -16px; } .ui-icon-triangle-1-s { background-position: -64px -16px; } .ui-icon-triangle-1-sw { background-position: -80px -16px; } .ui-icon-triangle-1-w { background-position: -96px -16px; } .ui-icon-triangle-1-nw { background-position: -112px -16px; } .ui-icon-triangle-2-n-s { background-position: -128px -16px; } .ui-icon-triangle-2-e-w { background-position: -144px -16px; } .ui-icon-arrow-1-n { background-position: 0 -32px; } .ui-icon-arrow-1-ne { background-position: -16px -32px; } .ui-icon-arrow-1-e { background-position: -32px -32px; } .ui-icon-arrow-1-se { background-position: -48px -32px; } .ui-icon-arrow-1-s { background-position: -64px -32px; } .ui-icon-arrow-1-sw { background-position: -80px -32px; } .ui-icon-arrow-1-w { background-position: -96px -32px; } .ui-icon-arrow-1-nw { background-position: -112px -32px; } .ui-icon-arrow-2-n-s { background-position: -128px -32px; } .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } .ui-icon-arrow-2-e-w { background-position: -160px -32px; } .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } .ui-icon-arrowstop-1-n { background-position: -192px -32px; } .ui-icon-arrowstop-1-e { background-position: -208px -32px; } .ui-icon-arrowstop-1-s { background-position: -224px -32px; } .ui-icon-arrowstop-1-w { background-position: -240px -32px; } .ui-icon-arrowthick-1-n { background-position: 0 -48px; } .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } .ui-icon-arrowthick-1-e { background-position: -32px -48px; } .ui-icon-arrowthick-1-se { background-position: -48px -48px; } .ui-icon-arrowthick-1-s { background-position: -64px -48px; } .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } .ui-icon-arrowthick-1-w { background-position: -96px -48px; } .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } .ui-icon-arrow-4 { background-position: 0 -80px; } .ui-icon-arrow-4-diag { background-position: -16px -80px; } .ui-icon-extlink { background-position: -32px -80px; } .ui-icon-newwin { background-position: -48px -80px; } .ui-icon-refresh { background-position: -64px -80px; } .ui-icon-shuffle { background-position: -80px -80px; } .ui-icon-transfer-e-w { background-position: -96px -80px; } .ui-icon-transferthick-e-w { background-position: -112px -80px; } .ui-icon-folder-collapsed { background-position: 0 -96px; } .ui-icon-folder-open { background-position: -16px -96px; } .ui-icon-document { background-position: -32px -96px; } .ui-icon-document-b { background-position: -48px -96px; } .ui-icon-note { background-position: -64px -96px; } .ui-icon-mail-closed { background-position: -80px -96px; } .ui-icon-mail-open { background-position: -96px -96px; } .ui-icon-suitcase { background-position: -112px -96px; } .ui-icon-comment { background-position: -128px -96px; } .ui-icon-person { background-position: -144px -96px; } .ui-icon-print { background-position: -160px -96px; } .ui-icon-trash { background-position: -176px -96px; } .ui-icon-locked { background-position: -192px -96px; } .ui-icon-unlocked { background-position: -208px -96px; } .ui-icon-bookmark { background-position: -224px -96px; } .ui-icon-tag { background-position: -240px -96px; } .ui-icon-home { background-position: 0 -112px; } .ui-icon-flag { background-position: -16px -112px; } .ui-icon-calendar { background-position: -32px -112px; } .ui-icon-cart { background-position: -48px -112px; } .ui-icon-pencil { background-position: -64px -112px; } .ui-icon-clock { background-position: -80px -112px; } .ui-icon-disk { background-position: -96px -112px; } .ui-icon-calculator { background-position: -112px -112px; } .ui-icon-zoomin { background-position: -128px -112px; } .ui-icon-zoomout { background-position: -144px -112px; } .ui-icon-search { background-position: -160px -112px; } .ui-icon-wrench { background-position: -176px -112px; } .ui-icon-gear { background-position: -192px -112px; } .ui-icon-heart { background-position: -208px -112px; } .ui-icon-star { background-position: -224px -112px; } .ui-icon-link { background-position: -240px -112px; } .ui-icon-cancel { background-position: 0 -128px; } .ui-icon-plus { background-position: -16px -128px; } .ui-icon-plusthick { background-position: -32px -128px; } .ui-icon-minus { background-position: -48px -128px; } .ui-icon-minusthick { background-position: -64px -128px; } .ui-icon-close { background-position: -80px -128px; } .ui-icon-closethick { background-position: -96px -128px; } .ui-icon-key { background-position: -112px -128px; } .ui-icon-lightbulb { background-position: -128px -128px; } .ui-icon-scissors { background-position: -144px -128px; } .ui-icon-clipboard { background-position: -160px -128px; } .ui-icon-copy { background-position: -176px -128px; } .ui-icon-contact { background-position: -192px -128px; } .ui-icon-image { background-position: -208px -128px; } .ui-icon-video { background-position: -224px -128px; } .ui-icon-script { background-position: -240px -128px; } .ui-icon-alert { background-position: 0 -144px; } .ui-icon-info { background: url(images/icon_sprite.png) 0 0 no-repeat !important; } .ui-icon-notice { background-position: -32px -144px; } .ui-icon-help { background-position: -48px -144px; } .ui-icon-check { background-position: -64px -144px; } .ui-icon-bullet { background-position: -80px -144px; } .ui-icon-radio-off { background-position: -96px -144px; } .ui-icon-radio-on { background-position: -112px -144px; } .ui-icon-pin-w { background-position: -128px -144px; } .ui-icon-pin-s { background-position: -144px -144px; } .ui-icon-play { background-position: 0 -160px; } .ui-icon-pause { background-position: -16px -160px; } .ui-icon-seek-next { background-position: -32px -160px; } .ui-icon-seek-prev { background-position: -48px -160px; } .ui-icon-seek-end { background-position: -64px -160px; } .ui-icon-seek-start { background-position: -80px -160px; } /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ .ui-icon-seek-first { background-position: -80px -160px; } .ui-icon-stop { background-position: -96px -160px; } .ui-icon-eject { background-position: -112px -160px; } .ui-icon-volume-off { background-position: -128px -160px; } .ui-icon-volume-on { background-position: -144px -160px; } .ui-icon-power { background-position: 0 -176px; } .ui-icon-signal-diag { background-position: -16px -176px; } .ui-icon-signal { background-position: -32px -176px; } .ui-icon-battery-0 { background-position: -48px -176px; } .ui-icon-battery-1 { background-position: -64px -176px; } .ui-icon-battery-2 { background-position: -80px -176px; } .ui-icon-battery-3 { background-position: -96px -176px; } .ui-icon-circle-plus { background-position: 0 -192px; } .ui-icon-circle-minus { background-position: -16px -192px; } .ui-icon-circle-close { background-position: -32px -192px; } .ui-icon-circle-triangle-e { background-position: -48px -192px; } .ui-icon-circle-triangle-s { background-position: -64px -192px; } .ui-icon-circle-triangle-w { background-position: -80px -192px; } .ui-icon-circle-triangle-n { background-position: -96px -192px; } .ui-icon-circle-arrow-e { background-position: -112px -192px; } .ui-icon-circle-arrow-s { background-position: -128px -192px; } .ui-icon-circle-arrow-w { background-position: -144px -192px; } .ui-icon-circle-arrow-n { background-position: -160px -192px; } .ui-icon-circle-zoomin { background-position: -176px -192px; } .ui-icon-circle-zoomout { background-position: -192px -192px; } .ui-icon-circle-check { background-position: -208px -192px; } .ui-icon-circlesmall-plus { background-position: 0 -208px; } .ui-icon-circlesmall-minus { background-position: -16px -208px; } .ui-icon-circlesmall-close { background-position: -32px -208px; } .ui-icon-squaresmall-plus { background-position: -48px -208px; } .ui-icon-squaresmall-minus { background-position: -64px -208px; } .ui-icon-squaresmall-close { background-position: -80px -208px; } .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } .ui-icon-grip-solid-vertical { background-position: -32px -224px; } .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } .ui-icon-grip-diagonal-se { background-position: -80px -224px; } /* Misc visuals ----------------------------------*/ /* Corner radius */ .ui-corner-tl { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; } .ui-corner-tr { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; } .ui-corner-bl { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; } .ui-corner-br { -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; } .ui-corner-top { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; } .ui-corner-bottom { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; } .ui-corner-right { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; } .ui-corner-left { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; } .ui-corner-all { -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } /* Overlays */ .ui-widget-overlay { background: #262b33; opacity: .70;filter:Alpha(Opacity=70); } .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* * jQuery UI Resizable 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Resizable#theming */ .ui-resizable { position: relative;} .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* * jQuery UI Selectable 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Selectable#theming */ .ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } /* * jQuery UI Accordion 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Accordion#theming */ /* IE/Win - Fix animation bug - #4615 */ .ui-accordion { width: 100%; } .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } .ui-accordion .ui-accordion-header, .ui-accordion .ui-accordion-content { -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; } .ui-accordion .ui-accordion-li-fix { display: inline; } .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } .ui-accordion .ui-accordion-header a { display: block; font-size: 12px; font-weight: bold; padding: .5em .5em .5em .7em; } .ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } .ui-accordion .ui-accordion-content-active { display: block; }/* * jQuery UI Autocomplete 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Autocomplete#theming */ .ui-autocomplete { position: absolute; cursor: default; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; -moz-box-shadow: 0 1px 5px rgba(0,0,0,0.3); -webkit-box-shadow: 0 1px 5px rgba(0,0,0,0.3); } /* workarounds */ * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ /* * jQuery UI Menu 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Menu#theming */ .ui-menu { list-style:none; padding: 2px; margin: 0; display:block; float: left; } .ui-menu .ui-menu { margin-top: -3px; } .ui-menu .ui-menu-item { margin:0; padding: 0; zoom: 1; float: left; clear: left; width: 100%; } .ui-menu .ui-menu-item a { text-decoration:none; display:block; padding:.2em .4em; line-height:1.5; zoom:1; } .ui-menu .ui-menu-item a.ui-state-hover, .ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; background: #5f83b9; color: #FFFFFF; text-shadow: 0px 1px 1px #234386; border-color: #466086; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; } /* * jQuery UI Button 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Button#theming */ .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ .ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ .ui-button-icons-only { width: 3.4em; } button.ui-button-icons-only { width: 3.7em; } /*states*/ .ui-button.ui-state-hover { -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset; -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset; } .ui-button.ui-state-focus { outline: none; color: #1c4257; border-color: #7096ab; background-image: -webkit-gradient( linear, left bottom, left top, color-stop(1, rgb(185,224,245)), color-stop(0, rgb(146,189,214)) ); background-image: -moz-linear-gradient( center top, rgb(185,224,245), rgb(146,189,214) ); -webkit-box-shadow: none; -moz-box-shadow: none; } /*button text element */ .ui-button .ui-button-text { display: block; line-height: 1.4; font-size: 14px; font-weight: bold; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); } .ui-button-text-only .ui-button-text { padding: .4em 1em; } .ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } .ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } .ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } .ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } /* no icon support for input elements, provide padding by default */ input.ui-button { padding: .4em 1em; } /*button icon element(s) */ .ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } .ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } .ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } .ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } /*button sets*/ .ui-buttonset { margin-right: 7px; } .ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } .ui-buttonset .ui-button.ui-state-active { color: #1c4257; border-color: #7096ab; } .ui-buttonset .ui-button.ui-state-active { background-image: -webkit-gradient( linear, left bottom, left top, color-stop(1, rgb(185,224,245)), color-stop(0, rgb(146,189,214)) ); background-image: -moz-linear-gradient( center top, rgb(185,224,245), rgb(146,189,214) ); -webkit-box-shadow: none; -moz-box-shadow: none; } /* workarounds */ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ /* * jQuery UI Dialog 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Dialog#theming */ .ui-dialog { position: absolute; padding: 0; width: 300px; overflow: hidden; } .ui-dialog { -webkit-box-shadow: 0 2px 12px rgba(0,0,0,0.6); -moz-box-shadow: 0 2px 12px rgba(0,0,0,0.6); } .ui-dialog .ui-dialog-titlebar { padding: 0.7em 1em 0.6em 1em; position: relative; border: none; border-bottom: 1px solid #979797; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; } .ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; font-size: 14px; text-shadow: 0 1px 0 rgba(255,255,255,0.5); } .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .8em; top: 55%; width: 16px; margin: -10px 0 0 0; padding: 0; height: 16px; } .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; background: url(images/icon_sprite.png) 0 -16px no-repeat; } .ui-dialog .ui-dialog-titlebar-close:hover span { background-position: -16px -16px; } .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; border: 0; } .ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } .ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } .ui-draggable .ui-dialog-titlebar { cursor: move; } /* * jQuery UI Slider 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Slider#theming */ .ui-slider { position: relative; text-align: left; background: #d7d7d7; } .ui-slider { -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; } .ui-slider .ui-slider-handle { background: url(images/slider_handles.png) 0px -23px no-repeat; position: absolute; z-index: 2; width: 23px; height: 23px; cursor: default; border: none; outline: none; -moz-box-shadow: none; -webkit-box-shadow: none; } .ui-slider .ui-state-hover, .ui-slider .ui-state-active { background-position: 0 0; } .ui-slider .ui-slider-range { background: #a3cae0; position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } .ui-slider .ui-slider-range { -moz-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; -webkit-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; } .ui-slider-horizontal { height: 5px; } .ui-slider-horizontal .ui-slider-handle { top: -8px; margin-left: -13px; } .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } .ui-slider-horizontal .ui-slider-range-min { left: 0; } .ui-slider-horizontal .ui-slider-range-max { right: 0; } .ui-slider-vertical { width: 5px; height: 100px; } .ui-slider-vertical .ui-slider-handle { left: -8px; margin-left: 0; margin-bottom: -13px; } .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } .ui-slider-vertical .ui-slider-range-min { bottom: 0; } .ui-slider-vertical .ui-slider-range-max { top: 0; }/* * jQuery UI Tabs 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Tabs#theming */ .ui-tabs { position: relative; zoom: 1; border: 0; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ .ui-tabs .ui-tabs-nav { margin: 0; padding: 0; background: transparent; border-width: 0 0 1px 0; } .ui-tabs .ui-tabs-nav { -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; } .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } .ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; font-size: 12px; font-weight: bold; text-shadow: 0 1px 0 rgba(255,255,255,0.5); } .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; background: #fff; border-color: #B6B6B6; } .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; outline: none; } .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ .ui-tabs .ui-tabs-panel { display: block; border-width: 0 1px 1px 1px; padding: 1em 1.4em; background: none; } .ui-tabs .ui-tabs-panel { -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; } .ui-tabs .ui-tabs-hide { display: none !important; } /* * jQuery UI Datepicker 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Datepicker#theming */ .ui-datepicker { width: 17em; padding: 0; display: none; border-color: #DDDDDD; } .ui-datepicker { -moz-box-shadow: 0 4px 8px rgba(0,0,0,0.5); -webkit-box-shadow: 0 4px 8px rgba(0,0,0,0.5); box-shadow: 0 4px 8px rgba(0,0,0,0.5); } .ui-datepicker .ui-datepicker-header { position:relative; padding:.35em 0; border: none; border-bottom: 1px solid #B6B6B6; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; } .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 6px; width: 1.8em; height: 1.8em; } .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { border: 1px none; } .ui-datepicker .ui-datepicker-prev { left:2px; } .ui-datepicker .ui-datepicker-next { right:2px; } .ui-datepicker .ui-datepicker-prev span { background-position: 0px -32px !important; } .ui-datepicker .ui-datepicker-next span { background-position: -16px -32px !important; } .ui-datepicker .ui-datepicker-prev-hover span { background-position: 0px -48px !important; } .ui-datepicker .ui-datepicker-next-hover span { background-position: -16px -48px !important; } .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; background: url(images/icon_sprite.png) no-repeat; } .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; font-size: 12px; text-shadow: 0 1px 0 rgba(255,255,255,0.6); } .ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } .ui-datepicker select.ui-datepicker-month-year {width: 100%;} .ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year { width: 49%;} .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } .ui-datepicker td { border: 0; padding: 1px; } .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } .ui-datepicker .ui-state-default { background: transparent; border-color: #FFF; } .ui-datepicker .ui-state-active { background: #5F83B9; border-color: #5F83B9; color: #FFF; font-weight: bold; text-shadow: 0 1px 1px #234386; } /* with multiple calendars */ .ui-datepicker.ui-datepicker-multi { width:auto; } .ui-datepicker-multi .ui-datepicker-group { float:left; } .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } .ui-datepicker-row-break { clear:both; width:100%; } /* RTL support */ .ui-datepicker-rtl { direction: rtl; } .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } .ui-datepicker-rtl .ui-datepicker-group { float:right; } .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ .ui-datepicker-cover { display: none; /*sorry for IE5*/ display/**/: block; /*sorry for IE5*/ position: absolute; /*must have*/ z-index: -1; /*must have*/ filter: mask(); /*must have*/ top: -4px; /*must have*/ left: -4px; /*must have*/ width: 200px; /*must have*/ height: 200px; /*must have*/ }/* * jQuery UI Progressbar 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Progressbar#theming */ .ui-progressbar { height: 12px; text-align: left; background: url(images/progress_bar.gif) 0 -14px repeat-x; } .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; background: url(images/progress_bar.gif) 0 0 repeat-x; } ================================================ FILE: public/css/style.css ================================================ /*--- Reset ---*/ * { margin: 0; padding: 0; } html, body { height: 100%; min-height: 100%; background-color: #000000; } /*--- Layout ---*/ body { font-family: Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.5em; color: #0d0d0d; background-color: #fff; } #container { position: relative; padding: 10px 10%; } /*--- Basics ---*/ h1, h2, h3, h4, h5, h6 { font-weight:normal; color:#111; line-height: 1; margin: 1.5em 0 0.5em 0; } h1 { font-size: 1.6em; } h2, h5 { font-size: 1.3em; color: #666; } h3, h6 { font-size: 1.2em; color: #00a8e6; } h4 { font-size: 1.1em; } h5 { font-size: 1.1em; } h6 { font-size: 1em; } p { margin-bottom: 1em; } strong { font-weight: bold; } em { font-style: italic; } a { text-decoration: none; color: #333; } a, h1 a, h2 a { text-decoration: none; } a:hover { color: #232323; } a:visited:hover { color: #232323; } a img { border: none; } /*--- Lists ---*/ li ul, li ol { margin: 0; } ul, ol { margin: 0 0 1em 2.75em; } dt, dd { font-style: italic; margin: .5em 0; } dt { font-weight: bold; } dd { margin-left: 1em; } /*--- Header ---*/ #header h1 { margin: .1em 0; font-size: 2.2em; } #header h2 { width: 70%; margin: .5em .5em 2em 0; color: #666; font-size: 1.3em; line-height: 22px; } /*--- Tables ---*/ table { clear: both; width: 100%; border-collapse: collapse; border-spacing: 0; border: 1px solid #e6e6e6; background: #eaeafa; margin: 12px 0; } td, th { padding: .25em 1em; border: 1px solid #a6a6c6; vertical-align: middle; text-align: left; font-weight: normal; color: #333; font-size: 0.85em; } table tr { background: #fff; } table.tabular tr:nth-child(even) { background: #eaeafa; } tfoot td { background: #d3d3f3; color: #333; text-align: left; padding: 1em 0.5em; font-size: 0.7em; } th { background: #d3d3f3; color: #333; text-align: left; font-weight: bold; padding: .5em .75em; } /*--- Forms ---*/ form { display: block; clear: both; background: #eaeafa; padding: 1em 2em 2em 2em; border: 1px solid #a6a6c6; } fieldset { padding: 2em; margin: 0 0 1em 0; border: 1px solid #a6a6c6; background: #f3f3f3; } legend { padding: .5em 1em; border: 1px solid #a6a6c6; background: #fff; font-size: 22px; } label { padding: 0 1em 0 0; color: #454545; font-weight: normal; } input[type=text],[type=password], textarea { font-family: Helvetica, Arial, sans-serif; padding: 2px 4px; border: 1px solid #a6a6c6; color: #454545; font-size: 1em; line-height: 1.25em; } input[type=text], input[type=password], textarea { clear: both; display: block; padding: .25em .5em; } input[type=text], input[type=password], textarea { width: 97%; max-width: 950px; margin: .5em 0 1em 0; padding:.5em; } select { clear: both; display: block; margin: .5em 0 1em 0; } div.checkbox { clear: both; padding: 1em 0; } .checkbox label { display: inline; } input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus { border-color: #00a8e6; outline: none; } /*--- Misc ---*/ hr { border: none; height: 0; border-bottom: 1px solid #e6e6e6; margin:1em 0; } sup, sub { color: #666; font-size: .65em; } acronym { font-weight: bold; font-style: italic; color: #333; } abbr { color: #333; } blockquote { padding: 0.15em .5em; margin: 0.5em 0; font-size: 2em; color: #666; display: block; font-style: italic; } blockquote:before, blockquote:after { display: inline; color: #e5e5e5; font-size: 3em; position: relative; top: 0.25em; left: -0.1em; } blockquote:before { content: '\D \201C'; } span.pager-page { font-family: Helvetica, Arial, sans-serif; padding: 3px 3px; margin: 3px 3px 3px 3px; color: #454545; line-height: 1.25em; } input.pager-page { display: inline !important; width: 30px; font-family: Helvetica, Arial, sans-serif; padding: 2px 2px; margin: 3px 3px 3px 3px; color: #454545; line-height: 1.25em; clear: none; } a.pager-page { font-family: Helvetica, Arial, sans-serif; padding: 3px 3px; margin: 3px 3px 3px 3px; border: 1px solid #a6a6c6; color: #454545; line-height: 1.25em; background-color: #efefef; } blockquote:after { content: '\201D'; } pre.code { padding: 10px; color: white; background-color: #883434; margin-top: 10px; } /*--- Shadows ---*/ pre.code { -moz-box-shadow: 0 0 3px rgba(0,0,0,.1); -webkit-box-shadow: 0 0 3px rgba(0,0,0,.1); box-shadow: 0 0 3px rgba(0,0,0,.1); } table, form { margin-top: 0px; margin-bottom: 12px; } table, form, pre > code, .shadow { -moz-box-shadow: 2px 2px 12px rgba(0,0,0,.15); -webkit-box-shadow: 2px 2px 12px rgba(0,0,0,0.15); box-shadow: 2px 2px 12px rgba(0,0,0,.15); } img.shadow { border: 1px solid rgba(255,255,255,.15); } input[type=text],input[type=password], textarea { -moz-box-shadow: inset 0 0 5px rgba(0,0,0,.2); -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,.2); box-shadow: inset 0 0 5px rgba(0,0,0,.2); } ================================================ FILE: scripts/create-controller.js ================================================ var ejs = require('ejs') , fs = require('fs') , path = require('path') , inflection = require('../lib/inflection'); /** * Script to create a default controller, requires the model to exist */ exports.execute = function(params,appPath) { if(params.length == 0 ) { console.log("You must specifiy a model name to generate the controller against!"); return; } /** * Create the model based on a singular (e.g. people becomes person, users becomes user) */ var modelName = params[0].singularize(); if(modelName != params[0]) { console.log("Using model name as singular not plural: " + modelName); } // Capitalise modelName = modelName.capitalize(); var modelFile = appPath + "/models/" + modelName + '.js' var controllerName = modelName.pluralize(); var controllerFile = appPath + "/controllers/" + controllerName + 'Controller.js' var controllerTemplate = __dirname + '/templates/create-controller.template.ejs'; // Check if the model exists var fileCheck = path.existsSync(modelFile); if(!fileCheck) { console.log("The model you have specified doesn't exist!"); console.log("You need to create the model first."); console.log("e.g. script create-model " + modelName); return; } // Check if the controller exists var fileCheck = path.existsSync(controllerFile); if(fileCheck) { if(params[1] != "force") { console.log("The controller already exists!"); console.log("Add an additional paramater of 'force' to over write the controller."); console.log("e.g. script create-controller " + modelName + " force"); return; } } // Read the template var str = fs.readFileSync(controllerTemplate, 'utf8'); // Render the model var ret = ejs.render(str, { locals: { controllerName:controllerName, modelName:modelName },open: "" }); // Write the file fs.writeFileSync(controllerFile, ret,'utf8'); console.log('Controller for model ' + modelName + ' created in controllers/' + controllerName + 'Controller.js'); }; ================================================ FILE: scripts/create-model.js ================================================ var ejs = require('ejs') , fs = require('fs') , path = require('path'), inflection = require('../lib/inflection'); /** * Script to create a default model */ exports.execute = function(params,appPath) { if(params.length == 0 ) { console.log("You must specifiy a model name."); return; } /** * Create the model based on a singular (e.g. people becomes person, users becomes user) */ var modelName = params[0].singularize(); if(modelName != params[0]) { console.log("Creating model using singular not plural: " + modelName); } // Capitalise modelName = modelName.capitalize(); // Define the files var modelFile = appPath + "/models/" + modelName + '.js' var modelTemplate = __dirname + '/templates/create-model.template.ejs'; // Check if it already exists var fileCheck = path.existsSync(modelFile); if(fileCheck) { if(params[1] != "force") { console.log("The model already exists!"); console.log("Add an additional paramater of 'force' to over write the model."); console.log("e.g. script create-model " + modelName + " force"); return; } } // Read the template var str = fs.readFileSync(modelTemplate, 'utf8'); // Render the model var ret = ejs.render(str, { locals: { name:modelName },open: "" }); // Write the file fs.writeFileSync(modelFile, ret,'utf8'); console.log('Model ' + modelName + ' created in models/' + modelName + '.js'); }; ================================================ FILE: scripts/create-test.js ================================================ var ejs = require('ejs') , fs = require('fs') , path = require('path') , inflection = require('../lib/inflection'); /** * Script to create a default test scripts, requires the model to exist */ exports.execute = function(params,appPath) { if(params.length == 0 ) { console.log("You must specifiy a model name to generate the tests against!"); return; } /** * Create the model based on a singular (e.g. people becomes person, users becomes user) */ var modelName = params[0].singularize(); if(modelName != params[0]) { console.log("Using model name as singular not plural: " + modelName); } // Capitalise modelName = modelName.capitalize(); var modelFile = appPath + "/models/" + modelName + '.js' var controllerName = modelName.pluralize(); var testFolder = appPath + "/tests/"; var unitTemplate = __dirname + '/templates/create-test.template.unit.ejs'; var integrationTemplate = __dirname + '/templates/create-test.template.integration.ejs'; var functionalTemplate = __dirname + '/templates/create-test.template.functional.ejs'; // Check if the model exists var fileCheck = path.existsSync(modelFile); if(!fileCheck) { console.log("The model you have specified doesn't exist!"); console.log("You need to create the model first."); console.log("e.g. script create-model " + modelName); return; } // Check if the unit test exists var fileCheck = path.existsSync(testFolder + "/unit/" + modelName + '.js'); if(fileCheck) { if(params[1] != "force") { console.log("Tests appear to already exist for this model!"); console.log("Add an additional paramater of 'force' to over write the tests."); console.log("e.g. script create-test " + modelName + " force"); return; } } // Read the template var tmpUnit = fs.readFileSync(unitTemplate, 'utf8'); var tmpIntegration = fs.readFileSync(integrationTemplate, 'utf8'); var tmpFunctional = fs.readFileSync(functionalTemplate, 'utf8'); // Render the views var retUnit = ejs.render(tmpUnit, { locals: { modelName:modelName, controllerName:controllerName },open: "" }); var retIntegration = ejs.render(tmpIntegration, { locals: { modelName:modelName, controllerName:controllerName },open: "" }); var retFunctional = ejs.render(tmpFunctional, { locals: { modelName:modelName, controllerName:controllerName },open: "" }); // Write the file fs.writeFileSync(testFolder + "/unit/" + modelName + '.js', retUnit,'utf8'); fs.writeFileSync(testFolder + "/integration/" + controllerName + 'Controller.js', retIntegration,'utf8'); fs.writeFileSync(testFolder + "/functional/" + modelName + '.js', retFunctional,'utf8'); console.log('Tests for ' + modelName + ' created in tests.'); }; ================================================ FILE: scripts/create-view.js ================================================ var ejs = require('ejs') , fs = require('fs') , path = require('path') , inflection = require('../lib/inflection'); /** * Script to create a default view, requires the model to exist */ exports.execute = function(params,appPath) { if(params.length == 0 ) { console.log("You must specifiy a model name to generate the views against!"); return; } /** * Create the model based on a singular (e.g. people becomes person, users becomes user) */ var modelName = params[0].singularize(); if(modelName != params[0]) { console.log("Using model name as singular not plural: " + modelName); } // Capitalise modelName = modelName.capitalize(); var modelFile = appPath + "/models/" + modelName + '.js' var controllerName = modelName.pluralize(); var viewFolder = appPath + "/views/" + controllerName.toLowerCase(); var viewIndexTemplate = __dirname + '/templates/create-view.template.index.ejs'; var viewEditTemplate = __dirname + '/templates/create-view.template.edit.ejs'; var viewShowTemplate = __dirname + '/templates/create-view.template.show.ejs'; // Check if the model exists var fileCheck = path.existsSync(modelFile); if(!fileCheck) { console.log("The model you have specified doesn't exist!"); console.log("You need to create the model first."); console.log("e.g. script create-model " + modelName); return; } // Check if the view exists var fileCheck = path.existsSync(viewFolder); if(fileCheck) { if(params[1] != "force") { console.log("The views folder already exists for this model!"); console.log("Add an additional paramater of 'force' to over write the views."); console.log("e.g. script create-view " + modelName + " force"); return; } } else { fs.mkdirSync(viewFolder,'755'); } // Read the template var tmpIndex = fs.readFileSync(viewIndexTemplate, 'utf8'); var tmpEdit = fs.readFileSync(viewEditTemplate, 'utf8'); var tmpShow = fs.readFileSync(viewShowTemplate, 'utf8'); // Render the views var retIndex = ejs.render(tmpIndex, { locals: { modelName:modelName, controllerName:controllerName },open: "" }); var retEdit = ejs.render(tmpEdit, { locals: { modelName:modelName, controllerName:controllerName },open: "" }); var retShow = ejs.render(tmpShow, { locals: { modelName:modelName, controllerName:controllerName },open: "" }); // Write the file fs.writeFileSync(viewFolder + "/index.html", retIndex,'utf8'); fs.writeFileSync(viewFolder + "/edit.html", retEdit,'utf8'); fs.writeFileSync(viewFolder + "/show.html", retShow,'utf8'); console.log('Views ' + modelName + ' created in views/' + modelName.toLowerCase()); }; ================================================ FILE: scripts/generate-all.js ================================================ /** * Script to create a model, controller and views */ exports.execute = function(params,appPath) { if(params.length == 0 ) { console.log("You must specifiy a model name to generate all of the assets for!"); return; } var modelScript = require('./create-model'); var controllerScript = require('./create-controller'); var viewScript = require('./create-view'); var testScript = require('./create-test'); modelScript.execute(params,appPath); controllerScript.execute(params,appPath); viewScript.execute(params,appPath); testScript.execute(params,appPath); }; ================================================ FILE: scripts/help.js ================================================ var ejs = require('ejs') , fs = require('fs'); /** * Help file */ exports.execute = function(params,appPath) { if(params.length == 0) { var str = fs.readFileSync(__dirname + '/templates/help.ejs', 'utf8'); } else { var str = fs.readFileSync(__dirname + '/templates/' + params[0] + '.help.ejs', 'utf8'); } var scripts = []; fs.readdir(__dirname + '/', function(err, files){ if(err) { console.log(err); } files.forEach(function(file){ if(file.replace('.js','') != file) { scripts.push(file.replace('.js','')); } }); var ret = ejs.render(str, { locals: { params: params, scripts: scripts },open: "" }); console.log(ret); }); }; ================================================ FILE: scripts/templates/create-controller.help.ejs ================================================ Express MVC Bootstrapper - Version 0.10 This is the help file for 'create-controller' command. Command format: node app.js script create-controller [MODELNAME] [MODELNAME] The name (case sensitive) for the model you want to create a controller for. ================================================ FILE: scripts/templates/create-controller.template.ejs ================================================ /** * Controller * Created by create-controller script @ **/ var mongoose = require('mongoose'), = mongoose.model(''), pager = require('../utils/pager.js'), ViewTemplatePath = ''; module.exports = { /** * Index action, returns a list either via the views//index.html view or via json * Default mapping to GET '/' * For JSON use '/.json' **/ index: function(req, res, next) { var from = req.params.from ? parseInt(req.params.from) - 1 : 0; var to = req.params.to ? parseInt(req.params.to) : 10; var total = 0; .count({}, function (err, count) { total = count; var pagerHtml = pager.render(from,to,total,'/'); .find({}) .sort('name', 1) .skip(from).limit(to) .find(function (err, ) { if(err) return next(err); switch (req.params.format) { case 'json': res.send(.map(function(u) { return u.toObject(); })); break; default: res.render(ViewTemplatePath,{:,pagerHtml:pagerHtml}); } }); }); }, /** * Show action, returns shows a single item via views//show.html view or via json * Default mapping to GET '//:id' * For JSON use '//:id.json' **/ show: function(req, res, next) { .findById(req.params.id, function(err, ) { if(err) return next(err); switch (req.params.format) { case 'json': res.send(.toObject()); break; default: res.render(ViewTemplatePath + "/show",{:}); } }); }, /** * Edit action, returns a form via views//edit.html view no JSON view. * Default mapping to GET '//:id/edit' **/ edit: function(req, res, next){ .findById(req.params.id, function(err, ) { if(err) return next(err); res.render(ViewTemplatePath + "/edit",{:}); }); }, /** * Update action, updates a single item and redirects to Show or returns the object as json * Default mapping to PUT '//:id', no GET mapping **/ update: function(req, res, next){ .findById(req.params.id, function(err, ) { if (!) return next(err); .name = req.body..name; .save(function(err) { if (err) { console.log(err); req.flash('error','Could not update : ' + err); res.redirect('/'); return; } switch (req.params.format) { case 'json': res.send(.toObject()); break; default: req.flash('info', ' updated'); res.redirect('//' + req.params.id); } }); }); }, /** * Create action, creates a single item and redirects to Show or returns the object as json * Default mapping to POST '/', no GET mapping **/ create: function(req, res, next){ var = new (req.body.); .save(function(err) { if (err) { req.flash('error','Could not create : ' + err); res.redirect('/'); return; } switch (req.params.format) { case 'json': res.send(.toObject()); break; default: req.flash('info',' created'); res.redirect('//' + .id); } }); }, /** * Delete action, deletes a single item and redirects to index * Default mapping to DEL '//:id', no GET mapping **/ destroy: function(req, res, next){ .findById(req.params.id, function(err, ) { if (!) { req.flash('error','Unable to locate the to delete!'); res.send('false'); return false; }; .remove(function(err) { if(err) { req.flash('error','There was an error deleting the !'); res.send('false'); } else { req.flash('info',' deleted'); res.send('true'); } }); }); } }; ================================================ FILE: scripts/templates/create-model.help.ejs ================================================ Express MVC Bootstrapper - Version 0.10 This is the help file for 'create-model' command. Command format: node app.js script create-model [MODELNAME] [MODELNAME] The name (case sensitive) for the model you want to create. ================================================ FILE: scripts/templates/create-model.template.ejs ================================================ /** * schema * Created by create-model script **/ var mongoose = require('mongoose'), Schema = mongoose.Schema, ObjectId = Schema.ObjectId; var = new Schema({ // Single default property name:{type: String, required: true} }); mongoose.model('', ); ================================================ FILE: scripts/templates/create-test.help.ejs ================================================ Express MVC Bootstrapper This is the help file for 'create-test' command. Command format: node app.js script create-test [MODELNAME] [MODELNAME] The name (case sensitive) for the model you want to create tests for. ================================================ FILE: scripts/templates/create-test.template.functional.ejs ================================================ /** * Functional Test * Created by create-test script @ **/ /** * Dependencies */ var should = require('should'); /** * Simple expresso tests for the model */ module.exports = { 'Placeholder for a real functional test': function(){ true.should.be.true; } }; ================================================ FILE: scripts/templates/create-test.template.integration.ejs ================================================ /** * Integration Test * Created by create-test script @ **/ /** * Dependencies */ var assert = require('assert'), inflection = require('lib/inflection'), mongoose = require('mongoose'), should = require('should'); /** * Variables to drive testing */ var model = ''; var app = require('app').boot(); var id; /** * Simple expresso tests for the AppController */ module.exports = { 'Shows an index page that contains the container name in the response with a 200 status code': function(done){ var controller = model.pluralize().toLowerCase(); assert.response(app, { url: '/' + controller , method: 'GET' }, function(res) { res.statusCode.should.equal(200); res.body.should.include.string(controller); done(); }); }, 'Adding a new object returns a 302 redirect where the new location contains the id of the newly created object': function(done){ var controller = model.pluralize().toLowerCase(); var data = model + '[name]=OriginalName'; assert.response(app, { url: '/' + controller, method: 'POST', headers: {'host':'dummyhost','Content-Length': data.length,'Content-Type':'application/x-www-form-urlencoded'}, data: data }, function(res) { res.statusCode.should.equal(302); id = res.headers['location'].split("/")[res.headers['location'].split("/").length-1]; done(); }); }, 'Viewing an existing object returns a page that contains the object ID and a 200 status code': function(done){ assert.response(app, { url: '/' + model + '/' + id, method: 'GET' }, function(res) { res.statusCode.should.equal(200); res.body.should.include.string(id); done(); }); }, 'Viewing a page limited view of the index with .json format returns a JSON list containing the object ID and 200 status code': function(done){ var controller = model.pluralize().toLowerCase(); assert.response(app, { url: '/' + controller + '/1-100.json', // Test database should be empty for this test method: 'GET' }, function(res) { res.statusCode.should.equal(200); res.body.should.include.string(id); res.headers['content-type'].should.equal('application/json'); done(); }); }, 'View existing object with .json format returns a JSON object containing its ID and a 200 status code ': function(done){ assert.response(app, { url: '/' + model + '/' + id + '.json', method: 'GET' }, function(res) { // Find the ID text on the page res.statusCode.should.equal(200); res.body.should.include.string(id); res.headers['content-type'].should.equal('application/json'); done(); }); }, 'Updating an object redirects to 302 where the new location contains the ID': function(done){ var data = model + '[name]=ModifiedName'; assert.response(app, { url: '/' + model + '/' + id, method: 'PUT', headers: {'host':'dummyhost','Content-Length': data.length,'Content-Type':'application/x-www-form-urlencoded'}, data: data }, function(res) { res.statusCode.should.equal(302); res.headers['location'].should.include.string(id); res.headers['location'].should.equal('http://dummyhost/' + model + '/' + id); done(); }); }, 'Viewing the updated object shows the modified data and a 200 status code': function(done){ assert.response(app, { url: '/' + model + '/' + id, method: 'GET' }, function(res) { res.statusCode.should.equal(200); res.body.should.include.string(id); res.body.should.include.string('ModifiedName'); done(); }); }, 'Deleting the object returns a 200 status code': function(done){ assert.response(app, { url: '/' + model + '/' + id, method: 'DELETE' }, function(res) { res.statusCode.should.equal(200); done(); }); }, 'Viewing a deleted object returns the default error page': function(done){ // Should this really be a 404??? assert.response(app, { url: '/' + model + '/' + id, method: 'GET' }, function(res) { res.statusCode.should.equal(200); res.body.should.include.string('Sorry an error has occurred'); done(); }); }, tearDown: function(done){ mongoose.disconnect(); done(); } }; ================================================ FILE: scripts/templates/create-test.template.unit.ejs ================================================ /** * Unit Test * Created by create-test script @ **/ /** * Dependencies */ var should = require('should') , mongoose = require('mongoose') , example = require('models/') , Schema = mongoose.Schema , SchemaType = mongoose.SchemaType , ValidatorError = SchemaType.ValidatorError , DocumentObjectId = mongoose.Types.ObjectId , MongooseError = mongoose.Error; /** * Simple expresso tests for the model */ module.exports = { 'Test that a model can be created': function(){ var = mongoose.model(''); var model = new (); model.isNew.should.be.true; }, 'Test that the model is an instance of a mongoose schema': function(){ var = mongoose.model(''); .schema.should.be.an.instanceof(Schema); .prototype.schema.should.be.an.instanceof(Schema); }, 'Test that an has all of the default fields and values': function(){ var = mongoose.model(''); var model = new (); model.isNew.should.be.true; model.get('_id').should.be.an.instanceof(DocumentObjectId); should.equal(undefined, model.get('name')); }, 'Test that saving a record with invalid fields returns a validation error': function(){ var = mongoose.model(''); var model = new (); model.set('name', ''); model.save(function(err){ err.should.be.an.instanceof(MongooseError); err.should.be.an.instanceof(ValidatorError); model.set('name', 'I exist!'); model.save(function(err){ should.strictEqual(err, null); }); }); } }; ================================================ FILE: scripts/templates/create-view.help.ejs ================================================ Express MVC Bootstrapper - Version 0.10 This is the help file for 'create-view' command. Command format: node app.js script create-view [MODELNAME] [MODELNAME] The name (case sensitive) for the model you want to create views for. ================================================ FILE: scripts/templates/create-view.template.edit.ejs ================================================

Editing <%= .name %>

<%- partial('../messages') %>

Name:

Cancel

================================================ FILE: scripts/templates/create-view.template.index.ejs ================================================

<%- partial('../messages') %>
<% .forEach(function(){ %> <% }) %>
Name
<%= .name %>
<%- pagerHtml %>

Name:

================================================ FILE: scripts/templates/create-view.template.show.ejs ================================================

Viewing

<%- partial('../messages') %>
ID<%= .id %>
Name<%= .name %>
Edit List ================================================ FILE: scripts/templates/help.ejs ================================================ Express MVC Bootstrapper This is the help file for the Express based application bootstrapper. Parameters marked with * are optional, and are shown with their defaults. Command format: eb : Run the application using the cluster module. eb cluster *server.port=3000 : Run the application using the cluster module. eb server *server.port=3000 : Run the application as a server. eb test : Run all tests. eb test unit|integration|functional : Run a particular type of test. eb script help * : This help script, optional script name for additional help. eb script *params : Run a script with , with params. eb script *params : Run a script with , with params. Available scripts: ================================================ FILE: tests/functional/README ================================================ ================================================ FILE: tests/functional/SampleTests.js ================================================ /** * Dependencies */ var should = require('should'); /** * Simple expresso tests for the Example model */ module.exports = { 'Placeholder for a real functional test': function(){ true.should.be.true; } }; ================================================ FILE: tests/integration/AppControllerTests.js ================================================ var assert = require('assert'), should = require('should'), mongoose = require('mongoose'); var app = require('app').boot(); /** * Simple expresso tests for the AppController */ module.exports = { 'Default route shows the home page with a 200 status code': function(done){ assert.response(app, { url: '/', method: 'GET' }, function(res) { res.statusCode.should.equal(200); res.body.should.include.string('Welcome!'); done(); }); }, 'An invalid route shows the 404 Error page': function(done){ assert.response(app, { url: '/this/is/an/invalid/route', }, function(res){ res.statusCode.should.equal(200); res.body.should.include.string('Cannot find /this/is/an/invalid/route'); done(); }); }, tearDown: function(done){ mongoose.disconnect(); done(); } }; ================================================ FILE: tests/unit/README ================================================ ================================================ FILE: tests/unit/SampleTests.js ================================================ /** * Dependencies */ var should = require('should'); /** * Simple expresso tests */ module.exports = { 'Placeholder for a real unit test': function(){ true.should.be.true; } }; ================================================ FILE: utils/pager.js ================================================ /** * Simple pager - couldn't find one for Express that worked for me. */ exports.version = '0.0.1'; exports.render = function(skip,limit,total,path){ var totalPages = Math.ceil(total/limit) + 1; var currentPage = skip/limit + 1; var result = "", start, finish; var selectedClass = 'page-selected'; var visiblePages = 5; // Remember how many we have var totalPageLinks = 0; result += pageSpan(currentPage); var additionalForward = currentPage < visiblePages ? visiblePages - currentPage : 0; for(i=currentPage + 1; (i < currentPage + visiblePages + additionalForward) && (i < totalPages); i++) { start = (i-1)*limit + 1; result += pageLink(path,start,limit,i); } if(currentPage < totalPages - 1) { result +=pageLink(path,skip + limit + 1,limit,">"); var lastPageStart = (totalPages-2)*limit + 1; result +=pageLink(path,lastPageStart,limit,">>"); } var additionalBackward = (totalPages - currentPage) < visiblePages ? visiblePages - (totalPages - currentPage) : 0; for(i=currentPage - 1; (i > currentPage - visiblePages - additionalBackward) && (i > 0); i--) { start = (i-1)*limit + 1; result = pageLink(path,start,limit,i) + result; } if(currentPage > 1) { result = pageLink(path,(skip - limit + 1),limit,"<") + result; result = pageLink(path,1,limit,"<<") + result; } result += " Go To: "; result += "" + (skip + 1) + " to " + (skip + limit) + " of " + (total) + ""; return result } function pageLink(path,skip,limit,page) { return "" + page + ""; } function pageSpan(page) { return "" + page + ""; } ================================================ FILE: utils/socketio.js ================================================ /** * NOT YET USED **/ var io = require('socket.io'); exports.version = '0.0.1'; exports.initialise = function(app){ // socket.io var socket = io.listen(app); socket.on('connection', function(client){ // new client is here! console.log("Connection: " . client); client.on('message', function(){ console.log("message"); }); client.on('disconnect', function(){ console.log("disconnect") }); }); }; ================================================ FILE: views/404.html ================================================

Cannot find <%= request.url %>

Sorry we failed to locate this page or resource.

================================================ FILE: views/500.html ================================================

Internal Server Error

Sorry an error has occurred, please try refreshing the page or navigate back to home.

================================================ FILE: views/app/index.html ================================================

Welcome!

The following controllers are available:

<% if (controllers.length) { %> <% } else { %>
No controllers available - try 'eb script generate-all ModelName'
<% } %>
You are viewing the default home page - edit views/app/index.html to edit this page!

Credits:

  • Node.js: Amazing javascript asynchronous IO library, install manually.
  • MongoDB: NoSQL Database, install manually.
  • NPM: Node package manager, used to install:
    • Express: Application Framework for Node.js
    • Mongoose: Node.JS ORM for Mongo
    • EJS: Embedded Javascript Templating Library
  • jQuery: Javascript Library
  • jQuery UI: UI Library
  • jQuery Aristo Template: Fantastic looking jQuery UI Template.

Contact me via github : Clifton @ Github

================================================ FILE: views/layout.html ================================================ Sample MVC Application
<%- body %>
================================================ FILE: views/messages.html ================================================ <% if (hasMessages) { %>
<% messages().forEach(function(msg){ %> <%- msg %>
<% }) %>
<% } %>