New Company Blog
This week we launched an awesome redesign of collectiveidea.com that you should really check out.
As part of it, we have a new company blog. I’ll be writing a lot more over there in the coming months, so go subscribe.
I’ll keep this site around (maybe move it to new software) but posts will be less technical. We’ll see. I’m never been very consistent anyway; you won’t notice a difference.
Helpful Cucumber Steps
There are a few Cucumber steps that have made their way into more and more of our projects. I thought I’d share for fun.
WTF Steps
These are simple wrappers for things you can already do easily with Cucumber, but instead of having to toss them in individual steps, you can toss them right in the feature when you’re trying to see what’s going on.
Given some setup stuff
When i go to a troublesome page
And I see wtf is going on
Then the result is good
Time Steps
If you need to do anything with time, time zones, or whatever, Timecop is your new best friend.
I started using it on an app we were developing where I had two parties, potentially in different time zones, scheduling appointments with each other. I wanted to test in a few places that they were getting reminders at the right time, seeing the correct time in those reminder emails1, etc.
The first let’s you set the current time quickly. For example,
Given the time is 10:00 UTC
This was great for my emails where I wanted to know that it was showing the right time to the user. I did this, then checked that the time was 5 am for my user in Detroit:
And the time is Jan 1 2010, 10:00 UTC
The time passing step is great when you need to do things that are scheduled in the future. For my reminder example, an appointment reminder is sent 24 hours before the event. Here’s what I do in my features:
Given an appointment between "Bob" and "Sue" in 2 days
When 25 hours pass
Then an email is sent to "Bob"...
Enjoy!
1 I found my emails were wrong. I was setting Time.zone in the mailer, and outputting times in the body. I found I had to explicitly call .in_time_zone in the mailer view, which I hadn’t expected. Yay tests!
Fun with Favicons
Fun with Favicons
While listing out sponsors for our upcoming Tech Embassy, I wanted a way to show some logos without spending too much time.
Enter the favicon, you know the ubiquitous icon that sits next to the URL in your browser window.
I wasn’t content to clutter my markup with links, however, so I did it all with JavaScript.
Here’s the resulting rendering:

