SlideShare uma empresa Scribd logo
1 de 88
Web Development with
      Sass and CoffeeScript
      Brian P. Hogan




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
What about you?



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Web pages run on CSS
               and JavaScript



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
CSS feels limited
                   and repetitive



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
and many people don’t
            really understand
               JavaScript


Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
We need to use
          better tools to build
            modern web apps.


Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
CoffeeScript lets us
          write complex JS with
             simpler syntax.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Sass gives us
                extensions to CSS.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Sass + CoffeeScript +
           automated workflow


Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
CoffeeScript



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com     Rate this talk at http://spkr8.com/t/8682
It’s more of a new
                syntax than a new
                     language.


Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Some jQuery




                           $(function() {
                               $("a#get").click(function(e) {
                               .get("/ajax/get",
                                  {name: "John",time: "2pm"},
                                  function(data) {
                                    $("#result").html(data);
                                  }
                               );
                             });
                           });




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com              Rate this talk at http://spkr8.com/t/8682
in CoffeeScript




                           $ ->
                             $("a#get").click (e) ->
                                $.get "/ajax/get",
                                  {name: "John", time: "2pm"},
                                  (data) ->
                                     $("#result").html(data)




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com              Rate this talk at http://spkr8.com/t/8682
CoffeeScript borrows
            from Python and Ruby
                  syntax.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
CoffeeScript uses
        significant whitespace
              for scope.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
