Digging into twitter bootstrap

22 Dec

I dove headfirst into twitter bootstrap a few weeks ago, here are some of my notes / findings.

How I use it – as part of a Rails 3.1 app, with SASS and Compass

Setup – pure CSS vs Less vs Sass

Twitter Bootstrap, Less, and Sass: Understanding Your Options for Rails 3.1

In my case we went with the twitter-bootstrap-rails gem – this lets us set variables in the bootstrap.less file and then we call another file that includes all of our sass. I spent a little time getting my custom variables in the bootstrap.less file to show up and then was a little disappointed with the amount of things you can do with the variables. A lot of the colors are hard coded in the source, even really obvious ones I suspect people would want to change, like filler color. In my opinion its almost so little, its a waste of time to get less up and running, might as well just overwrite static styles until better variables are available. Also from reading their response to issues on github improving the variable flexibility isn’t a high priority for them. (if you are already using less in your projects, then using some of the mixins may be helpful – I wanted to keep my project sass though, and found it easier to just create mixins on that side). All a matter of preference, I guess.

Note – if you are transitioning from using blueprint with compass make sure blueprint is really gone, I had some hidden places it was getting included and it does not play nice with Twitter Bootstrap.

Customizing the Look

For the most part this is self explanatory.

I did get tripped up in my attempt to overwrite the header and buttons in ie. The Compass mixin I used in my custom styles didn’t include the ie filter code which caused ie to fall back to the twitter bootstrap colors instead of just the background-color.  I added this mixin, sass mixin for ie linear gradient filter, and used it in addition to the compass gradient mixin.

So for exmaple:

.topbar-inner {
@include linear-gradient(color-stops($color_gray2, $color_gray));
@include ie-linear-gradient($color_gray2, $color_gray);
}

another way to handle it is to write a mixin that just kills the filter

@mixin kill-filter() {
 filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 -ms-filter: none;
 }

Modals Baby

Pretty modals were one of the reasons we are making the switch to twitter bootstrap.

Great intro – http://paynedigital.com/2011/11/bootbox-js-alert-confirm-dialogs-for-twitter-bootstrap

I’d stay away from using .fade with the modals as it breaks links and buttons in chrome (discussion of the issue)

You can add the close modal x, just adding <a href=”#” class=”close”>x</a> in the modal header, it styles and just works, magic!

Get the Gist

I pulled together some of the styles and mixins I found helpful getting Twitter Bootstrap and Compass to be a full solution for me. Still a work in progress, add / comment on twitter_bootstrap_addons.scss

Thankful

24 Nov

In the spirit of Thanksgiving, I wanted to jot down a few things I am thankful for:

  • My wife – who’s humor and support I couldn’t live without
  • My family – they are awesome!
  • My job – I absolutely love what I do, I am so lucky to have the opportunity to work on something I believe in and with kind and super smart people.
  • My friends – I’m fairly certain they are the best friends anyone could have
  • My community – Somerville rocks
  • My home
  • My health
  • The open source community – without it my job would be impossible

I’m sure there are tons of things I forgot, but at least its a start! Happy Thanksgiving everyone!

displaying rss feeds in your rails app

4 May

Its very common to need to display recent news / posts from a blog outside of your Rails application. There are a few javascript widgets (like google reader) that make it easy to do that, but they suck from a performance standpoint. Its pretty easy to roll your own, here’s an example of how:

I got most of my info from http://rubyrss.com/

This is my home_helper.rb file

require 'rss/1.0'
require 'rss/2.0'
require 'open-uri'

module HomeHelper
  
  def blog_feed
    source = "http://feeds.feedburner.com/37signals/beMH" # url or local file
    content = "" # raw content of rss feed will be loaded here
    open(source) do |s| content = s.read end
    rss = RSS::Parser.parse(content, false)
    
    html = "<ul>"
    rss.items.each do |i|
    html << "<li><a href='#{i.link}'>#{i.title}</a></li>"
    html << "</ul>"
    html
    
    end
  end
end

and then in my view I can just write

<%= blog_feed %>

You’ll see that it loops through all of the items in the feed by default, if you want to limit that you can use .first()

