Here is where I post things

Laziness. Impatience. Hubris.

Sass for Beginners

I set out to learn about front-end architecture with grid systems because I haven’t done hands-on work with a grid system before, but quickly it became clear that I needed to learn some Sass fundamentals. Here’s a walkthrough of the features I learned about and my tips for folks at the same stage of learning.

First of all, for shame that my life has been Sass-less. I know many Sass developers and even attended the inaugural SassConf last year, so I have no excuse for not having used it on a personal project before. As a former full-time CSS writer, Sass always looked weird and confusing to me. I could grasp the use of variables and math, but pretty much everything else just seemed really complicated.

I started with the Team Treehouse Sass Basics course. It moves at a fairly slow pace, but is taught by the creator of Sass Hampton Catlin who is fairly silly in his presentation style, so it’s fun to watch. The super-simplified explanations helped me understand and internalize how Sass differs from CSS. Instantly, I could see how Sass makes CSS more Ruby-like, something I’m quite comfortable with on day thirty-something of my Ruby course.

Sass makes CSS more Ruby-like

After I became comfortable with the basic syntax of Sass, I gave up the Treehouse videos in favor of a great beginner slide deck that allowed me to work at my own pace: https://speakerdeck.com/anotheruiguy/sass-101-a-newbs-guide

Working with Sass

If you’re not in a Rails app that already has Sass, assuming you have Ruby installed, you can gem install sass. Then all you need to start working with Sass is a something.scss file. Run sass --watch . to have Sass watch your current directory and automatically compile something.css every time you save something.scss

Alternately, if you just want to see how the language works, you can try out the examples in Sassmeister

An important thing to know about working with Sass is that you don’t have to use any of it’s features if you don’t want. You can write plain old CSS in your Sass file and it will render fine, so you can really use the level of Sass you’re comfortable with and grow to the more advanced features gradually.

Nesting and Variables

One of the major banes of CSS is having to repeat yourself over and over again, and Hampton tells us in the Treehouse videos that the first and primary goal of Sass is not having to repeat yourself as much. Two of the simplest tools for this are nesting and variables.

When Sass compiles, it automatically writes the repetitive CSS selectors based on the nesting present in your Sass file. The & signifies a direct parent relationship. So, for example:

Sass:

.content .blog-entry {
    margin: 20px 0;
    p {
      color: gray;
      line-height: 1.2em;
    }
    a {
      color: blue;
      &:hover {
        text-decoration: underline;
      }
    }
}

Compiled CSS:

.content .blog-entry {
  margin: 20px 0; 
}
  .content .blog-entry p {
    color: gray;
    line-height: 1.2em; 
  }
  .content .blog-entry a {
    color: blue; 
  }
    .content .blog-entry a:hover {
      text-decoration: underline; 
    }

Not massively different, but you can see how on a real project with a large amount of style, this can save you considerable repetition. It also makes updating class names simple.

Variables can be defined with the $ operator to further DRY out your stylesheets.

Sass:

$full-screen: 900px;
$small-screen: 320px;

.content {
  width: $full-screen;
  @media only screen and (max-width: $small-screen) {
    width: 97%;
  }
}

Compiled CSS:

.content {
  width: 900px; 
}
  @media only screen and (max-width: 320px) {
    .content {
      width: 97%; 
    } 
  }

Extends

Extends allow you to add a selector to a previously defined block of code.

Sass:

.blog .entry {
  h1 {
    color: black;
    font: {
      size: 2em;
      weight: bold;
      variant: small-caps;
    }
  }
  h2 {
    font-size: 1.5em;
    @extend h1
  }
}

CSS:

.blog .entry h1, .blog .entry h2 {
  color: black;
  font-size: 2em;
  font-weight: bold;
  font-variant: small-caps; 
}
.blog .entry h2 {
  font-size: 1.5em; 
}

You can also use % to denote “silent extends” for reusable code blocks.

Sass:

%marquee-text {
  font: {
    size: 3em;
    family: Merriweather;
  }
}
.content-marquee {
  color: gray;
  @extend %marquee-text;
}
.media-marquee {
  color: purple;
  @extend %marquee-text;
}

Compiled CSS:

.content-marquee, .media-marquee {
  font-size: 3em;
  font-family: Merriweather; 
}

.content-marquee {
  color: gray; 
}

.media-marquee {
  color: purple; 
}

At this point, I’m not sure why silent extends exist, given mixins, but I’m just learning so I’ll give it some time to sink in.

Mixins

Mixins allow you to use the same block of style in various places throughout your code. The @mixin keyword is used to define a mixin block. If you pretend @mixin is def it all feels comfortably like a Ruby method!

@mixin border($radius, $style) {
  -moz-border-radius: $radius;
  -webkit-border-radius: $radius;
  border-radius: $radius;
  border: $style;
}