CoffeeScript compiles
          to regular, plain old
               JavaScript.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Declaring variables and objects

                                               var box, colors, firstName, lastName;

      firstName = "Homer"                      firstName = "Homer";
      lastName = "Simpson"                     lastName = "Simpson";

      colors = ["Green", "Blue", "Red"]        colors = ["Green", "Blue", "Red"];

      box =                                    box = {
        height: 40                                height: 40,
        width: 60                                 width: 60,
        color: red                                color: red
                                               };




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com             Rate this talk at http://spkr8.com/t/8682
JavaScript functions

        // function declaration. Visible anywhere (hoisting)
          (function hello(name){
           alert("Hello " + name + "!");
        }


        // function expression, visible to the scope of the var
        var hello = function(name){
          alert("Hello " + name + "!");
        }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com            Rate this talk at http://spkr8.com/t/8682
Function declaration in CoffeeScript


       hello ->
         alert "Hello"




       hello (name) ->
         alert "Hello #{name}"



                                -> (thin arrow)




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com          Rate this talk at http://spkr8.com/t/8682
CoffeeScript uses function expressions.


       hello (name) ->
         alert "Hello #{name}!"




        var hello = function(name){
          alert("Hello " + name + "!");
        }




                   #{} interpolates strings.

Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com       Rate this talk at http://spkr8.com/t/8682
New syntax
              means new features.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
a jQuery example

                $(function() {
                  var displayError, displaySuccess, url;
                  $("form").submit(function(event) {});
                  event.preventDefault();
                  url = $(this).attr("href");
                  $.ajax({
                     url: url + ".js",
                     success: function(data, status, xhr) {
                        displaySuccess($("#form"));
                     },
                     error: function(xhr, status, error) {
                        displayError(error);
                     }
                  });
                  displaySuccess = function(form) {
                     var element;
                     element = $("<p>Thanks for signing up!").addClass("success");
                     element.insertAfter(form);
                     form.hide();
                  };
                  displayError = function(error) {
                     $("#notice").attr("html", error);
                  };
                });


Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                     Rate this talk at http://spkr8.com/t/8682
jQuery $(function(){})

                $ ->
                  $("form").submit (event) ->

                     event.preventDefault()
                     url = $(this).attr "href"

                     $.ajax
                       url: url + ".js"
                       success: (data, status, xhr) ->
                         displaySuccess($("form"))
                       error: (xhr, status, error) ->
                         displayError error

                  displaySuccess = (form) ->
                   element = $("<p>Thanks for signing up!").addClass("success")
                   element.insertAfter form
                   form.hide()

                  displayError = (error) ->
                    $("#notice").attr "html", error




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                    Rate this talk at http://spkr8.com/t/8682
jQuery event handler

                $ ->
                  $("form").submit (event) ->

                     event.preventDefault()
                     url = $(this).attr "href"

                     $.ajax
                       url: url + ".js"
                       success: (data, status, xhr) ->
                         displaySuccess($("form"))
                       error: (xhr, status, error) ->
                         displayError error

                  displaySuccess = (form) ->
                   element = $("<p>Thanks for signing up!").addClass("success")
                   element.insertAfter form
                   form.hide()

                  displayError = (error) ->
                    $("#notice").attr "html", error




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                    Rate this talk at http://spkr8.com/t/8682
jQuery $.ajax

                $ ->
                  $("form").submit (event) ->

                     event.preventDefault()
                     url = $(this).attr "href"

                     $.ajax
                       url: url + ".js"
                       success: (data, status, xhr) ->
                         displaySuccess($("form"))
                       error: (xhr, status, error) ->
                         displayError error

                  displaySuccess = (form) ->
                   element = $("<p>Thanks for signing up!").addClass("success")
                   element.insertAfter form
                   form.hide()

                  displayError = (error) ->
                    $("#notice").attr "html", error




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                    Rate this talk at http://spkr8.com/t/8682
success and error callbacks

                $ ->
                  $("form").submit (event) ->

                     event.preventDefault()
                     url = $(this).attr "href"

                     $.ajax
                       url: url + ".js"
                       success: (data, status, xhr) ->
                         displaySuccess($("form"))
                       error: (xhr, status, error) ->
                         displayError error

                  displaySuccess = (form) ->
                   element = $("<p>Thanks for signing up!").addClass("success")
                   element.insertAfter form
                   form.hide()

                  displayError = (error) ->
                    $("#notice").attr "html", error




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                    Rate this talk at http://spkr8.com/t/8682
-> leaves (this) scope alone.

                $ ->
                  $("form").submit (event) ->

                     event.preventDefault()
                     url = $(this).attr "href"

                     $.ajax
                       url: url + ".js"
                       success: (data, status, xhr) ->
                         displaySuccess($("form"))
                       error: (xhr, status, error) ->
                         displayError error

                  displaySuccess = (form) ->
                   element = $("<p>Thanks for signing up!").addClass("success")
                   element.insertAfter form
                   form.hide()

                  displayError = (error) ->
                    $("#notice").attr "html", error




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                    Rate this talk at http://spkr8.com/t/8682
=>



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
=> binds this to the function body

                $ ->
                  $("form").submit (event) ->

                     event.preventDefault()
                     url = $(this).attr "href"

                     $.ajax
                       url: url + ".js"
                       success: (data, status, xhr) =>
                         displaySuccess($(this))
                       error: (xhr, status, error) ->
                         displayError error

                  displaySuccess = (form) ->
                   element = $("<p>Thanks for signing up!").addClass("success")
                   element.insertAfter form
                   form.hide()

                  displayError = (error) ->
                    $("#notice").attr "html", error




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                    Rate this talk at http://spkr8.com/t/8682
Comprehensions



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Simple iteration


                  alert color for color in ["red", "green", "blue"]




         var colors = ["red", "green", "blue"];
         for (i = 0, length = colors.length; i < length; i++) {
           var color = colors[i];
           alert(color);
         }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                    Rate this talk at http://spkr8.com/t/8682
“for in”


         people = [
           {name: "Homer", age: 42}
           {name: "Bart", age: 10}
         ]

         for person in people
           alert "#{person.name} is #{person.age} years old"




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com         Rate this talk at http://spkr8.com/t/8682
That’s just the
                        beginning.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Existential operator (?)


          total ?= 0




         if (typeof total !== "undefined" && total !== null) {
            total;
         } else {
            total = 0;
         };




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com       Rate this talk at http://spkr8.com/t/8682
Object-oriented
                        JavaScript



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Classes
                         var Person, p;
                         Person = (function() {
                           function Person(options) {
                              this.firstname = options.firstname;
                              this.lastname = options.lastname;
                              this.age = options.age;
                           }
                           Person.prototype.fullname = function() {
                              return "" + this.firstname + " " + this.lastname;
                           };
                           return Person;
                         })();

                         p = new Person({
                           firstname: "Brian",
                           lastname: "Hogan"
                         });

                         alert(p.fullname());




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                     Rate this talk at http://spkr8.com/t/8682
Classes
                         var Person, p;
                         Person = (function() {
                           function Person(options) {
                              this.firstname = options.firstname;
                              this.lastname = options.lastname;
                                   class Person
                              this.age = options.age;
                                     constructor: (options) ->
                           }
                                       @firstname = options.firstname
                           Person.prototype.fullname = function() {
                                       @lastname = options.lastname
                              return "" + this.firstname + " " + this.lastname;
                                       @age = options.age
                           };
                           return Person;
                                     fullname: ->
                         })();
                                       "#{@firstname} #{@lastname}"
                         p = new Person({
                           firstname: "Brian",
                           lastname:="Hogan"
                                  p   new Person
                         });      alert p.fullname()


                         alert(p.fullname());




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                     Rate this talk at http://spkr8.com/t/8682
We can even extend classes!


       class basicWindow
         constructor: ->                      class mainWindow extends basicWindow
           @window = Ti.UI.createWindow({       constructor: ->
              backgroundColor: "#F5F5ED"          super
           })                                     @window.backgroundColor = "#fff"

         open: ->
           @window.open()




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com               Rate this talk at http://spkr8.com/t/8682
How do we use it?
                                In the web browser itself

                                via Node.js

                                With Ruby, via Guard




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com            Rate this talk at http://spkr8.com/t/8682
In the browser?
                       <script language="text/coffeescript">
                         people = [
                           {name: "Homer", age: 42}
                           {name: "Bart", age: 10}
                         ]

                         for person in people
                           do (person) ->
                             alert "#{person.name} is #{person.age} years old"
                       </script>

                       <script src="coffee-script.js"></script>




                                (this is slow.)

Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                     Rate this talk at http://spkr8.com/t/8682
With Node.js
              Install Node.js

              Install npm

              npm install -g coffee-script

              coffee --compile --output js/ coffee/

              coffee -o js/ -cw coffee/




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Ruby and Guard
              Install Ruby

              gem install guard-coffeescript

              In our project

                   guard init coffeescript

                   guard




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com    Rate this talk at http://spkr8.com/t/8682
Guard watches input
      folders for changes
      and writes output
      files.

Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Guard works with Sass
      too.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Sass
                                Syntactically Awesome
                                Stylesheets




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com      Rate this talk at http://spkr8.com/t/8682
Sass gives CSS
      everything programmers
      want.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
CSS

                                .sidebar {
                                  color: #000;
                                  border: 1px solid #000;
                                }

                                .sidebar p {
                                  margin-bottom: 20px;
                                }

                                .sidebar ul {
                                  margin-bottom: 10px;
                                }

                                .sidebar h1 {
                                  margin-bottom: 0;
                                }

                                .main{
                                  color: #000;
                                }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com               Rate this talk at http://spkr8.com/t/8682
CSS

                                .sidebar {
                                  color: #000;
                                  border: 1px solid #000;
                                }

                                .sidebar p {
                                  margin-bottom: 20px;
                                }

                                .sidebar ul {
                                  margin-bottom: 10px;
                                }

                                .sidebar h1 {
                                  margin-bottom: 0;
                                }

                                .main{
                                  color: #000;
                                }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com               Rate this talk at http://spkr8.com/t/8682
CSS

                                .sidebar {
                                  color: #000;
                                  border: 1px solid #000;
                                }

                                .sidebar p {
                                  margin-bottom: 20px;
                                }

                                .sidebar ul {
                                  margin-bottom: 10px;
                                }

                                .sidebar h1 {
                                  margin-bottom: 0;
                                }

                                .main{
                                  color: #000;
                                }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com               Rate this talk at http://spkr8.com/t/8682
Sass to
      the rescue!




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Variables!

                                $measure: 20px
                                $color: #ce4dd6

                                .sidebar
                                  background-olor: $color
                                  border: 1px solid lighten($color, 20%)

                                  p
                                       margin-bottom: $measure

                                  ul
                                       margin-bottom: $measure / 2

                                  h1
                                       margin-bottom: 0




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                         Rate this talk at http://spkr8.com/t/8682
Variables and helper functions!

                                $measure: 20px
                                $color: #ce4dd6

                                .sidebar
                                  background-olor: $color
                                  border: 1px solid lighten($color, 20%)

                                  p
                                       margin-bottom: $measure

                                  ul
                                       margin-bottom: $measure / 2

                                  h1
                                       margin-bottom: 0




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                         Rate this talk at http://spkr8.com/t/8682
Scope with nesting

                                $measure: 20px
                                $color: #ce4dd6

                                .sidebar
                                  background-olor: $color
                                  border: 1px solid lighten($color, 20%)

                                  p
                                       margin-bottom: $measure

                                  ul
                                       margin-bottom: $measure / 2

                                  h1
                                       margin-bottom: 0




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                         Rate this talk at http://spkr8.com/t/8682
Indented Sass                                                SCSS
         $measure: 20px                             $measure: 20px;
         $color: #000                               $color: #000;

         .sidebar                                   .sidebar{
           color: $color                              color: $color;
           border: 1px solid $color                   border: 1px solid $color;

           p                                            p{
                margin-bottom: $measure                      margin-bottom: $measure;
                                                        }
           ul
                margin-bottom: $measure / 2             ul{
                                                          margin-bottom: $measure / 2;
           h1                                           }
                margin-bottom: 0
                                                        h1{
                                                          margin-bottom: 0;
                                                        }
                                                    }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                 Rate this talk at http://spkr8.com/t/8682
But wait...
          there’s more!




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Modularization

            _mixins.scss                    @import "mixins";
                                            @import "reset";
                                            @import "base";

            _reset.scss                     @import "fonts";




            _base.scss




            _fonts.scss




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com         Rate this talk at http://spkr8.com/t/8682
Reusable Functions (mixins)
                                             blockquote {
      @mixin rounded($radius){
                                               width: 225px;
                border-radius: $radius;
                                               padding: 15px 30px;
           -moz-border-radius: $radius;
                                               margin: 0;
        -webkit-border-radius: $radius;
                                               position: relative;
      }
                                               background: #faa;
                                               @include rounded(20px);
                                             }



                                              .button {
                                                cursor: pointer;
                                                color: #000;
                                                text-decoration: none;
                                                @include rounded(12px);
                                              }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com             Rate this talk at http://spkr8.com/t/8682
Mixins + Interation + Variables

            @mixin shadow($x, $y, $offset, $color)
              @each $prefix in "", -moz-, -webkit-, -o-, -khtml-
                #{$prefix}box-shadow: $x $y $offset $color




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com        Rate this talk at http://spkr8.com/t/8682
Mixins + Interation + Variables

            @mixin shadow($x, $y, $offset, $color)
              @each $prefix in "", -moz-, -webkit-, -o-, -khtml-
                #{$prefix}box-shadow: $x $y $offset $color




                       box-shadow: 5px 5px 5px #dddddd;
                       -moz-box-shadow: 5px 5px 5px #dddddd;
                       -webkit-box-shadow: 5px 5px 5px #dddddd;
                       -o-box-shadow: 5px 5px 5px #dddddd;
                       -khtml-box-shadow: 5px 5px 5px #dddddd; }




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com            Rate this talk at http://spkr8.com/t/8682
Create well-organized
          folders and libraries
             of stylesheets.




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
or use Compass.




                   http://compass-style.org/




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Compass has helpers

             @import 'compass'
             @include box-shadow(#ddd 5px 5px 5px)




                       box-shadow: 5px 5px 5px #dddddd;
                       -moz-box-shadow: 5px 5px 5px #dddddd;
                       -webkit-box-shadow: 5px 5px 5px #dddddd;
                       -o-box-shadow: 5px 5px 5px #dddddd;}




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com            Rate this talk at http://spkr8.com/t/8682
How do we use it?

                                via Sass

                                via a supported IDE

                                With Ruby, via Guard




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com              Rate this talk at http://spkr8.com/t/8682
with Sass

              Install Ruby

              $ gem install sass

              $ sass --watch sass:stylesheets




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com       Rate this talk at http://spkr8.com/t/8682
Ruby and Guard
              Install Ruby

              gem install guard-sass

              In our project

                   guard init sass

                   guard



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com    Rate this talk at http://spkr8.com/t/8682
Using Sass and
                         CoffeeScript
                           together


Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Mindscape Web
                            Workbench
               http://www.mindscapehq.com/products/web-workbench




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com         Rate this talk at http://spkr8.com/t/8682
Ruby and Guard
              Install Ruby

              gem install guard-sass guard-
              coffeescript

              In our project

                   guard init sass

                   guard init coffeescript

                   guard

Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com    Rate this talk at http://spkr8.com/t/8682
Let’s talk deployment



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Rails 3.1 and
                           Capistrano



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Asset Packaging



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
So instead of this...




             <link rel="stylesheet" href="stylesheets/layout.css">
             <link rel="stylesheet" href="stylesheets/style.css">
             <script src="javascripts/jquery-1.7.0.min.js"></script>
             <script src="javascripts/app.js"></script>




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com             Rate this talk at http://spkr8.com/t/8682
...let’s do this:




             <link rel="stylesheet" href="assets/app.css">
             <script src="assets/app.js"></script>




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com           Rate this talk at http://spkr8.com/t/8682
Ruby + Guard + Jammit

                      Install Ruby

                      $ gem install guard-jammit




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com        Rate this talk at http://spkr8.com/t/8682
Sass, CoffeeScript,
                Jammit
              watch Sass files for changes

                   Place output css in tmp/ folder

              watch CoffeeScript files for changes

                   Place output js in tmp/ folder

              Use Jammit to combine them.

Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com    Rate this talk at http://spkr8.com/t/8682
config/assets.yml
               stylesheets:
                 app:
                   - tmp/app.css
                   - tmp/style.css

               javascripts:
                 app:
                   - javascripts/jquery-1.6.4.js
                   - tmp/app.js




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com          Rate this talk at http://spkr8.com/t/8682
Guardfile

                guard "coffeescript", :input => "coffeescripts", :output => "tmp"

                guard "sass", :input => "sass", :output => "tmp"

                guard "jammit" do
                  watch(/^javascripts/(.*).js/)
                  watch(/^stylesheets/(.*).css/)
                  watch(/^tmp/(.*).js/)
                  watch(/^tmp/(.*).css/)
                end




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                        Rate this talk at http://spkr8.com/t/8682
Jammit places
                          files in
                        public/assets
            <link rel="stylesheet" href="assets/app.css">
            <script src="assets/app.js"></script>




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com        Rate this talk at http://spkr8.com/t/8682
Deploy with Rake
                   SERVER = "yourhost.com"
                   USERNAME = "yourusername"
                   REMOTE_FOLDER = "/home/#{USERNAME}/yourhost.com"
                   REMOTE_FOLDER = 22
                   require 'net/scp'

                   desc "compile CSS, js files"
                   task :compile do
                     require 'guard'
                     Guard.setup
                     Guard::Dsl.evaluate_guardfile
                     Guard::guards.each{|guard| guard.run_all}
                   end

                   desc "Deploy web site"
                   task :deploy => :compile do
                     Net::SSH.start(SERVER, USERNAME, {:port => PORT} ) do |ssh|
                       ssh.sftp.rmdir File.join(REMOTE_FOLDER, "public")
                       ssh.scp.upload! "public", REMOTE_FOLDER, :recursive => true
                     end
                   end




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com                     Rate this talk at http://spkr8.com/t/8682
qedproject
      https://github.com/napcs/qedproject




Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com       Rate this talk at http://spkr8.com/t/8682
qedproject
              Install Ruby

              gem install qedproject

              qedproject myapp -c -s -a -l jquery

                   creates app with Sass,
                   CoffeeScript, Asset packaging, and
                   jQuery

                   Sets up Guard and a simple Rake
                   file for deployment
Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com       Rate this talk at http://spkr8.com/t/8682
Demo



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com    Rate this talk at http://spkr8.com/t/8682
Short syntax                     Nested
                                           Selectors
          Catch errors at
          compile time                     Variables

          List                             Mixins
          Comprehensions
                                           Composition
          Classes



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
With asset packaging
and automated deployment...



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
...CoffeeScript and Sass
      make developers happy.



Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com   Rate this talk at http://spkr8.com/t/8682
Questions?




    http://pragprog.com/book/wbdev/web-
            development-recipes
Brian P. Hogan
twitter: @bphogan
www.webdevelopmentrecipes.com       Rate this talk at http://spkr8.com/t/8682

Mais conteúdo relacionado

Mais procurados

PHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vulnPHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vulnSandro Zaccarini
 
Php web backdoor obfuscation
Php web backdoor obfuscationPhp web backdoor obfuscation
Php web backdoor obfuscationSandro Zaccarini
 
GraphQL, l'avenir du REST par François ZANINOTTO
GraphQL, l'avenir du REST par François ZANINOTTOGraphQL, l'avenir du REST par François ZANINOTTO
GraphQL, l'avenir du REST par François ZANINOTTOLa Cuisine du Web
 
Building Things Fast - and getting approval
Building Things Fast - and getting approvalBuilding Things Fast - and getting approval
Building Things Fast - and getting approvalSimon Willison
 
SULTHAN's - PHP MySQL programs
SULTHAN's - PHP MySQL programsSULTHAN's - PHP MySQL programs
SULTHAN's - PHP MySQL programsSULTHAN BASHA
 
Finding things on the web with BOSS
Finding things on the web with BOSSFinding things on the web with BOSS
Finding things on the web with BOSSChristian Heilmann
 
Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]foundsearch
 
Php 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodPhp 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodJeremy Kendall
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and ProfitOlaf Alders
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Code obfuscation, php shells & more
Code obfuscation, php shells & moreCode obfuscation, php shells & more
Code obfuscation, php shells & moreMattias Geniar
 
Building Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraBuilding Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraMarkus Lanthaler
 
WordPressでIoTをはじめよう
WordPressでIoTをはじめようWordPressでIoTをはじめよう
WordPressでIoTをはじめようYuriko IKEDA
 
Date difference[1]
Date difference[1]Date difference[1]
Date difference[1]shafiullas
 

Mais procurados (20)

PHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vulnPHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vuln
 
Api pain points
Api pain pointsApi pain points
Api pain points
 
Php web backdoor obfuscation
Php web backdoor obfuscationPhp web backdoor obfuscation
Php web backdoor obfuscation
 
GraphQL, l'avenir du REST par François ZANINOTTO
GraphQL, l'avenir du REST par François ZANINOTTOGraphQL, l'avenir du REST par François ZANINOTTO
GraphQL, l'avenir du REST par François ZANINOTTO
 
Building Things Fast - and getting approval
Building Things Fast - and getting approvalBuilding Things Fast - and getting approval
Building Things Fast - and getting approval
 
SULTHAN's - PHP MySQL programs
SULTHAN's - PHP MySQL programsSULTHAN's - PHP MySQL programs
SULTHAN's - PHP MySQL programs
 
Finding things on the web with BOSS
Finding things on the web with BOSSFinding things on the web with BOSS
Finding things on the web with BOSS
 
PHP Tutorial (funtion)
PHP Tutorial (funtion)PHP Tutorial (funtion)
PHP Tutorial (funtion)
 
Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]Elasticsearch – mye mer enn søk! [JavaZone 2013]
Elasticsearch – mye mer enn søk! [JavaZone 2013]
 
