From 077d5ec7bd7af2d941b6fab148b25b2d13a28137 Mon Sep 17 00:00:00 2001 From: petecoop Date: Wed, 21 Jan 2015 00:19:16 +0000 Subject: [PATCH] Added Marko template engine support. Closes #75 --- .dependencies.json | 1 + README.md | 1 + app/index.js | 3 +- app/templates/basic-coffee/app.js | 48 ++++++++++++------- app/templates/basic-coffee/package.json | 9 ++-- .../basic-coffee/routes/index.coffee | 12 +++-- app/templates/basic/app.js | 24 +++++++--- app/templates/basic/package.json | 3 +- app/templates/basic/routes/index.js | 12 +++-- .../mvc-coffee/app/controllers/home.coffee | 14 ++++-- .../mvc-coffee/config/express.coffee | 24 +++++++--- app/templates/mvc-coffee/package.json | 9 ++-- app/templates/mvc/app/controllers/home.js | 14 ++++-- app/templates/mvc/config/express.js | 33 ++++++++----- app/templates/mvc/package.json | 3 +- .../components/app-footer/template.marko | 2 + .../components/app-header/template.marko | 10 ++++ app/templates/views/marko/error.marko | 7 +++ app/templates/views/marko/index.marko | 6 +++ app/templates/views/marko/marko-taglib.json | 3 ++ package.json | 2 +- test/test-creation.js | 27 +++++++++++ 22 files changed, 200 insertions(+), 67 deletions(-) create mode 100644 app/templates/views/marko/components/app-footer/template.marko create mode 100644 app/templates/views/marko/components/app-header/template.marko create mode 100644 app/templates/views/marko/error.marko create mode 100644 app/templates/views/marko/index.marko create mode 100644 app/templates/views/marko/marko-taglib.json diff --git a/.dependencies.json b/.dependencies.json index 1eb07a0..c90ea6b 100644 --- a/.dependencies.json +++ b/.dependencies.json @@ -8,6 +8,7 @@ "jade": "~1.9.1", "ejs": "~2.1.4", "swig": "~1.4.2", + "marko": "~1.3.24", "express-handlebars": "~1.1.0", "compression": "~1.3.0", "method-override": "~2.3.0", diff --git a/README.md b/README.md index 0ba5765..767385e 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ An Expressjs generator for Yeoman, based on the express command line tool. - Handlebars - Swig - EJS + - Marko - Supported CSS pre-processors - SASS (both node-sass and ruby sass) - LESS diff --git a/app/index.js b/app/index.js index 5885a19..f43e1dc 100644 --- a/app/index.js +++ b/app/index.js @@ -49,7 +49,8 @@ module.exports = generators.Base.extend({ 'Jade', 'Swig', 'EJS', - 'Handlebars' + 'Handlebars', + 'Marko' ] }]; diff --git a/app/templates/basic-coffee/app.js b/app/templates/basic-coffee/app.js index fcad706..10e218b 100644 --- a/app/templates/basic-coffee/app.js +++ b/app/templates/basic-coffee/app.js @@ -19,9 +19,9 @@ var app = express(); app.engine('handlebars', exphbs({ defaultLayout: 'main', partialsDir: ['views/partials/'] -}));<% } %> +}));<% } %><% if(options.viewEngine != 'marko'){ %> app.set('views', path.join(__dirname, 'views')); -app.set('view engine', '<%= options.viewEngine %>'); +app.set('view engine', '<%= options.viewEngine %>');<% } %> // app.use(favicon(__dirname + '/public/img/favicon.ico')); app.use(logger('dev')); @@ -37,35 +37,47 @@ app.use('/users', users); /// catch 404 and forward to error handler app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); + var err = new Error('Not Found'); + err.status = 404; + next(err); }); /// error handlers // development error handler // will print stacktrace +<% if(options.viewEngine == 'marko'){ %> + var errorTemplate = require('marko').load(require.resolve('./views/error.marko'));<% } %> if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err, - title: 'error' + app.use(function(err, req, res, next) { + res.status(err.status || 500);<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render({ + message: err.message, + error: err, + title: 'error' + }, res);<% } else { %> + res.render('error', { + message: err.message, + error: err, + title: 'error' + });<% } %> }); - }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {}, - title: 'error' - }); + res.status(err.status || 500);<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render({ + message: err.message, + error: err, + title: 'error' + }, res);<% } else { %> + res.render('error', { + message: err.message, + error: {}, + title: 'error' + });<% } %> }); diff --git a/app/templates/basic-coffee/package.json b/app/templates/basic-coffee/package.json index 63920f9..ebf30a7 100644 --- a/app/templates/basic-coffee/package.json +++ b/app/templates/basic-coffee/package.json @@ -15,9 +15,11 @@ "jade": "~1.9.1"<% } %><% if(options.viewEngine == 'ejs'){ %>, "ejs": "~2.1.4"<% } %><% if(options.viewEngine == 'swig'){ %>, "swig": "~1.4.2"<% } %><% if(options.viewEngine == 'handlebars'){ %>, - "express-handlebars": "~1.1.0"<% } %> + "express-handlebars": "~1.1.0"<% } %><% if(options.viewEngine == 'marko'){ %>, + "marko": "~1.3.24"<% } %> }, - "devDependencies": {<% if(options.buildTool == 'grunt'){ %> + "devDependencies": { + "coffee-script": "~1.8.0",<% if(options.buildTool == 'grunt'){ %> "grunt": "~0.4.5", "grunt-develop": "~0.4.0"<% if(options.cssPreprocessor == 'sass'){ %>, "grunt-contrib-sass": "~0.8.1"<% } %><% if(options.cssPreprocessor == 'node-sass'){ %>, @@ -27,8 +29,7 @@ "grunt-contrib-watch": "~0.6.1", "request": "~2.51.0", "time-grunt": "~1.0.0", - "load-grunt-tasks": "~2.0.0", - "coffee-script": "~1.8.0"<% } %><% if(options.buildTool == 'gulp'){ %> + "load-grunt-tasks": "~2.0.0"<% } %><% if(options.buildTool == 'gulp'){ %> "gulp": "~3.8.10"<% if(options.cssPreprocessor == 'sass'){ %>, "gulp-ruby-sass": "~0.7.1"<% } %><% if(options.cssPreprocessor == 'node-sass'){ %>, "gulp-sass": "~1.3.2"<% } %><% if(options.cssPreprocessor == 'less'){ %>, diff --git a/app/templates/basic-coffee/routes/index.coffee b/app/templates/basic-coffee/routes/index.coffee index d7583ce..ec26e14 100644 --- a/app/templates/basic-coffee/routes/index.coffee +++ b/app/templates/basic-coffee/routes/index.coffee @@ -1,8 +1,14 @@ express = require 'express' -router = express.Router() +router = express.Router()<% if(options.viewEngine == 'marko'){ %> +marko = require 'marko'<% } %> # GET home page. -router.get '/', (req, res) -> - res.render 'index', { title: 'Express' } +<% if(options.viewEngine == 'marko'){ %> +indexTemplate = marko.load require.resolve '../views/index.marko'<% } %> +router.get '/', (req, res) -><% if(options.viewEngine == 'marko'){ %> + indexTemplate.render + title: 'Express' + , res<% } else { %> + res.render 'index', { title: 'Express' }<% } %> module.exports = router diff --git a/app/templates/basic/app.js b/app/templates/basic/app.js index 1fc6b12..761b20f 100644 --- a/app/templates/basic/app.js +++ b/app/templates/basic/app.js @@ -17,9 +17,9 @@ var app = express(); app.engine('handlebars', exphbs({ defaultLayout: 'main', partialsDir: ['views/partials/'] -}));<% } %> +}));<% } %><% if(options.viewEngine != 'marko'){ %> app.set('views', path.join(__dirname, 'views')); -app.set('view engine', '<%= options.viewEngine %>'); +app.set('view engine', '<%= options.viewEngine %>');<% } %> // app.use(favicon(__dirname + '/public/img/favicon.ico')); app.use(logger('dev')); @@ -44,26 +44,38 @@ app.use(function(req, res, next) { // development error handler // will print stacktrace +<% if(options.viewEngine == 'marko'){ %> + var errorTemplate = require('marko').load(require.resolve('./views/error.marko'));<% } %> if (app.get('env') === 'development') { app.use(function(err, req, res, next) { - res.status(err.status || 500); + res.status(err.status || 500);<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render({ + message: err.message, + error: err, + title: 'error' + }, res);<% } else { %> res.render('error', { message: err.message, error: err, title: 'error' - }); + });<% } %> }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { - res.status(err.status || 500); + res.status(err.status || 500);<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render({ + message: err.message, + error: err, + title: 'error' + }, res);<% } else { %> res.render('error', { message: err.message, error: {}, title: 'error' - }); + });<% } %> }); diff --git a/app/templates/basic/package.json b/app/templates/basic/package.json index 77e867c..6fc157f 100644 --- a/app/templates/basic/package.json +++ b/app/templates/basic/package.json @@ -15,7 +15,8 @@ "jade": "~1.9.1"<% } %><% if(options.viewEngine == 'ejs'){ %>, "ejs": "~2.1.4"<% } %><% if(options.viewEngine == 'swig'){ %>, "swig": "~1.4.2"<% } %><% if(options.viewEngine == 'handlebars'){ %>, - "express-handlebars": "~1.1.0"<% } %> + "express-handlebars": "~1.1.0"<% } %><% if(options.viewEngine == 'marko'){ %>, + "marko": "~1.3.24"<% } %> }, "devDependencies": {<% if(options.buildTool == 'grunt'){ %> "grunt": "~0.4.5", diff --git a/app/templates/basic/routes/index.js b/app/templates/basic/routes/index.js index 896c948..73b84a0 100644 --- a/app/templates/basic/routes/index.js +++ b/app/templates/basic/routes/index.js @@ -1,9 +1,15 @@ var express = require('express'); -var router = express.Router(); +var router = express.Router();<% if(options.viewEngine == 'marko'){ %> +var marko = require('marko');<% } %> /* GET home page. */ -router.get('/', function(req, res) { - res.render('index', { title: 'Express' }); +<% if(options.viewEngine == 'marko'){ %> +var indexTemplate = marko.load(require.resolve('../views/index.marko'));<% } %> +router.get('/', function(req, res) {<% if(options.viewEngine == 'marko'){ %> + indexTemplate.render({ + title: 'Express' + }, res);<% } else { %> + res.render('index', { title: 'Express' });<% } %> }); module.exports = router; diff --git a/app/templates/mvc-coffee/app/controllers/home.coffee b/app/templates/mvc-coffee/app/controllers/home.coffee index b8767e8..20e69db 100644 --- a/app/templates/mvc-coffee/app/controllers/home.coffee +++ b/app/templates/mvc-coffee/app/controllers/home.coffee @@ -1,17 +1,23 @@ express = require 'express' -router = express.Router()<% if(options.database == 'mongodb'){ %> +router = express.Router()<% if(options.viewEngine == 'marko'){ %> +marko = require 'marko'<% } %><% if(options.database == 'mongodb'){ %> mongoose = require 'mongoose' Article = mongoose.model 'Article'<% } %><% if(options.database == 'mysql' || options.database == 'postgresql'){ %> db = require '../models'<% } %> module.exports = (app) -> app.use '/', router - +<% if(options.viewEngine == 'marko'){ %> +indexTemplate = marko.load require.resolve '../views/index.marko'<% } %> router.get '/', (req, res, next) -> <% if(options.database == 'mongodb'){ %> Article.find (err, articles) -> return next(err) if err<% } %><% if(options.database == 'mysql' || options.database == 'postgresql'){ %> - db.Article.findAll().success (articles) -><% } %> + db.Article.findAll().success (articles) -><% } %><% if(options.viewEngine == 'marko'){ %> + indexTemplate.render + title: 'Generator-Express MVC', + articles: articles + , res<% } else { %> res.render 'index', title: 'Generator-Express MVC' - articles: articles + articles: articles<% } %> diff --git a/app/templates/mvc-coffee/config/express.coffee b/app/templates/mvc-coffee/config/express.coffee index c78dabc..4317867 100644 --- a/app/templates/mvc-coffee/config/express.coffee +++ b/app/templates/mvc-coffee/config/express.coffee @@ -16,9 +16,9 @@ module.exports = (app, config) -><% if(options.viewEngine == 'swig'){ %> layoutsDir: config.root + '/app/views/layouts/' defaultLayout: 'main' partialsDir: [config.root + '/app/views/partials/'] - )<% } %> + )<% } %><% if(options.viewEngine != 'marko'){ %> app.set 'views', config.root + '/app/views' - app.set 'view engine', '<%= options.viewEngine %>' + app.set 'view engine', '<%= options.viewEngine %>'<% } %> # app.use(favicon(config.root + '/public/img/favicon.ico')); app.use logger 'dev' @@ -45,19 +45,31 @@ module.exports = (app, config) -><% if(options.viewEngine == 'swig'){ %> # development error handler # will print stacktrace + <% if(options.viewEngine == 'marko'){ %> + errorTemplate = require('marko').load require.resolve '../app/views/error.marko'<% } %> if app.get('env') == 'development' app.use (err, req, res, next) -> - res.status err.status || 500 + res.status err.status || 500<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render + message: err.message, + error: err + title: 'error' + , res<% } else { %> res.render 'error', message: err.message error: err - title: 'error' + title: 'error'<% } %> # production error handler # no stacktraces leaked to user app.use (err, req, res, next) -> - res.status err.status || 500 + res.status err.status || 500<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render + message: err.message, + error: {} + title: 'error' + , res<% } else { %> res.render 'error', message: err.message error: {} - title: 'error' + title: 'error'<% } %> diff --git a/app/templates/mvc-coffee/package.json b/app/templates/mvc-coffee/package.json index a48c361..39004f0 100644 --- a/app/templates/mvc-coffee/package.json +++ b/app/templates/mvc-coffee/package.json @@ -23,9 +23,11 @@ "jade": "~1.9.1"<% } %><% if(options.viewEngine == 'ejs'){ %>, "ejs": "~2.1.4"<% } %><% if(options.viewEngine == 'swig'){ %>, "swig": "~1.4.2"<% } %><% if(options.viewEngine == 'handlebars'){ %>, - "express-handlebars": "~1.1.0"<% } %> + "express-handlebars": "~1.1.0"<% } %><% if(options.viewEngine == 'marko'){ %>, + "marko": "~1.3.24"<% } %> }, - "devDependencies": {<% if(options.buildTool == 'grunt'){ %> + "devDependencies": { + "coffee-script": "~1.8.0",<% if(options.buildTool == 'grunt'){ %> "grunt": "~0.4.5", "grunt-develop": "~0.4.0"<% if(options.cssPreprocessor == 'sass'){ %>, "grunt-contrib-sass": "~0.8.1"<% } %><% if(options.cssPreprocessor == 'node-sass'){ %>, @@ -35,8 +37,7 @@ "grunt-contrib-watch": "~0.6.1", "request": "~2.51.0", "time-grunt": "~1.0.0", - "load-grunt-tasks": "~2.0.0", - "coffee-script": "~1.8.0"<% } %><% if(options.buildTool == 'gulp'){ %> + "load-grunt-tasks": "~2.0.0"<% } %><% if(options.buildTool == 'gulp'){ %> "gulp": "~3.8.10"<% if(options.cssPreprocessor == 'sass'){ %>, "gulp-ruby-sass": "~0.7.1"<% } %><% if(options.cssPreprocessor == 'node-sass'){ %>, "gulp-sass": "~1.3.2"<% } %><% if(options.cssPreprocessor == 'less'){ %>, diff --git a/app/templates/mvc/app/controllers/home.js b/app/templates/mvc/app/controllers/home.js index 277fea4..33c958a 100644 --- a/app/templates/mvc/app/controllers/home.js +++ b/app/templates/mvc/app/controllers/home.js @@ -1,5 +1,6 @@ var express = require('express'), - router = express.Router(),<% if(options.database == 'mongodb'){ %> + router = express.Router(),<% if(options.viewEngine == 'marko'){ %> + marko = require('marko'),<% } %><% if(options.database == 'mongodb'){ %> mongoose = require('mongoose'), Article = mongoose.model('Article');<% } %><% if(options.database == 'mysql' || options.database == 'postgresql'){ %> db = require('../models');<% } %><% if(options.database == 'none'){ %> @@ -8,16 +9,21 @@ var express = require('express'), module.exports = function (app) { app.use('/', router); }; - +<% if(options.viewEngine == 'marko'){ %> +var indexTemplate = marko.load(require.resolve('../views/index.marko'));<% } %> router.get('/', function (req, res, next) { <% if(options.database == 'mongodb'){ %> Article.find(function (err, articles) { if (err) return next(err);<% } %><% if(options.database == 'mysql' || options.database == 'postgresql'){ %> db.Article.findAll().success(function (articles) {<% } %><% if(options.database == 'none'){ %> - var articles = [new Article(), new Article()];<% } %> + var articles = [new Article(), new Article()];<% } %><% if(options.viewEngine == 'marko'){ %> + indexTemplate.render({ + title: 'Generator-Express MVC', + articles: articles + }, res);<% } else { %> res.render('index', { title: 'Generator-Express MVC', articles: articles - });<% if(options.database !== 'none'){ %> + });<% } %><% if(options.database !== 'none'){ %> });<% } %> }); diff --git a/app/templates/mvc/config/express.js b/app/templates/mvc/config/express.js index f8cbd72..1b53675 100644 --- a/app/templates/mvc/config/express.js +++ b/app/templates/mvc/config/express.js @@ -16,9 +16,9 @@ module.exports = function(app, config) {<% if(options.viewEngine == 'swig'){ %> layoutsDir: config.root + '/app/views/layouts/', defaultLayout: 'main', partialsDir: [config.root + '/app/views/partials/'] - }));<% } %> + }));<% } %><% if(options.viewEngine != 'marko'){ %> app.set('views', config.root + '/app/views'); - app.set('view engine', '<%= options.viewEngine %>'); + app.set('view engine', '<%= options.viewEngine %>');<% } %> // app.use(favicon(config.root + '/public/img/favicon.ico')); app.use(logger('dev')); @@ -41,25 +41,36 @@ module.exports = function(app, config) {<% if(options.viewEngine == 'swig'){ %> err.status = 404; next(err); }); - + <% if(options.viewEngine == 'marko'){ %> + var errorTemplate = require('marko').load(require.resolve('../app/views/error.marko'));<% } %> if(app.get('env') === 'development'){ app.use(function (err, req, res, next) { - res.status(err.status || 500); + res.status(err.status || 500);<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render({ + message: err.message, + error: err, + title: 'error' + }, res);<% } else { %> res.render('error', { message: err.message, error: err, title: 'error' - }); + });<% } %> }); } app.use(function (err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {}, - title: 'error' - }); + res.status(err.status || 500);<% if(options.viewEngine == 'marko'){ %> + errorTemplate.render({ + message: err.message, + error: {}, + title: 'error' + }, res);<% } else { %> + res.render('error', { + message: err.message, + error: {}, + title: 'error' + });<% } %> }); }; diff --git a/app/templates/mvc/package.json b/app/templates/mvc/package.json index 003904f..96cf440 100644 --- a/app/templates/mvc/package.json +++ b/app/templates/mvc/package.json @@ -23,7 +23,8 @@ "jade": "~1.9.1"<% } %><% if(options.viewEngine == 'ejs'){ %>, "ejs": "~2.1.4"<% } %><% if(options.viewEngine == 'swig'){ %>, "swig": "~1.4.2"<% } %><% if(options.viewEngine == 'handlebars'){ %>, - "express-handlebars": "~1.1.0"<% } %> + "express-handlebars": "~1.1.0"<% } %><% if(options.viewEngine == 'marko'){ %>, + "marko": "~1.3.24"<% } %> }, "devDependencies": {<% if(options.buildTool == 'grunt'){ %> "grunt": "~0.4.5", diff --git a/app/templates/views/marko/components/app-footer/template.marko b/app/templates/views/marko/components/app-footer/template.marko new file mode 100644 index 0000000..308b1d0 --- /dev/null +++ b/app/templates/views/marko/components/app-footer/template.marko @@ -0,0 +1,2 @@ + + diff --git a/app/templates/views/marko/components/app-header/template.marko b/app/templates/views/marko/components/app-header/template.marko new file mode 100644 index 0000000..1cc8457 --- /dev/null +++ b/app/templates/views/marko/components/app-header/template.marko @@ -0,0 +1,10 @@ + + + + + + $data.title + + + + diff --git a/app/templates/views/marko/error.marko b/app/templates/views/marko/error.marko new file mode 100644 index 0000000..67ae419 --- /dev/null +++ b/app/templates/views/marko/error.marko @@ -0,0 +1,7 @@ + + + $data.message + $data.error.status + $data.error.stack + + diff --git a/app/templates/views/marko/index.marko b/app/templates/views/marko/index.marko new file mode 100644 index 0000000..f972ea6 --- /dev/null +++ b/app/templates/views/marko/index.marko @@ -0,0 +1,6 @@ + + +

