165
TITANIUM DEVELOPMENT WITH COFFEESCRIPT, COMPASS, AND SASS Accelerated WYNNNETHERLAND

Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Embed Size (px)

DESCRIPTION

JavaScript and Titanium's JavaScript Stylesheets would be the quickest way to develop native mobile applications if it weren't for CoffeeScript and Sass. This talk will show you how to speed up your dev cycles and use CoffeeScript and Sass not only to write code faster, but better organize your JavaScript and JSS.

Citation preview

Page 1: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

TITANIUM DEVELOPMENT WITHCOFFEESCRIPT, COMPASS, AND SASS

Accelerated

WYNNNETHERLAND

Page 2: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

$ whoami

Page 5: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Mobile?Web?Both?

Page 6: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Nice to meet ya.

Page 7: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

PIXELS I'VE PUSHEDWith some very talented folks.

Page 8: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 9: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 11: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 12: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 13: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 14: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Titanium powered kiosk!

Page 15: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 16: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 17: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

TITANIUM STACKA polyglot's

Page 18: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

COFFEESCRIPT

Page 19: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

It's still just JavaScript.

Page 20: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

var foo = function () {

}foo = () ->

I’d rather write this.JAVASCRIPT COFFEESCRIPT

Page 21: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

var button = Titanium.UI.createButton({ title: 'I am a Button', height: 40, width: 200, top: 10});

button.addEventListener('click', function(e) { alert("Oooh, that tickles!");});

JAVASCRIPT

Page 22: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10

button.addEventListener 'click', (e) -> alert "Oooh, that tickles!"

COFFEESCRIPT

Page 23: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

It's about more than aesthetics

; { }For me,

Page 24: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Some of my favorite features...

Page 25: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

for own key, value of query uri += "#{ key }=#{ escape(value) }&"

COFFEESCRIPT

var key, value;var __hasProp = Object.prototype.hasOwnProperty;for (key in query) { if (!__hasProp.call(query, key)) continue; value = query[key]; uri += "" + key + "=" + (escape(value)) + "&";}

JAVASCRIPT

Page 26: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

for own key, value of query uri += "#{ key }=#{ escape(value) }&"

COFFEESCRIPT

Comprehensions

Page 27: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

for own key, value of query uri += "#{ key }=#{ escape(value) }&"

COFFEESCRIPT

Interpolation

Page 28: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

courseButtonSubhead = Ti.UI.createLabel className: 'optRowSubhead' text: "#{GolfStatus.App.currentGame?.green?.name}"

COFFEESCRIPT

The Existential Operator

Page 29: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

class GolfStatus.Models.Game

constructor: (@owner, @course, @playingFor='brag', @scoringFormat='low_net') -> @players = {} @addPlayer @owner if @owner @green = @course.greens[0] if @course @currentHole = 1 @maxHolePlayed = 1

# elsewheregame = new GolfStatus.Models.Game(...)

COFFEESCRIPT

Simple inheritance pattern

Page 30: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

class GolfStatus.Models.Game

constructor: (@owner, @course, @playingFor='brag', @scoringFormat='low_net') -> @players = {} @addPlayer @owner if @owner @green = @course.greens[0] if @course @currentHole = 1 @maxHolePlayed = 1

COFFEESCRIPT

@

Page 31: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

class GolfStatus.Models.Game

constructor: (@owner, @course, @playingFor='brag', @scoringFormat='low_net') -> @players = {} @addPlayer @owner if @owner @green = @course.greens[0] if @course @currentHole = 1 @maxHolePlayed = 1

COFFEESCRIPT

Default values

Page 32: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

class GolfStatus.Models.Game

constructor: (@owner, @course, @playingFor='brag', @scoringFormat='low_net') -> @players = {} @addPlayer @owner if @owner @green = @course.greens[0] if @course @currentHole = 1 @maxHolePlayed = 1

COFFEESCRIPT

More human conditionals

Page 33: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

GolfStatus.Models.Game::PlayingForTypes = brag: 'Bragging Rights' cash: 'Status Cash'

