PhoneGap with HAML, SCSS, and CoffeeScript

“PhoneGap”:http://www.phonegap.com/ is an HTML application platform that runs natively on iOS. After the initial project setup, PhoneGap allows you to pretend you are just writing a web application, meaning you spend your day in HTML, CSS and javascript instead of Objective-C.

When I had the opportunity to write a PhoneGap application for a project demo, I decided to take the development process one step further and use the goodness of HAML, SCSS and CoffeeScript instead of straight HTML, CSS and javascript.

Setting up the development environment was relatively simple. I put the source code for HAML, SCSS and CoffeeScript in a similar file tree next to the www directory. I then automated the process of converting the HAML, SCSS and CoffeeScript using a file change monitor to execute conversion scripts whenever a modification occurred.

Below is the layout and tooling I used for the project.

h2. PhoneGap File Layout

├── src
│   ├── coffee_script
│   │   ├── application.coffee
│   │   └── namespace.coffee
│   ├── haml
│   │   ├── helpers.rb
│   │   ├── index.haml
│   │   └── partials
│   │       └── _home.haml
│   └── sass
│       └── main.scss
└── www
    ├── images
    ├── index.html
    ├── javascripts
    │   ├── addons
    │   │   ├── backbone-min.js
    │   │   ├── jquery-1.5.2.min.js
    │   │   └── underscore-min.js
    │   ├── application.js
    │   └── namespace.js
    ├── phonegap.0.9.4.js
    ├── phonegap.0.9.4.min.js
    └── stylesheets
        └── main.css

h2. Tools

h3. Ruby and Bundler

“Ruby”:http://www.ruby-lang.org/en/ and the ruby gem management tool, “Bundler”:http://gembundler.com/, simplified the dependency setup and scripting necessary for the development environment. Here is a copy of Bundler’s Gemfile I used on the project.

source 'http://rubygems.org'

gem 'haml'
gem 'sass'
gem 'thor'
gem 'watchr'
gem 'sinatra'
gem 'rack'

h3. Watchr

The ruby gem “Watchr”:https://github.com/mynyml/watchr monitors system files and executes a block of code when changes are detected. Watchr uses a simple DSL to configure its usage.

watch /src\/.*\.haml/ do |md| `thor convert:haml` end
watch /src\/.*\.rb/ do |md| `thor convert:haml` end
watch /src\/.*\.scss/ do |md| `thor convert:sass` end
watch /src\/.*\.sass/ do |md| `thor convert:sass` end
watch /src\/.*\.coffee/ do |md| `thor convert:coffee` end

h3. Thor

We scripted repetitive tasks using the ruby gem “Thor”:https://github.com/wycats/thor.

ROOT =  File.expand_path(File.dirname(__FILE__) + "/..")

class Convert < Thor
  desc "haml", "converts and puts haml in www"
  def haml
    `haml -r #{ROOT}/src/haml/helpers.rb #{ROOT}/src/haml/index.haml #{ROOT}/www/index.html`
  end

  desc "sass", "converts and puts sass in www"
  def sass
    `sass --update #{ROOT}/src/sass:#{ROOT}/www/stylesheets`
  end

  desc "coffee", "converts and puts coffeescript in www"
  def coffee
    `coffee -o #{ROOT}/www/javascripts -c #{ROOT}/src/coffee_script/`
  end

  desc "all", "Convert haml, sass and coffee"
  def all
    invoke :haml
    invoke :sass
    invoke :coffee
  end

  desc "watch", "Start watchr to convert haml, sass and coffee source as it is modified"
  def watch
    invoke :all
    system "cd #{ROOT} && watchr tasks/converters.watchr"
  end
end

h3. Sinatra

A PhoneGap application at its heart is mostly a web application therefore you can view and rapidly iterate the application using “Sinatra”:http://www.sinatrarb.com/, a simple web server, and your favorite web browser.

_config.ru_

$LOAD_PATH << File.expand_path(File.dirname(__FILE__))

require 'app'
run Sinatra::Application

_app.rb_

require 'sinatra'

set :public, File.dirname(__FILE__) + '/www'

h2. Additional Resources

Here are several links I found useful during my PhoneGap project.

* “Official PhoneGap Docs”:http://www.phonegap.com/docs
* “Introduction to PhoneGap tutorial”:http://mobile.tutsplus.com/tutorials/phonegap/phonegap-development/
* “Introduction to iPhone SDK Development”:http://mobile.tutsplus.com/tutorials/iphone/introduction-to-iphone-sdk-development/
* “Deploying iPhone applications (the official way)”:https://mobiforge.com/design-development/deploying-iphone-apps-real-devices
* “Safari Visual Effects How To”:http://developer.apple.com/library/safari/#codinghowtos/Mobile/GraphicsMediaAndVisualEffects/_index.html
* “Handling Retina Display in CSS”:http://webapp-net.com/Forums/viewtopic.php?id=487
* “Using Custom Fonts for iOS”:http://wiki.phonegap.com/w/page/28514708/iPad-or-iOS-4:-Use-Custom-Fonts

Conversation
  • Clever additions. You transformed your PhoneGap environment into a modern Rails environment. Pretty slick!

  • Chris Braddock says:

    SO GOOD. Thank you.

  • trans says:

    Thanks for article.

    One point. Sinatra probably isn’t needed, given that we are serving everything from “public”, running a rack file (or directory) server should do the trick. Something like config.ru:

    use Rack::Static, :urls => [“/public”]

  • william says:

    Nice ! I personally use guard with it’s sub-modules.
    I think it’s a better alternative to thor/watchr.

    I just have a question… How do you use partials ?

    I would be interrested to render templates (using icanhaz/mustache) for backbone in the single index.html file, while writing them in HAML.

    Regards

  • Any way to make this work with the scaffolding from balckbone-rails (https://github.com/codebrew/backbone-rails)?

  • Steve Batcup says:

    This was so handy, thank you so much.

  • Ben says:

    This would be more handy with the complete set of files you used. Where does the Gemfile go? What files are these Thor and Watchr commands in? Where does the Sinatra code live? A lot of little Gists is a lot less useful than a repo with everything already set up.

    As someone new to Ruby, I find that details like this are frequently missing in Ruby (and particularly Rails) tutorials. It makes it very difficult for new users to figure out what to do.

  • Comments are closed.