cscj

Collection+JSON Views in CoffeeScript

npm install cscj
2 downloads in the last week
13 downloads in the last month

CoffeeScript meets Collection+JSON (cscj) Build Status

cscj is a little templating library that makes writing the Collection+JSON media type painless.

Public API

cscj = require "cscj"

view = """
@collection ->
  @href "http://example.com"
"""

fn = cscj.compile view, options
fn(locals)

Options

  • locals Local variable object
  • filename Used in exceptions
  • debug Outputs tokens and function body generated

Syntax

A collection is started by defining the root:

@collection ->

  # Collection parts go here

Collection

@collection ->

  # Let's set our `href`
  @href "http://example.com"

  # Oops there was an error!
  @error title: "Not Found!", code: "404", message: "This is not the collection your are looking for"

  # We can also specify the error type
  @error "password", title: "Invalid password": code: "400", message: "Too short"

  # We can add some links
  @link href: "http://example.com", rel: "index"
  @link href: "http://example.com/users", rel: "users"
  @link href: "http://example.com/posts", rel: "posts"

  # Add an item
  @item ->

    # Item parts go here

  # Add a query
  @query ->

    # Query parts go here

  # Add a template
  @template ->

    # Template parts go here

Item

@item ->

  # Href
  @href "http://example.com/users/1"

  # Links
  @link href: "http://example.com/users/1/photos", rel: "photos"
  @link href: "http://example.com/users/1/friends", rel: "friends"

  # Data
  @datum name: "firstName", value: "Cameron", prompt: "First Name"
  @datum name: "lastName", value: "Bytheway", prompt: "Last Name"

Query

@query ->

  # Href
  @href "http://example.com/users"

  # Rel
  @rel "users"

  # Data
  @datum name: "firstName", prompt: "First Name"
  @datum name: "lastName", prompt: "Last Name"

  # Optional

  # Encoding is defined by the extension for URI Templates
  # https://github.com/mamund/collection-json/blob/master/extensions/uri-templates.md
  @encoding "uri-template"

Template

@template ->

  # Data
  @datum name: "firstName", prompt: "First Name"
  @datum name: "lastName", prompt: "Last Name"

  # Optional

  # The following are defined by the extension for multiple templates
  # https://github.com/mamund/collection-json/blob/master/extensions/templates.md

  @href "http://example.com/users/avatar"

  @rel "avatar"

  @type "application/x-www-form-urlencoded"

  @name "avatar"

Referencing Local Variables

When we pass in locals, they are referenced as normal variables:

# example.coffee
cscj = require "cscj"

cscj.renderFile "./view.coffee", {root: "http://example.com"}, (error, collection)->
  console.log collection
# view.coffee
@collection ->

  @href root

Running this code will output:

{
   "collection":{
      "href":"http://example.com",
      "version":"1.0"
   }
}

You can also define helpers:

# example2.coffee
cscj = require "cscj"

locals =
  links: (collection)->
    collection.link rel: "index", href: "http://example.com"
    collection.link rel: "users", href: "http://example.com/users"
  root: "http://example.com"

cscj.renderFile "./view.coffee", locals, (error, collection)->
  console.log collection
# view.coffee
@collection ->

  @href root
  links @

Running this code will output:

{
   "collection":{
      "href":"http://example.com",
      "version":"1.0",
      "links": [
        { "href": "http://example.com", "rel": "index" },
        { "href": "http://example.com/users", "rel": "users" }
      ]
   }
}

Using CoffeeScript

Since the template is just CoffeeScript you can do some powerful stuff:

@collection ->
  ...
  for item in items
    @item ->

      @href item.href

      # Iterate the links in the item
      for link in item.links
        @link rel: link.rel, href: link.href

      # Iterate the keys in the item and add them to the `data` array
      for key, value of item
        @datum name: key, value: value if not (key in ["href", "links"])
  ...

Example

# views/index.coffee
@collection ->

  root = "http://localhost:5000"

  @error code: "404", message: "This is a test"

  @href root

  @link href: root, rel: "index"

  @item ->
    @href "#{root}/people/1"
    @link href: "#{root}/1/photos", rel: "photos"
    @datum name: "firstName", value: "Cameron", prompt: "First Name"
    @datum name: "lastName", value: "Bytheway", prompt: "Last Name"

  @query ->
    @href "#{root}/people"
    @rel "people"
    @datum name: "firstName", prompt: "First Name"
    @datum name: "lastName", prompt: "Last Name"

  @template ->
    @datum name: "firstName", prompt: "First Name"
    @datum name: "lastName", prompt: "Last Name"

which would render

{
   "collection":{
      "href":"http://localhost:5000",
      "version":"1.0",
      "error":{ "code":"404", "message":"This is a test" },
      "links":[
         { "href":"http://localhost:5000", "rel":"index" }
      ],
      "items":[
         {
            "href":"http://localhost:5000/people/1",
            "links":[
               { "href":"http://localhost:5000/1/photos", "rel":"photos" }
            ],
            "data":[
               { "name":"firstName", "value":"Cameron", "prompt":"First Name" },
               { "name":"lastName", "value":"Bytheway", "prompt":"Last Name" }
            ]
         }
      ],
      "queries":[
         {
            "href":"http://localhost:5000/people",
            "rel":"people",
            "data":[
               { "name":"firstName", "prompt":"First Name" },
               { "name":"lastName", "prompt":"Last Name" }
            ]
         }
      ],
      "template":{
         "data":[
            { "name":"firstName", "prompt":"First Name" },
            { "name":"lastName", "prompt":"Last Name" }
         ]
      }
   }
}

Tests

npm install -d
npm test
npm loves you