From 2db3c3ed93d7c6386dfd809f431879b14b90c712 Mon Sep 17 00:00:00 2001 From: Kadir Pekel Date: Sun, 3 Jul 2011 23:27:15 +0300 Subject: [PATCH] improved sub application modularization and template rendering layout system, updated examples due to changes --- README.md | 13 +++- examples/coffeekup/views/layout.coffeekup | 4 ++ examples/coffeekup/views/main.coffeekup | 17 +++-- examples/connect/app.coffee | 2 +- examples/connect/layout.eco | 7 +++ examples/helpers/app.coffee | 2 +- examples/helpers/layout.eco | 7 +++ examples/layout/app.coffee | 7 +-- examples/layout/layout.eco | 2 +- examples/sandbox/base/index.coffee | 6 +- examples/sandbox/base/views/layout.eco | 10 --- examples/sandbox/comments/index.coffee | 6 +- examples/sandbox/comments/views/list.eco | 1 - examples/sandbox/extensions.coffee | 6 -- examples/sandbox/index.coffee | 18 +++--- examples/sandbox/posts/index.coffee | 6 +- examples/sandbox/server.js | 2 + examples/sandbox/settings.coffee | 8 +++ .../home.eco => templates/base/index.html} | 2 +- .../sandbox/templates/comment_layout.html | 18 ++++++ .../sandbox/templates/comments/index.html | 1 + examples/sandbox/templates/layout.html | 13 ++++ .../list.eco => templates/posts/index.html} | 0 examples/simple_auth/layout.eco | 7 +++ examples/templating/app.coffee | 2 +- examples/templating/layout.eco | 7 +++ examples/templating/main.eco | 2 +- examples/templating/nested.eco | 2 +- examples/websockets/app.coffee | 4 +- lib/coffeemate.coffee | 63 ++++++++++++++----- package.json | 2 +- 31 files changed, 165 insertions(+), 82 deletions(-) create mode 100644 examples/coffeekup/views/layout.coffeekup create mode 100644 examples/connect/layout.eco create mode 100644 examples/helpers/layout.eco delete mode 100644 examples/sandbox/base/views/layout.eco delete mode 100644 examples/sandbox/comments/views/list.eco delete mode 100644 examples/sandbox/extensions.coffee create mode 100644 examples/sandbox/server.js create mode 100644 examples/sandbox/settings.coffee rename examples/sandbox/{base/views/home.eco => templates/base/index.html} (50%) create mode 100644 examples/sandbox/templates/comment_layout.html create mode 100644 examples/sandbox/templates/comments/index.html create mode 100644 examples/sandbox/templates/layout.html rename examples/sandbox/{posts/views/list.eco => templates/posts/index.html} (100%) create mode 100644 examples/simple_auth/layout.eco create mode 100644 examples/templating/layout.eco diff --git a/README.md b/README.md index df88b2a..7284695 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ mate.context.highlight = (color, txt) -> mate.get '/greet/:name', -> # this is context variable @greet_msg = "Hello, #{@req.params.name}" - @render 'home.eco' + @render 'home' # Stream it mate.io.sockets.on 'connection', (socket) -> @@ -42,6 +42,17 @@ mate.io.sockets.on 'connection', (socket) -> mate.listen 3000 ``` +``` html + + + + + + <%- @include @body %> + + +``` + ``` html diff --git a/examples/coffeekup/views/layout.coffeekup b/examples/coffeekup/views/layout.coffeekup new file mode 100644 index 0000000..b09c5a9 --- /dev/null +++ b/examples/coffeekup/views/layout.coffeekup @@ -0,0 +1,4 @@ +html -> + head + body -> + include @body \ No newline at end of file diff --git a/examples/coffeekup/views/main.coffeekup b/examples/coffeekup/views/main.coffeekup index 616a7ff..383bd23 100644 --- a/examples/coffeekup/views/main.coffeekup +++ b/examples/coffeekup/views/main.coffeekup @@ -1,10 +1,7 @@ -html -> - head - body -> - h1 "A cup of coffee demonstration" - div -> - include "nested1" - div -> - include "nested2" - div -> - include "nested3" \ No newline at end of file +h1 "A cup of coffee demonstration" +div -> + include "nested1" +div -> + include "nested2" +div -> + include "nested3" \ No newline at end of file diff --git a/examples/connect/app.coffee b/examples/connect/app.coffee index 801ce78..07a8d39 100644 --- a/examples/connect/app.coffee +++ b/examples/connect/app.coffee @@ -4,6 +4,6 @@ mate.logger() mate.static(__dirname + '/public') mate.get '/', -> - @render 'main.eco' + @render 'main' mate.listen 3000 diff --git a/examples/connect/layout.eco b/examples/connect/layout.eco new file mode 100644 index 0000000..68571b5 --- /dev/null +++ b/examples/connect/layout.eco @@ -0,0 +1,7 @@ + + + + + <%- @include @body %> + + diff --git a/examples/helpers/app.coffee b/examples/helpers/app.coffee index d0222f1..5bdb3a2 100644 --- a/examples/helpers/app.coffee +++ b/examples/helpers/app.coffee @@ -4,6 +4,6 @@ mate.context.highlight = (msg) -> "#{msg}" mate.get '/', -> - @render 'main.eco' + @render 'main' mate.listen 3000 diff --git a/examples/helpers/layout.eco b/examples/helpers/layout.eco new file mode 100644 index 0000000..68571b5 --- /dev/null +++ b/examples/helpers/layout.eco @@ -0,0 +1,7 @@ + + + + + <%- @include @body %> + + diff --git a/examples/layout/app.coffee b/examples/layout/app.coffee index b02af3e..3a6dc91 100644 --- a/examples/layout/app.coffee +++ b/examples/layout/app.coffee @@ -1,12 +1,7 @@ mate = require '../../lib/coffeemate' -# build your own layout structure -mate.context.custom_render = (template_name) -> - @content = template_name - @render 'layout.eco' - mate.get '/', -> @foo = 'bar' - @custom_render 'main.eco' + @render 'main' mate.listen 3000 diff --git a/examples/layout/layout.eco b/examples/layout/layout.eco index 0cedd59..52c752e 100644 --- a/examples/layout/layout.eco +++ b/examples/layout/layout.eco @@ -2,7 +2,7 @@
This is HEADER
-
<%- @include @content %>
+
<%- @include @body %>
This is FOOTER
\ No newline at end of file diff --git a/examples/sandbox/base/index.coffee b/examples/sandbox/base/index.coffee index 43fa059..3a41b9c 100644 --- a/examples/sandbox/base/index.coffee +++ b/examples/sandbox/base/index.coffee @@ -1,5 +1,3 @@ -mate = require('../../../lib/coffeemate').newInstance() +mate = require '../../../lib/coffeemate' -mate.get '/', -> @view 'home' - -module.exports = mate \ No newline at end of file +mate.get '/', -> @render 'base/index' diff --git a/examples/sandbox/base/views/layout.eco b/examples/sandbox/base/views/layout.eco deleted file mode 100644 index 767726c..0000000 --- a/examples/sandbox/base/views/layout.eco +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - <%- @include @view %> -
- home - - diff --git a/examples/sandbox/comments/index.coffee b/examples/sandbox/comments/index.coffee index 61eca7b..34ece9c 100644 --- a/examples/sandbox/comments/index.coffee +++ b/examples/sandbox/comments/index.coffee @@ -1,5 +1,3 @@ -mate = require('../../../lib/coffeemate').newInstance() +mate = require '../../../lib/coffeemate' -mate.get '/', -> @view 'list' - -module.exports = mate \ No newline at end of file +mate.get '/', -> @render 'comments/index', 'comment_layout' diff --git a/examples/sandbox/comments/views/list.eco b/examples/sandbox/comments/views/list.eco deleted file mode 100644 index 146f238..0000000 --- a/examples/sandbox/comments/views/list.eco +++ /dev/null @@ -1 +0,0 @@ -

