SlideShare uma empresa Scribd logo
1 de 165
Baixar para ler offline
TITANIUM DEVELOPMENT WITH
Accelerated

     COFFEESCRIPT, COMPASS, AND SASS




                         WYNNNETHERLAND
$ whoami
NETHERLAND
Mobile?
Web?
Both?
Nice to meet ya.
PIXELS I'VE PUSHED
With some very talented folks.
Play golf?
Find this dude and
get in on the beta.!
Titanium powered kiosk!
A polyglot's


TITANIUM STACK
COFFEESCRIPT
It's still just JavaScript.
var foo = function () {
                                foo = () ->
  }


JAVASCRIPT                  COFFEESCRIPT

                            I’d rather write this.
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
button = Titanium.UI.createButton
    title: 'I am a Button'
    height: 40
    width: 200
    top: 10



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




COFFEESCRIPT
For me,

It's about more than aesthetics




                                  ; {}
Some of my favorite features...
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
Comprehensions

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



COFFEESCRIPT
Interpolation

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



COFFEESCRIPT
The Existential Operator

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



COFFEESCRIPT
Simple inheritance pattern
  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

  # elsewhere
  game = new GolfStatus.Models.Game(...)



COFFEESCRIPT
@
  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
  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
  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
Easy object.prototype
   GolfStatus.Models.Game::PlayingForTypes =
     brag: 'Bragging Rights'
     cash: 'Status Cash'

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



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


COFFEESCRIPT
Because string building sucks.
And so much more.
http://wynn.fm/2Y
GET
THE
BOOK.

        http://wynn.fm/g8
STYLESHEETS
Are you using JSS?
JSS works like CSS.
Why do we have CSS?
<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>




                                                                                 content
  </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.

✂
                                                                           presentation
A   example
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
var buttonOne = Titanium.UI.createButton({
    title:'I am a Button',
    height:40,
    width:200,

                                  Presentation
    top:10
  });


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



JAVASCRIPT
var buttonOne = Titanium.UI.createButton({
  id: "buttonOne",                                 JAVASCRIPT
           Behavior and composition in
  className: "button"
});

var buttonTwo = Titanium.UI.createButton({
  id: "buttonTwo",
  className: "button"
});
                                                 .js
#buttonOne {
  title:'I am a Button';                                  JSS
  width:200;
  height:40;
  top:10
}
#buttonTwo {


                                        Presentation in
  title:'I am also a Button';
  image:'../images/chat.png';
  width:200;
  height:40;


                                                .jss
  top:60
}
.button {
  height: 40;
  width: 200;
}
var buttonOne = Titanium.UI.createButton({
  id: "buttonOne",                                JAVASCRIPT
  className: "button"

                                             Style hooks
});

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




#buttonOne {
  title:'I am a Button';                                 JSS
  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;
}
JSS

There's a better way to write CSS.
Patte
                                  rns &
             io n s &        plugins
  SS e xtens
C
     co mpiler

                        &
gem install compass
Is it JSS or Sassy CSS?

   #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;
   }



JSS / SCSS
                                    Yes?
I prefer Sass' original indented, whitespace aware syntax.


    #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
Which do you prefer?
#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
#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
Pick one. Or not. Mix and match.
Organize with partials.
stylesheets
├── _activity.sass
├── _base.sass
├── _confirmation.sass
├── _course.scss
├── _courses.sass
├── _friends.scss
├── _gameplay.sass
├── _leaderboard.sass
├── _leaders.sass
├── _login.sass
├── _requests.sass       @import   'base'
├── _tourcard.sass       @import   'login'
└── app.sass             @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
...
stylesheets

                         Mix scss with sass
├── _activity.sass
├── _base.sass
├── _confirmation.sass

                         if you're so inclined.
├── _course.scss
├── _courses.sass
├── _friends.scss
├── _gameplay.sass
├── _leaderboard.sass
├── _leaders.sass
├── _login.sass
├── _requests.sass            @import   'base'
├── _tourcard.sass            @import   'login'
└── app.sass                  @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
...
Don't Repeat Yourself
.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
DRY it up.               Nesting
  .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




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
DRY it up.                        Mixins
  =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




SASS
DRY it up.                          Mixins with params
  =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'




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
DRY it up.                        @extend
  .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




SASS
DRY it up.                                          @extend
      .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';


                                   One less class in our .js
        top: 60
      }




JSS
Craft themes with color functions.
variables
  $button-base: #a7a7a7

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

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




SASS
variables
  $button-base: #a7a7a7

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

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




SASS
color functions
  $button-base: #a7a7a7

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

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




SASS
color functions
  $button-base: #a7a7a7

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

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