GolfStatus.Models.Game::ScoringFormats = low_net: 'Low Net' low_grows: 'Low Gross'

COFFEESCRIPT

Easy object.prototype

Page 34: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

noticeHTML =''' <html> <head></head> <body> '''noticeHTML += "<div>#{noticeText}</div>"noticeHTML += ''' </body> </html> '''

COFFEESCRIPT

Heredocs

Page 35: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Because string building sucks.

Page 36: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

And so much more.

Page 37: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

http://wynn.fm/2Y

Page 39: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

STYLESHEETS

Page 40: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Are you using JSS?

Page 41: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

JSS works like CSS.

Page 42: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Why do we have CSS?

Page 43: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

content

presentation

<ul class='wynning'> <li class='logo-mark'> <a href='/about'>Wynn Netherland</a> on design, development, and general geekery. </li> <li> <a class='gowalla' href='http://gowalla.com/pengwynn'>Gowalla</a> </li> <li> <a class='facebook' href='http://facebook.com/pengwynn'>Facebook</a> </li> <li> <a class='dribbble' href='http://dribbble.com/pengwynn'>Dribbble</a> </li> <li> <a class='linked-in' href='http://linkedin.com/in/netherland'>LinkedIn</a> </li> <li> <a class='github' href='http://github.com/pengwynn'>GitHub</a> </li> <li> <a class='twitter' href='http://twitter.com/pengwynn'>Twitter</a> </li>

...

✂You gotta keep 'em separated.

Page 44: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

A example

Page 45: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

var buttonOne = Titanium.UI.createButton({ title:'I am a Button', height:40, width:200, top:10});

var buttonTwo = Titanium.UI.createButton({ title:'I am also a Button', image:'../images/chat.png', width:200, height:40, top:60});

JAVASCRIPT

Page 46: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

var buttonOne = Titanium.UI.createButton({ title:'I am a Button', height:40, width:200, top:10});

var buttonTwo = Titanium.UI.createButton({ title:'I am also a Button', image:'../images/chat.png', width:200, height:40, top:60});

Presentation

JAVASCRIPT

Page 47: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne { title:'I am a Button'; width:200; height:40; top:10}#buttonTwo { title:'I am also a Button'; image:'../images/chat.png'; width:200; height:40; top:60}.button { height: 40; width: 200;}

var buttonOne = Titanium.UI.createButton({ id: "buttonOne", className: "button"});

var buttonTwo = Titanium.UI.createButton({ id: "buttonTwo", className: "button"});

Behavior and composition in

Presentation in

.js

.jss

JSS

JAVASCRIPT

Page 48: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne { title:'I am a Button'; width:200; height:40; top:10}#buttonTwo { title:'I am also a Button'; image:'../images/chat.png'; width:200; height:40; top:60}.button { height: 40; width: 200;}

var buttonOne = Titanium.UI.createButton({ id: "buttonOne", className: "button"});

var buttonTwo = Titanium.UI.createButton({ id: "buttonTwo", className: "button"});

Style hooksJAVASCRIPT

JSS

Page 49: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

There's a better way to write CSS.JSS

Page 50: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

&CSS extensions &

compiler

Patterns &plugins

Page 51: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

gem install compass

Page 52: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne { title: 'I am a Button'; width: 200; height: 40; top: 10}#buttonTwo { title: 'I am also a Button'; image: '../images/chat.png'; width: 200; height: 40; top: 60}.button { height: 40; width: 200;}

Is it JSS or Sassy CSS?

Yes?JSS / SCSS

Page 53: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne title: 'I am a Button' width: 200 height: 40 top: 10

#buttonTwo title: 'I am also a Button' image: '../images/chat.png' width: 200 height: 40 top: 60

.button height: 40 width: 200

I prefer Sass' original indented, whitespace aware syntax.

SASS

Page 54: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Which do you prefer?

Page 55: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne { title: 'I am a Button'; width: 200; height: 40; top: 10}#buttonTwo { title: 'I am also a Button'; image: '../images/chat.png'; width: 200; height: 40; top: 60}.button { height: 40; width: 200;}