Comment List

\ No newline at end of file diff --git a/examples/sandbox/extensions.coffee b/examples/sandbox/extensions.coffee deleted file mode 100644 index 056364f..0000000 --- a/examples/sandbox/extensions.coffee +++ /dev/null @@ -1,6 +0,0 @@ -mate = require '../../lib/coffeemate' - -mate.context.view = (viewname, layout) -> - viewpath = @container.route.slice(1) - @view = "#{viewpath}/views/#{viewname}.eco" - @render if layout then "#{viewpath}/views/#{layout}.eco" else "base/views/layout.eco" diff --git a/examples/sandbox/index.coffee b/examples/sandbox/index.coffee index bd579bd..516377c 100644 --- a/examples/sandbox/index.coffee +++ b/examples/sandbox/index.coffee @@ -1,19 +1,15 @@ mate = require '../../lib/coffeemate' -# use some of connect middlewares -mate.logger() -mate.static("#{__dirname}/public") - -# import extensions -require './extensions' +# import configuration +require './settings' # import sub applications -mate.use '/base', require './base' -mate.use '/posts', require './posts' -mate.use '/comments', require './comments' +mate.sub '/base', -> require './base' +mate.sub '/posts', -> require './posts' +mate.sub '/comments', -> require './comments' # redirect root mate.get '/', -> @redirect '/base' - + # start the engines -mate.listen 3000 \ No newline at end of file +mate.listen 3000 diff --git a/examples/sandbox/posts/index.coffee b/examples/sandbox/posts/index.coffee index 61eca7b..fbd27bd 100644 --- a/examples/sandbox/posts/index.coffee +++ b/examples/sandbox/posts/index.coffee @@ -1,5 +1,3 @@ -mate = require('../../../lib/coffeemate').newInstance() +mate = require '../../../lib/coffeemate' -mate.get '/', -> @view 'list' - -module.exports = mate \ No newline at end of file +mate.get '/', -> @render 'posts/index' diff --git a/examples/sandbox/server.js b/examples/sandbox/server.js new file mode 100644 index 0000000..c40c7d8 --- /dev/null +++ b/examples/sandbox/server.js @@ -0,0 +1,2 @@ +require('coffee-script'); +module.exports = require('./index.coffee'); diff --git a/examples/sandbox/settings.coffee b/examples/sandbox/settings.coffee new file mode 100644 index 0000000..1302be1 --- /dev/null +++ b/examples/sandbox/settings.coffee @@ -0,0 +1,8 @@ +mate = require '../../lib/coffeemate' + +mate.options.renderDir = 'templates' +mate.options.renderExt = '.html' + +# use some of connect middlewares +mate.logger() +mate.static("#{__dirname}/public") diff --git a/examples/sandbox/base/views/home.eco b/examples/sandbox/templates/base/index.html similarity index 50% rename from examples/sandbox/base/views/home.eco rename to examples/sandbox/templates/base/index.html index 4162ff8..c367b26 100644 --- a/examples/sandbox/base/views/home.eco +++ b/examples/sandbox/templates/base/index.html @@ -1,2 +1,2 @@