Php 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodPhp 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the Good
 
PHP 1
PHP 1PHP 1
PHP 1
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Code obfuscation, php shells & more
Code obfuscation, php shells & moreCode obfuscation, php shells & more
Code obfuscation, php shells & more
 
Building Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraBuilding Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and Hydra
 
Inc
IncInc
Inc
 
php part 2
php part 2php part 2
php part 2
 
WordPressでIoTをはじめよう
WordPressでIoTをはじめようWordPressでIoTをはじめよう
WordPressでIoTをはじめよう
 
Date difference[1]
Date difference[1]Date difference[1]
Date difference[1]
 

Semelhante a Web Development with CoffeeScript and Sass

AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkara JUG
 
Primefaces Confess 2012
Primefaces Confess 2012Primefaces Confess 2012
Primefaces Confess 2012cagataycivici
 
Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web AppsMark
 
Introduction to Facebook Graph API and OAuth 2
Introduction to Facebook Graph API and OAuth 2Introduction to Facebook Graph API and OAuth 2
Introduction to Facebook Graph API and OAuth 2Thai Pangsakulyanont
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers StealBen Scofield
 
Testing Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScriptTesting Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScriptBrian Hogan
 
Data Visualisations In IavaScript
Data Visualisations In IavaScriptData Visualisations In IavaScript
Data Visualisations In IavaScriptannashipman
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Designunodelostrece
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineAndy McKay
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen LjuSkills Matter
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen LjuSkills Matter
 