rss.items.first(3).each do |i|

This needs a little clean up and error handling but its gives you a basic idea how how to get a feed parsed and displayed on your site.

i have some places in a database and I want to show them on a map – a quick tutorial using google maps api and rails

3 Feb

There is a tutorial over on the Google Maps API article page that shows how to use PHP/MySQL and the Google Maps API v3 to create a map that polls data from a database and shows as markers. I put together some notes to do the same thing using Rails.

First I created a migration to add a places table.

class CreatePlaces < ActiveRecord::Migration
  def self.up
    create_table :places do |t|
      t.string :state
      t.float :lat
      t.float :lng
      t.string :website
      t.integer :user_id
      t.timestamps
    end
  end

  def self.down
    drop_table :places
  end
end

You'll notice that each user has a place, so I updated the models to make that association and add some validation.
in user.rb

has_one :place

in place.rb
class Place < ActiveRecord::Base
  attr_accessible :state, :lat, :lng, :website, :user_id
  
  belongs_to :user
  
  validates_uniqueness_of :state, :user_id, : on => :create
  validates_presence_of :lat, :lng
end

I then added CRUD functionality for the places and added in some data. (If you are new to Rails, check out the getting started guide)

Next you want to output this data to a format that google maps can pick up, I used JSON.

  def index
    @places = Place.with_user_data

    respond_to do |format|
      format.html # index.html.haml
      format.json { render :json => @places }
    end
  end

If this is your first time using JSON I suggest getting the JSON viewer for firefox and reading How To Read JSON Using JQuery.

You’ll notice I used a named scope when creating the places object, this is so that I could explicitly select all the fields that needed to rendered to the JSON file.
in place.rb

named_scope :with_user_data, {
    :select => "places.*, users.first_name, users.last_name",
    :joins => :user
  }

At this point all of the data should be ready to view.

http://localhost:3000/places.json

**note that this image shows an example using jurisdictions instead of places and with additional data, but you’ll get the point **

To display the map I created a separate controller, set the layout to nil, and then accessed the map via Fancybox.

That said the actual view code is very bare

=content_for :head do
   %script{:src => "/javascripts/places_map.js "}
%body
      #map

And then the map javascript

var map;
	var arrMarkers = [];
	var arrInfoWindows = [];
	
	function mapInit(){
		var centerCoord = new google.maps.LatLng(38, -97); 
		var mapOptions = {
			zoom: 3,
			center: centerCoord,
			mapTypeId: google.maps.MapTypeId.TERRAIN
		};
		map = new google.maps.Map(document.getElementById("map"), mapOptions);
		
		$.getJSON("/places.json", {}, function(json){
			$.each(json, function(i,item){
				$("#markers").append('<li><a href="#" rel="' + i + '">' + item.place.name + '</a></li>');
				var marker = new google.maps.Marker({
					position: new google.maps.LatLng(item.place.lat, item.place.lng),
					map: map,
					title: item.place.state
				});
				arrMarkers[i] = marker;
				var infowindow = new google.maps.InfoWindow({
					content: "<h3>"+ item.place.state +"</h3><p>"+ item.place.first_name + "&nbsp;" +  item.place.last_name + ", &nbsp;" + "</p>",
					maxWidth: 100   
				});
				arrInfoWindows[i] = infowindow;
				google.maps.event.addListener(marker, 'click', function() {
					infowindow.open(map, marker);
				});
			});
		});
		    
	}
	$(function(){
		// initialize map (create markers, infowindows and list)
		mapInit();
		
		// "live" bind click event
		$("#markers a").live("click", function(){
			var i = $(this).attr("rel");
			arrInfoWindows[i].open(map, arrMarkers[i]);
		});
	});

And there you have it.

Let me know if you have any questions or comments.

Spree templating (rails3, spree.3)

18 Jan

I recently started a new project that included a spree store and I hadn’t done a spree implementation since they changed their contemplating logic. I had a really hard time finding comprehensive documentation on how to ‘skin’ the site to match that of my clients, so here are my notes.

The setup – Rails 3, Ruby 1.9.2, Spree .30.1

Getting Spree running