.blog .entry {
  @include border(5px, 3px solid white);
}

Mixins also support string interpolation(!)

Sass:

@mixin standard-border($side) {
    border-#{$side}: solid 1px gray;
}
.header {
    @include standard-border("top");
}

CSS:

.header {
  border-top: solid 1px gray; 
}

The thing that blew my mind the most (so far) is that Sass has an @each keyword that allows you to iterate in your stylesheet. Sass is seriously a dream come true for a CSS-er turned Ruby-ist.

Sass has an @each keyword that allows you to iterate in your stylesheet

Sass

@each $profile in github, twitter, linkedin {
  .#{$profile}-icon {
    width: 50px;
    height: 50px;
    background-image: url('/images/#{$profile}.png')
  }
}

CSS:

.github-icon {
  width: 50px;
  height: 50px;
  background-image: url("/images/github.png"); 
}

.twitter-icon {
  width: 50px;
  height: 50px;
  background-image: url("/images/twitter.png"); 
}

.linkedin-icon {
  width: 50px;
  height: 50px;
  background-image: url("/images/linkedin.png"); 
}

Now that I know some basics of Sass, I’m ready to tackle the grid systems I set out to explore. Stay tuned!

Sass references/resources:

Sass 101 speaker deck – Dale Sande

Sassmeister

Sass Basics – Team Treehouse, Hampton Catlin

Building a Responsive Image Search in an Hour With Sinatra

So I was gearing up to build something to work with APIs and practice Sinatra, but then I realized I was going to build a food app again. I decided I needed an influx of fresh ideas, so yesterday I asked my non-technical friend, Jackie, what I should build. She had two ideas, one of which sounded insanely difficult and the other sounded maybe easy enough to get done in time. Jackie is getting married this Spring and simply wanted a way to search for images, browse the results, and pin the ones that caught her eye to Pinterest, in effect building a wedding mood board.

Sinatra makes setting up web apps pretty simple and image searching is a pretty standard request, so I decided to give it a go.

Finding a search solution

First I checked out the Google Search API. It was a bit confusing and I wasn’t completely sure what features were available for web search vs custom site search or which features were free and which required a paid account. So, I turned to the comforting world of Ruby Gems and looked for a good wrapper. I found one called Google Search (aptly) that hadn’t been updated in a couple years, but I didn’t see any other options, so I gave it a try.

require 'google-search'
g = Google::Search::Image.new

The gem didn’t have too much documentation, so I played with it in irb a bit, and it seemed pretty straightforward. After requiring the gem and instantiating the class, I got an object I could try different methods on.

#=> <Google::Search::Image:0x00000102153990 @color=nil, @image_size=nil, @image_type=nil, @file_type=nil, @safety_level=nil, @type=:image, @version=1.0, @offset=0, @size=:large, @language=:en, @query=nil, @api_key=:notsupplied, @options={}>

Seeing that there was a query attribute, I figured I could shove something in there:

g.query = "kittens"

And running g.methods let me know that my object behaves like an enumerable.

g.each { |i| puts i.uri } #=> so many kittens, you have no idea

At this point, I felt comfortable that the google-search gem would at least meet my basic needs for image search functionality. Time to build!

Setting up Sinatra

I put together a basic Sinatra scaffolding, set up bundler and rspec. Once I get that running, I start thinking about my endpoints and how the search will work. I set up some routes and make sure the urls are working as expected when I rackup.

module JackieImageSearch
  class App < Sinatra::Base

    get '/' do

      erb :"index.html"
    end

    get '/search' do
      @term = params[:query]

      @search_results = Google::Search::Image.new
      @search_results.query = @term

      erb :"show_results.html"
    end

  end
end

Once the urls are set up, it takes me a few minutes of fiddling with it to get the controller and form working together properly.

<form action="/search" method="get">
  <label for="query">Search</label>
  <input type="text" id="query" name="query" />
  <input type="submit" value="search">
</form>

Once I have my get request actually passing it’s params to my results page, I’m ready to build out the view and my logic for displaying the results. I start with a simple list of image URLs, then after I confirm that is working, I built out the actual image tags as list items. And at this point, I realize I’m basically done! How awesome is it that you can build a working search in 45 minutes using open source tools?

Making it pretty

So, now I need to see if I can make it pretty. Or at least prettier. A long list of giant images is not so pleasant to scroll through. My initial thought is to just style the images to scale down to some reasonable size and display them in simple fixed-height/width rows. But I really hate the idea of a fixed width for this site, so I do a Google search for “responsive image grid” with pretty low expectations. I find a pure CSS solution that looks simple enough, copy/paste and adapt my erb to give it a try.

<section id="photos">
<% @search_results.each do |result| %>
    <img src="<%= result.uri %>" />
<% end %>
</section>

To my surprise, it works right away.

Results for green vase