HappyKardashian.com for #FVCP
HappyKardashian.com for #FVCPHappyKardashian.com for #FVCP
HappyKardashian.com for #FVCPEric Michalsen
 
Cheap frontend tricks
Cheap frontend tricksCheap frontend tricks
Cheap frontend tricksambiescent
 

Semelhante a Web Development with CoffeeScript and Sass (20)

AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFaces
 
Primefaces Confess 2012
Primefaces Confess 2012Primefaces Confess 2012
Primefaces Confess 2012
 
Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web Apps
 
Introduction to Facebook Graph API and OAuth 2
Introduction to Facebook Graph API and OAuth 2Introduction to Facebook Graph API and OAuth 2
Introduction to Facebook Graph API and OAuth 2
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
YAP / Open Mail Overview
YAP / Open Mail OverviewYAP / Open Mail Overview
YAP / Open Mail Overview
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
Testing Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScriptTesting Client-side Code with Jasmine and CoffeeScript
Testing Client-side Code with Jasmine and CoffeeScript
 
Data Visualisations In IavaScript
Data Visualisations In IavaScriptData Visualisations In IavaScript
Data Visualisations In IavaScript
 
Intro to jquery
Intro to jqueryIntro to jquery
Intro to jquery
 
Os Pruett
Os PruettOs Pruett
Os Pruett
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
HappyKardashian.com for #FVCP
HappyKardashian.com for #FVCPHappyKardashian.com for #FVCP
HappyKardashian.com for #FVCP
 
Cheap frontend tricks
Cheap frontend tricksCheap frontend tricks
Cheap frontend tricks
 
Hacking with hhvm
Hacking with hhvmHacking with hhvm
Hacking with hhvm
 
