$30 off During Our Annual Pro Sale. View Details »

Front-end meta languages and the Rails 3.1 asset pipeline

Roy Tomeij
October 07, 2011

Front-end meta languages and the Rails 3.1 asset pipeline

Front-end code should be fun to write and fast to run. Combine front-end meta languages like Haml, Sass & CoffeeScript with the Rails 3.1 asset pipeline and achieve both.

This talk is geared towards people who want to get started with front-end meta languages. It was presented at ArrrrCamp 2011 in Ghent, Belgium.

Roy Tomeij

October 07, 2011
Tweet

More Decks by Roy Tomeij

Other Decks in Programming

Transcript

  1. None
  2. None
  3. Roy Tomeij 80beans & SliceCraft @roy roy@80beans.com

  4. Compilers don’t create bad code. Coders create bad code.

  5. What?

  6. What are front-end meta languages? Front-end meta languages are languages

    that compile to HTML, CSS or JavaScript.
  7. Why?

  8. Why? • Quick results • DRY (Don’t Repeat Yourself) •

    Unforgiving compilers, so less errors • Better performance "out of the box" • Code is easier to maintain and transfer
  9. Languages?

  10. Which languages? • Haml • Sass (& Compass) • CoffeeScript

  11. Haml

  12. Haml • Mature; version 1.0 dates back to 2006 •

    Runs on Ruby (with a gem for Rails) • Ported to e.g. PHP, Python, .NET, Java & Perl • Indentation based • Customizable output (minification, quotes, etc.) • Sadly, doesn’t come with Rails 3.1
  13. !!! %section#about %h1 About us %p.introduction = link_to 'foo', 'bar'

    #carousel.projects :javascript alert('initialize'); %form{:method => 'post'} %fieldset %legend Some form... <!DOCTYPE html> <section id="about"> <h1>About us</h1> <p class="introduction"> <a href="bar">foo</a> </p> <div id="carousel" class="projects"> <script> <![CDATA[ alert('initialize'); ]]> </script> </div> <form method="post"> <fieldset> <legend>Some form...</legend> </fieldset> </form> </section>
  14. LSassie

  15. Sass • Used to be part of Haml • Went

    solo in version 3.1 • Indentation based (.sass) and CSS-based (.scss) • Customizable output (minified, etc.) • Ships with Rails 3.1
  16. section color: #ff0 p.introduction font-size: 2em #carousel font-weight: bold &.projects

    background: #000 section { color: #ff0; } section p.introduction { font-size: 2em; } #carousel { font-weight: bold; } #carousel.projects { background: #000; } Sass CSS
  17. section color: #ff0 p.introduction font-size: 2em #carousel font-weight: bold &.projects

    background: #000 section { color: #ff0; p.introduction { font-size: 2em; } } #carousel { font-weight: bold; &.projects { background: #000; } } Sass SCSS
  18. Fancy stuff

  19. More Sass (fancy stuff) • Variables • Mixins • Partials

    • Operations & built-in functions (math, colors, etc.) • User defined functions • Way more!
  20. $contrast: #ff0 $hover: #ccc =link-with-border($side: top) color: $hover border-#{$side}: solid

    1px $contrast a color: $contrast background: image-url("rails.png") &:hover +link-with-border &.alternative +link-with-border(bottom) // Partials @import "homepage" @import "dir/*" @import "dir/**/*" a { color: #ff0; background: url(/assets/ ↵ rails-22b(...).png) } a:hover { color: #ccc; border-top: solid 1px #ff0; } a.alternative { color: #ccc; border-bottom: solid 1px #ff0; } <contents of partials>
  21. $color: white p width: ceil(10.4px + 2px) color: complement(green) color:

    $color color: desaturate(red, 20%) color: mix(rgba(255, 0, 0, 0.5), #00f) &:hover color: darken($color, 50%) p { width: 13px; color: purple; color: white; color: #e61919; color: rgba(63, 0, 191, 0.75); } p:hover { color: gray; }
  22. $grid-width: 40px $gutter-width: 20px @function grid-width($n) @return $n * $grid-width

    + ($n - 1) * $gutter-width a width: grid-width(3) a { width: 160px; }
  23. Comp ass

  24. Compass • Collection of Sass mixins and functions • Does

    the tedious work, like managing vendor prefixes • Handles image sprites (and the likes) • Has mixins for CSS frameworks like Blueprint, YUI, 960.gs
  25. @import "compass" .foo @include border-radius(10px) .be background-image: ↵ inline-image("flags/be.png") .foo

    { -moz-border-radius: 10px; -webkit-border-radius: 10px; -o-border-radius: 10px; -ms-border-radius: 10px; -khtml-border-radius: 10px; border-radius: 10px; } .be { background-image: ↵ url('data:image/ ↵ png;base64,R0lGODlhMAAw(...)'); }
  26. Sprites

  27. @import "flags/*.png" @each $country in au, be, es, nl, us

    .#{$country} background: sprite($flags, $country) .au, .be, .es, .nl, .us { background: url(/assets/flags- ↵ s78dbbc28c3.png) no-repeat; } .au { background-position: 0 0; } .be { background-position: 0 -44px; } .es { background-position: 0 -22px; } .nl { background-position: 0 -33px; }
  28. CoffeeScript

  29. CoffeeScript • Not a JS library • Works seamlessly with

    any JS library • Compiled code is JS Lint friendly • Ships with Rails 3.1
  30. some_var = 10 $('a').each -> console.log 'foo' foo = (bar)

    -> return false unless bar "Bar has #{bar} as value." this.available_globally = -> alert some_var (function() { var foo, some_var; some_var = 10; $('a').each(function() { return console.log('foo'); }); foo = function(bar) { if (!bar) { return false; } return "Bar has " + bar + " as value."; }; this.available_globally = function() { return alert(some_var); }; }).call(this);
  31. # Assignment number = 42 opposite = true # Conditions

    number = -42 if opposite # Existence alert "Arrrr!" if jack? (function() { var number, opposite; number = 42; opposite = true; if (opposite) { number = -42; } if (typeof jack != "undefined" ↵ && jack !== null) { alert("Arrrr!"); } }).call(this);
  32. # Object pirates = captain: name: "Jack Sparrow" clothing: "dirty"

    babe: name: "Elizabeth Swann" clothing: "dress" # Drink alcohol drink booze for booze ↵ in ['beer', 'wine'] (function() { var booze, pirates, _i, _len, _ref; pirates = { captain: { name: "Jack Sparrow", clothing: "dirty" }, babe: { name: "Elizabeth Swann", clothing: "dress" } }; _ref = ['beer', 'wine']; for (_i = 0, _len = _ref.length; _i < _len; _i++) booze = _ref[_i]; drink(booze); } }).call(this);
  33. Asset pipeline

  34. Rails 3.1 asset pipeline • Pre-processes assets • Uses Sprockets

    to concatenate and minify assets • “Fast by default” / Near zero configuration • Your web app will load faster • PS: It’s still early, there’s room for improvement
  35. Proper fingerprinting • No more “file.png?12345678” • Didn’t work 5-20%

    of the time • Issues with CDN’s & multi-server setups • Now: “file-37a52b9c.png”
  36. What goes where? • app/assets: application owned assets • lib/assets:

    your own (reusable) libraries • vendor/assets: third party assets, like jQuery plugins • In the end, it’s all compiled to public/assets • PS: You can still use “public” (I don’t)
  37. Chaining processors • Want to parse your Sass as ERB

    or something else first? • Name your file application.css.sass.something_else.erb • Use case: put the Rails ENV in a Sass variable
  38. Sprockets & Sass • Don’t use Sprockets directives for Sass

    • Use Sass’ @import instead
  39. Pre-compiling • Run “rake assets:precompile” • Concatenating-minifying-compressing-moving action

  40. Questions? and some goodies too @roy / roy@80beans.com

  41. More info • http://guides.rubyonrails.org/asset_pipeline.html • http://haml-lang.com/ • http://sass-lang.com/ • http://compass-style.org/

    • http://jashkenas.github.com/coffee-script/ • http://thesassway.com/ • CoffeeScript book available from http://pragprog.com/ (20% discount with code “arrrrcamp2011”) • Awesome intro slide by Ivana Setiawan
  42. Pictures • http://www.flickr.com/photos/uggboy/4087240166/ • http://www.flickr.com/photos/thisisnotaheidi/522583791/ • http://www.flickr.com/photos/kk/106960641/ • http://www.flickr.com/photos/8725928@N02/3125908458/ •

    http://www.flickr.com/photos/bjwolfebmx/2904133868/ • http://www.flickr.com/photos/roadsidepictures/1435060357/ • http://www.flickr.com/photos/martinlabar/75645691/ • http://www.flickr.com/photos/estherase/4124679737/ • http://www.flickr.com/photos/stuckincustoms/3930943796/