A private online five year diary

Part of my 2011 retrospective highlighted that i want to spend more time on fun pet projects.

As i was doing my retrospective i had an idea for an online 5-year diary. My mum has one, actually it used to be my nanna’s, and now mum is continuing it. I have heard, and i can imagine, that there is something rather nice about seeing what you were doing on this day years ago, and the memories it brings back.

Some people keep them going for much longer than five years: here’s one i found on flickr that spans one day over 11 years!

Pop's diary
Pop’s diary, by Rob Fenwick

I went to look in the shops to get some ideas about what 5-year diaries are like. Some key points i discovered: they have a bookmark so that it’s easy to get to today. They often have a lock and key: that gave me the idea that these things are private. They have a space at the top for reminders of birthdays and anniversaries.

I wanted to start my own online 5-year diary on the beginning of the year. On the 1st of January i began coding a Rails app, and by the evening fiveyeardiary.herokuapp.com existed! it looked like this:

Talk about lean startup! :D

By day 2 i’d grabbed the Twitter Bootstrap CSS and applied some styling like this:

As startup ideas go, this is quite terrible, because you have to use it for a year before it becomes really useful! So i decided to experiment with other views. As it’s a web app, we can mix things around in ways that you can’t in a physical book.

For example, wouldn’t it be interesting to see what you do every monday?

Or maybe you’d want to see it like a traditional diary, a week at a time:

Once i’ve got a few months in, it might also be interesting to see what i do on the same day of each month. We can do that! :)

I’ve been using it now for 3 weeks and i’m really liking it. As time goes on i’ve found i write more, and my entries have become more personal. Hence the blurring out! ;)

I really like the fact that this is not social and it’s not networking! Nothing i write here is going to appear in someone’s RSS feed, or get cross-posted to a blog, or announced on twitter or facebook. This is my private space for my private thoughts.

Soon i will add search capabilities. I have a vague idea about mood analysis of what you’ve written. I also see the possibilities of mobile apps, which is quite exciting. I’m aware that people will want to use this in very different ways, so i’m waiting to see what people want most.

If you would like to start your own five year diary, writing as much or little as you like every day, you can find it, currently here: fiveyeardiary.herokuapp.com. It may move at some point, but your private notes will be migrated securely.

It’s also open source, so if you prefer to host your own it’s easy to do so, either locally or on heroku. You can find out how at github.com/sermoa/fiveyeardiary

I’m keen for feedback, so please let me know what you’d like to see, and i’ll see what i can do! :)

Advertisements

Beautiful CSS3 buttons with SASS

I had a very pleasant experience yesterday of making some nicely styled buttons with no background images, just pure CSS, using SASS to help me. What i’m about to share is by no means new or innovative, but i was impressed by it, so i decided i would write about it.

SASS = Syntactically Awesome Stylesheets

SASS is CSS styling for programmers. As programmers, we are basically lazy. We hate repeating ourselves. If we can find a way of making our lives easier, we will take it. I really like SASS for its mixin capabilities and colour manipulation, which i will demonstrate here.

Rails 3.1 Asset Pipeline

I’m really enjoying Rails 3.1 because it makes using SASS so simple. You add any files you like (CSS, SASS, SCSS) into app/assets/stylesheets and it compiles them all up into one CSS file. On a production server it minifies it too. It does similar magic for javascript files, which you’re now welcome to write in the very brilliant CoffeeScript. I love it!

So, then, buttons!

Let’s start with a nice HTML5 nav element containing a few links we want to turn into buttons.

<nav>
  <ul>
    <li><a href='/carrots'>Carrots</a></li>
    <li><a href='/pineapples'>Pineapples</a></li>
    <li><a href='/ginger'>Ginger</a></li>
  </ul>
</nav>

So this is what we start with:

Basic list alignment

First of all, let me do some basic manipulation to remove the bullet points and line them up side by side. Notice how with SASS (or SCSS) you can nest CSS definitions very nicely.

nav {
  ul {
    list-style-type: none;
    padding-left: 0;

    li {                                                                                                                                       
      float: left;
      padding: 0 5px;
    }   
  }
}

Add a background colour

It would be really good if these buttons had a background colour, say something very fetching like purple. While i’m here i’ll also change the text colour to white, make the text a bit bigger, and bold, and add some padding.

nav {
  ul {
    list-style-type: none;
    padding-left: 0;
  
    li {
      float: left;
      padding: 0 5px;
  
      a {
        background-color: #618;
        font-size: 1.1em;
        font-weight: bold;
        color: #fff;
        padding: 4px 16px;
        text-decoration: none;
      }
    }
  }
}

