UNPKG

10.3 kBMarkdownView Raw
1# CoffeeCup <☕/>
2## Markup as CoffeeScript
3
4This is a clone of @mauricemach [CoffeeKup](https://github.com/mauricemach/coffeekup).
5
6I am renaming and trying to keep this project alive.
7
8CoffeeCup is a templating engine for [node.js](http://nodejs.org) and browsers that lets you to write your HTML templates in 100% pure [CoffeeScript](http://coffeescript.org).
9
10It was created in celebration of [whyday](http://whyday.org/), as an application of the concept used in [Markaby](https://github.com/markaby/markaby) ("Markup as Ruby", by Tim Fletcher and why the lucky stiff) to CoffeeScript.
11
12Here's what a template written for CoffeeCup looks like:
13
14 doctype 5
15 html ->
16 head ->
17 meta charset: 'utf-8'
18 title "#{@title or 'Untitled'} | A completely plausible website"
19 meta(name: 'description', content: @description) if @description?
20
21 link rel: 'stylesheet', href: '/css/app.css'
22
23 style '''
24 body {font-family: sans-serif}
25 header, nav, section, footer {display: block}
26 '''
27
28 script src: '/js/jquery.js'
29
30 coffeescript ->
31 $(document).ready ->
32 alert 'Alerts suck!'
33 body ->
34 header ->
35 h1 @title or 'Untitled'
36
37 nav ->
38 ul ->
39 (li -> a href: '/', -> 'Home') unless @path is '/'
40 li -> a href: '/chunky', -> 'Bacon!'
41 switch @user.role
42 when 'owner', 'admin'
43 li -> a href: '/admin', -> 'Secret Stuff'
44 when 'vip'
45 li -> a href: '/vip', -> 'Exclusive Stuff'
46 else
47 li -> a href: '/commoners', -> 'Just Stuff'
48
49 div '#myid.myclass.anotherclass', style: 'position: fixed', ->
50 p 'Divitis kills! Inline styling too.'
51
52 section ->
53 # A helper function you built and included.
54 breadcrumb separator: '>', clickable: yes
55
56 h2 "Let's count to 10:"
57 p i for i in [1..10]
58
59 # Another hypothetical helper.
60 form_to @post, ->
61 textbox '#title', label: 'Title:'
62 textbox '#author', label: 'Author:'
63 submit 'Save'
64
65 footer ->
66 # CoffeeScript comments. Not visible in the output document.
67 comment 'HTML comments.'
68 p 'Bye!'
69
70Interactive demo at [coffeekup.org](http://coffeekup.org).
71
72## _why?
73
74- **One language to rule them all**. JavaScript is everywhere, thus so is CoffeeScript. Servers, browsers, even databases. If extending this to rendering logic and UI structure (server and client side) is desirable to you, CoffeeKup is your friend.
75
76- **More specifically, one _outstanding_ language**. CoffeeScript is one hell of a clean, expressive, flexible and powerful language. It's hard to find such combination, especially if you need it to run in the browser too.
77
78- **Not yet another specialized language to learn**. Transferable knowledge FTW.
79
80- **Embed your templates in CoffeeScript nicely**. Templates are just functions, so they don't lose syntax highlighting and syntax checking when embedded in CoffeeScript apps.
81
82- **Embed CoffeeScript in your templates nicely**. In the same manner, you can write the contents of `<script>` blocks in CoffeeScript, and keep the highlighting. Perhaps more significantly, the CoffeeScript compiler doesn't have to be called just to convert these blocks to JS, as in other templating engines.
83
84- **Extensive editor support**. You benefit from the already existing list of excellent CoffeeScript [text editor plugins](https://github.com/jashkenas/coffee-script/wiki/Text-editor-plugins).
85
86- **Client-server consistency**. The same template language _and_ implementation in node.js or the browser.
87
88- **Easily extendable into a higher level "DSL"**. Since all elements are just functions, it's very easy to define your own custom "tags", which will work and look the same as "native" ones.
89
90- **HTML 5 ready**. Boring legacy doctypes and elements also available.
91
92- **Optional auto-escaping**. You can also use the `h` helper on a case-by-case basis.
93
94- **Optional formatting**, with line breaks and indentation.
95
96- **Pick your poison**. Works with both CoffeeScript and JavaScript apps.
97
98## Why not?
99
100CoffeeKup may not be your best choice in those cases:
101
102- You're after the cleanest syntax possible, above all. In this regard a specialized language such as [Jade](http://jade-lang.com) just can't be beaten.
103
104- You use divs and/or classes for everything. While in CoffeeKup you can do `div '#id.class.class'`, specialized languages often have an even shorter syntax for that.
105
106- You want CoffeeScript for rendering logic, but you'd rather stick with HTML for markup. Then you're looking for [Eco](http://github.com/sstephenson/eco).
107
108- For your specific project/team/preferences, you think a limited and/or separate language for templating is actually beneficial.
109
110## Installing
111
112Just grab [node.js](http://nodejs.org/#download) and [npm](http://github.com/isaacs/npm) and you're set:
113
114 npm install coffeecup
115
116To get the `coffeecup` command, install it globally:
117
118 npm install coffeecup -g
119
120Or to use the latest version:
121
122 git clone git@github.com:gradus/coffeecup.git && cd coffeecup
123 cake build
124 npm link
125 cd ~/myproject
126 npm link coffeecup
127
128## Using
129
130 cc = require 'coffeecup'
131
132 cc.render -> h1 "You can feed me templates as functions."
133 cc.render "h1 'Or strings. I am not too picky.'"
134
135Defining variables:
136
137 template = ->
138 h1 @title
139 form method: 'post', action: 'login', ->
140 textbox id: 'username'
141 textbox id: 'password'
142 button @title
143
144 helpers =
145 textbox: (attrs) ->
146 attrs.type = 'text'
147 attrs.name = attrs.id
148 input attrs
149
150 ck.render(template, title: 'Log In', hardcode: helpers)
151
152Precompiling to functions:
153
154 template = ck.compile(template, locals: yes, hardcode: {zig: 'zag'})
155
156 template(foo: 'bar', locals: {ping: 'pong'})
157
158With [express](http://expressjs.com):
159
160 app.set 'view engine', 'coffee'
161 app.register '.coffee', require('coffeecup').adapters.express
162
163 app.get '/', (req, res) ->
164 # Will render views/index.coffee:
165 res.render 'index', foo: 'bar'
166
167With [zappa](http://github.com/mauricemach/zappa):
168
169 get '/': ->
170 @franks = ['miller', 'oz', 'sinatra', 'zappa']
171 render 'index'
172
173 view index: ->
174 for name in @franks
175 a href: "http://en.wikipedia.org/wiki/Frank_#{name}", -> name
176
177With [meryl](https://github.com/kadirpekel/meryl/tree/master/examples/coffeekup-template):
178
179 coffeekup = require 'coffeecup'
180
181 meryl.get '/', (req, resp) ->
182 people = ['bob', 'alice', 'meryl']
183 resp.render 'layout', content: 'index', context: {people: people}
184
185 meryl.run
186 templateExt: '.coffee'
187 templateFunc: coffeecup.adapters.meryl
188
189On the browser:
190
191 <script src="template.js"></script>
192 <script>
193 $('body').append(templates.template({foo: 'bar'}));
194 </script>
195
196This is one of many browser deployment possibilities, pre-compiling your template on the server to a standalone function. To see all serving suggestions, check out [regular](http://github.com/gradus/coffeecup/blob/master/examples/browser/regular/index.html), [decaf](http://github.com/gradus/coffeecup/blob/master/examples/browser/decaf/index.html) and [crème](http://github.com/gradus/coffeecup/blob/master/examples/browser/creme/index.html).
197
198Command-line:
199
200 $ coffeecup -h
201
202 Usage:
203 coffeecup [options] path/to/template.coffee
204
205 --js compile template to js function
206 -n, --namespace global object holding the templates (default: "templates")
207 -w, --watch watch templates for changes, and recompile
208 -o, --output set the directory for compiled html
209 -p, --print print the compiled html to stdout
210 -f, --format apply line breaks and indentation to html output
211 -u, --utils add helper locals (currently only "render")
212 -v, --version display CoffeeKup version
213 -h, --help display this help message
214
215See [/examples](http://github.com/gradus/coffeekup/tree/master/examples) for complete versions (you have to run `cake build` first).
216
217Please note that even though all examples are given in CoffeeScript, you can also use their plain JavaScript counterparts just fine.
218
219## Resources
220
221- [API reference](https://github.com/gradus/coffeekup/blob/master/docs/reference.md)
222
223- [Mailing list](https://groups.google.com/group/coffeekup)
224
225- [Issues](https://github.com/gradus/coffeecup/issues)
226
227- **IRC**: #coffeekup on irc.freenode.net
228
229- [A Beginners's Introduction to CoffeeKup](https://github.com/mark-hahn/coffeekup-intro)
230
231## Tools
232
233- [html2coffeekup](https://github.com/brandonbloom/html2coffeekup) - Converts HTML to CoffeeKup templates.
234
235- [htmlkup](https://github.com/colinta/htmlkup) - Another HTML converter, stdin/stdout based.
236
237- [ice](https://github.com/ludicast/ice) - CoffeeKup and Eco in Rails ([screencast](http://vimeo.com/25907220)).
238
239- [coffee-world](https://github.com/khoomeister/coffee-world) - Tool to watch and compile HTML with CoffeeKup, CSS with coffee-css and JS with CoffeeScript.
240
241- [cupcake](https://github.com/twilson63/cupcake) - Express app generator with CoffeeKup support.
242
243## Related projects
244
245- [ck](https://github.com/aeosynth/ck) - "a smaller, faster coffeekup": Alternative, barebones implementation.
246
247- [ckup](https://github.com/satyr/ckup) - "Markup as Coco": Similar engine but for [Coco](https://github.com/satyr/coco) ("Unfancy CoffeeScript").
248
249- [Eco](https://github.com/sstephenson/eco) - "Embedded CoffeeScript templates": "EJS/ERB" for CoffeeScript.
250
251- [timbits](https://github.com/Postmedia/timbits) - "Widget framework based on Express and CoffeeScript".
252
253- [coffee-css](https://github.com/khoomeister/coffee-css) - "More CSS for CoffeeScript".
254
255- [ccss](https://github.com/aeosynth/ccss) - "CoffeeScript CSS".
256
257## Compatibility
258
259Latest version tested with node 0.4.9 and CoffeeScript 1.1.1.
260
261## Special thanks
262
263 - [Jeremy Ashkenas](https://github.com/jashkenas), for the amazing CoffeeScript language.
264 - [why the lucky stiff](Why_the_lucky_stiff), for the inspiration.