SCSS

Page 56: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne title: 'I am a Button' width: 200 height: 40 top: 10

#buttonTwo title: 'I am also a Button' image: '../images/chat.png' width: 200 height: 40 top: 60

.button height: 40 width: 200

SASS

Page 57: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Pick one. Or not. Mix and match.

Page 58: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Organize with partials.

Page 59: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

stylesheets├── _activity.sass├── _base.sass├── _confirmation.sass├── _course.scss├── _courses.sass├── _friends.scss├── _gameplay.sass├── _leaderboard.sass├── _leaders.sass├── _login.sass├── _requests.sass├── _tourcard.sass└── app.sass

@import 'base'@import 'login'@import 'activity'@import 'course'@import 'courses'@import 'friends'@import 'leaderboard'@import 'leaders'@import 'requests'@import 'tourcard'@import 'confirmation'@import 'gameplay'

Resources├── app.js├── app.jss...

Page 60: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

stylesheets├── _activity.sass├── _base.sass├── _confirmation.sass├── _course.scss├── _courses.sass├── _friends.scss├── _gameplay.sass├── _leaderboard.sass├── _leaders.sass├── _login.sass├── _requests.sass├── _tourcard.sass└── app.sass

@import 'base'@import 'login'@import 'activity'@import 'course'@import 'courses'@import 'friends'@import 'leaderboard'@import 'leaders'@import 'requests'@import 'tourcard'@import 'confirmation'@import 'gameplay'

Resources├── app.js├── app.jss...

Mix scss with sassif you're so inclined.

Page 61: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Don't Repeat Yourself

Page 62: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

.user-info bottom: 1 color: #333 font-size: 11 font-weight: bold height: auto left: 0 shadowColor: #fff shadowOffset-x: 0 shadowOffset-y: -1 text-align: center width: 92

SASS

Page 63: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

.user-info bottom: 1 color: #333 font: size: 11 weight: bold height: auto left: 0 shadowColor: #fff shadowOffset: x: 0 y: '-1' text-align: center width: 92

DRY it up. Nesting

SASS

Page 64: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne title: 'I am a Button' width: 200 height: 40 top: 10

#buttonTwo title: 'I am also a Button' image: '../images/chat.png' width: 200 height: 40 top: 60

.button height: 40 width: 200

SASS

Page 65: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

=button height: 40 width: 200

#buttonOne +button title: 'I am a Button' top: 10

#buttonTwo +button title: 'I am also a Button' image: '../images/chat.png' top: 60

DRY it up. Mixins

SASS

Page 66: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

=bottom-right($height: 40, $width: 200) height: $size width: $size right: 0 bottom: 0

#buttonOne +bottom-right title: 'I am a Button'

#buttonTwo +bottom-right(50, 300) title: 'I am also a Button' image: '../images/chat.png'

DRY it up. Mixins with params

SASS

Page 67: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

#buttonOne title: 'I am a Button' width: 200 height: 40 top: 10

#buttonTwo title: 'I am also a Button' image: '../images/chat.png' width: 200 height: 40 top: 60

.button height: 40 width: 200

SASS

Page 68: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

.button height: 40 width: 200

#buttonOne @extend .button title: 'I am a Button' top: 10

#buttonTwo @extend .button title: 'I am also a Button' image: '../images/chat.png' top: 60

DRY it up. @extend

SASS

Page 69: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

.button, #buttonOne, #buttonTwo { height: 40; width: 200;}

#buttonOne { title: 'I am a Button'; width: 200;}#buttonTwo { title: 'I am also a Button'; image: '../images/chat.png'; top: 60}

DRY it up. @extend

One less class in our .jsJSS

Page 70: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Craft themes with color functions.

Page 71: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

$button-base: #a7a7a7

#buttonOne color: $button-base title: "Button 1"

#buttonTwo color: $button-base title: "Button 2"

variables

SASS

Page 72: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

$button-base: #a7a7a7

#buttonOne color: $button-base title: "Button 1"

#buttonTwo color: $button-base title: "Button 2"

variables

SASS