Spree’s getting started guide is really helpful is getting the initial store up and running.

I decided not to bring over all the test data instead just created an admin user and started from scratch.

rake db:admin:create

Through the admin (/admin) configuration tab, you can change the store name and  title .

When you look around your spree app file structure you’ll notice you don’t see any of the views and if you edit the application layout nothing happens. To add your theme you will have to create an extension and make your customizations there.

Create an extension for your theme
First change the spree gemfile to in your Gemfile to

gem 'spree', :git => "git://github.com/railsdog/spree.git", :tag => "v0.30.1"

and run bundle install

You can then create the extension

rails g spree:extension foo

A foo folder will now be in your project directory.

You can edit the application layout /foo/app/views/layouts/spree_application.html.erb

I did all my stylesheet editing outside of the extension – public/stylesheets (doesn’t seem like a best practice, but it didn’t work when i added css inside of the extensions public folder)

Hooks
Now lets say you want to add some code to one of the views, hooks is the best way to do this. Hooks basically provide a bookmark in the code that you can insert_before, insert_after, remove, or replace.

This is from an older version, but it was the best explanation of how to use hooks I could find: Spree hooks (v 0.11)

Add hooks in the following file /foo/lib/foo_hooks.rb

class FooHooks < Spree::ThemeSupport::HookListener

insert_before :homepage_products, :text => "HELLO!"

insert_after :product_description do
'<p><%= link_to("Back to products", products_path) %></p>'
end
end

Note – I noticed that you have to restart rails server for the hook changes to work.

To get a full list of hooks you can run grep -rh ‘hook :’ core/app/views | sed ‘s/^.*hook\s*//;s/[, ].*//’ | sort | uniq   or view this basic list of hooks from the spree guides.

If you can’t access the part of the file you need with hooks, you can override the core views.

Overriding Spree Core Files
By default files in your extension will override the core files.

For example I copied
/Users/me/.rvm/gems/ruby-1.9.2-p0/gems/spree_core-0.30.1/app/views/products/index.html.erb
to /foo/app/views/products/index.html.erb
and then made the needed changes.

imageMagick, postgreSQL, git, macPorts -> a mess of errors and how I fixed it

18 Jan

It seemed like a simple task, install imageMagick, but the ramifications were far from simple. I’ll be honest, I’m not sure where exactly I went wrong, so bear with me as I walk you threw what happened to me and how I fixed it.

  • I installed ImageMagick (it takes forever by the way)
  • I went back into my project (a Rails 3 spree site) and it threw a postgres error
  • I went into some other projects (all Rails 2.x) and also got prostgres errors
  • After some researching I found info that suggested using the postgres-pr gem instead of pg, this fixed the Rails 2.x projects but not my Rails 3 project.
  • I took a break from dealing with this issue and decided to make a quick change to one of the Rails 2.x projects, when i went to commit, i got a git error
    git dyld: Library not loaded
  • A teammate had seen this error before and suggested I update MacPorts
    sudo port -d selfupdate
  • This again took forever, but once it was done, git was back to working and I was able to get my Rails 3 project up and running using the pg gem!
  • After restarting my computer postgresql server wouldn’t start. I had to reset the service that auto starts postgres server
    sudo launchctl load -w
    /Library/LaunchDaemons/org.macports.postgresql83-server.plist
    and restart and I was back to good.

I <3 middelman, a ruby static site generator

3 Jan

After using Rails for so many projects, going back to building a big static site was painful until I found middleman.

What I love about Middleman

  • super easy to get running
  • uses templates
  • utilizes haml / sass
  • you can use ruby helpers
  • nice workflow
  • its easy to migrate into rails – if the site switches over to an app
  • a lot of other goodies

So if you have an static site on the horizon, I highly suggest giving middleman a try.

A Week in the Life of a Web Dev / Project Manager

13 Dec

Like most people I wear lots of hats at work so I thought it would be interesting to write it all down and share with the world.

