Home

Awesome

CoffeeKup <☕/>

Markup as CoffeeScript

CoffeeKup is a templating engine for node.js and browsers that lets you to write your HTML templates in 100% pure CoffeeScript.

It was created in celebration of whyday, as an application of the concept used in Markaby ("Markup as Ruby", by Tim Fletcher and why the lucky stiff) to CoffeeScript.

Here's what a template written for CoffeeKup looks like:

doctype 5
html ->
  head ->
    meta charset: 'utf-8'
    title "#{@title or 'Untitled'} | A completely plausible website"
    meta(name: 'description', content: @description) if @description?
    
    link rel: 'stylesheet', href: '/css/app.css'
    
    style '''
      body {font-family: sans-serif}
      header, nav, section, footer {display: block}
    '''
    
    script src: '/js/jquery.js'
    
    coffeescript ->
      $(document).ready ->
        alert 'Alerts suck!'
  body ->
    header ->
      h1 @title or 'Untitled'
      
      nav ->
        ul ->
          (li -> a href: '/', -> 'Home') unless @path is '/'
          li -> a href: '/chunky', -> 'Bacon!'
          switch @user.role
            when 'owner', 'admin'
              li -> a href: '/admin', -> 'Secret Stuff'
            when 'vip'
              li -> a href: '/vip', -> 'Exclusive Stuff'
            else
              li -> a href: '/commoners', -> 'Just Stuff'

    div '#myid.myclass.anotherclass', style: 'position: fixed', ->
      p 'Divitis kills! Inline styling too.'

    section ->
      # A helper function you built and included.
      breadcrumb separator: '>', clickable: yes
      
      h2 "Let's count to 10:"
      p i for i in [1..10]
      
      # Another hypothetical helper.
      form_to @post, ->
        textbox '#title', label: 'Title:'
        textbox '#author', label: 'Author:'
        submit 'Save'

    footer ->
      # CoffeeScript comments. Not visible in the output document.
      comment 'HTML comments.'
      p 'Bye!'

Interactive demo at coffeekup.org.

_why?

Why not?

CoffeeKup may not be your best choice in those cases:

Installing

Just grab node.js and npm and you're set:

npm install coffeekup

To get the coffeekup command, install it globally:

npm install coffeekup -g

Or to use the latest version:

git clone git@github.com:mauricemach/coffeekup.git && cd coffeekup
cake build
npm link
cd ~/myproject
npm link coffeekup

Using

ck = require 'coffeekup'

ck.render -> h1 "You can feed me templates as functions."
ck.render "h1 'Or strings. I am not too picky.'"

Defining variables:

template = ->
  h1 @title
  form method: 'post', action: 'login', ->
    textbox id: 'username'
    textbox id: 'password'
    button @title

helpers =
  textbox: (attrs) ->
    attrs.type = 'text'
    attrs.name = attrs.id
    input attrs

ck.render(template, title: 'Log In', hardcode: helpers)

Precompiling to functions:

template = ck.compile(template, locals: yes, hardcode: {zig: 'zag'})

template(foo: 'bar', locals: {ping: 'pong'})

With express:

app.set 'view engine', 'coffee'
app.register '.coffee', require('coffeekup').adapters.express

app.get '/', (req, res) ->
  # Will render views/index.coffee:
  res.render 'index', foo: 'bar'

With zappa:

get '/': ->
  @franks = ['miller', 'oz', 'sinatra', 'zappa']
  render 'index'

view index: ->
  for name in @franks
    a href: "http://en.wikipedia.org/wiki/Frank_#{name}", -> name

With meryl:

coffeekup = require 'coffeekup'

meryl.get '/', (req, resp) ->
  people = ['bob', 'alice', 'meryl']
  resp.render 'layout', content: 'index', context: {people: people}

meryl.run
  templateExt: '.coffee'
  templateFunc: coffeekup.adapters.meryl

On the browser:

<script src="template.js"></script>
<script>
  $('body').append(templates.template({foo: 'bar'}));
</script>

This 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, decaf and crème.

Command-line:

$ coffeekup -h

Usage:
  coffeekup [options] path/to/template.coffee

      --js           compile template to js function
  -n, --namespace    global object holding the templates (default: "templates")
  -w, --watch        watch templates for changes, and recompile
  -o, --output       set the directory for compiled html
  -p, --print        print the compiled html to stdout
  -f, --format       apply line breaks and indentation to html output
  -u, --utils        add helper locals (currently only "render")
  -v, --version      display CoffeeKup version
  -h, --help         display this help message

See /examples for complete versions (you have to run cake build first).

Please note that even though all examples are given in CoffeeScript, you can also use their plain JavaScript counterparts just fine.

Resources

Tools

Related projects

Compatibility

Latest version tested with node 0.4.9 and CoffeeScript 1.1.1.

Special thanks