Page 73: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

$button-base: #a7a7a7

#buttonOne color: $button-base title: "Button 1"

#buttonTwo color: darken($button-base, 20%) title: "Button 2"

color functions

SASS

Page 74: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

$button-base: #a7a7a7

#buttonOne color: $button-base title: "Button 1"

#buttonTwo color: darken($button-base, 20%) title: "Button 2"

color functions

SASS

Page 75: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

hue(#cc3) # => 60degsaturation(#cc3) # => 60%lightness(#cc3) # => 50%

adjust-hue(#cc3, 20deg) # => #9c3saturate(#cc3, 10%) # => #d9d926desaturate(#cc3, 10%) # => #bfbf40lighten(#cc3, 10%) # => #d6d65cdarken(#cc3, 10%) # => #a3a329

grayscale(#cc3) # => desaturate(#cc3, 100%) = #808080complement(#cc3) # => adjust-hue(#cc3, 180deg) = #33c

mix(#cc3, #00f) # => #e56619mix(#cc3, #00f, 10%) # => #f91405mix(#cc3, #00f, 90%) # => #d1b72d

more color functions

SASS

Page 76: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

mix(rgba(51, 255, 51, 0.75), #f00) # => rgba(178, 95, 19, 0.875)mix(rgba(51, 255, 51, 0.90), #f00) # => rgba(163, 114, 22, 0.95)

alpha(rgba(51, 255, 51, 0.75)) # => 0.75opacity(rgba(51, 255, 51, 0.75)) # => 0.75

opacify(rgba(51, 255, 51, 0.75), 0.1) # => rgba(51, 255, 51, 0.85)fade-in(rgba(51, 255, 51, 0.75), 0.1) # => rgba(51, 255, 51, 0.85)

transparentize(rgba(51, 255, 51, 0.75), 0.1) # => rgba(51, 255, 51, 0.65)fade-out(rgba(51, 255, 51, 0.75), 0.1) # => rgba(51, 255, 51, 0.65)

even more color functions

SASS

with alpha support!

Page 77: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Building a hybrid native+web app?

Page 78: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Share your stylesheet variables!

Page 79: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

No more vendor namespaces.Selector inheritance.URL helpers.So much more.

Page 80: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

I could write a book.

Page 81: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Oh wait. We did!

Page 85: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Patterns

Page 86: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Web languages. Native apps.

Page 87: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Stateful.

Page 88: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Event driven.

Page 89: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

MVC?

Page 90: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Views...

Page 91: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

... are really ViewControllers.

Page 92: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

So we create View factories...

Page 93: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

... and Model factories ...

Page 94: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

...and factories that make miniature models of factories.

Page 95: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

The Titanium WayTM

Page 96: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10

button.addEventListener 'click', (e) -> alert "Oooh, that tickles!"

COFFEESCRIPT

Look familiar?

Page 97: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

So how do you manufacture your own views?

Page 98: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Compose from other views.

Page 99: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts)

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10 window.add button

# methods say = (msg) -> alert(msg)

# event handlers button.addEventListener 'click', -> say('hello')

window

COFFEESCRIPT

Page 100: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts)

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10 window.add button

# methods say = (msg) -> alert(msg)

# event handlers button.addEventListener 'click', -> say('hello')

window

Create the factory method in the appropriate namespace.

COFFEESCRIPT

Page 101: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts)

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10 window.add button

# methods say = (msg) -> alert(msg)

# event handlers button.addEventListener 'click', -> say('hello')

window

Compose the view fromTitanium types or others ofyour own

COFFEESCRIPT

Page 102: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts)

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10 window.add button

# methods say = (msg) -> alert(msg)

# event handlers button.addEventListener 'click', -> say('hello')

window

Methods in familiar place

COFFEESCRIPT

Page 103: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts)

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10 window.add button

# methods say = (msg) -> alert(msg)

# event handlers button.addEventListener 'click', -> say('hello')

window

And event handlers...

COFFEESCRIPT

Page 104: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts)

button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10 window.add button

# methods say = (msg) -> alert(msg)