Monday
Monday is one of the two days of the week that I go into the office, it is by far my most business filled day of the week. Here’s what happened:

  • got into the office around 8:30 am
  • tested an app we moved over to a new server
  • wrote a blog post
  • reviewed scope and features list of a project that has resurfaced
  • compared beta launch website with full site architecture and sent content to do list to client
  • worked back and forth with a developer on a client timeline
  • helped an elearning client with some training
  • conference call to discuss custom feature list for spree e-commerce implementation
  • conference call to discuss setting up a blog
  • team meeting
  • recommend an approach for phase 2 of a project
  • reviewed testing feedback on a new product we are working on
  • 6 pm i finally opened terminal and textmate to start coding
  • working on the dashboard ux to new product, focused on fixing some styles and pulling stats from an account to display correctly.
  • called it a day a little after 7pm

Tuesday
A work from home day, which always feels nice after a long Monday.

  • Got up, made my coffee, ate an eggo, and hit inbox 0
  • reviewed our contractor hours, logged into projects, and passed on to payroll
  • quick call with a client about some press they are getting today and a few updates they wanted made before hand
  • updated manuals and training documentation for an elearning client
  • made some changes to a clients display of their twitter feed, cross browser fixes, deployed to production
  • created an outline of information needed to set up client blog
  • conf call with a client and their PCI compliance consultant
  • did some research and then a bunch of small tasks
  • tested a spree app for client feature requests and researched possible solutions
  • called it a day at 5:30

Wednesday
Another office day.

  • got into the office around 9am
  • helped an elearning client outline steps needed for switching courses over for the new year
  • made a pretty graphic timeline for a project
  • made a pre-launch checklist for another project
  • ran a monthly account report for a client and then projected tasks and budget for the next few months
  • worked on fixing a deployment bug
  • collaborated with team on finalizing new product pricing
  • spent lots of time in rails console working on some data associations
  • reviewed ux of a screen with team, made some front-end updates
  • send a proposal to a prospective client
  • answered a bunch of emails and called it a day around 7pm

Thursday
A work at home day

  • start working around 8am
  • followed up on a few things, hit inbox 0
  • start working on moving a site from middleman (a ruby static site generator) to a rails app
  • got side tracked with a publisher who misplaced a client ad placement, a client request for a proposal, and a lost deal
  • finished up transitioning the sites template and homepage to rails, deployed to staging
  • pulled down a new e-commerce site I need to do some work on, noticed it was in rails3, spent some time getting it running on my local
  • switched gears to a project that’s v2 is launching soon, worked on some bugs that only show up on the staging site
  • stopped working around 6pm

Friday
Another work at home day

  • fit in a short workout before sitting down at 9am
  • started off where i left off last night, working on a bug on the staging server, finally fixed it
  • reviewed the security of a bunch of new features, made some tweaks and notes to client clarifying roles
  • pulled together the details needed for a client invoice
  • started coding an area of an app that shows certain recent activity of account users
  • wrapped up my day around 4, needed to get a head start on the weekend!

inbox 0

6 Dec

A messy inbox drives me nuts, each morning I work down to inbox 0 and most nights before leaving work (unless it was a crazy day) i try and hit it again. I recently talked about hitting inbox 0 in presently (our internal microblog) and was asked how do i do it? Heres how:

  • I take it seriously and recognize that its a task that takes time
  • When I sit down to process my email I’m ready to focus on it, I close everything else but my browser running gmail  and my tasks.txt file
  • I start at the top and read each email at the end decided, does this require an action? If so, will that action take less than 2 minutes , if so I do the action (pulled from David Allens 2 min rule) and then file the email. If it will take greater than 2 minutes, I star the email, file it in my client folder/label and jot in down in my tasks.txt file. If the email requires no action I either trash it or file it
  • Once I’ve hit inbox 0, I go in and review my starred emails, making sure any completed / followed up on emails are removed and the right stuff is on my tasks list.
  • To fly threw this process, I find the gmail web interface with keyboard shortcuts enabled works best. s, v, label, j, enter, #, gi, gs, learn it, love it. Gmail keyboard shortcuts explained

my toolbox – a collection of my favorite helpers

2 Dec

I’ve started to an overview list of my favorite gems, plugins and solutions to common requests.

Take a peek over at github.

Follow

Get every new post delivered to your Inbox.