huhu
huhuhuhu
huhu
 
Django
DjangoDjango
Django
 

Mais de Brian Hogan

Creating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoCreating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoBrian Hogan
 
Automating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and AnsibleAutomating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and AnsibleBrian Hogan
 
Create Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantCreate Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantBrian Hogan
 
Getting Started Contributing To Open Source
Getting Started Contributing To Open SourceGetting Started Contributing To Open Source
Getting Started Contributing To Open SourceBrian Hogan
 
Rethink Frontend Development With Elm
Rethink Frontend Development With ElmRethink Frontend Development With Elm
Rethink Frontend Development With ElmBrian Hogan
 
FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.Brian Hogan
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web DesignBrian Hogan
 
Building A Gem From Scratch
Building A Gem From ScratchBuilding A Gem From Scratch
Building A Gem From ScratchBrian Hogan
 
Intro To Advanced Ruby
Intro To Advanced RubyIntro To Advanced Ruby
Intro To Advanced RubyBrian Hogan
 
Turning Passion Into Words
Turning Passion Into WordsTurning Passion Into Words
Turning Passion Into WordsBrian Hogan
 
HTML5 and CSS3 Today
HTML5 and CSS3 TodayHTML5 and CSS3 Today
HTML5 and CSS3 TodayBrian Hogan
 
Web Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To ComplexWeb Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To ComplexBrian Hogan
 
Stop Reinventing The Wheel - The Ruby Standard Library
Stop Reinventing The Wheel - The Ruby Standard LibraryStop Reinventing The Wheel - The Ruby Standard Library
Stop Reinventing The Wheel - The Ruby Standard LibraryBrian Hogan
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Brian Hogan
 
Make GUI Apps with Shoes
Make GUI Apps with ShoesMake GUI Apps with Shoes
Make GUI Apps with ShoesBrian Hogan
 
Story-driven Testing
Story-driven TestingStory-driven Testing
Story-driven TestingBrian Hogan
 
Learning To Walk In Shoes
Learning To Walk In ShoesLearning To Walk In Shoes
Learning To Walk In ShoesBrian Hogan
 

Mais de Brian Hogan (20)

Creating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with HugoCreating and Deploying Static Sites with Hugo
Creating and Deploying Static Sites with Hugo
 
Automating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and AnsibleAutomating the Cloud with Terraform, and Ansible
Automating the Cloud with Terraform, and Ansible
 
Create Development and Production Environments with Vagrant
Create Development and Production Environments with VagrantCreate Development and Production Environments with Vagrant
Create Development and Production Environments with Vagrant
 
Docker
DockerDocker
Docker
 
Getting Started Contributing To Open Source
Getting Started Contributing To Open SourceGetting Started Contributing To Open Source
Getting Started Contributing To Open Source
 
Rethink Frontend Development With Elm
Rethink Frontend Development With ElmRethink Frontend Development With Elm
Rethink Frontend Development With Elm
 
FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.FUD-Free Accessibility for Web Developers - Also, Cake.
FUD-Free Accessibility for Web Developers - Also, Cake.
 
Responsive Web Design
Responsive Web DesignResponsive Web Design
Responsive Web Design
 
Building A Gem From Scratch
Building A Gem From ScratchBuilding A Gem From Scratch
Building A Gem From Scratch
 
Intro To Advanced Ruby
Intro To Advanced RubyIntro To Advanced Ruby
Intro To Advanced Ruby
 
Turning Passion Into Words
Turning Passion Into WordsTurning Passion Into Words
Turning Passion Into Words
 
HTML5 and CSS3 Today
HTML5 and CSS3 TodayHTML5 and CSS3 Today
HTML5 and CSS3 Today
 
Web Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To ComplexWeb Development With Ruby - From Simple To Complex
Web Development With Ruby - From Simple To Complex
 
Stop Reinventing The Wheel - The Ruby Standard Library
Stop Reinventing The Wheel - The Ruby Standard LibraryStop Reinventing The Wheel - The Ruby Standard Library
Stop Reinventing The Wheel - The Ruby Standard Library
 
Intro to Ruby
Intro to RubyIntro to Ruby
Intro to Ruby
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 
Make GUI Apps with Shoes
Make GUI Apps with ShoesMake GUI Apps with Shoes
Make GUI Apps with Shoes
 
The Why Of Ruby
The Why Of RubyThe Why Of Ruby
The Why Of Ruby
 
Story-driven Testing
Story-driven TestingStory-driven Testing
Story-driven Testing
 
Learning To Walk In Shoes
Learning To Walk In ShoesLearning To Walk In Shoes
Learning To Walk In Shoes
 

Último

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
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 

Último (20)

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
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 