# event handlers button.addEventListener 'click', -> say('hello')

window

Return your view

COFFEESCRIPT

Page 105: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Models

Page 106: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

CoffeeScript classes

Page 107: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

class GolfStatus.Models.Game

constructor: (@owner, @course, @playingFor='brag', @scoringFormat='low_net') ->

serialize: ->

deserialize: (data) ->

save: ->

resume: ->

dataForSubmit: () ->

submit: (error) ->

...

COFFEESCRIPT

Page 108: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

API Wrappers

Page 109: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

class GolfStatus.API

# Initialize with login and password constructor: (@login, @password) ->

COFFEESCRIPT

CoffeeScript class

Page 110: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

...

# Build the full API URI for a request requestURI: (path, query={}) ->

uri = "#{GolfStatus.API_ENDPOINT}#{path}.json?" for own key, value of query uri += "#{ key }=#{ escape(value) }&"

uri

COFFEESCRIPT

URI building

Page 111: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

# Common request handling across all verbs request: (path, options, authenticated=true) -> # Default to GET options.method ?= 'GET' options.query ?= {} options.success ?= -> Ti.API.info options.error ?= -> Ti.API.error

xhr = Ti.Network.createHTTPClient() xhr.onreadystatechange = (e) -> ... # Default event handlers # Basic auth # other common stuff

...

if options.body data = JSON.stringify(options.body) Ti.API.debug data xhr.send(data) else xhr.send()

COFFEESCRIPT

HTTP Request building

Page 112: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

# High level method for GET requests get: (path, options, authenticated=true) -> options.method = 'GET' @request path, options, authenticated

# High level method for POST requests post: (path, options, authenticated=true) -> options.method = 'POST' @request path, options, authenticated

# High level method for DELETE requests delete: (path, options, authenticated=true) -> options.method = 'DELETE' @request path, options, authenticated

COFFEESCRIPT

High level methods for HTTP verbs

Page 113: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

# ### Authenticate the user ### authenticate: (options) -> Ti.API.debug "GolfStatus.API.authenticate" @get '/me', options

# ### Logout the user ### logout: (options) -> Ti.API.debug "GolfStatus.API.logout" @delete '/logout', options

# ### Forgot password forgotPassword: (email, options) -> Ti.API.debug "GolfStatus.API.forgotPassword" options.query = {} options.query.email = email @post '/passwords', options, false

# ### Convenience method to get current user info ### me: (options) -> Ti.API.debug "GolfStatus.API.me" @authenticate options

COFFEESCRIPT

Higher level API methods

Page 114: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Folder structure

Page 115: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

.├── Resources # Titanium root│   └── vendor # JavaScript frameworks├── src # CoffeeScript root│   └── golf_status # App root│   ├── models│   └── views│   ├── account # App domains│   ├── activity│   ├── courses│   ├── leaderboard│   └── play└── stylesheets # Sass

Page 116: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Stitching it all together

Page 117: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

app.js

Page 118: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

GolfStatus = Models: {} Views: Account: {} Activity: {} Courses: {} Leaderboard: {} Play: {}

Ti.include('vendor/date.js')Ti.include('vendor/underscore.js')Ti.include('golf_status.js')

GolfStatus.App.init()

COFFEESCRIPT

Page 119: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

GolfStatus = Models: {} Views: Account: {} Activity: {} Courses: {} Leaderboard: {} Play: {}

Ti.include('vendor/date.js')Ti.include('vendor/underscore.js')Ti.include('golf_status.js')

GolfStatus.App.init()

COFFEESCRIPT

Set up your namespaces

Page 120: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

GolfStatus = Models: {} Views: Account: {} Activity: {} Courses: {} Leaderboard: {} Play: {}

Ti.include('vendor/date.js')Ti.include('vendor/underscore.js')Ti.include('golf_status.js')

GolfStatus.App.init()

COFFEESCRIPT

third party frameworks

Page 121: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

GolfStatus = Models: {} Views: Account: {} Activity: {} Courses: {} Leaderboard: {} Play: {}