$data.title

+

Welcome to $data.title

+ + diff --git a/app/templates/views/marko/marko-taglib.json b/app/templates/views/marko/marko-taglib.json new file mode 100644 index 0000000..89cb29b --- /dev/null +++ b/app/templates/views/marko/marko-taglib.json @@ -0,0 +1,3 @@ +{ + "tags-dir": "./components" +} diff --git a/package.json b/package.json index 90316a3..ae914f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "generator-express", - "version": "2.5.3", + "version": "2.5.4", "description": "A nodejs express generator for Yeoman", "keywords": [ "yeoman-generator", diff --git a/test/test-creation.js b/test/test-creation.js index 83348ca..04694dc 100644 --- a/test/test-creation.js +++ b/test/test-creation.js @@ -261,6 +261,19 @@ describe('Express generator', function () { }); }); + describe('Basic generator with Marko', function () { + var expected = [ + 'views/components/app-header/template.marko', + 'views/components/app-footer/template.marko', + 'views/index.marko', + 'views/error.marko', + 'views/marko-taglib.json' + ]; + + it('creates expected files', function (done) { + runGenerationTest.call(this, expected, 'basic', 'marko', 'none', false, 'none', 'grunt', done); + }); + }); describe('MVC generator with Jade', function () { @@ -404,6 +417,20 @@ describe('Express generator', function () { }); }); + describe('MVC generator with Marko', function () { + var expected = [ + 'app/views/components/app-header/template.marko', + 'app/views/components/app-footer/template.marko', + 'app/views/index.marko', + 'app/views/error.marko', + 'app/views/marko-taglib.json' + ]; + + it('creates expected files', function (done) { + runGenerationTest.call(this, expected, 'mvc', 'marko', 'none', false, 'none', 'grunt', done); + }); + }); + describe('MVC generator with MySQL', function () { var expected = [ 'app/models/index.js'