The neat thing about SASS is we can start to take this styling out into a mixin module:

@mixin button-style($base-color) {
  background-color: $base-color;
  font-size: 1.1em;      
  font-weight: bold;     
  color: #fff;
  padding: 4px 16px;     
  text-decoration: none; 
}

nav {
  ul { 
    list-style-type: none;
    padding-left: 0;   

    li {
      float: left;
      padding: 0 5px;    

      a {
        @include button-style(#618);
      }
    }
  }                                                                                                                                            
}

Rounded corners

Now obviously, buttons need rounded corners, don’t they! I can write a mixin for that:

@mixin rounded-corners($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;                                                                                                                 
  border-radius: $radius;
}

@mixin button-style($base-color) {
  background-color: $base-color;
  font-size: 1.1em;
  font-weight: bold;
  color: #fff;
  padding: 4px 16px;
  text-decoration: none;
  @include rounded-corners(5px);
}

Box shadow

A bit of subtle shadow lifts the buttons off the page a bit:

@mixin box-shadow($h, $v, $radius, $spread, $color) {
  -webkit-box-shadow: $h $v $radius $spread $color;
  -moz-box-shadow: $h $v $radius $spread $color;
  box-shadow: $h $v $radius $spread $color;
}

@mixin button-style($base-color) {
  background-color: $base-color;
  font-size: 1.1em;
  font-weight: bold;
  color: #fff;
  padding: 4px 16px;
  text-decoration: none;
  @include rounded-corners(5px);
  @include box-shadow(1px, 1px, 3px, 0, #333);                                                                                                 
}

Text shadow

Some text shadow could also be quite nice. Notice as i’m going along i am building up SASS mixins that i can easily use in other places.

@mixin text-shadow($h, $v, $radius, $color) {
  text-shadow: $h $v $radius $color;
  filter: dropshadow(color=$color, offx=$h, offy=$v);
}
  
@mixin button-style($base-color) {
  background-color: $base-color; 
  font-size: 1.1em;
  font-weight: bold;
  color: #fff;
  padding: 4px 16px;
  text-decoration: none;
  @include rounded-corners(5px);
  @include box-shadow(1px, 1px, 3px, 0, #333);
  @include text-shadow(1px, 1px, 2px, #000);                                                                                                   
}

Gradient and colour manipulation

Now here’s a clever trick. To make the button more 3D i can apply a gradient, using a lighter version of the base colour that was passed in. Here SASS becomes really helpful.

@mixin linear-gradient($from, $to) {
  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from($from), to($to));
  background-image: -webkit-linear-gradient(top, $from, $to);
  background-image:    -moz-linear-gradient(top, $from, $to);
  background-image:     -ms-linear-gradient(top, $from, $to);
  background-image:      -o-linear-gradient(top, $from, $to);
}

@mixin button-style($base-color) {
  background-color: $base-color;
  font-size: 1.1em;
  font-weight: bold;
  color: #fff;
  padding: 4px 16px;
  text-decoration: none;
  @include rounded-corners(5px);
  @include box-shadow(1px, 1px, 3px, 0, #333);
  @include text-shadow(1px, 1px, 2px, #000);
  @include linear-gradient(lighten($base-color, 10%), $base-color);                                                                            
}

A sneaky little tip: reverse the gradient on hover. It gives a tactile feedback. You could also darken the box shadow if you wanted a different effect.

The hover gradient reverse made me realise that the buttons could do with a slight border. I’ll use 10% darker than the base colour. I’ll give a 1px border, but 2px or even 3px would also look cool, for a really bold effect.

@mixin button-style($base-color) {
  background-color: $base-color;
  font-size: 1.1em;
  font-weight: bold;
  color: #fff;
  padding: 4px 16px;
  text-decoration: none;
  border: 1px solid darken($base-color, 10%);                                                                                                  
  @include rounded-corners(5px);
  @include box-shadow(1px, 1px, 3px, 0, #333);
  @include text-shadow(1px, 1px, 2px, #000);
  @include linear-gradient(lighten($base-color, 10%), $base-color);

  &:hover {
    @include linear-gradient($base-color, lighten($base-color, 10%));
  }
}

Imagine you are hovering over the carrots button:

Inner glow

To show a different effect, you could inset the box shadow with a lighter colour to give a highlight. You can have two box shadows, but it’ll clutter up my mixins, so i’ll leave you to figure that out on your own if you want both the highlight and the shadow.

Oh, i’ve increased the border and the rounded corner radius to emphasise this effect:

@mixin inset-box-shadow($h, $v, $radius, $spread, $color) {
  -webkit-box-shadow: inset $h $v $radius $spread $color;
  -moz-box-shadow: inset $h $v $radius $spread $color;
  box-shadow: inset $h $v $radius $spread $color;
}

@mixin button-style($base-color) {
  background-color: $base-color;
  font-size: 1.1em;
  font-weight: bold;
  color: #fff;
  padding: 4px 16px;
  text-decoration: none;
  border: 2px solid darken($base-color, 10%);
  @include rounded-corners(7px);
  @include text-shadow(1px, 1px, 2px, #000);
  @include linear-gradient(lighten($base-color, 10%), $base-color);
  @include inset-box-shadow(0px, 1px, 2px, 0px, lighten($base-color, 50%));

  &:hover {
    @include linear-gradient($base-color, lighten($base-color, 10%));
  }
}

The triumphant finale

I now have some button styles that i can apply wherever i want them. Because i used SASS to manipulate the colours, i only need to pass the base colour and it will apply a nice gradient, borders and glow.

So still without changing the original HTML, i can do this:

@mixin green-button {
  @include button-style(#152);
}

nav ul li:first-child a {
  @include green-button;                                                                                                                       
}

And you see, i now have a green-button mixin that i can happily apply to any link i want to! This is why i like SASS: it turns styling into programming! :D

I should say, i know these aren’t the prettiest buttons. I am more interested in the technique than the design, and i’m making them less subtle than they would ideally be, to prove the effect. When i figured out these techniques this week i was privileged to work from a gorgeous design by John Ryan, and the results turned out much prettier than these! :)

Resources

Here are a few useful resources to do with CSS3 and button generations:

Cucumber running headless Selenium with Jenkins (the easy way)

Selenium is a great way to test your javascript from Cucumber. It opens up a browser and you actually see it clicking around, filling in fields and submitting forms right before your eyes. It’s cool.

Jenkins is a brilliant continuous integration and deployment tool. I recently set it up for a new project i’ve started. It checks for git commits, pulls the latest code, runs all the specs and cucumber scenarios, and if they all pass, it deploys the code to five different websites. It’s great because we just have to git push and all five websites will get updated.

But Jenkins runs all its commands on the command line, and it doesn’t actually have a display on which it can run a browser. This isn’t too big a problem. You can use Xvfb virtual frame buffer which can emulate a display for you.

The old way to do this was to configure Xvfb to make a display (we usually use 99 to avoid conflicts) and write little shell scripts to start and stop this display, and export an environment variable to make sure the display is used ………… YAWN!

Now enter the gem headless. It does all those boring things behind the scenes, making it much simpler. I got this tip from 8th light’s blog post Jenkins, RVM, and Selenium. To get headless Selenium you simply have to do the following:

Install Xvfb:

sudo apt-get install xvfb

Require headless in your Gemfile:

gem 'headless'

Add this little snippet to features/support/env.rb:

if ENV['HEADLESS'] == 'true'
  require 'headless'

  headless = Headless.new
  headless.start

  at_exit do
    headless.destroy
  end
end

Tag your cucumber scenarios with @javascript for those that require selenium.

Call cucumber like this:

HEADLESS=true cucumber

It Just Works™!

As an added bonus, when i’m working remotely i’m often tunelling via SSH to a shared screen on a remote server. I can use the same HEADLESS=true trick to run my selenium scenarios remotely.

Pretty autospec growl messages

It’s interesting how you can sometimes notice something through someone else’s eyes that you’d previously overlooked. This week i have been mostly working with my apprentice Despo on a Rails project. Despo noticed that running specs in Rails takes a long time to initialize, which something i am well aware of but i guess i’ve sort of got used to it.

So we decided to do something about it. The first thing we did was set up Spork. If you want to know how to do that i recommend this post by Chris: How to get Spork working NOW on Rails 3, Rspec 2 and Cucumber.

As Chris mentioned at the end of that post, autotest and autotest-growl play well with Spork, so that is what we did next. The results can be quite nice!

Autotest notices which files have changed and starts running the relevant specs:

Autotest notices modifications

Growl can be configured to show failure messages in red:

Growl can be configured to show failure messages in red

Success messages are shown in green:

Success messages are shown in green

Growl can also show when specs are pending:

Growl can also show when specs are pending

How did we achieve this?

Firstly you will need to install the gems autotest and autotest-growl. Either include them in a bundle, or install them system-wide if you want to use them across all projects.

If you use RVM for different versions of ruby you might find this command useful:

for version in $(rvm list strings); do rvm use $version@global && gem install autotest && gem install autotest-growl; done

Secondly you will need a .autotest file. You can either put it in your project’s root directory, or in your home directory ~/.autotest

Here is mine so you can see what it looks like:

#!/usr/bin/env ruby
require 'rubygems'
require 'autotest/growl'

Autotest::Growl::image_dir = File.join(ENV['HOME'], '.autotest_images')
Autotest::Growl::show_modified_files = true

Autotest.add_hook :initialize do |autotest|
  %w(.git .DS_Store db log tmp).each do |exception|
    autotest.add_exception(exception)
  end
  autotest.order = :random
end

Thirdly you will need to install Growl and configure it to your liking. I have mine set to Music Video because it’s so impossible to miss!

The only trouble with the Music Video style is it can only display one message at a time, so i make it fade in and last for just 1 second. Happily, with growl colouring, you don’t really need to read the message – the colour tells you immediately what happened.

The colours you need to set are:

  • Very Low for passed
  • Moderate for pending
  • Normal for info
  • Emergency for failed (or syntax error)

Here is my Growl configuration:

Here is my Growl configuration

Finally, if you want cute pictures to come up with your growl messages, you simply need to put them in ~/.autotest_images – named passed.png, pending.png, info.png, failed.png and error.png.

These are my autotest images

Running autotest

Now, of course, you need to know how to run it!

With Rails 3 you need

AUTOFEATURE=true autotest

With Rails 2 it’s

AUTOFEATURE=true autospec

If you only want to run specs and not features, just take away the AUTOFEATURE=true bit.

But what about FSEvent?

The normal behaviour for autotest is to constantly poll your filesystem looking for changes. This is wasteful as it will use a lot of CPU and drain your battery, but there is an alternative. From Mac OSX 10.5 onwards an FSEvent service reports modified files.

To make use of FSEvent, you should be able to just install the autotest-fsevent gem and require 'autotest/fsevent' in your .autotest file.

Unfortunately, when i tried it, the mere presence of the autotest-fsevent gem seems to cause the specs not to run. It notices changes but doesn’t do anything about them. So if anyone can help me to understand what’s up with that, i would be grateful!

In the mean time, i’m just trying to remember to stop autotest whenever i’ve finished using it.

Alphabetical Pagination, version 0.2.3

Thanks to a few people’s input we’ve got a few improvements and fixes to our alphabetical pagination plugin.

There is now a handy helper you can use for the pagination links:

<%= alphabetically_paginate(@pins) %>

At a request from our user experience guru, it lists all the letters of the alphabet and links the active letters. For example:

New alphabetical pagination helper

The best news is, the old way still works, so it’s backwards compatible. You don’t have to use the helper if you don’t want to.

Rails alphabetical pagination

A common problem we often run into at eden is paginating a list of things alphabetically. I thought it was possible with will_paginate but apparently not, so yesterday we created our own simple solution, and today we rolled it into a plugin.

Here’s a little tutorial of how to use it.

So i have a nice simple view of Gowalla pins ordered by name. Please forgive the scaffolding! ;)

Gowalla pins

This page is quite long. Of course, we could use standard pagination to make it 10 per page or something, but it wouldn’t be very helpful if you were looking for a pin with a particular name. You’d have to click through the pages to find it. Wouldn’t it be neat to list a page for each letter?

Enter paginate_alphabetically!

Simply install it as a plugin:

rails plugin install http://github.com/edendevelopment/paginate_alphabetically.git

Enable pagination in the model:

class Pin < ActiveRecord::Base
  paginate_alphabetically :by => :name
end

Make the controller fetch the right pins:


class PinsController < ApplicationController
  def index
    @pins = Pin.alphabetical_group(params[:letter])
  end
end

Add pagination links in the view:

<ul class='pagination'>
  <strong>Jump to:</strong>
  <%- Pin.pagination_letters.each do |letter| -%>
    <li><%= link_to(letter, pins_path(:letter => letter)) %></li>
  <%- end -%>
</ul>

Perhaps a touch of CSS:

ul.pagination {
  list-style: none;
  color: lightgray;
  padding: 1em 0.5em;
}

ul.pagination strong {
  color: black;
}

ul.pagination li {
  display: inline;
  font-size: 1.1em;
}

ul.pagination li:before {
  content: '| ';
}

And here it is:

Gowalla pins beginning with E

The cool thing is you can add this to any of your models, and paginate by any attribute you wish.

Tested with Rails 2.3.5 and Rails 3 release candidate.

Get it from github: http://github.com/edendevelopment/paginate_alphabetically
or RubyGems: http://rubygems.org/gems/paginate_alphabetically

Thanks to Tom, Enrique and tooky for their help making this.