Ti.include('vendor/date.js')Ti.include('vendor/underscore.js')Ti.include('golf_status.js')

GolfStatus.App.init()

COFFEESCRIPT

All of our app in just one file

Page 122: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

GolfStatus = Models: {} Views: Account: {} Activity: {} Courses: {} Leaderboard: {} Play: {}

Ti.include('vendor/date.js')Ti.include('vendor/underscore.js')Ti.include('golf_status.js')

GolfStatus.App.init()

COFFEESCRIPT

Fire up the app and first window

Page 123: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Lean app.js makes for flexibility

Page 124: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Tapping through to test deep screens bites!

Page 125: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

# GolfStatus.App.init()

window = GolfStatus.Views.Play.createGameWindow()window.open()

COFFEESCRIPT

Comment out init andfire up the deepest view.

Page 126: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

make

Page 127: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

run-iphone:& @DEVICE_TYPE=iphone make run

test-iphone:& @DEVICE_TYPE=iphone make test

run-ipad:& @DEVICE_TYPE=ipad make run

test-ipad:& @DEVICE_TYPE=ipad make test

run:& @if [ "${DEVICE_TYPE}" == "" ]; then\& & echo "Please run \"make run-[iphone|ipad]\" instead.";\& & exit 1;\& fi& @mkdir -p ${PROJECT_ROOT}/${PROJECT_NAME}/Resources/test/& @echo "" > ${PROJECT_ROOT}/${PROJECT_NAME}/Resources/test/enabled.js& @make launch-titanium

http://wynn.fm/g9guilhermechapiewski (Guilherme Chapiewski)

Page 128: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

rakeI'm a Rubyist, so I speak

Page 129: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Compile

Page 130: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

def compile_sass puts "Compiling stylesheets".blue input = "stylesheets/app.sass" output = "Resources/app.jss" system "sass --compass -C -t expanded #{input} > #{output}"end

RAKEFILE

Page 131: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

def compile_coffee paths = `find src/golf_status -name '*.coffee'`.split("\n") compilation = ( puts "Compiling CoffeeScript (golf_status.js)".blue output = "Resources/golf_status.js" system "coffee --join #{output} -b -c #{paths.join(' ')}" and puts "Compiling CoffeeScript (app.js)".blue system "coffee -p --bare src/app.coffee > Resources/app.js" )

if compilation puts "Successfully compiled CoffeeScript".green else puts "Error compiling CoffeeScript".red end compilationend

RAKEFILE

Page 132: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

def compile_coffee paths = `find src/golf_status -name '*.coffee'`.split("\n") compilation = ( puts "Compiling CoffeeScript (golf_status.js)".blue output = "Resources/golf_status.js" system "coffee --join #{output} -b -c #{paths.join(' ')}" puts "Compiling CoffeeScript (app.js)".blue system "coffee -p --bare src/app.coffee > Resources/app.js" )

if compilation puts "Successfully compiled CoffeeScript".green else puts "Error compiling CoffeeScript".red end compilationend

RAKEFILE Compile App namespaces to single file

Page 133: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

def compile_coffee paths = `find src/golf_status -name '*.coffee'`.split("\n") compilation = ( puts "Compiling CoffeeScript (golf_status.js)".blue output = "Resources/golf_status.js" system "coffee --join #{output} -b -c #{paths.join(' ')}" puts "Compiling CoffeeScript (app.js)".blue system "coffee -p --bare src/app.coffee > Resources/app.js" )

if compilation puts "Successfully compiled CoffeeScript".green else puts "Error compiling CoffeeScript".red end compilationend

RAKEFILE Compile app.js which includes the app library

Page 134: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Build

Page 135: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

def build(options={}) return unless compile options[:device] ||= 'iphone' puts "Building with Titanium... (DEVICE_TYPE:#{options[:device]})".blue sh %Q{bash -c "#{TI_BUILD} run #{PROJECT_ROOT}/ #{IPHONE_SDK_VERSION} #{APP_ID} #{APP_NAME} #{APP_DEVICE}" \| perl -pe 's/^\\[DEBUG\\].*$/\\e[35m$&\\e[0m/g;s/^\\[INFO\\].*$/\\e[36m$&\\e[0m/g;s/^\\[WARN\\].*$/\\e[33m$&\\e[0m/g;s/^\\[ERROR\\].*$/\\e[31m$&\\e[0m/g;'}