Coffeemate Sandbox

-posts \ No newline at end of file +posts diff --git a/examples/sandbox/templates/comment_layout.html b/examples/sandbox/templates/comment_layout.html new file mode 100644 index 0000000..1019c13 --- /dev/null +++ b/examples/sandbox/templates/comment_layout.html @@ -0,0 +1,18 @@ + + + + + + +
+
+ <%- @include @body %> +
+
+ + + diff --git a/examples/sandbox/templates/comments/index.html b/examples/sandbox/templates/comments/index.html new file mode 100644 index 0000000..31332da --- /dev/null +++ b/examples/sandbox/templates/comments/index.html @@ -0,0 +1 @@ +

Comment List

diff --git a/examples/sandbox/templates/layout.html b/examples/sandbox/templates/layout.html new file mode 100644 index 0000000..36bc568 --- /dev/null +++ b/examples/sandbox/templates/layout.html @@ -0,0 +1,13 @@ + + + + + +
+
+ <%- @include @body %> +
+
+ + + diff --git a/examples/sandbox/posts/views/list.eco b/examples/sandbox/templates/posts/index.html similarity index 100% rename from examples/sandbox/posts/views/list.eco rename to examples/sandbox/templates/posts/index.html diff --git a/examples/simple_auth/layout.eco b/examples/simple_auth/layout.eco new file mode 100644 index 0000000..68571b5 --- /dev/null +++ b/examples/simple_auth/layout.eco @@ -0,0 +1,7 @@ + + + + + <%- @include @body %> + + diff --git a/examples/templating/app.coffee b/examples/templating/app.coffee index 9909b80..2f7e2a6 100644 --- a/examples/templating/app.coffee +++ b/examples/templating/app.coffee @@ -2,6 +2,6 @@ mate = require '../../lib/coffeemate' mate.get '/:page?', -> @foo = 'bar' # this is a context variable - @render 'main.eco' + @render 'main' mate.listen 3000 diff --git a/examples/templating/layout.eco b/examples/templating/layout.eco new file mode 100644 index 0000000..68571b5 --- /dev/null +++ b/examples/templating/layout.eco @@ -0,0 +1,7 @@ + + + + + <%- @include @body %> + + diff --git a/examples/templating/main.eco b/examples/templating/main.eco index 55ea04d..41f28c3 100644 --- a/examples/templating/main.eco +++ b/examples/templating/main.eco @@ -1,3 +1,3 @@

this is main template for path: <%= @req.url %>

This is foo: <%= @foo %>
-
<%- @include 'nested.eco' %>
+
<%- @include 'nested' %>
diff --git a/examples/templating/nested.eco b/examples/templating/nested.eco index e25f346..a96ceed 100644 --- a/examples/templating/nested.eco +++ b/examples/templating/nested.eco @@ -1,3 +1,3 @@

this is nested template