Seamless Responsive Image Grid: http://css-tricks.com/seamless-responsive-photo-grid/

Adding the Pin buttons I knew would be fairly trivial because social apps like Pinterest always provide little JavaScript buttons for site admins to embed. I visit the Pinterest developer portal and snatch the “appear on hover” button. It only requires including a JS file, so I do so and test out the functionality. It works with the exception of denying my “localhost” source location.

So, could I improve the code? Yes. Could it use more style? Absolutely. But I’m pretty pleased that we live in a world where tools are readily available to build a working search with a remarkably Pinterest-like interface in under an hour.

Check it out on GitHub: https://github.com/NegaMorgan/jackie-image-search

Writing RSpec Tests for Dummies

This week I struggled with conceptualizing and expressing useful tests in RSpec. After getting past the basic DSL of RSpec, describe and it blocks, I would find myself lost about how to express my expectations.

My first instinct when I’m struggling with a concept is to read all the material I can find online and do any tutorials I can get my hands on, but everything I found on RSpec referred to the deprecated “should” syntax. I didn’t want to further confuse the issue in my head by reading materials that demonstrated a deprecated syntax. So I embarked on a trial-and-error process of building a simple class with some reasonably thorough tests.

I found a few resources and tricks that helped me get a handle on the subject.

Tests are just expect() paired with a “matcher”

Behaviour is asserted by pairing expect().to and expect().not_to with a Matcher predicate.

expect(a_result).to eq("this value")
expect(a_result).not_to eq("that value")

We have typically used the eq() method as a matcher, but it’s useful to know the other slightly different equality measures.

eq(expected) # same value
eql(expected) # same value and type
equal(expected) # same exact object

Basic matchers cheatsheet: https://learn.thoughtbot.com/test-driven-rails-resources/matchers.pdf

More matchers in RSpec docs: http://rubydoc.info/gems/rspec-expectations/file/README.md#Built-in_matchers

Fun with RSpec

If I see another artist or movie spec, I might jump out a window, so I decided to build a really simple little model of something I enjoy, gin.

class Gin
  attr_accessor :name, :style, :notes
  GINS = []
  def initialize
    GINS << self
  end
  def self.all
    GINS
  end
  def self.reset_all
    GINS.clear
  end
end

And now to the fun part, writing the tests.

  describe 'Gin Attributes' do

    let(:tanqueray) { Gin.new }

    it 'can have a name' do
      tanqueray.name = "Tanqueray"
      expect(tanqueray.name).to eq("Tanqueray")
    end

    it 'can have a style' do
      tanqueray.style = "London Dry"
      expect(tanqueray.style).to eq("London Dry")
      expect(tanqueray.style).to match(/London Dry/)
    end

    it 'can have multiple notes of flavor' do
      notes = ["angelica root","liquorice","juniper","coriander"]

      tanqueray.notes = ["juniper","coriander","angelica root","liquorice"]
      expect(tanqueray.notes.length).to eq(4)
      expect(tanqueray.notes).to match_array(notes)
      expect(tanqueray.notes).to have(4).notes
    end

  end

match() is great for when you need a regex. I also found match_array() useful. I especially like the readability of expect(tanqueray.notes).to have(4).notes. The addition of .notes at the end is not required and is pure sugar.

From there, I moved on to a new describe block to spec out my class methods. In addition to the standard eq(), I used a comparison operator, which is also supported.

  describe 'Gin class methods' do

    before(:each) do
      Gin.all.clear
    end

    it 'can list all Gins' do

      hendricks = Gin.new
      expect(Gin.all.length).to eq(1)

      barr_hill = Gin.new
      expect(Gin.all.count).to be > 1
    end

    it 'can reset the list of Gins' do
      gins = [Gin.new, Gin.new]
      Gin.reset_all
      expect(Gin.all.length).to eq(Gin.all.clear.length)
    end

  end

I didn’t get as far as I had intended with these tests, so I hope to follow this up with a further exploration of test set up and tear down. I had a tough time getting that to work elegantly so think I still have much to learn there.

Satisfy and custom matchers

If the standard matchers don’t work well for a given scenario, you can also use satisfy to get a little more manual with it, and RSpec also allows for custom matchers to be defined.

satisfy is valid for objects and blocks, and allows the target to be tested against an arbitrarily specified block of code.

    it 'can have multiple notes of flavor' do
      expect(tanqueray.notes).to satisfy {|n| n.count == 4}
    end

Other points I made note of along the way:

Add --format documentation to your .rspec file after you run rspec --init; this is helpful for the test writing process.

This was the most useful cheatsheet I found and is referenced throughout this article. https://www.anchor.com.au/wp-content/uploads/rspec_cheatsheet_attributed.pdf

My Productivity Set-Up With Alfred, Divvy and BetterTouchTool