Web Development with CoffeeScript and Sass

  • 1. Web Development with Sass and CoffeeScript Brian P. Hogan Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 2. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 3. What about you? Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 4. Web pages run on CSS and JavaScript Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 5. CSS feels limited and repetitive Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 6. and many people don’t really understand JavaScript Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 7. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 8. We need to use better tools to build modern web apps. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 9. CoffeeScript lets us write complex JS with simpler syntax. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 10. Sass gives us extensions to CSS. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 11. Sass + CoffeeScript + automated workflow Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 12. CoffeeScript Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 13. It’s more of a new syntax than a new language. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 14. Some jQuery $(function() { $("a#get").click(function(e) { .get("/ajax/get", {name: "John",time: "2pm"}, function(data) { $("#result").html(data); } ); }); }); Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 15. in CoffeeScript $ -> $("a#get").click (e) -> $.get "/ajax/get", {name: "John", time: "2pm"}, (data) -> $("#result").html(data) Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 16. CoffeeScript borrows from Python and Ruby syntax. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 17. CoffeeScript uses significant whitespace for scope. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 18. CoffeeScript compiles to regular, plain old JavaScript. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 19. Declaring variables and objects var box, colors, firstName, lastName; firstName = "Homer" firstName = "Homer"; lastName = "Simpson" lastName = "Simpson"; colors = ["Green", "Blue", "Red"] colors = ["Green", "Blue", "Red"]; box = box = { height: 40 height: 40, width: 60 width: 60, color: red color: red }; Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 20. JavaScript functions // function declaration. Visible anywhere (hoisting) (function hello(name){ alert("Hello " + name + "!"); } // function expression, visible to the scope of the var var hello = function(name){ alert("Hello " + name + "!"); } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 21. Function declaration in CoffeeScript hello -> alert "Hello" hello (name) -> alert "Hello #{name}" -> (thin arrow) Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 22. CoffeeScript uses function expressions. hello (name) -> alert "Hello #{name}!" var hello = function(name){ alert("Hello " + name + "!"); } #{} interpolates strings. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 23. New syntax means new features. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 24. a jQuery example $(function() { var displayError, displaySuccess, url; $("form").submit(function(event) {}); event.preventDefault(); url = $(this).attr("href"); $.ajax({ url: url + ".js", success: function(data, status, xhr) { displaySuccess($("#form")); }, error: function(xhr, status, error) { displayError(error); } }); displaySuccess = function(form) { var element; element = $("<p>Thanks for signing up!").addClass("success"); element.insertAfter(form); form.hide(); }; displayError = function(error) { $("#notice").attr("html", error); }; }); Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 25. jQuery $(function(){}) $ -> $("form").submit (event) -> event.preventDefault() url = $(this).attr "href" $.ajax url: url + ".js" success: (data, status, xhr) -> displaySuccess($("form")) error: (xhr, status, error) -> displayError error displaySuccess = (form) -> element = $("<p>Thanks for signing up!").addClass("success") element.insertAfter form form.hide() displayError = (error) -> $("#notice").attr "html", error Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 26. jQuery event handler $ -> $("form").submit (event) -> event.preventDefault() url = $(this).attr "href" $.ajax url: url + ".js" success: (data, status, xhr) -> displaySuccess($("form")) error: (xhr, status, error) -> displayError error displaySuccess = (form) -> element = $("<p>Thanks for signing up!").addClass("success") element.insertAfter form form.hide() displayError = (error) -> $("#notice").attr "html", error Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 27. jQuery $.ajax $ -> $("form").submit (event) -> event.preventDefault() url = $(this).attr "href" $.ajax url: url + ".js" success: (data, status, xhr) -> displaySuccess($("form")) error: (xhr, status, error) -> displayError error displaySuccess = (form) -> element = $("<p>Thanks for signing up!").addClass("success") element.insertAfter form form.hide() displayError = (error) -> $("#notice").attr "html", error Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 28. success and error callbacks $ -> $("form").submit (event) -> event.preventDefault() url = $(this).attr "href" $.ajax url: url + ".js" success: (data, status, xhr) -> displaySuccess($("form")) error: (xhr, status, error) -> displayError error displaySuccess = (form) -> element = $("<p>Thanks for signing up!").addClass("success") element.insertAfter form form.hide() displayError = (error) -> $("#notice").attr "html", error Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 29. -> leaves (this) scope alone. $ -> $("form").submit (event) -> event.preventDefault() url = $(this).attr "href" $.ajax url: url + ".js" success: (data, status, xhr) -> displaySuccess($("form")) error: (xhr, status, error) -> displayError error displaySuccess = (form) -> element = $("<p>Thanks for signing up!").addClass("success") element.insertAfter form form.hide() displayError = (error) -> $("#notice").attr "html", error Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 30. => Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 31. => binds this to the function body $ -> $("form").submit (event) -> event.preventDefault() url = $(this).attr "href" $.ajax url: url + ".js" success: (data, status, xhr) => displaySuccess($(this)) error: (xhr, status, error) -> displayError error displaySuccess = (form) -> element = $("<p>Thanks for signing up!").addClass("success") element.insertAfter form form.hide() displayError = (error) -> $("#notice").attr "html", error Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 32. Comprehensions Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 33. Simple iteration alert color for color in ["red", "green", "blue"] var colors = ["red", "green", "blue"]; for (i = 0, length = colors.length; i < length; i++) { var color = colors[i]; alert(color); } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 34. “for in” people = [ {name: "Homer", age: 42} {name: "Bart", age: 10} ] for person in people alert "#{person.name} is #{person.age} years old" Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 35. That’s just the beginning. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 36. Existential operator (?) total ?= 0 if (typeof total !== "undefined" && total !== null) { total; } else { total = 0; }; Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 37. Object-oriented JavaScript Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 38. Classes var Person, p; Person = (function() { function Person(options) { this.firstname = options.firstname; this.lastname = options.lastname; this.age = options.age; } Person.prototype.fullname = function() { return "" + this.firstname + " " + this.lastname; }; return Person; })(); p = new Person({ firstname: "Brian", lastname: "Hogan" }); alert(p.fullname()); Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 39. Classes var Person, p; Person = (function() { function Person(options) { this.firstname = options.firstname; this.lastname = options.lastname; class Person this.age = options.age; constructor: (options) -> } @firstname = options.firstname Person.prototype.fullname = function() { @lastname = options.lastname return "" + this.firstname + " " + this.lastname; @age = options.age }; return Person; fullname: -> })(); "#{@firstname} #{@lastname}" p = new Person({ firstname: "Brian", lastname:="Hogan" p new Person }); alert p.fullname() alert(p.fullname()); Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 40. We can even extend classes! class basicWindow constructor: -> class mainWindow extends basicWindow @window = Ti.UI.createWindow({ constructor: -> backgroundColor: "#F5F5ED" super }) @window.backgroundColor = "#fff" open: -> @window.open() Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 41. How do we use it? In the web browser itself via Node.js With Ruby, via Guard Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 42. In the browser? <script language="text/coffeescript"> people = [ {name: "Homer", age: 42} {name: "Bart", age: 10} ] for person in people do (person) -> alert "#{person.name} is #{person.age} years old" </script> <script src="coffee-script.js"></script> (this is slow.) Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 43. With Node.js Install Node.js Install npm npm install -g coffee-script coffee --compile --output js/ coffee/ coffee -o js/ -cw coffee/ Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 44. Ruby and Guard Install Ruby gem install guard-coffeescript In our project guard init coffeescript guard Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 45. Guard watches input folders for changes and writes output files. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 46. Guard works with Sass too. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 47. Sass Syntactically Awesome Stylesheets Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 48. Sass gives CSS everything programmers want. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 49. CSS .sidebar { color: #000; border: 1px solid #000; } .sidebar p { margin-bottom: 20px; } .sidebar ul { margin-bottom: 10px; } .sidebar h1 { margin-bottom: 0; } .main{ color: #000; } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 50. CSS .sidebar { color: #000; border: 1px solid #000; } .sidebar p { margin-bottom: 20px; } .sidebar ul { margin-bottom: 10px; } .sidebar h1 { margin-bottom: 0; } .main{ color: #000; } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 51. CSS .sidebar { color: #000; border: 1px solid #000; } .sidebar p { margin-bottom: 20px; } .sidebar ul { margin-bottom: 10px; } .sidebar h1 { margin-bottom: 0; } .main{ color: #000; } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 52. Sass to the rescue! Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 53. Variables! $measure: 20px $color: #ce4dd6 .sidebar background-olor: $color border: 1px solid lighten($color, 20%) p margin-bottom: $measure ul margin-bottom: $measure / 2 h1 margin-bottom: 0 Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 54. Variables and helper functions! $measure: 20px $color: #ce4dd6 .sidebar background-olor: $color border: 1px solid lighten($color, 20%) p margin-bottom: $measure ul margin-bottom: $measure / 2 h1 margin-bottom: 0 Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 55. Scope with nesting $measure: 20px $color: #ce4dd6 .sidebar background-olor: $color border: 1px solid lighten($color, 20%) p margin-bottom: $measure ul margin-bottom: $measure / 2 h1 margin-bottom: 0 Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 56. Indented Sass SCSS $measure: 20px $measure: 20px; $color: #000 $color: #000; .sidebar .sidebar{ color: $color color: $color; border: 1px solid $color border: 1px solid $color; p p{ margin-bottom: $measure margin-bottom: $measure; } ul margin-bottom: $measure / 2 ul{ margin-bottom: $measure / 2; h1 } margin-bottom: 0 h1{ margin-bottom: 0; } } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 57. But wait... there’s more! Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 58. Modularization _mixins.scss @import "mixins"; @import "reset"; @import "base"; _reset.scss @import "fonts"; _base.scss _fonts.scss Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 59. Reusable Functions (mixins) blockquote { @mixin rounded($radius){ width: 225px; border-radius: $radius; padding: 15px 30px; -moz-border-radius: $radius; margin: 0; -webkit-border-radius: $radius; position: relative; } background: #faa; @include rounded(20px); } .button { cursor: pointer; color: #000; text-decoration: none; @include rounded(12px); } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 60. Mixins + Interation + Variables @mixin shadow($x, $y, $offset, $color) @each $prefix in "", -moz-, -webkit-, -o-, -khtml- #{$prefix}box-shadow: $x $y $offset $color Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 61. Mixins + Interation + Variables @mixin shadow($x, $y, $offset, $color) @each $prefix in "", -moz-, -webkit-, -o-, -khtml- #{$prefix}box-shadow: $x $y $offset $color box-shadow: 5px 5px 5px #dddddd; -moz-box-shadow: 5px 5px 5px #dddddd; -webkit-box-shadow: 5px 5px 5px #dddddd; -o-box-shadow: 5px 5px 5px #dddddd; -khtml-box-shadow: 5px 5px 5px #dddddd; } Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 62. Create well-organized folders and libraries of stylesheets. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 63. or use Compass. http://compass-style.org/ Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 64. Compass has helpers @import 'compass' @include box-shadow(#ddd 5px 5px 5px) box-shadow: 5px 5px 5px #dddddd; -moz-box-shadow: 5px 5px 5px #dddddd; -webkit-box-shadow: 5px 5px 5px #dddddd; -o-box-shadow: 5px 5px 5px #dddddd;} Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 65. How do we use it? via Sass via a supported IDE With Ruby, via Guard Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 66. with Sass Install Ruby $ gem install sass $ sass --watch sass:stylesheets Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 67. Ruby and Guard Install Ruby gem install guard-sass In our project guard init sass guard Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 68. Using Sass and CoffeeScript together Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 69. Mindscape Web Workbench http://www.mindscapehq.com/products/web-workbench Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 70. Ruby and Guard Install Ruby gem install guard-sass guard- coffeescript In our project guard init sass guard init coffeescript guard Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 71. Let’s talk deployment Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 72. Rails 3.1 and Capistrano Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 73. Asset Packaging Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 74. So instead of this... <link rel="stylesheet" href="stylesheets/layout.css"> <link rel="stylesheet" href="stylesheets/style.css"> <script src="javascripts/jquery-1.7.0.min.js"></script> <script src="javascripts/app.js"></script> Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 75. ...let’s do this: <link rel="stylesheet" href="assets/app.css"> <script src="assets/app.js"></script> Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 76. Ruby + Guard + Jammit Install Ruby $ gem install guard-jammit Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 77. Sass, CoffeeScript, Jammit watch Sass files for changes Place output css in tmp/ folder watch CoffeeScript files for changes Place output js in tmp/ folder Use Jammit to combine them. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 78. config/assets.yml stylesheets: app: - tmp/app.css - tmp/style.css javascripts: app: - javascripts/jquery-1.6.4.js - tmp/app.js Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 79. Guardfile guard "coffeescript", :input => "coffeescripts", :output => "tmp" guard "sass", :input => "sass", :output => "tmp" guard "jammit" do watch(/^javascripts/(.*).js/) watch(/^stylesheets/(.*).css/) watch(/^tmp/(.*).js/) watch(/^tmp/(.*).css/) end Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 80. Jammit places files in public/assets <link rel="stylesheet" href="assets/app.css"> <script src="assets/app.js"></script> Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 81. Deploy with Rake SERVER = "yourhost.com" USERNAME = "yourusername" REMOTE_FOLDER = "/home/#{USERNAME}/yourhost.com" REMOTE_FOLDER = 22 require 'net/scp' desc "compile CSS, js files" task :compile do require 'guard' Guard.setup Guard::Dsl.evaluate_guardfile Guard::guards.each{|guard| guard.run_all} end desc "Deploy web site" task :deploy => :compile do Net::SSH.start(SERVER, USERNAME, {:port => PORT} ) do |ssh| ssh.sftp.rmdir File.join(REMOTE_FOLDER, "public") ssh.scp.upload! "public", REMOTE_FOLDER, :recursive => true end end Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 82. qedproject https://github.com/napcs/qedproject Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 83. qedproject Install Ruby gem install qedproject qedproject myapp -c -s -a -l jquery creates app with Sass, CoffeeScript, Asset packaging, and jQuery Sets up Guard and a simple Rake file for deployment Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 84. Demo Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 85. Short syntax Nested Selectors Catch errors at compile time Variables List Mixins Comprehensions Composition Classes Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 86. With asset packaging and automated deployment... Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 87. ...CoffeeScript and Sass make developers happy. Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682
  • 88. Questions? http://pragprog.com/book/wbdev/web- development-recipes Brian P. Hogan twitter: @bphogan www.webdevelopmentrecipes.com Rate this talk at http://spkr8.com/t/8682

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. Everyone who&amp;#x2019;s done something on the web knows something about these languages.\n
  5. Despite the new properties from CSS3, the language itself lacks basic features that programmers expect.\n
  6. \n
  7. Instead many developers go out to StackOverflow and swipe some code, slap it in the project, and cause all sorts of trouble for previous developers.\n
  8. The solution is for us to use better tools and workflows to build our applications.\n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. It borrows the indentation of Python and some of the language features of both Python and Ruby.\n
  17. \n
  18. \n
  19. Variable declarations are all done by omitting the var keyword. CoffeeScript automatically adds this so we don&amp;#x2019;t accidentally get a variable in the wrong scope.\n
  20. We can define functions many ways in Javascript. These are the two most popular - we can use &amp;#x201C;function declarations&amp;#x201D; or we can use function expressions. \n
  21. The thin arrow defines our functions. If we want to take in parameters, we list them before the fat arrow. Everything within the function is indented. \n
  22. If we have no params for our function, we simply use the dash rocket. If we do want to have params come in, we can specify them before the dash rocket in parentheses.\n
  23. CoffeeScript always turns out regular JavaScript, but some of that JavaScript can be really, really hard to follow, so people don&amp;#x2019;t write it very often.\n
  24. Let&amp;#x2019;s take a look at this jquery example. We have a form submission, and we have two events attached to the ajax request we fire during the form submission. It&amp;#x2019;s a lot of callbacks and it&amp;#x2019;s a bit hard to follow.\n
  25. We can replace the documentReady jQuery method with a simple dollar sign and a dash rocket\n
  26. Then we can locate an element just like we would with jQuery, but we declare the click handler with the dash rocket again.\n
  27. jQuery&amp;#x2019;s ajax method takes a settings object. We can define the object literal using CoffeeScript&amp;#x2019;s syntax\n
  28. Then since CoffeeScript uses the function expression form of function declaration, we declare the success and error callbacks using the same dashrocket feature.\n
  29. the &amp;#x2018;this&amp;#x2019; keyword references the current context we&amp;#x2019;re in. In the submit handler, (this) refers to the element that received the click. But in the success handler, we don&amp;#x2019;t have access to that element anymore - &amp;#x2018;this&amp;#x2019; has changed so we have to use jquery again to grab the element.\n
  30. This is the fat arrow. It works like the thin arrow except for one very important feature - it passes the scope of this into the function\n
  31. Now &amp;#x201C;this&amp;#x201D; is bound and handled for us. We do a lot of hacks to avoid this in JavaScript. CoffeeScript gives us a language feature to solve that.\n
  32. We can use CoffeeScript syntax to loop over collections much more easily.\n
  33. Like in Ruby, we can iterate over arrays easily. This is equivalent to the typical &amp;#x201C;for&amp;#x201D; loop we are all used to writing\n
  34. We can even iterate over collections of objects this way. This writes 100% cross-browser javascript code. We often bring in things like Underscore.js or jquery just for things like this, but with CoffeeScript we&amp;#x2019;re not forcing our users to download those libraries just so we can have some convenience.\n
  35. CoffeeScript has some amazing syntax that saves us some time.\n
  36. We can use this to initialize a variable if it&amp;#x2019;s not already defined.\n
  37. JavaScript isn&amp;#x2019;t really an object-oriented language, even though programmers pretend it is. \n
  38. We can have classes in JavaScript. But to do that, we&amp;#x2019;d need to write monster code like this.\n
  39. We can replace that with this CoffeeScript code.... which is a LOT nicer.\n
  40. \n
  41. but how do we actually *use* it?\n
  42. We can use it in the browser. CoffeeScript is actually written in CoffeeScript, thus the interpreter is a JS file.\n
  43. We can also install Node.JS and NPM to get the &amp;#x2018;coffee&amp;#x2019; command on our machines.\n
  44. Or we can use Guard and Ruby. \n
  45. Guard is a simple commandline utility that watches folders for changes and executes tasks. It works on Windows and OSX and many Linux flavors.\n
  46. More on Guard in a bit, but first, let&amp;#x2019;s talk about Sass\n
  47. Sass is how I write my stylesheets\n
  48. As a programmer, I miss certain things in CSS, like variables and functions\n
  49. Look at how much CSS makes us repeat ourselves. We have to repeat this sidebar selector three times just so we can specify that we want to target elements within the sidebar scope.\n
  50. These repeated color codes make it hard for us to refactor styles later.\n
  51. And look at these measurements. These should be computed or something.\n
  52. \n
  53. We can declare variables and even work with them. Notice that the 20px value can be divided, while still retaining its suffix?\n
  54. We can also work with colors. We can use functions to alter the colors.\n
  55. And we can nest selectors so we can avoid repeating ourselves. This makes scoping so much more apparent.\n
  56. There&amp;#x2019;s a different syntax, if the whitespace indentation stuff isn&amp;#x2019;t your thing.\n
  57. The variables and nesting go a long way to making our CSS less repetitive, but we can go even farther.\n
  58. We can break up our styles into smaller files that we can compose together, and then build one main stylesheet out of those parts.\n
  59. We can create mixins, or reusable functions to build up a library of common, useful features for our stylesheets.\n
  60. And we can make them even more powerful, by combining mixins and iteration with our variables.\n
  61. This is a great way to reduce duplication in our code.\n
  62. We can then create some pretty amazing collections of reusable code.\n
  63. But we can also use Compass, a nice framework for working with Sass\n
  64. So instead, we just use Compass&amp;#x2019; helpers instead of building our own. And there are a lot of them.\n
  65. but how do we actually *use* it?\n
  66. \n
  67. Or we can use Guard and Ruby. \n
  68. So now you&amp;#x2019;re all excited about these things.\n
  69. Support in Visual Studio 2010 for Sass and CoffeeScript\n
  70. Or we can use Guard and Ruby. Guard can watch for CoffeeScript and Sass files at the same time.\n
  71. Deployment should be automated. The days of moving files by FTP should be over, so there should be some script or process that pushes apps to production.\n
  72. Basically done for you thanks to the asset pipeline. Deployment is handled by Capistrano tasks.\n
  73. We&amp;#x2019;ve got all these stylesheets and JavaScript files, but our browser shouldn&amp;#x2019;t have to make people download all of these files.\n
  74. This makes the end user download multiple files which means additional HTTP requests.\n
  75. Let&amp;#x2019;s combine our css and JS files so we eliminate the need for those extra requests.\n
  76. To do this, we can use Ruby, Guard, and Jammit.\n
  77. We can put Guard to work along with Jammit, an asset packager which will combine our JS and CSS files into single files, with compression.\n
  78. So we list our stylesheets that we want to combine, and we do the same with JS. We tell Jammit to look in the tmp folder, which is where Sass and CoffeeScript are placing the generated JS files. Our web page will reference these in the public/ folder\n
  79. This is a Guardfile that specifies the folders we want to watch. \n
  80. We just need to make sure our web page looks in the assets/ folder for the files.\n
  81. We then script the deployment. We could use any scripting language, really, but by using Rake, which is written in Ruby, we can actually invoke Guard and tell it to force compilation of our assets. When we run our deploy task, our compile task runs first, thanks to the =&gt; dependency declaration.\n
  82. qedproject is a simple command-line utility written in Ruby for creating projects that let you work with sass and Coffeescript. It&amp;#x2019;s a work in progress but I use it when I&amp;#x2019;m trying to figure something out.\n
  83. \n
  84. \n
  85. To sum it up, here are the main benefits to both of these technologies\n
  86. \n
  87. I&amp;#x2019;ve stopped writing regular CSS, and I&amp;#x2019;m looking to stop writing regular JavaScript. There are too many productivity advantages.\n
  88. Thanks for coming.\n