SASS
more color functions
  hue(#cc3) # => 60deg
  saturation(#cc3) # => 60%
  lightness(#cc3) # => 50%

  adjust-hue(#cc3, 20deg) # => #9c3
  saturate(#cc3, 10%) # => #d9d926
  desaturate(#cc3, 10%) # => #bfbf40
  lighten(#cc3, 10%) # => #d6d65c
  darken(#cc3, 10%) # => #a3a329

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

  mix(#cc3, #00f) # => #e56619
  mix(#cc3, #00f, 10%) # => #f91405
  mix(#cc3, #00f, 90%) # => #d1b72d



SASS
even more color functions
  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.75
  opacity(rgba(51, 255, 51, 0.75)) # => 0.75
                                                   with alpha support!
  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)



SASS
Building a hybrid native+web app?
Share your stylesheet variables!
No more vendor namespaces.
Selector inheritance.
URL helpers.
So much more.
I could write a book.
Oh wait. We did!
Isn’t she Sassy, folks?




GET
THE
BOOK.

                        http://wynn.fm/ti-sass
Save 40% and get early access!


           sass40

Sadly, sass100 is not a valid code.




                             http://wynn.fm/ti-sass
Patterns
Web languages. Native apps.
Stateful.
Event driven.
MVC?
Views...
... are really ViewControllers.
So we create View factories...
... and Model factories ...
...and factories that make miniature
                 models of factories.
The Titanium WayTM
button = Titanium.UI.createButton
    title: 'I am a Button'
    height: 40

                             Look familiar?
    width: 200
    top: 10



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




COFFEESCRIPT
So how do you manufacture your own views?
Compose from other views.
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
MyApp.Views.createLoginWindow = (opts={}) ->

     window = Ti.UI.createWindow(opts)

     button = Titanium.UI.createButton
       title: 'I am a Button'
       height: 40
       width: 200           Create the factory method in
                              the appropriate namespace.
       top: 10
     window.add button

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

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

     window


COFFEESCRIPT
MyApp.Views.createLoginWindow = (opts={}) ->

     window = Ti.UI.createWindow(opts)

     button = Titanium.UI.createButton
       title: 'I am a Button'
       height: 40
       width: 200             Compose the view from
       top: 10
     window.add button        Titanium types or others   of
     # methods               your own
     say = (msg) ->
       alert(msg)

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

     window


COFFEESCRIPT
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    in familiar place
     # methods
     say = (msg) ->
       alert(msg)

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

     window


COFFEESCRIPT
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          And event   handlers...
     # methods
     say = (msg) ->
       alert(msg)

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

     window


COFFEESCRIPT
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            Return   your view
     # methods
     say = (msg) ->
       alert(msg)

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

     window


COFFEESCRIPT
Models
CoffeeScript classes
class GolfStatus.Models.Game

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

    serialize: ->

    deserialize: (data) ->

    save: ->

    resume: ->

    dataForSubmit: () ->

    submit: (error)   ->


   ...




COFFEESCRIPT
API Wrappers
CoffeeScript class
  class GolfStatus.API

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




COFFEESCRIPT
URI building

  ...

    # 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
HTTP Request building
    # 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
High level methods for HTTP verbs
    # 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
Higher level API methods
    # ### 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
Folder structure
.
├──   Resources                 #   Titanium root
│     └── vendor                #   JavaScript frameworks
├──   src                       #   CoffeeScript root
│     └── golf_status           #   App root
│         ├── models
│         └── views
│             ├── account       # App domains
│             ├── activity
│             ├── courses
│             ├── leaderboard
│             └── play
└──   stylesheets               # Sass
Stitching it all together
app.js
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
GolfStatus =
    Models: {}
    Views:              Set up your namespaces
      Account: {}
      Activity: {}
      Courses: {}
      Leaderboard: {}
      Play: {}

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

  GolfStatus.App.init()


COFFEESCRIPT
GolfStatus =
    Models: {}
    Views:
      Account: {}
      Activity: {}
      Courses: {}

                             third party frameworks
      Leaderboard: {}
      Play: {}

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

  GolfStatus.App.init()


COFFEESCRIPT
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()      All of our app in just one file

COFFEESCRIPT
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()   Fire up the app and first window

COFFEESCRIPT
Lean app.js makes for flexibility
Tapping through to test deep screens bites!
# GolfStatus.App.init()

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




                                  Comment out init and
                                fire up the deepest view.


COFFEESCRIPT
make
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




            guilhermechapiewski (Guilherme Chapiewski)

                                                   http://wynn.fm/g9
I'm a Rubyist, so I speak


        rake
Compile
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
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
    compilation
  end




RAKEFILE
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
    compilation
  end




RAKEFILE               Compile App namespaces to single file
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
    compilation
  end




RAKEFILE       Compile app.js which includes the app library
Build
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
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
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




        Pipe to PERL for some colored terminal goodness

RAKEFILE
Choose what works for you.
JavaScript Frameworks
Underscore.js
https://github.com/documentcloud/underscore




                     From Jeremy Ashkenas,
                   the creator of CoffeeScript.
Don't Repeat Yourself Not Repeating Yourself
Ti GEM
Automating these patterns. A work in progress.
gem install ti
Generate.
ti new <name> <id> <platform>
ti new codestrong-app com.codestrong.app iphone
├──   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
ti generate <model/controller/view> <name>
Golf.Views.GamePlay.createScoreCardView = (options) ->
  view = Ti.UI.createView (options)
  view
ti scaffold <window/tabgroup/view> <domain> <name>
Compile.
ti compile <all/coffee/sass>
Build.
ti build <all/iphone/android/ipad/desktop/>
Ti GEM

@revans               @baldrailers

            @rupakg
Get involved!
We've got BIG ideas.
Testing.
Jasmine
Jasmine
https://github.com/akahigeg/jasmine-titanium
XIB
xib2js
https://github.com/daoki2/xib2js
js2coffee
http://ricostacruz.com/js2coffee/
QUESTIONS?


http://spkr8.com/t/8342

Mais conteúdo relacionado

Mais procurados

Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is AwesomeAstrails
 
What we can learn from WordPress as a developer
What we can learn from WordPress as a developerWhat we can learn from WordPress as a developer
What we can learn from WordPress as a developerChandra Maharzan
 
Google Visualization API
Google  Visualization  APIGoogle  Visualization  API
Google Visualization APIJason Young
 
WordPress 3.4 Theme Customizer
WordPress 3.4 Theme CustomizerWordPress 3.4 Theme Customizer
WordPress 3.4 Theme CustomizerChandra Maharzan
 
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingYury Chemerkin
 
Ufind proxo(cucurhatan).cfg
Ufind proxo(cucurhatan).cfgUfind proxo(cucurhatan).cfg
Ufind proxo(cucurhatan).cfgAhmad Hidayat
 
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridasFrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridasLoiane Groner
 
JS.Chi CSS Animations
JS.Chi CSS AnimationsJS.Chi CSS Animations
JS.Chi CSS AnimationsJustin Meyer
 
Acceptance Testing with Webrat
Acceptance Testing with WebratAcceptance Testing with Webrat
Acceptance Testing with WebratLuismi Cavallé
 
Node meetup feb_20_12
Node meetup feb_20_12Node meetup feb_20_12
Node meetup feb_20_12jafar104
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingFabio Akita
 
Beyond the Final Frontier of jQuery Selectors
Beyond the Final Frontier of jQuery SelectorsBeyond the Final Frontier of jQuery Selectors
Beyond the Final Frontier of jQuery SelectorsAlexander Shopov
 
قالب المواضيع
قالب المواضيعقالب المواضيع
قالب المواضيعkhaliled
 

Mais procurados (20)

Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is Awesome
 
What we can learn from WordPress as a developer
What we can learn from WordPress as a developerWhat we can learn from WordPress as a developer
What we can learn from WordPress as a developer
 
Google Visualization API
Google  Visualization  APIGoogle  Visualization  API
Google Visualization API
 
WordPress 3.4 Theme Customizer
WordPress 3.4 Theme CustomizerWordPress 3.4 Theme Customizer
WordPress 3.4 Theme Customizer
 
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
 
Ufind proxo(cucurhatan).cfg
Ufind proxo(cucurhatan).cfgUfind proxo(cucurhatan).cfg
Ufind proxo(cucurhatan).cfg
 
Convidar para page !!
Convidar para page !!Convidar para page !!
Convidar para page !!
 
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridasFrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
FrontInBahia 2014: 10 dicas de desempenho para apps mobile híbridas
 
Python 1
Python 1Python 1
Python 1
 
JS.Chi CSS Animations
JS.Chi CSS AnimationsJS.Chi CSS Animations
JS.Chi CSS Animations
 
Emmet cheat-sheet
Emmet cheat-sheetEmmet cheat-sheet
Emmet cheat-sheet
 
Canvas - The Cure
Canvas - The CureCanvas - The Cure
Canvas - The Cure
 
Acceptance Testing with Webrat
Acceptance Testing with WebratAcceptance Testing with Webrat
Acceptance Testing with Webrat
 
Node meetup feb_20_12
Node meetup feb_20_12Node meetup feb_20_12
Node meetup feb_20_12
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
Daily notes
Daily notesDaily notes
Daily notes
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented Programming
 
Beyond the Final Frontier of jQuery Selectors
Beyond the Final Frontier of jQuery SelectorsBeyond the Final Frontier of jQuery Selectors
Beyond the Final Frontier of jQuery Selectors
 
Potential Friend Finder
Potential Friend FinderPotential Friend Finder
Potential Friend Finder
 
قالب المواضيع
قالب المواضيعقالب المواضيع
قالب المواضيع
 

Destaque

CoffeeScriptってなんぞ?
CoffeeScriptってなんぞ?CoffeeScriptってなんぞ?
CoffeeScriptってなんぞ?Hayato Mizuno
 
Introduction to CoffeeScript
Introduction to CoffeeScriptIntroduction to CoffeeScript
Introduction to CoffeeScriptStalin Thangaraj
 
Happy Programming with CoffeeScript
Happy Programming with CoffeeScriptHappy Programming with CoffeeScript
Happy Programming with CoffeeScriptEddie Kao
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overviewjeresig
 
Web Development with CoffeeScript and Sass
Web Development with CoffeeScript and SassWeb Development with CoffeeScript and Sass
Web Development with CoffeeScript and SassBrian Hogan
 
Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design PatternsAddy Osmani
 
JavaScript - An Introduction
JavaScript - An IntroductionJavaScript - An Introduction
JavaScript - An IntroductionManvendra Singh
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Scalable JavaScript Application Architecture
Scalable JavaScript Application ArchitectureScalable JavaScript Application Architecture
Scalable JavaScript Application ArchitectureNicholas Zakas
 
JavaScript Programming
JavaScript ProgrammingJavaScript Programming
JavaScript ProgrammingSehwan Noh
 

Destaque (11)

CoffeeScriptってなんぞ?
CoffeeScriptってなんぞ?CoffeeScriptってなんぞ?
CoffeeScriptってなんぞ?
 
Introduction to CoffeeScript
Introduction to CoffeeScriptIntroduction to CoffeeScript
Introduction to CoffeeScript
 
Happy Programming with CoffeeScript
Happy Programming with CoffeeScriptHappy Programming with CoffeeScript
Happy Programming with CoffeeScript
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
 
Web Development with CoffeeScript and Sass
Web Development with CoffeeScript and SassWeb Development with CoffeeScript and Sass
Web Development with CoffeeScript and Sass
 
Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design Patterns
 
JavaScript - An Introduction
JavaScript - An IntroductionJavaScript - An Introduction
JavaScript - An Introduction
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Scalable JavaScript Application Architecture
Scalable JavaScript Application ArchitectureScalable JavaScript Application Architecture
Scalable JavaScript Application Architecture
 
JavaScript Programming
JavaScript ProgrammingJavaScript Programming
JavaScript Programming
 
Javascript Best Practices
Javascript Best PracticesJavascript Best Practices
Javascript Best Practices
 

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

Accelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemAccelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemWynn Netherland
 
CSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the BackendCSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the BackendFITC
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybarafatec
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybarafatec
 
The things browsers can do! SAE Alumni Convention 2014
The things browsers can do! SAE Alumni Convention 2014The things browsers can do! SAE Alumni Convention 2014
The things browsers can do! SAE Alumni Convention 2014Christian Heilmann
 
Implementing Awesome: An HTML5/CSS3 Workshop
Implementing Awesome: An HTML5/CSS3 WorkshopImplementing Awesome: An HTML5/CSS3 Workshop
Implementing Awesome: An HTML5/CSS3 WorkshopShoshi Roberts
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...Codemotion
 
2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript SecurityJohannes Hoppe
 
Rapid Prototyping
Rapid PrototypingRapid Prototyping
Rapid PrototypingEven Wu
 
Drawing on canvas
Drawing on canvasDrawing on canvas
Drawing on canvassuitzero
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02PL dream
 
Yes, browsers can do that! Hybrid and future web meetup at Jayway
Yes, browsers can do that! Hybrid and future web meetup at JaywayYes, browsers can do that! Hybrid and future web meetup at Jayway
Yes, browsers can do that! Hybrid and future web meetup at JaywayChristian Heilmann
 
Let jQuery Rock Your World
Let jQuery Rock Your WorldLet jQuery Rock Your World
Let jQuery Rock Your WorldMatt Gifford
 
CSS3 Takes on the World
CSS3 Takes on the WorldCSS3 Takes on the World
CSS3 Takes on the WorldJonathan Snook
 

Semelhante a Wynn Netherland: Accelerating Titanium Development with CoffeeScript, Compass, and Sass (20)

Accelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gemAccelerated Native Mobile Development with the Ti gem
Accelerated Native Mobile Development with the Ti gem
 
CSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the BackendCSS: A Slippery Slope to the Backend
CSS: A Slippery Slope to the Backend
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybara
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybara
 
Borrador del blog
Borrador del blogBorrador del blog
Borrador del blog
 
The things browsers can do! SAE Alumni Convention 2014
The things browsers can do! SAE Alumni Convention 2014The things browsers can do! SAE Alumni Convention 2014
The things browsers can do! SAE Alumni Convention 2014
 
Implementing Awesome: An HTML5/CSS3 Workshop
Implementing Awesome: An HTML5/CSS3 WorkshopImplementing Awesome: An HTML5/CSS3 Workshop
Implementing Awesome: An HTML5/CSS3 Workshop
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
Massimo Artizzu - The tricks of Houdini: a magic wand for the future of CSS -...
 
2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security
 
Rapid Prototyping
Rapid PrototypingRapid Prototyping
Rapid Prototyping
 
Drawing on canvas
Drawing on canvasDrawing on canvas
Drawing on canvas
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
 
Yes, browsers can do that! Hybrid and future web meetup at Jayway
Yes, browsers can do that! Hybrid and future web meetup at JaywayYes, browsers can do that! Hybrid and future web meetup at Jayway
Yes, browsers can do that! Hybrid and future web meetup at Jayway
 
Let jQuery Rock Your World
Let jQuery Rock Your WorldLet jQuery Rock Your World
Let jQuery Rock Your World
 
Accelerated Stylesheets
Accelerated StylesheetsAccelerated Stylesheets
Accelerated Stylesheets
 
Codigo taller-plugins
Codigo taller-pluginsCodigo taller-plugins
Codigo taller-plugins
 
Lettering js
Lettering jsLettering js
Lettering js
 
CSS3 Takes on the World
CSS3 Takes on the WorldCSS3 Takes on the World
CSS3 Takes on the World
 

Mais de Axway Appcelerator

Axway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & Roadmap
Axway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & RoadmapAxway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & Roadmap
Axway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & RoadmapAxway Appcelerator
 
2014 Dublin Web Summit by Jeff Haynie
2014 Dublin Web Summit by Jeff Haynie2014 Dublin Web Summit by Jeff Haynie
2014 Dublin Web Summit by Jeff HaynieAxway Appcelerator
 
Stop Debating, Start Measuring
Stop Debating, Start MeasuringStop Debating, Start Measuring
Stop Debating, Start MeasuringAxway Appcelerator
 
Mobile & The New Experience Economy (And What it Means for IT)
Mobile & The New Experience Economy  (And What it Means for IT)Mobile & The New Experience Economy  (And What it Means for IT)
Mobile & The New Experience Economy (And What it Means for IT)Axway Appcelerator
 
Apps, APIs & Analytics: What "Mobile First" Really Means
Apps, APIs & Analytics: What "Mobile First" Really MeansApps, APIs & Analytics: What "Mobile First" Really Means
Apps, APIs & Analytics: What "Mobile First" Really MeansAxway Appcelerator
 
Appcelerator Presentation Template
Appcelerator Presentation TemplateAppcelerator Presentation Template
Appcelerator Presentation TemplateAxway Appcelerator
 
Codestrong 2012 keynote jonathan rende, appcelerator's vp of products
Codestrong 2012 keynote   jonathan rende, appcelerator's vp of productsCodestrong 2012 keynote   jonathan rende, appcelerator's vp of products
Codestrong 2012 keynote jonathan rende, appcelerator's vp of productsAxway Appcelerator
 
Codestrong 2012 keynote jeff haynie, appcelerator's ceo
Codestrong 2012 keynote   jeff haynie, appcelerator's ceoCodestrong 2012 keynote   jeff haynie, appcelerator's ceo
Codestrong 2012 keynote jeff haynie, appcelerator's ceoAxway Appcelerator
 
Codestrong 2012 keynote how to build a top ten app
Codestrong 2012 keynote   how to build a top ten appCodestrong 2012 keynote   how to build a top ten app
Codestrong 2012 keynote how to build a top ten appAxway Appcelerator
 
Codestrong 2012 breakout session at&t api platform and trends
Codestrong 2012 breakout session  at&t api platform and trendsCodestrong 2012 breakout session  at&t api platform and trends
Codestrong 2012 breakout session at&t api platform and trendsAxway Appcelerator
 
Codestrong 2012 breakout session what's new in titanium studio
Codestrong 2012 breakout session   what's new in titanium studioCodestrong 2012 breakout session   what's new in titanium studio
Codestrong 2012 breakout session what's new in titanium studioAxway Appcelerator
 
Codestrong 2012 breakout session using appcelerator cloud services in your ...
Codestrong 2012 breakout session   using appcelerator cloud services in your ...Codestrong 2012 breakout session   using appcelerator cloud services in your ...
Codestrong 2012 breakout session using appcelerator cloud services in your ...Axway Appcelerator
 
Codestrong 2012 breakout session the role of cloud services in your next ge...
Codestrong 2012 breakout session   the role of cloud services in your next ge...Codestrong 2012 breakout session   the role of cloud services in your next ge...
Codestrong 2012 breakout session the role of cloud services in your next ge...Axway Appcelerator
 
Codestrong 2012 breakout session new device platform support for titanium
Codestrong 2012 breakout session   new device platform support for titaniumCodestrong 2012 breakout session   new device platform support for titanium
Codestrong 2012 breakout session new device platform support for titaniumAxway Appcelerator
 
Codestrong 2012 breakout session mobile platform and infrastructure
Codestrong 2012 breakout session   mobile platform and infrastructureCodestrong 2012 breakout session   mobile platform and infrastructure
Codestrong 2012 breakout session mobile platform and infrastructureAxway Appcelerator
 
Codestrong 2012 breakout session making money on appcelerator's marketplace
Codestrong 2012 breakout session   making money on appcelerator's marketplaceCodestrong 2012 breakout session   making money on appcelerator's marketplace
Codestrong 2012 breakout session making money on appcelerator's marketplaceAxway Appcelerator
 
Codestrong 2012 breakout session live multi-platform testing
Codestrong 2012 breakout session   live multi-platform testingCodestrong 2012 breakout session   live multi-platform testing
Codestrong 2012 breakout session live multi-platform testingAxway Appcelerator
 
Codestrong 2012 breakout session leveraging titanium as part of your mobile...
Codestrong 2012 breakout session   leveraging titanium as part of your mobile...Codestrong 2012 breakout session   leveraging titanium as part of your mobile...
Codestrong 2012 breakout session leveraging titanium as part of your mobile...Axway Appcelerator
 
Codestrong 2012 breakout session i os internals and best practices
Codestrong 2012 breakout session   i os internals and best practicesCodestrong 2012 breakout session   i os internals and best practices
Codestrong 2012 breakout session i os internals and best practicesAxway Appcelerator
 

Mais de Axway Appcelerator (20)

Axway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & Roadmap
Axway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & RoadmapAxway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & Roadmap
Axway Appcelerator - Titanium SDK 6.1.0 - Status, Releases & Roadmap
 
2014 Dublin Web Summit by Jeff Haynie
2014 Dublin Web Summit by Jeff Haynie2014 Dublin Web Summit by Jeff Haynie
2014 Dublin Web Summit by Jeff Haynie
 
Making the Mobile Mind Shift
Making the Mobile Mind ShiftMaking the Mobile Mind Shift
Making the Mobile Mind Shift
 
Stop Debating, Start Measuring
Stop Debating, Start MeasuringStop Debating, Start Measuring
Stop Debating, Start Measuring
 
Mobile & The New Experience Economy (And What it Means for IT)
Mobile & The New Experience Economy  (And What it Means for IT)Mobile & The New Experience Economy  (And What it Means for IT)
Mobile & The New Experience Economy (And What it Means for IT)
 
Apps, APIs & Analytics: What "Mobile First" Really Means
Apps, APIs & Analytics: What "Mobile First" Really MeansApps, APIs & Analytics: What "Mobile First" Really Means
Apps, APIs & Analytics: What "Mobile First" Really Means
 
Appcelerator Presentation Template
Appcelerator Presentation TemplateAppcelerator Presentation Template
Appcelerator Presentation Template
 
Codestrong 2012 keynote jonathan rende, appcelerator's vp of products
Codestrong 2012 keynote   jonathan rende, appcelerator's vp of productsCodestrong 2012 keynote   jonathan rende, appcelerator's vp of products
Codestrong 2012 keynote jonathan rende, appcelerator's vp of products
 
Codestrong 2012 keynote jeff haynie, appcelerator's ceo
Codestrong 2012 keynote   jeff haynie, appcelerator's ceoCodestrong 2012 keynote   jeff haynie, appcelerator's ceo
Codestrong 2012 keynote jeff haynie, appcelerator's ceo
 
Codestrong 2012 keynote how to build a top ten app
Codestrong 2012 keynote   how to build a top ten appCodestrong 2012 keynote   how to build a top ten app
Codestrong 2012 keynote how to build a top ten app
 
Codestrong 2012 breakout session at&t api platform and trends
Codestrong 2012 breakout session  at&t api platform and trendsCodestrong 2012 breakout session  at&t api platform and trends
Codestrong 2012 breakout session at&t api platform and trends
 
Codestrong 2012 breakout session what's new in titanium studio
Codestrong 2012 breakout session   what's new in titanium studioCodestrong 2012 breakout session   what's new in titanium studio
Codestrong 2012 breakout session what's new in titanium studio
 
Codestrong 2012 breakout session using appcelerator cloud services in your ...
Codestrong 2012 breakout session   using appcelerator cloud services in your ...Codestrong 2012 breakout session   using appcelerator cloud services in your ...
Codestrong 2012 breakout session using appcelerator cloud services in your ...
 
Codestrong 2012 breakout session the role of cloud services in your next ge...
Codestrong 2012 breakout session   the role of cloud services in your next ge...Codestrong 2012 breakout session   the role of cloud services in your next ge...
Codestrong 2012 breakout session the role of cloud services in your next ge...
 
Codestrong 2012 breakout session new device platform support for titanium
Codestrong 2012 breakout session   new device platform support for titaniumCodestrong 2012 breakout session   new device platform support for titanium
Codestrong 2012 breakout session new device platform support for titanium
 
Codestrong 2012 breakout session mobile platform and infrastructure
Codestrong 2012 breakout session   mobile platform and infrastructureCodestrong 2012 breakout session   mobile platform and infrastructure
Codestrong 2012 breakout session mobile platform and infrastructure
 
Codestrong 2012 breakout session making money on appcelerator's marketplace
Codestrong 2012 breakout session   making money on appcelerator's marketplaceCodestrong 2012 breakout session   making money on appcelerator's marketplace
Codestrong 2012 breakout session making money on appcelerator's marketplace
 
Codestrong 2012 breakout session live multi-platform testing
Codestrong 2012 breakout session   live multi-platform testingCodestrong 2012 breakout session   live multi-platform testing
Codestrong 2012 breakout session live multi-platform testing
 
Codestrong 2012 breakout session leveraging titanium as part of your mobile...
Codestrong 2012 breakout session   leveraging titanium as part of your mobile...Codestrong 2012 breakout session   leveraging titanium as part of your mobile...
Codestrong 2012 breakout session leveraging titanium as part of your mobile...
 
Codestrong 2012 breakout session i os internals and best practices
Codestrong 2012 breakout session   i os internals and best practicesCodestrong 2012 breakout session   i os internals and best practices
Codestrong 2012 breakout session i os internals and best practices
 

Último

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 

Último (20)

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 

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

  • 1. TITANIUM DEVELOPMENT WITH Accelerated COFFEESCRIPT, COMPASS, AND SASS WYNNNETHERLAND
  • 4.
  • 7. PIXELS I'VE PUSHED With some very talented folks.
  • 8.
  • 9.
  • 10. Play golf? Find this dude and get in on the beta.!
  • 11.
  • 12.
  • 13.
  • 15.
  • 16.
  • 19. It's still just JavaScript.
  • 20. var foo = function () { foo = () -> } JAVASCRIPT COFFEESCRIPT I’d rather write this.
  • 21. 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
  • 22. button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 top: 10 button.addEventListener 'click', (e) -> alert "Oooh, that tickles!" COFFEESCRIPT
  • 23. For me, It's about more than aesthetics ; {}
  • 24. Some of my favorite features...
  • 25. 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
  • 26. Comprehensions for own key, value of query uri += "#{ key }=#{ escape(value) }&" COFFEESCRIPT
  • 27. Interpolation for own key, value of query uri += "#{ key }=#{ escape(value) }&" COFFEESCRIPT
  • 28. The Existential Operator courseButtonSubhead = Ti.UI.createLabel className: 'optRowSubhead' text: "#{GolfStatus.App.currentGame?.green?.name}" COFFEESCRIPT
  • 29. Simple inheritance pattern 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 # elsewhere game = new GolfStatus.Models.Game(...) COFFEESCRIPT
  • 30. @ 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
  • 31. Default values 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
  • 32. More human conditionals 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
  • 33. Easy object.prototype GolfStatus.Models.Game::PlayingForTypes = brag: 'Bragging Rights' cash: 'Status Cash' GolfStatus.Models.Game::ScoringFormats = low_net: 'Low Net' low_grows: 'Low Gross' COFFEESCRIPT
  • 34. Heredocs noticeHTML =''' <html> <head></head> <body> ''' noticeHTML += "<div>#{noticeText}</div>" noticeHTML += ''' </body> </html> ''' COFFEESCRIPT
  • 36. And so much more.
  • 38. GET THE BOOK. http://wynn.fm/g8
  • 42. Why do we have CSS?
  • 43. <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> content </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. ✂ presentation
  • 44. A example
  • 45. 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
  • 46. var buttonOne = Titanium.UI.createButton({ title:'I am a Button', height:40, width:200, Presentation top:10 }); var buttonTwo = Titanium.UI.createButton({ title:'I am also a Button', image:'../images/chat.png', width:200, height:40, top:60 }); JAVASCRIPT
  • 47. var buttonOne = Titanium.UI.createButton({ id: "buttonOne", JAVASCRIPT Behavior and composition in className: "button" }); var buttonTwo = Titanium.UI.createButton({ id: "buttonTwo", className: "button" }); .js #buttonOne { title:'I am a Button'; JSS width:200; height:40; top:10 } #buttonTwo { Presentation in title:'I am also a Button'; image:'../images/chat.png'; width:200; height:40; .jss top:60 } .button { height: 40; width: 200; }
  • 48. var buttonOne = Titanium.UI.createButton({ id: "buttonOne", JAVASCRIPT className: "button" Style hooks }); var buttonTwo = Titanium.UI.createButton({ id: "buttonTwo", className: "button" }); #buttonOne { title:'I am a Button'; JSS 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; }
  • 49. JSS There's a better way to write CSS.
  • 50. Patte rns & io n s & plugins SS e xtens C co mpiler &
  • 52. Is it JSS or Sassy CSS? #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; } JSS / SCSS Yes?
  • 53. I prefer Sass' original indented, whitespace aware syntax. #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
  • 54. Which do you prefer?
  • 55. #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
  • 56. #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
  • 57. Pick one. Or not. Mix and match.
  • 59. stylesheets ├── _activity.sass ├── _base.sass ├── _confirmation.sass ├── _course.scss ├── _courses.sass ├── _friends.scss ├── _gameplay.sass ├── _leaderboard.sass ├── _leaders.sass ├── _login.sass ├── _requests.sass @import 'base' ├── _tourcard.sass @import 'login' └── app.sass @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 ...
  • 60. stylesheets Mix scss with sass ├── _activity.sass ├── _base.sass ├── _confirmation.sass if you're so inclined. ├── _course.scss ├── _courses.sass ├── _friends.scss ├── _gameplay.sass ├── _leaderboard.sass ├── _leaders.sass ├── _login.sass ├── _requests.sass @import 'base' ├── _tourcard.sass @import 'login' └── app.sass @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 ...
  • 62. .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
  • 63. DRY it up. Nesting .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 SASS
  • 64. #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
  • 65. DRY it up. Mixins =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 SASS
  • 66. DRY it up. Mixins with params =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' SASS
  • 67. #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
  • 68. DRY it up. @extend .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 SASS
  • 69. DRY it up. @extend .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'; One less class in our .js top: 60 } JSS
  • 70. Craft themes with color functions.
  • 71. variables $button-base: #a7a7a7 #buttonOne color: $button-base title: "Button 1" #buttonTwo color: $button-base title: "Button 2" SASS
  • 72. variables $button-base: #a7a7a7 #buttonOne color: $button-base title: "Button 1" #buttonTwo color: $button-base title: "Button 2" SASS
  • 73. color functions $button-base: #a7a7a7 #buttonOne color: $button-base title: "Button 1" #buttonTwo color: darken($button-base, 20%) title: "Button 2" SASS
  • 74. color functions $button-base: #a7a7a7 #buttonOne color: $button-base title: "Button 1" #buttonTwo color: darken($button-base, 20%) title: "Button 2" SASS
  • 75. more color functions hue(#cc3) # => 60deg saturation(#cc3) # => 60% lightness(#cc3) # => 50% adjust-hue(#cc3, 20deg) # => #9c3 saturate(#cc3, 10%) # => #d9d926 desaturate(#cc3, 10%) # => #bfbf40 lighten(#cc3, 10%) # => #d6d65c darken(#cc3, 10%) # => #a3a329 grayscale(#cc3) # => desaturate(#cc3, 100%) = #808080 complement(#cc3) # => adjust-hue(#cc3, 180deg) = #33c mix(#cc3, #00f) # => #e56619 mix(#cc3, #00f, 10%) # => #f91405 mix(#cc3, #00f, 90%) # => #d1b72d SASS
  • 76. even more color functions 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.75 opacity(rgba(51, 255, 51, 0.75)) # => 0.75 with alpha support! 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) SASS
  • 77. Building a hybrid native+web app?
  • 78. Share your stylesheet variables!
  • 79. No more vendor namespaces. Selector inheritance. URL helpers. So much more.
  • 80. I could write a book.
  • 81. Oh wait. We did!
  • 82. Isn’t she Sassy, folks? GET THE BOOK. http://wynn.fm/ti-sass
  • 83. Save 40% and get early access! sass40 Sadly, sass100 is not a valid code. http://wynn.fm/ti-sass
  • 84.
  • 89. MVC?
  • 91. ... are really ViewControllers.
  • 92. So we create View factories...
  • 93. ... and Model factories ...
  • 94. ...and factories that make miniature models of factories.
  • 96. button = Titanium.UI.createButton title: 'I am a Button' height: 40 Look familiar? width: 200 top: 10 button.addEventListener 'click', (e) -> alert "Oooh, that tickles!" COFFEESCRIPT
  • 97. So how do you manufacture your own views?
  • 99. 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
  • 100. MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts) button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 Create the factory method in the appropriate namespace. top: 10 window.add button # methods say = (msg) -> alert(msg) # event handlers button.addEventListener 'click', -> say('hello') window COFFEESCRIPT
  • 101. MyApp.Views.createLoginWindow = (opts={}) -> window = Ti.UI.createWindow(opts) button = Titanium.UI.createButton title: 'I am a Button' height: 40 width: 200 Compose the view from top: 10 window.add button Titanium types or others of # methods your own say = (msg) -> alert(msg) # event handlers button.addEventListener 'click', -> say('hello') window COFFEESCRIPT
  • 102. 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 in familiar place # methods say = (msg) -> alert(msg) # event handlers button.addEventListener 'click', -> say('hello') window COFFEESCRIPT
  • 103. 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 And event handlers... # methods say = (msg) -> alert(msg) # event handlers button.addEventListener 'click', -> say('hello') window COFFEESCRIPT
  • 104. 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 Return your view # methods say = (msg) -> alert(msg) # event handlers button.addEventListener 'click', -> say('hello') window COFFEESCRIPT
  • 105. Models
  • 107. class GolfStatus.Models.Game constructor: (@owner, @course, @playingFor='brag', @scoringFormat='low_net') -> serialize: -> deserialize: (data) -> save: -> resume: -> dataForSubmit: () -> submit: (error) -> ... COFFEESCRIPT
  • 109. CoffeeScript class class GolfStatus.API # Initialize with login and password constructor: (@login, @password) -> COFFEESCRIPT
  • 110. URI building ... # 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
  • 111. HTTP Request building # 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
  • 112. High level methods for HTTP verbs # 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
  • 113. Higher level API methods # ### 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
  • 115. . ├── Resources # Titanium root │   └── vendor # JavaScript frameworks ├── src # CoffeeScript root │   └── golf_status # App root │   ├── models │   └── views │   ├── account # App domains │   ├── activity │   ├── courses │   ├── leaderboard │   └── play └── stylesheets # Sass
  • 116. Stitching it all together
  • 117. app.js
  • 118. 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
  • 119. GolfStatus = Models: {} Views: Set up your namespaces Account: {} Activity: {} Courses: {} Leaderboard: {} Play: {} Ti.include('vendor/date.js') Ti.include('vendor/underscore.js') Ti.include('golf_status.js') GolfStatus.App.init() COFFEESCRIPT
  • 120. GolfStatus = Models: {} Views: Account: {} Activity: {} Courses: {} third party frameworks Leaderboard: {} Play: {} Ti.include('vendor/date.js') Ti.include('vendor/underscore.js') Ti.include('golf_status.js') GolfStatus.App.init() COFFEESCRIPT
  • 121. 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() All of our app in just one file COFFEESCRIPT
  • 122. 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() Fire up the app and first window COFFEESCRIPT
  • 123. Lean app.js makes for flexibility
  • 124. Tapping through to test deep screens bites!
  • 125. # GolfStatus.App.init() window = GolfStatus.Views.Play.createGameWindow() window.open() Comment out init and fire up the deepest view. COFFEESCRIPT
  • 126. make
  • 127. 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 guilhermechapiewski (Guilherme Chapiewski) http://wynn.fm/g9
  • 128. I'm a Rubyist, so I speak rake
  • 130. 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
  • 131. 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 compilation end RAKEFILE
  • 132. 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 compilation end RAKEFILE Compile App namespaces to single file
  • 133. 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 compilation end RAKEFILE Compile app.js which includes the app library
  • 134. Build
  • 135. 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
  • 136. 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
  • 137. 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 Pipe to PERL for some colored terminal goodness RAKEFILE
  • 138.
  • 139. Choose what works for you.
  • 141. Underscore.js https://github.com/documentcloud/underscore From Jeremy Ashkenas, the creator of CoffeeScript.
  • 142. Don't Repeat Yourself Not Repeating Yourself
  • 143. Ti GEM Automating these patterns. A work in progress.
  • 146. ti new <name> <id> <platform>
  • 147. ti new codestrong-app com.codestrong.app iphone
  • 148. ├── 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
  • 150. Golf.Views.GamePlay.createScoreCardView = (options) -> view = Ti.UI.createView (options) view
  • 154. Build.
  • 156. Ti GEM @revans @baldrailers @rupakg
  • 158. We've got BIG ideas.
  • 162. XIB