21 avr. 2014

Meteor walktrough: Samples from JSConf 2013

Introduction

Meteor is a full stack JS framework: JS is used on the server side as well as on the client side. This allows a code mutualisation between this generally separated world. Meteor really shines in its way of handling this mutualisation. It allows you to specify where your code will be used. It relies on a Node and MongoDB.

In October 2013, Emily Stark, one of the core developper behind Meteor, has presented at the Asia JSConf 2013 a nice tutorial. I simply provides hereafter the transformed files in CoffeeScript, Jade and Stylus that will help you out understanding and playing with it while watching the associated video:

Settings

First, you need a running installation of MongoDB and Node. On OSX, it is done using Homebrew:
brew install mongodb node
Now, it is time to import Meteor:
curl https://install.meteor.com/ | sh
Note: The regular installation through NPM does not import the sample application for the generators. Therefore, I recommend using the regular automated shell script.

Meteor comes with an handy package management named Meteorite and its official repository Atmosphere. In essence, its purpose is to handle all packages that merges the world of the server side, NPM, and the world of the client, Bower. It is installed as regular Node package:
npm install -g meteorite

Preparing the playground

Now create a sample app:
mrt create JsConfAsia
cd JsConfAsia
Remove unused package and add some nice other ones:
mrt remove autopublish
mrt add meteor-jade
mrt add meteor-coffeescript
mrt add meteor-bootstrap-3
mrt add meteor-stylus
Just remove the created file, that we are going to recreate:
rm JsConfAsia.*

Replacing the files

Now, in order to better follow the nice video, I propose you this set  of simple file:
  1. JsConfAsia.styl
    body
      font-family: Helvetica, Arial, sans-serif
    p
      margin: 0
      padding: 0
    li
      padding-bottom: 5px
    
  2. JsConfAsia.jade.html
    head
      title JsConfAsia
    body
      .container
        +header
        +talksList
    
    template(name='header')
      h2 Judge jsconf.asia talks
      h3 Be ruthless
    
    template(name='talksList')
      ul
        each talks
          li
            p: <strong>#{title}</strong> by #{speaker} (#{votes} votes)
            .btn-group.btn-group-sm
              button.btn.btn-success.upvote
                <span class="glyphicon glyphicon-thumbs-up"></span> +1
              button.btn.btn-danger.downvote
                <span class="glyphicon glyphicon-thumbs-down"></span> -1
    
  3. JsConfAsia.jade.html
    Talks = new Meteor.Collection 'talks'
    
    Meteor.methods
      upvote: (talkId) ->
        talk = Talks.findOne talkId
        Talks.update talkId, {$set: {votes: talk.votes + 1}}
      downvote: (talkId) ->
        talk = Talks.findOnedOne talkId
        if talk.votes isnt 0
          Talks.update talkId, {$set: {votes: talk.votes - 1}}
    
    if Meteor.isServer
      Meteor.publish 'talks', ->
        Talks.find()
    else if Meteor.isClient
      Meteor.subscribe 'talks'
      Template.talksList.talks = ->
        Talks.find {}, {sort: {votes: -1}}
      Template.talksList.events
        'click .upvote': ->
          Meteor.call 'upvote', @_id
        'click .downvote': ->
          Meteor.call 'downvote', @_id

Adding some sample data into MongoDB

Meteor eases the use of MongoDB shell with this little command:
mrt mongo
Now, simply cut and paste the following value:
db.talks.insert({title: "Clone Toy Story in 24h with CSS", speaker: "Lea Verou", votes: 0});
db.talks.insert({title: "Enhance! Enhance!", speaker: "That Adobe guy", votes: 0});
db.talks.insert({title: "Templates: the child of Satan", speaker: "Peter Hunt", votes: 0});
To exit and come back to your shell CLI, hit the classic key stroke: ctrl+c.

Execute Meteor

Just execute the basic command:
mrt
And open your browser of choice on http://localhost:3000.

This should provide the following reactive and multi-users web app in less than 100 lines of codes:
Classy!