Recently, I worked with a cantankerous but brilliant web developer who would always amaze me with how fast he did things on his computer. After several months of watching in awe, I demanded a full day productivity training, and he was kind enough to comply. These are the things I’ve learned and how I adapted them to better suit me.

For productivity and speed, the rule of thumb is: mouse/cursor is slow, keyboard is fast.

I tend to add that gestures are even faster. So, this is the set up I have to be super fast on my computer.

Alfred 2

The first thing my trainer introduced me to was Alfred. Much has been written about it, so I won’t go into great detail, but I don’t think of Alfred as a launcher; Alfred is my interface, my meta-GUI. Using Alfred means I don’t have to know where anything is on my computer. Anything. I don’t need to know how to interact with different websites and services, I can teach it to Alfred one time (workflow it), and then interact only with Alfred in the manner I have defined. In that sense, I deliberately make myself as dumb as possible about the location and functionality of individual applications and files. I don’t want to store that information in my brain, I want to abstract it out and delegate that responsibility to Alfred.

Before Alfred, I used OS X “Spaces” to group my open applications logically, then switched between the Spaces for different tasks. But, that meant an extra mental step of, “I want iTunes –> where is iTunes? –> it’s a personal app, so I keep it in my 4th space”. So in a sense, I’ve forced myself to perform logic every time I want to retrieve iTunes. With Alfred, Instead I can abstract that out to, “I want iTunes –> Alfred, give me iTunes,” which is less taxing on my brain and allows me to focus on other things. Over time, this has become an even shorter mental step for me of, “I want something…”, because as soon as my brain has the realization that I want something to materialize on my computer, I know that Alfred will give it to me. When I’m done with an application for the moment, I hide it command + h instead of switching spaces. I don’t care where it is if I’m not using it.

Also, pro-tip, you can store your Alfred preferences in Dropbox so it automatically syncs to all your computers. This is great for keeping work/home settings sync’d up.

Divvy

Divvy is a window manager; it resizes your application windows to predefined shapes and locations. You can choose your own custom hotkeys to control Divvy, I prefer:

ctrl + option + command + d

This brings up the Divvy interface for me, and I can manage my settings. Divvy allows you to define your own window shapes, choose your own shortcut keys, and set whether the command is application specific or global to all apps.

I want all my computer interactions to be stupid-simple, so I start all my Divvy commands with:

ctrl + option + command

The keys are right next to each other and it makes my commands unlikely to conflict with other applications. So, each Divvy command for me is my Divvy shortcut plus an option. I’m terrible with left and right, so I call left and right windows with my left and right arrow keys. Same for top and bottom. The rest are just letters I chose: m for middle, c for center, f for fullscreen, etc.

I stole my hotkey schema from my trainer, but his window configurations were arranged more around responsive web design, which I imagine Divvy would be an excellent tool for.

BetterTouchTool

BetterTouchTool is my dark horse candidate for favorite productivity app. The keyboard can be very fast, but there are some things that I do so often, that even punching two keys is taxing to my gentle sensibilities. I have become completely reliant on my BTT 3-finger-swipe system for managing my most used applications.

BTT allows you to define exhaustive, custom, and very specific gestures on your trackpad. I don’t do anything wildly complex with mine, really just four things I find key:

3 finger swipe down = close a tab

3 finger swipe up = open a tab

3 finger swipe left/right = move to the right/left tab (natural scrolling style)

3 finger double tap = hide an app

Sounds simple, un-earth-shattering, but when I’m in the midst of busy daily activities, the ability to close an unwanted window with such ease and simplicity is priceless to me. I use BTT heavily while interacting with Chrome, Sublime Text, and iTerm (my Terminal app). It makes it lightning fast to interact with tabs, even dare I say, fun. I don’t mind pop-ups at all anymore, they’re like whack-a-mole!

With Chrome, you have command + shift + t to restore an accidentally closed tab. And with Sublime, you’ll be prompted to save an unsaved file. With Terminal, on the other hand, it’s a little bit dangerous to use 3 finger swipe down, but I maintain my sessions with tmux, so I don’t have to worry about losing my place in what I’m working on.

Bonus: TextExpander

TextExpander is great for things you have to type over and over again and don’t want to store in your brain. It’s like variables for everything on your computer. So, you set a variable (“snippet”) in your TextExpander preferences, and then any time you type that string in any GUI application, TextExpander will expand that text into the value of your snippet.

The one catch is, you have to give the application access to everything you type on your computer.

I don’t use it all that much, but I know if I type ddate anywhere on my computer, it will expand to a formatted date for the current day. In fact, I had to disable it just to write this blog post. “ddate” is one of the default strings that is enabled for TextExpander.

In my last job, I used TextExpander for storing employee numbers because I needed to refer to them frequently, but couldn’t possibly remember them and didn’t want to have to manually look them up every day. I can see it being useful for frequently used blocks of code in Sublime.