This is foo: <%= @foo %>
-
<%- @include 'leaf.eco' %>
+
<%- @include 'leaf' %>
diff --git a/examples/websockets/app.coffee b/examples/websockets/app.coffee index c212f10..aa9c1b2 100644 --- a/examples/websockets/app.coffee +++ b/examples/websockets/app.coffee @@ -1,7 +1,9 @@ mate = require '../../lib/coffeemate.coffee' +mate.options.renderLayout = no + mate.get '/', -> - @render 'main.eco' + @render 'main' mate.io.sockets.on 'connection', (socket, i=0) -> setInterval (-> socket.emit 'news', "Breaking news #{i++}"), 500 diff --git a/lib/coffeemate.coffee b/lib/coffeemate.coffee index 11652a3..db220d9 100644 --- a/lib/coffeemate.coffee +++ b/lib/coffeemate.coffee @@ -9,6 +9,7 @@ fs = require 'fs' path = require 'path' connect = require 'connect' eco = require 'eco' +util = require 'util' # Context object that instantiated in every request to # form router handlers' and templates' @/this reference @@ -28,7 +29,7 @@ class CoffeemateContext redirect: (location) -> @resp.writeHead 301, location: location @resp.end() - + # This method renders the template that read from given templateName # using eco template engine as default. # It uses sync file read operation to obtain template contents @@ -41,14 +42,23 @@ class CoffeemateContext @container.options.renderDir, "#{templateName}#{@container.options.renderExt}" template = fs.readFileSync templatePath - @container.options.renderFunc "#{template}", @ + content = @container.options.renderFunc "#{template}", @ # This method renders the template that read from given templateName # and writes the output to the client socket stream # + # You can explicitly set 'layoutName' if want to override the default + # 'renderLayoutName' option value + # # @param {String} templateName - # @api public - render: (templateName) -> + # @param {String} layoutName + # @api public + render: (templateName, layoutName) -> + if @container.options.renderLayout + layoutName ?= @container.options.renderLayoutName + @[@container.options.renderLayoutPlaceholder] = templateName + @resp.end @include layoutName + return @resp.end @include templateName # Coffeemate core object @@ -70,13 +80,33 @@ class Coffeemate extends connect.HTTPServer # # @api public constructor: -> - @options = renderFunc: eco.render, renderDir: '', renderExt: '' - @routes = [] + @options = + renderFunc: eco.render, + renderDir: '', + renderExt: '.eco', + renderLayout: yes, + renderLayoutName: 'layout', + renderLayoutPlaceholder: 'body' + @routeMap = {} + @baseUrl = '/' connect.HTTPServer.call @, [] # enable socket.io if available try @io = require('socket.io').listen @ - + + # This method helps you define sub applications under given base path. + # The context of callback is coffeemate instance itself and any router definition + # in this context will be constructed based on the baseUrl + # + # @param {String} baseUrl + # @param {String} callback + # @api public + sub: (baseUrl, callback) -> + previousBaseUrl = @baseUrl + @baseUrl = baseUrl + callback.call @ + @baseUrl = previousBaseUrl + module # Factory method for creating new Coffeemate instances # @@ -96,27 +126,27 @@ class Coffeemate extends connect.HTTPServer arg.buildRouter() for arg in args when arg instanceof Coffeemate connect.HTTPServer::use.apply @, args - # sugarize coffeekup! + # Enable special coffeekup templating magic! # # @api public coffeekup: (locals) -> renderFunc = require('coffeekup').render - locals ?= {} locals.include ?= (partialName) -> text ck_options.context.include partialName - @options.renderFunc = (tmpl, ctx) -> renderFunc tmpl, context: ctx, locals: locals # Build connect router middleware from internal route stack and automatically use it. # # @api private buildRouter: -> - @use @middleware.router (app) => - for route in @routes - do (route) => - app[route.method] route.pattern, (req, resp) => - route.callback.apply new CoffeemateContext(@, req, resp) + self = @ + for root, routes of @routeMap + @use root, @middleware.router (app) -> + for route in routes + do (route) -> + app[route.method] route.pattern, (req, resp) -> + route.callback.apply new CoffeemateContext(self, req, resp) # Override 'connect.HTTPServer.listen' to create a pre-hook space for # preparing router definitions @@ -139,7 +169,8 @@ for item of Coffeemate::middleware for method in Coffeemate::middleware.router.methods do (method) -> Coffeemate::[method] = (pattern, callback) -> - @routes.push method: method, pattern: pattern, callback: callback + @routeMap[@baseUrl] ?= [] + @routeMap[@baseUrl].push method: method, pattern: pattern, callback: callback @ # Handle uncaught exceptions explicitly to prevent node exiting diff --git a/package.json b/package.json index 1db8baa..629f602 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "readme": "http://github.com/coffeemate/coffeematel#readme" -, "version": "0.3.0" +, "version": "0.4.0" , "description": "the coffee creamer!" , "main": "lib/coffeemate.coffee" , "author": "Kadir Pekel "