We simply iterate over the links, look for /favicon.ico, and add it as a background image to the left of the link. It has the nice side benefit of not showing a broken image if it can’t be found (hence all the missing ones in the image above).
Line 11 is a little bit of voodoo: CSS3 has support for background-size, which lets you resize the image. I needed this because one favicon was bigger than the typical 16×16px. This code works in current versions of FireFox and Safari 4. Other browsers aren’t so lucky, so use this at your own risk. In my case, the offending favicon wasn’t much of an issue, and I’m doing this for fun.
It would be nice if it would find favicons in locations other than /favicon.ico. It would be even nicer if everyone had apple-touch-icon.png files, but that’s a dream for another day.
HTML5 in the Wild
I was able to use HTML5 in the real world in a bit way recently, on the launch of Idea Foundry. Here is my report, with some fun goodies for Rails developers.
Please dig through the code and tell me what you think. I’d love to hear feedback about what we’re doing right/wrong/stupid. Or use it as an example to build your sites.
Fun with new elements
We’re using all sorts of fun new elements like <section> <article> <header> <footer> <nav> <aside> and <mark>
We’re using <section> to break up logical groups of content, and using the new recommended pattern of restarting headers at <h1> inside every section.
The result is that we don’t have anything other than <h1>s and <h2>s! Here is an example from the speakers section on the jQuery page:
<section id="speakers">
<h1>Speakers</h1>
<section>
<h1><a href="http://englishrules.com" class="url fn">Karl Swedberg</a></h1>
<img alt="Photo of Karl" class="photo" src="/images/karl_70.jpg?1239761601" title="Karl Swedberg">
<div class="note"><p>After having owned a coffee house, taught high school English, and edited copy for an advertising agency, Karl Swedberg began his career as a web developer four years ago. He now works for <a href="http://fusionary.com/">Fusionary Media</a> in Grand Rapids, Michigan, where he specializes in client-side scripting and interaction design. Karl is a member of the jQuery JavaScript Library project team and the co-author of the book <cite>Learning jQuery 1.3</cite>. His blog, <a href="http://learningjquery.com/">LearningjQuery.com</a>, is a popular source for jQuery tutorials, tips, and techniques.</p></div>
</section>
</section>
Because we’re nesting sections, that 2nd <h1> has the effect of being an <h2>. Depending on how deep you nest, it can change priority without changing code. This is one of the changes I’ve been looking forward to most, and I’m quite enjoying it.
I learned a lot more about how <header> and <footer> are meant to work. For example, I had our large lighter brown footer as the <footer>, but this is wrong as the footer is not meant to have sections inside. Instead, just the copyright line at the bottom is the footer. It surprised me a bit, but made sense when I thought about it.
SinsWins of Omission
I had a lot of fun leaving out the / in self-closing tags: <img src="example.png"> instead of <img src="example.png" />. This would have freaked me out in my XHTML-loving days, but I’ve been liberated.
A handy help is sensible defaults for the type attribute when including CSS and JS. You can leave off the type and get type="text/css" and type="text/javascript" assumed as the default.
A have a private branch of the site where I left off some optional closing tags: </p> </li> and even </body> but I left them in for now. Baby steps.
Rails Plugin
I made an experimental Rails plugin for HTML5 fun and it is up on GitHub.
What does it do? At the moment it overrides the default helpers to:
- Remove the default
type="text/css"andtype="text/javascript"values. - Remove the / on self-closing tags (
<link><img><input>etc.)
I don’t know what to add next, maybe some fun with forms. I simply began with what I wanted for Idea Foundry.
Conclusions
I like HTML5. I really didn’t need this project to tell me that, but it was a lot of fun to implement a real site in it. There are, of course, some IE quirks, but they are pretty easy to get around.
I’ve done far too much reading on HTML5 and associated specs over the years to think that these small items are much more than scratching the surface. They are, however, great starting points if you’re new to HTML.
HTML5’s biggest adoption hurdle is nothing technical. It is getting web developers to rethink their assumptions and practices. The brilliance is that you don’t have to change if you don’t want. All the new pieces are optional, not forced. Let’s go build some sites!
Idea Foundry
I haven’t talked about it here yet, but we spent the last few months rebranding Training by Collective Idea into Idea Foundry.
Why the change? Well first we ran into some trademark issues with our original name, so we fell back to Training by Collective Idea to get by. We really didn’t like how generic this sounded, so we went through what seemed like every name imaginable before settling on Idea Foundry.
We announced it a couple weeks ago with a design refresh and an incredible lineup of 6 back-to-back weeks this spring. We also have a new twitter account @ideafoundry so follow along! We’ll have lots more to announce this summer too.
I’m a bit excited.
Sorry Haml, you won't take over the world.
This passage from Smashing Magazine surprised me:
…recent versions of Rails let you take your pick of templating languages, and nowadays the Ruby interwebs have been all abuzz about an alternative system called Haml.
While I think Haml is very interesting and well done, the big secret is that it will never be mainstream.
Why? One simple reason: HTML is easier. Now I know lots of developers will say No way! HTML is verbose, confusing and hard to read
or Haml is so much cleaner and quicker to write.
Both of these are true, but everyone already knows HTML.
Everyone. Any kid who’s edited their blog template or MySpace page knows the basics of HTML. They might not know the best-practices, but they understand it. Haml might be cleaner and easier for the programmer brain, but HTML is universal.
Markup vs. Programming
This isn’t a case of lower level languages (assembly) being replaced by higher-level languages (C, etc.), but there’s a temptation to make that comparison. C code is effectively transformed into assembly code in the same way Haml is transformed into HTML. But markup languages are not programming languages.
Let me repeat that: markup languages are not programming languages.
A markup language isn’t meant to be translated from high to low level. I’m writing this in the Textile markup language, but it’s really nothing more than macros to help me write HTML quicker. HTML is the canonical format of this post.
In the same way, Haml is effectively a set of macros. Contrast this to other templating languages (see any blog or CMS). A templating language doesn’t try to reinvent HTML, rather it helps you write more HTML by interspersing programming. In the end, it’s all HTML.
Haml is harder
Why do I think Haml won’t ever be big? Because it’s too different. While all the templating languages vary a bit, they are all readable to anyone who knows HTML. Haml is readable to Ruby users, and that’s about it.
I won’t argue that Haml is cleaner, more concise or easier to code. The problem is that HTML is universal. Your Rails team might be quicker in Haml, but you’ve made your code less maintainable to others and less readable to the masses. Most designers are going to understand HTML even if they don’t write much of it.
I don’t want to say you shouldn’t use Haml or that it is bad in any way. Just realize that there are trade-offs to using a markup language that pretends to be a programming language. You may not like HTML or angle brackets, but they’re here to stay. It’ll take a sea change to get us off HTML, not a new way to write it.
measurement: The Voodoo Library
So over a year ago I wanted a Ruby library that could do measurement conversions. Inches to centimeters, gallons to cups, anything. I got a bit carried away and abstracted all the units into yaml files, while going on a metaprogramming binge in the 179-line library.
I never released it, and don’t entirely remember why I wanted it in the first place, but Brandon asked me about it today, so I pulled it up, it worked, and I pushed it to GitHub.
It works pretty well, and I have a decent set of units:
> include Measurement::Length
> Inch.new(12).to_centimeters
=> #<Measurement::Length::Centimeter:0x173c2b4 @units=30.48>
>
> include Measurement::Volume
> Milliliter.new(100).to_teaspoons
=> #<Measurement::Volume::Teaspoon:0x1720e88 @units=45.0>
All the units (with conversions and abbreviations) are in yaml files:
Meter:
abbreviation: m
prefix: si
Foot:
abbreviation: ft
to_base: 0.3048
Inch:
abbreviation: in
parent: Foot
to_parent: 1.0/12.0
And I’m having way too much fun with prefixes (mega-, centi-, etc.) in their own files:
mega:
prefix: M
base: 10
exponent: 6
kilo:
prefix: k
base: 10
exponent: 3
…
centi:
prefix: c
base: 10
exponent: -2
I’m not really sure how this whole thing works anymore, but I’m having fun looking at it again. Tell me what to add, or fork it yourself and let’s measure. In the meantime, ponder why beer, wine and oil barrels are all different measurements (36, 31, 42 gallons, respectively).
Elsewhere.
A few things to note that aren’t on this blog:
New Training Dates
We announced new dates for our training classes. We’ll be in San Antonio, Texas January 20–23 with both our Ruby on Rails and ExpressionEngine classes.
Then, we’ll be in Washington D.C. in March, but we are still finalizing the details.
We’ll obviously be back in Holland, Michigan in the spring. Follow the Training Blog to keep posted.
RailsTips
I wrote an article over at RailsTips.org about the fantastic Rails plugin, delayed_job. Check it out, and thanks to John Nunemaker for letting me rant on his blog for a change.
awesome_nested_set
Brandon posted a great article about our awesome_nested_set plugin for Rails. It was an article I was supposed to write months ago, so thanks to Brandon for taking over and talking about it. It’s a plugin that has been invaluable to use for a number of months, and I’m glad to see a lot of people using it.
IE7 and Google Maps
I had an issue with YardVote.com not showing my Google Map properly in IE7 (and probably IE6). The map would just be blank, and no errors were coming up.
The fix ended up being pretty simple though it took far to long to discover.
I was calling the map function using Prototype’s dom:loaded event. While this should work (prototype works around IE’s limitations), it wasn’t in IE. Not wanting to delay execution for good browsers, I ended up with this ugly code:
// Dunno why IE doesn't like dom:loaded.
if (Prototype.Browser.IE) {
Event.observe(window, "load", Map.show);
} else {
Event.observe(window, "dom:loaded", Map.show);
}
Certainly not ideal, but not that it works I can go back to doing fun stuff. Stupid IE.
YardVote.com
I had a fun idea last weekend and spent a few hours coding up what is now YardVote.com.
Walking around my very conservative town, I noticed a ton of Obama yard signs, and hardly any McCain signs. I had this conversation with a number of people before deciding to plot them on a map.
This is a big playground for me, so I’m going to be adding fun features and see where it goes. I don’t really have an agenda though. I was just curious what would happen. So far, a number of people have started logging signs as they drive home from work or bike. I want it to be more than just Holland, MI and I have some fun mapping features in the works for when the data gets unwieldy.
Check it out and tell me what you think. Oh, and the source is on GitHub so fork away!
On Tags and Hashtags
I’m at BarCamp Grand Rapids this weekend, where they’ve setup tags for us to use: barcampgrandrapids3 on most site, and #bcgr3 on twitter.
I have problems here.
- Standardize. Its nice that we’re thinking about a shorter tag for twitter, but we should use one tag across all services.
- Readability. Similar to the first point, #bcgr3 means nothing to the average person. At least #barcampgr would make sense to people who’ve heard of barcamps (and is also the name of the website).
- The ‘3’ is irrelevant. Every site that uses tags, also timestamps. Find me one that doesn’t, I dare you. Tagging each year’s camp the same makes it more searchable and then you can then filter based on dates if you want.
- Combine. Though this one probably won’t get adopted, using a combination of tags would be even more useful. If you tagged #barcamp and #grandrapids you would be searchable as the combination, and separately.
That’s all. Just wanted to rant. I hereby nominate #barcampgr as the One Tag to Rule Them All.
Excel has a per-cell character limit.
Note: Excel (on a 32-bit system) has a limit on the number of characters (bytes) per-cell that is somewhere around 32,000. NeoOffice’s limit (on a 64-bit system) is around 64,000. Careful when you’re shoving large amounts of text into a file.
This public service announcement has been brought to you by Frustration, and Debugging a CSV Exporter.
Training by Collective Idea
I’m really excited that we launched the site for Training by Collective Idea this afternoon.
Ours is a new take on training. Not only are we putting together amazing training courses (starting with Ruby on Rails) but we’re making it fun.
We’re starting by bringing people to Holland, Michigan. Most training takes place in an out-of the way hotel or conference center with no character. Holland in the summer simply feels like a vacation, and using the brand new CityFlats Hotel as our venue adds to the unique flavor of our Training.
Then, we’re not ending the day and sending you back to your room. We’re giving you opportunities to see the area and meet other Rubyists, as well as helping you explore on your own.
The content of the Rails Training has already been praised by students around the world. We’re not focusing just on the fun—we’re simply adding it on.
If you want to learn Ruby on Rails, this Training is for you. Sign up today and you can save 20%.
Git Submodules, Part 2
In response to my previous article, Ryan McGeary made some good comments that I think warrant a followup.
but isn’t there a small advantage to a piston or braid-like approach where all the files are in your own repository?
Definitely in some cases, but I value keeping my repository small over having everything inside. Especially during development, when I want to keep up-to-date with my submodules (especially Rails).
Once a project launches (and/or slows down), storing external dependencies in the repository is more desirable, and my opinion may change. Same goes for gems. I don’t like storing them in the project unless or until I need to.
Also, adding Piston/Braid is one more dependency.
What happens during deployments? Doesn’t the deployment now rely on a possible many remote repositories to succeed? Consider both vendor/rails and a possible many vendor/plugins each with their own submodule.
This is an important thought, and about the only thing that makes me hesitant about submodules, but I still like ‘em.
If you go with a typical Capistrano deployment, you’ll have to download each submodule each time you deploy (same as with svn:externals). This is one of the biggest problems I have with svn:externals, because if a single plugin wasn’t available (I’m looking at you, acts_as_taggable_on_steroids), it kills the checkout.
The same is true with git submodules but there is a very important difference: When you hit the network.
When I do a git pull, it doesn’t look at the submodules at all. Even if I changed them. Even when I do a git submodule update, it will only try to pull new files if I explicitly updated the submodule (see previous post).
Contrast that with svn:externals, which will have to hit the remote repository just to see if anything’s changed.
If you switch your deployment strategy to set :deploy_via, :remote_cache, your average deploy won’t look for submodule updates at all. You can safely deploy if a submodule isn’t available, as it will be already on the server, when you need to update a submodule, you can have a cap task to do that.
Obviously there are other ideas. Maybe I’ll post on that later too.
I think I also missed an important point. How does Matt’s git submodule update avoid pulling a later version of edge rails than the original revision that you intended? The .gitmodules file only seems to specify the public clone url without any commit revision.
The .gitmodules file only stores the paths, but the commit version does get stored with the main project. I created a project on GitHub to demonstrate what happens. Specifically look at this commit, which adds the submodule, to see what’s going on:
+Subproject commit 60be4b09f51d2560802ebd744893bb6f737ef57c
Clone the repository and see how it works locally too. Even though it includes all of Rails, the .git directory (and my github usage) is tiny.
Git Submodules
Now that everyone’s on Git, people are starting to play with submodules.
Here’s why you should too.
Just like svn:externals
- They aren’t stored in your repository.
- Only a reference to the location is stored (can be local or remote)
Just like Piston
- A reference to the commit is stored. It will be tied to that revision until you say otherwise.
This sounds kinda confusing, and at least one aspect is probably not what you expect.
Example
For MicroRevie.ws, I wanted to add Rails as a submodule, as I like living on the edge. I used Koz’s version on GitHub (since the official Rails git repo isn’t yet available), so in my git project I typed:
git submodule add git://github.com/NZKoz/koz-rails.git vendor/rails
This tells git where the code is from (remember, this could be local too) and where I want it to live.
If I then run git status I’ll see a new file called .gitmodules. The file looks like:
[submodule "vendor/rails"]
path = vendor/rails
url = git://github.com/NZKoz/koz-rails.git
Fantastic! Once I git add and git commit the files, they’re locked into my repository. They are not stored in my repository, however, just references. When I push the main MicroRevie.ws project up to GitHub, it small and fast (better than Piston!).
When Matt pulls down his copy of the project, he needs to run these two commands to use the submodules:
git submodule init
git submodule update
Updating a submodule
Here’s where submodules are more like Piston. You must explicitly update submodules. Here are the steps:
cd vendor/rails
git pull
cd -
git commit -a
Or in English: go into the submodule, pull updates, then get out and commit.
When you commit, you are again only committing a change in reference. You’re not storing tons of new updates, just a reference to the new revision. You can even go backwards, but that’s left as an exercise for the reader.
When Matt wants to get my changes, he can’t just do a git pull. He has to also type:
git submodule update
And he’ll be updated to the version I committed.
Is it worth it?
Yes. However, I’ve defended (and simultaneously cursed) svn:externals, so I’m not the final judge.
In the end though, I really like git submodules better than either externals or Piston. For me it comes down to:
- Don’t need any extra software (such as Piston, and yes I’m aware of Braid)
- Doesn’t clog up my repository with tons of extra files (Piston, again.)
- Doesn’t force me to the newest version (
like externals doUpdate: Mark points out in the comments that svn does allow you to specify a revision. Very good catch!, such as when Rails or rspec make incompatible changes… which has happened)
Try them out. At worst, you’ll remove the references and be out a few minutes of your time.