end

RAKEFILE

Page 136: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

def build(options={}) return unless compile options[:device] ||= 'iphone' puts "Building with Titanium... (DEVICE_TYPE:#{options[:device]})".blue sh %Q{bash -c "#{TI_BUILD} run #{PROJECT_ROOT}/ #{IPHONE_SDK_VERSION} #{APP_ID} #{APP_NAME} #{APP_DEVICE}" \| perl -pe 's/^\\[DEBUG\\].*$/\\e[35m$&\\e[0m/g;s/^\\[INFO\\].*$/\\e[36m$&\\e[0m/g;s/^\\[WARN\\].*$/\\e[33m$&\\e[0m/g;s/^\\[ERROR\\].*$/\\e[31m$&\\e[0m/g;'}

end

RAKEFILE Build with Titanium Python command line

Page 137: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

def build(options={}) return unless compile options[:device] ||= 'iphone' puts "Building with Titanium... (DEVICE_TYPE:#{options[:device]})".blue sh %Q{bash -c "#{TI_BUILD} run #{PROJECT_ROOT}/ #{IPHONE_SDK_VERSION} #{APP_ID} #{APP_NAME} #{APP_DEVICE}" \| perl -pe 's/^\\[DEBUG\\].*$/\\e[35m$&\\e[0m/g;s/^\\[INFO\\].*$/\\e[36m$&\\e[0m/g;s/^\\[WARN\\].*$/\\e[33m$&\\e[0m/g;s/^\\[ERROR\\].*$/\\e[31m$&\\e[0m/g;'}

end

RAKEFILE

Pipe to PERL for some colored terminal goodness

Page 138: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass
Page 139: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Choose what works for you.

Page 140: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

JavaScript Frameworks

Page 141: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Underscore.jshttps://github.com/documentcloud/underscore

From Jeremy Ashkenas,the creator of CoffeeScript.

Page 142: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Don't Repeat Yourself Not Repeating Yourself

Page 143: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Ti GEM

Automating these patterns. A work in progress.

Page 144: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

gem install ti

Page 145: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Generate.

Page 146: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

ti new <name> <id> <platform>

Page 147: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

ti new codestrong-app com.codestrong.app iphone

Page 148: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

├── Coffeefile├── Guardfile├── LICENSE├── Rakefile├── Readme.mkd├── Resources│   ├── app.js│   ├── app.jss│   ├── images│   │   ├── KS_nav_ui.png│   │   └── KS_nav_views.png│   ├── lsrc.js│   └── vendor├── app│   ├── app.coffee│   └── lsrc│   ├── api.coffee│   ├── app.coffee│   ├── helpers│   │   └── application.coffee│   ├── models│   ├── stylesheets│   │   ├── app.sass│   │   └── partials│   └── views├── build├── config│   └── config.rb├── docs├── spec│   ├── app_spec.coffee│   ├── helpers│   ├── models│   └── views├── tiapp.xml└── tmp

Page 149: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

ti generate <model/controller/view> <name>

Page 150: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Golf.Views.GamePlay.createScoreCardView = (options) -> view = Ti.UI.createView (options) view

Page 151: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

ti scaffold <window/tabgroup/view> <domain> <name>

Page 152: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Compile.

Page 153: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

ti compile <all/coffee/sass>

Page 154: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Build.

Page 155: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

ti build <all/iphone/android/ipad/desktop/>

Page 157: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Get involved!

Page 158: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

We've got BIG ideas.

Page 159: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Testing.

Page 160: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Jasmine

Page 161: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

Jasminehttps://github.com/akahigeg/jasmine-titanium

Page 162: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

XIB

Page 163: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

xib2jshttps://github.com/daoki2/xib2js

Page 164: Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass

js2coffeehttp://ricostacruz.com/js2coffee/