<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

 <title>Warpspire</title>
 
 <link href="http://warpspire.com/" />
 <updated>2011-12-05T16:07:02-08:00</updated>
 <id>http://warpspire.com/</id>
 <author>
   <name>Kyle Neath</name>
   <email>kneath+warpspire@gmail.com</email>
 </author>

 
 <feedburner:info uri="warpspire" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://warpspire.com/feed" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry>
   <title>Knyle Style Sheets</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/638PHGPAAOU/kss" />
   
   <updated>2011-12-05T00:00:00-08:00</updated>
   <id>http://warpspire.com/posts/kss</id>
   <content type="html">&lt;p&gt;So I&amp;rsquo;ve been writing CSS for somewhere around 13 years now. Some might think I&amp;rsquo;ve learned the right way to write CSS in that time — but if you ask me all I&amp;rsquo;ve learned is the most efficient way to drive someone insane.&lt;/p&gt;

&lt;p&gt;CSS is complicated. It&amp;rsquo;s not object oriented. It&amp;rsquo;s not hierarchical. It&amp;rsquo;s a specificity based cascade applied to a dynamic hierarchical data structure that few people truly comprehend. Trying to impart this knowledge on someone is a very difficult task with extremely minimal rewards. I used to think that imparting this knowledge was the path toward writing maintainable CSS within a team.&lt;/p&gt;

&lt;h2&gt;Maintainability comes from shared understanding&lt;/h2&gt;

&lt;p&gt;It&amp;rsquo;s hard to define maintainability. In my eyes it has to do with creating an &lt;em&gt;shared understanding&lt;/em&gt;. Anyone who has owned an aircooled Volkswagen knows how to adjust valves on any other aircooled Volkswagen. This is because of one of the best technical books ever written: &lt;a href="http://www.amazon.com/Keep-Volkswagen-Alive-Step-Step/dp/1566913101"&gt;How to Keep Your Volkswagen Alive&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Everyone I know who owned a Bug, Bus, Ghia or Thing owns a copy of this book and &lt;em&gt;understands&lt;/em&gt; how to work on their car. This book is in large part responsible for that shared understanding.&lt;/p&gt;

&lt;p&gt;How can we create a shared understanding with CSS?&lt;/p&gt;

&lt;h2&gt;Documentation&lt;/h2&gt;

&lt;p&gt;For all of the talk of &lt;a href="https://github.com/stubbornella/oocss/wiki"&gt;Object Oriented CSS&lt;/a&gt;, &lt;a href="http://smacss.com/"&gt;SMACSS&lt;/a&gt; and pre-processors like &lt;a href="http://sass-lang.com/"&gt;SASS/SCSS&lt;/a&gt; &amp;amp; &lt;a href="http://lesscss.org/"&gt;LESS&lt;/a&gt;&amp;hellip; no one is talking about documentation.&lt;/p&gt;

&lt;p&gt;Documentation is the key to shared understanding.&lt;/p&gt;

&lt;h2&gt;Enter KSS&lt;/h2&gt;

&lt;p&gt;Inspired by &lt;a href="http://tomdoc.org"&gt;TomDoc&lt;/a&gt;, &lt;a href="https://github.com/kneath/kss"&gt;KSS&lt;/a&gt; attempts to provide a methodology for writing maintainable, documented CSS within a team. Specifically, KSS is a documentation specification and styleguide format. It is not a preprocessor, CSS framework, naming convention, or specificity guideline. This means it works great with ideas like OOCSS, SMACSS, SASS, and LESS.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve created a &lt;a href="https://github.com/kneath/kss/blob/master/SPEC.md"&gt;specification&lt;/a&gt; for KSS as well as a &lt;a href="https://rubygems.org/gems/kss"&gt;ruby gem&lt;/a&gt; to parse the documentation.&lt;/p&gt;

&lt;p&gt;In a nutshell, KSS looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="c"&gt;/*&lt;/span&gt;
&lt;span class="c"&gt;A button suitable for giving stars to someone.&lt;/span&gt;

&lt;span class="c"&gt;:hover             - Subtle hover highlight.&lt;/span&gt;
&lt;span class="c"&gt;.stars-given       - A highlight indicating you&amp;#39;ve already given a star.&lt;/span&gt;
&lt;span class="c"&gt;.stars-given:hover - Subtle hover highlight on top of stars-given styling.&lt;/span&gt;
&lt;span class="c"&gt;.disabled          - Dims the button to indicate it cannot be used.&lt;/span&gt;

&lt;span class="c"&gt;Styleguide 2.1.3.&lt;/span&gt;
&lt;span class="c"&gt;*/&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.button.star&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.button.star.stars-given&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.button.star.disabled&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The idea is to write simple, yet machine parseable documentation such that you can automatically create a living styleguide like this one:&lt;/p&gt;

&lt;div class="figure"&gt;
&lt;a href="http://assets.warpspire.com/images/kss/styleguide-full.png"&gt;
  &lt;img src="http://assets.warpspire.com/images/kss/styleguide-thumb.png" alt="Styleguide screencapture" /&gt;
 &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;KSS aims to create a shared understanding&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ve tried really hard to make sure that KSS is flexible enough to work with as many styles of CSS development as possible. It&amp;rsquo;s purpose is to create a shared understanding through code documentation and styleguides. Not to tell you how to write CSS.&lt;/p&gt;

&lt;p&gt;And well. I think that&amp;rsquo;s an important idea. Hope you like it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kneath/kss"&gt;https://github.com/kneath/kss&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/638PHGPAAOU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/kss</feedburner:origLink></entry>
 
 <entry>
   <title>Knyle style recruiting</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/gfWDONKioXg/knyle-style-recruiting" />
   
   <updated>2011-11-07T00:00:00-08:00</updated>
   <id>http://warpspire.com/posts/knyle-style-recruiting</id>
   <content type="html">&lt;p&gt;Otherwise known as Kyle Neath&amp;rsquo;s guide to hiring the best people in the world: an examination into why recruiters are useless piles of humanflesh hellbent on destroying the souls of good designers and developers across the world.&lt;/p&gt;

&lt;p&gt;Too harsh? Most likely. But here&amp;rsquo;s the thing: recruiters do not give a fuck about doing good in the world. They do not care about making people happy. They do not care about building a good company. They do not care about treating email addresses as human beings. They only care about their percentage.&lt;/p&gt;

&lt;h2&gt;Employees are the best recruiters&lt;/h2&gt;

&lt;p&gt;At its core, the idea of a recruiter never made sense. Are they going to be working with their hire? Are they a designer, developer, copywriter or someone who knows what kind of skills and personality traits to look for?&lt;/p&gt;

&lt;p&gt;No. They&amp;rsquo;re salespeople. And I bet they&amp;rsquo;re great at hiring other salespeople.&lt;/p&gt;

&lt;p&gt;It just seems so obvious to me that employees make the best recruiters. Recruiters have nothing to gain from a good employee, but employees have everything to gain. If you consider yourself a manager, don&amp;rsquo;t you want to be responsible for building the team of people you&amp;rsquo;re going to manage? If you&amp;rsquo;re a developer, don&amp;rsquo;t you want to work with other great developers?&lt;/p&gt;

&lt;h2&gt;How I hire people&lt;/h2&gt;

&lt;p&gt;I happen to think I&amp;rsquo;ve become pretty good at recruiting over the years. We&amp;rsquo;ve built a pretty &lt;a href="https://github.com/about"&gt;amazing team&lt;/a&gt; at GitHub, and I&amp;rsquo;d like to explain how I go about finding the next GitHubber.&lt;/p&gt;

&lt;h3&gt;Friendship&lt;/h3&gt;

&lt;p&gt;If you want to hire great designers and developers, you should be friends with them. Be interested in who they are and what they do. This is not rocket science. When you&amp;rsquo;re friends with someone you&amp;rsquo;ll notice when they&amp;rsquo;re frustrated with their job or know when they&amp;rsquo;re looking for something new. And even if they&amp;rsquo;re not looking for something new — maybe they have a (designer/developer) friend who is.&lt;/p&gt;

&lt;h3&gt;Research&lt;/h3&gt;

&lt;p&gt;Take time to look up potential hires online. If you&amp;rsquo;re hiring in the tech industry, they&amp;rsquo;re almost certain to have an internet presence. Look up their current job. See what they do. Take a look on &lt;a href="http://dribbble.com"&gt;dribbble&lt;/a&gt;, browse their code on &lt;a href="https://github.com"&gt;GitHub&lt;/a&gt; — look at their work. More often than not, it&amp;rsquo;s completely unnecessary to interview for skills. You can find that out with a half hour online. Who knows, you might even find &lt;a href="http://ozmm.org/posts/who_we_hire.html"&gt;someone new to hire&lt;/a&gt; in the process.&lt;/p&gt;

&lt;p&gt;Research is the proper tool to &lt;strong&gt;understand whether someone has the skills to work for you&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;Grab a beer&lt;/h3&gt;

&lt;p&gt;It&amp;rsquo;s vitally important that you sit down face to face and &lt;a href="http://pjhyett.com/2010/05/27/the-beer-test.html"&gt;grab a beer&lt;/a&gt; with every potential hire. Or sit down for dinner. Smoke a joint. I don&amp;rsquo;t care what it is — you need to sit down in a relaxed environment and figure out what kind of person they are.&lt;/p&gt;

&lt;p&gt;Talk about their family, friends, hobbies, current job, dream job — anything you can think of. Some good things to figure out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this person a good human?&lt;/li&gt;
&lt;li&gt;Do they have a drive to build good things?&lt;/li&gt;
&lt;li&gt;Do &lt;em&gt;they&lt;/em&gt; want to work on the things &lt;em&gt;you&lt;/em&gt; want them to?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Grabbing a beer will help you figure out if &lt;strong&gt;someone will fit in.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;Job boards, Twitter, and advertising&lt;/h3&gt;

&lt;p&gt;I always try and use my personal connections to find potential hires first, but sometimes I come up empty handed. When that fails, you need to stretch out and get some new blood. There&amp;rsquo;s no shortage of Job boards out there: &lt;a href="https://jobs.github.com"&gt;GitHub Jobs&lt;/a&gt;, &lt;a href="http://dribbble.com/jobs"&gt;Dribbble&lt;/a&gt;, &lt;a href="http://jobs.37signals.com/"&gt;37Signals&lt;/a&gt;, &lt;a href="http://www.authenticjobs.com/"&gt;Authentic Jobs&lt;/a&gt; — the list goes on. Pick a few and post some ads. Maybe sponsor a &lt;a href="https://www.facebook.com/groups/sfdesignlunch/"&gt;local meetup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But remember you&amp;rsquo;re posting an &lt;strong&gt;advertisement.&lt;/strong&gt; This isn&amp;rsquo;t a fact sheet. Make that shit sexy. Make potential hires read it and think &lt;em&gt;I want that job.&lt;/em&gt; Explain specifically what they&amp;rsquo;ll be doing day to day, what they&amp;rsquo;ll be responsible for, and who they&amp;rsquo;ll be working with. Explain what your company is. Explain what it is your company wants to do.&lt;/p&gt;

&lt;p&gt;And if you have anything listed under requirements, you better damn well mean it. Don&amp;rsquo;t ask for a college degree if you don&amp;rsquo;t actually &lt;em&gt;require&lt;/em&gt; it. That&amp;rsquo;s just dumb.&lt;/p&gt;

&lt;h2&gt;Credit where credit is due&lt;/h2&gt;

&lt;p&gt;These ideas aren&amp;rsquo;t exactly unique, and in fact they&amp;rsquo;re really not even mine.&lt;/p&gt;

&lt;p&gt;In 2004 I was working for an agency and we hired a full time recruiter. Props to that man for showing me just how incompetent recruiters can be. Never in my life did I think someone would create a MySpace account and contact every teenager in the city trolling for leads. He really redefined the phrase &lt;em&gt;unqualified candidate&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In 2009 I started working with &lt;a href="https://twitter.com/defunkt"&gt;Chris&lt;/a&gt;, &lt;a href="https://twitter.com/mojombo"&gt;Tom&lt;/a&gt; and &lt;a href="https://twitter.com/pjhyett"&gt;PJ&lt;/a&gt;. For every person that thinks GitHub&amp;rsquo;s success is due to luck — I want to remind you how important the &lt;em&gt;people&lt;/em&gt; are in a successful company. And these guys spend a lot of time making sure we have the right people.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://tom.preston-werner.com/2008/11/03/how-to-meet-your-next-cofounder.html"&gt;How to meet your next cofounder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/6443"&gt;Getting a job with open source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Spend time on recruiting: it&amp;rsquo;s important.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/gfWDONKioXg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/knyle-style-recruiting</feedburner:origLink></entry>
 
 <entry>
   <title>Mustache, ERB and the future of templating</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/0H1ok_9WoaI/mustache-style-erb" />
   
   <updated>2011-10-17T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/mustache-style-erb</id>
   <content type="html">&lt;p&gt;There are days that I feel like I&amp;rsquo;ve spent the better part of my life inside templating languages. I&amp;rsquo;ve rocked hundreds of different styles of templates over the past 8 years. Smarty,  vBulletin templates, generations of Wordpress, J2EE, XSLT, CFML, ERB, HAML, Mustache and every form of in-house bastardized template language that exists.&lt;/p&gt;

&lt;p&gt;So when I say that &lt;a href="http://mustache.github.com"&gt;{{ mustache }}&lt;/a&gt; is my favorite templating language I&amp;rsquo;ve ever worked with, I mean it with a great deal of sincerity and experience. It&amp;rsquo;s syntactically elegant, focused on output (HTML), encourages documentation, and discourages unmaintainable magic. I want to use it everywhere.&lt;/p&gt;

&lt;h2&gt;I mustache you, why mustache?&lt;/h2&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/mustache-erb/mustache.png" alt=-"Mustache - Logic-less template" /&gt;&lt;/div&gt;


&lt;p&gt;Mustache is more than a syntax. It&amp;rsquo;s a different approach to traditional templating — mustache templates have no logic. The template files themselves are HTML and mustaches:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;div class='line' id='LC1'&gt;&lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;devlist&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC2'&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="cp"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;developers&lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC3'&gt;&amp;nbsp;&amp;nbsp;&lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC4'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC5'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nt"&gt;&amp;lt;h4&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;show_url&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;em&amp;gt;&lt;/span&gt;(&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;github_username&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;)&lt;span class="nt"&gt;&amp;lt;/em&amp;gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC6'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;languages&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;languages&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC7'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC8'&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;location&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;location&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC9'&gt;&amp;nbsp;&amp;nbsp;&lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC10'&gt;&amp;nbsp;&amp;nbsp;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;developers&lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;&lt;/div&gt;&lt;div class='line' id='LC11'&gt;&lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You cannot modify variables. You cannot apply filters. You can only output variables or a collection of variables. Everything else happens inside of a &lt;em&gt;view&lt;/em&gt;. A view can be written in any language of your choosing: C, Objective-C, Ruby, Python, Javascript, etc. I&amp;rsquo;ll use Ruby since that&amp;rsquo;s what we use:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Jobs&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Views&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Developers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Layout&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;developers&lt;/span&gt;
        &lt;span class="vi"&gt;@results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;fullname&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;capitalize&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;fullname&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;:github_username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;:location&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;location&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;:show_url&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/developers/&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;:languages&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;language&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;developers_count&lt;/span&gt;
        &lt;span class="vi"&gt;@results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_hits&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It&amp;rsquo;s just a good old Ruby class. Oh the wonder you can do with a class! Include modules, extend classes (such as that Layout class), and define any method you so desire. With any documentation your heart desires (something that&amp;rsquo;s missing from every templating strategy I&amp;rsquo;ve ever used).&lt;/p&gt;

&lt;p&gt;I thought I loved Mustache a year ago, but over time I&amp;rsquo;ve learned just how revolutionary separating templates from views is toward maintainability and collaboration. Anyone who knows HTML can edit Mustache templates. And all the magic that happens on the whole &lt;strong&gt;V&lt;/strong&gt; side of MVC can be fully documented and separated into re-usable Ruby classes and modules.&lt;/p&gt;

&lt;h2&gt;You want me to switch templating languages on my legacy app?&lt;/h2&gt;

&lt;p&gt;For all this talk, the application I spend most of my time working on is still ERB. In fact, the rails app that powers &lt;a href="https://github.com"&gt;GitHub&lt;/a&gt; has over &lt;strong&gt;500 erb templates&lt;/strong&gt;. We have dozens of people throwing hundreds of commits a day at the codebase in over &lt;strong&gt;150 branches&lt;/strong&gt;. Switching to Mustache would be a disaster requiring everyone to stop development, switch patterns, and introduce an unknown number of bugs to our customers. A shitty trade.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t want to stop new feature development, but I do want better templates. And I know that Mustache is the direction I&amp;rsquo;d like to go. Luckily for me, I work with the smartest people in the world. A little while ago &lt;a href="https://github.com/sr"&gt;Simon&lt;/a&gt; introduced a new templating strategy that I really like.&lt;/p&gt;

&lt;h2&gt;Mustache-style ERB templates&lt;/h2&gt;

&lt;p&gt;We&amp;rsquo;ve started using the mustache style but completely within ERB — we haven&amp;rsquo;t modified the template rendering chain at all. Inside of a new helper, we&amp;rsquo;ll create a view class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;NavigationHelper&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepositoryNavigationView&lt;/span&gt;
    &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Helpers&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;NumberHelper&lt;/span&gt;

    &lt;span class="kp"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:current_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:current_repository&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@current_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
      &lt;span class="vi"&gt;@current_repository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# What symbols should we trigger highlighting for various tabs?&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# Returns an array of symbols.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;highlights_for_code&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:repo_source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:repo_downloads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:repo_commits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:repo_tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:repo_branches&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;highlights_for_pulls&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:repo_pulls&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;highlights_for_issues&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:repo_issues&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Should we show the wiki tab? We try and show it when it&amp;#39;s useful to&lt;/span&gt;
    &lt;span class="c1"&gt;# someone using these rules:&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# - Never show it if the wiki is disabled under the admin section.&lt;/span&gt;
    &lt;span class="c1"&gt;# - Show it if you have admin access to the repository&lt;/span&gt;
    &lt;span class="c1"&gt;# - Show it if there is content&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# Returns true to show the tab.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_wiki?&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;current_repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_wiki?&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;logged_in?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;current_repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pushable_by?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;current_repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wiki&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Nicely documented, isolated from application-wide helpers and easy to find. Inside of the &lt;code&gt;html.erb&lt;/code&gt;, create a new instance of this view object:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="erb"&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NavigationHelper&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RepositoryNavigationView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_repository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@omit_repository_toolbar&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  &amp;lt;ul class=&amp;quot;tabs&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;    &amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;selected_link_to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Code&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:highlight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_code&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;    &amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;selected_link_to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Network&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;network_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:highlight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_network&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;    &amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;selected_link_to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Pull Requests&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pull_requests_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:highlight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_pulls&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;

&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show_issues?&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;      &amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;selected_link_to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Issues&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;issues_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:highlight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_issues&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;

&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show_wiki?&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;      &amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;selected_link_to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Wiki&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wikis_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:highlight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_wiki&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;

&lt;span class="x"&gt;    &amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;selected_link_to&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Stats &amp;amp;amp; Graphs&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;graphs_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:highlight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_graphs&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;  &amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="x"&gt;  &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render_subnav&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repositories/code&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_code&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render_subnav&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repositories/network&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_network&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render_subnav&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repositories/graphs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_graphs&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render_subnav&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repositories/wiki&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;highlights_for_wiki&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If you&amp;rsquo;re used to regular ERB templates it&amp;rsquo;s immediately obvious where this data comes from — it&amp;rsquo;s right at the top of the file! Ack the project for &lt;code&gt;RepositoryNavigationView&lt;/code&gt; and you&amp;rsquo;ve found your view class. No magic.&lt;/p&gt;

&lt;p&gt;One huge advantage of this tactic is that you can still use all the same Rails/ERB shortcuts for quick prototyping. If someone doesn&amp;rsquo;t want to learn the new template strategy right away, they can use the same methods they&amp;rsquo;ve been using for years.&lt;/p&gt;

&lt;h2&gt;Graceful upgrade path&lt;/h2&gt;

&lt;p&gt;Switching templating languages is something that needs to be done gracefully when you&amp;rsquo;re working with others. Ripping out everyone&amp;rsquo;s foundation is a recipe for unhappy developers. Rails is all about patterns, and sticking to those patterns is really important.&lt;/p&gt;

&lt;p&gt;This strategy allows us to slowly convert the codebase to a better documented, view/template separation that anyone who&amp;rsquo;s worked with ERB can understand. And if we choose to switch to true-and-blue Mustache some day, our code will be 80% there already.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/0H1ok_9WoaI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/mustache-style-erb</feedburner:origLink></entry>
 
 <entry>
   <title>Brew Methods</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/HhNJIrymBLg/" />
   
   <updated>2011-09-20T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/link-brewmethods</id>
   <content type="html">&lt;p&gt;A wonderfully simple site dedicated to the art and style of creating fine coffee. Learn how to use that Chemex properly!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/HhNJIrymBLg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://brewmethods.com/</feedburner:origLink></entry>
 
 <entry>
   <title>Design Hacks for the Pragmatic Minded Video</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/kFoTm9pv1OI/522-roa2011-design-hacks-for-the-pragmatic-minded" />
   
   <updated>2011-09-05T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/link-rbonales-talk</id>
   <content type="html">&lt;p&gt;The Ruby on Ales folks got around to publishing the video of my &lt;a href="http://warpspire.com/talks/designhacks"&gt;Design Hacks&lt;/a&gt; talk.  The audio is a little weird in the begining, but hang on — it clears up a few minutes in.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/kFoTm9pv1OI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://confreaks.net/videos/522-roa2011-design-hacks-for-the-pragmatic-minded</feedburner:origLink></entry>
 
 <entry>
   <title>Relentless Quality</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/dDtdof5RxUA/relentless-quality" />
   
   <updated>2011-08-25T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/relentless-quality</id>
   <content type="html">&lt;p&gt;If there&amp;rsquo;s one thing I&amp;rsquo;ll remember about Alex Mahernia, it&amp;rsquo;s footer spacing. Here we are at 10pm in the office and we&amp;rsquo;d be trying to launch a site. The only thing left is an A-OK from the creative director. And without fail, he&amp;rsquo;d yell at me to come into his office and point at his screen. &amp;ldquo;The footer spacing is too big on this page.&amp;rdquo; So I&amp;rsquo;d go back to battle the CSS until every single page on the site had consistent footer spacing in every browser.&lt;/p&gt;

&lt;p&gt;Motherfucking footer spacing.&lt;/p&gt;

&lt;p&gt;And what did it matter? Are our clients really going to lose customers because there&amp;rsquo;s an extra 10 pixels of footer spacing in IE6 on one of the pages? Is the client going to refuse payment because of these pixels? HOW MUCH BLOOD ARE THESE PIXELS WORTH?&lt;/p&gt;

&lt;p&gt;But it was never about the footer spacing. It was about quality. It was about cultivating a culture of &lt;strong&gt;relentless quality&lt;/strong&gt; in everything we produced.&lt;/p&gt;

&lt;h2&gt;Quality versus the Ego&lt;/h2&gt;

&lt;p&gt;Every time Alex called me into his office and showed me a page with an extra 7 pixels of spacing my blood pressure went through the roof. I took it as a personal insult. But he wasn&amp;rsquo;t insulting me. It was about producing a quality product.&lt;/p&gt;

&lt;p&gt;Quality has no room for egos. Other people will have better solutions. You are going to miss things. You are going to break things. You are going to make mistakes. And people are going to point it out.&lt;/p&gt;

&lt;p&gt;And I think it&amp;rsquo;s okay to get upset. Take that feeling and turn it inwards. Vow to &lt;strong&gt;make things better&lt;/strong&gt;. Make sure you&amp;rsquo;re always producing the best quality product you can.&lt;/p&gt;

&lt;h2&gt;Move fast and break things&lt;/h2&gt;

&lt;p&gt;If you take a look at any of Facebook&amp;rsquo;s recruiting marketing, you&amp;rsquo;ll see a phrase repeated over and over:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Move fast and break things&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;And with good reason — the idea it embodies is fantastic. Unfortunately I see a lot of people interpreting this quote as something like this:&lt;/p&gt;

&lt;p&gt; &lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/relentless-quality/breakthings.png" /&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;It reminds me of another misinterpretation that&amp;rsquo;s always bugged me:&lt;/p&gt;

&lt;p&gt; &lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/relentless-quality/shipfast.png" /&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Quality isn&amp;rsquo;t something to be sacrificed.  Move fast and break things, &lt;strong&gt;then move fast and fix it.&lt;/strong&gt;  Ship early, ship often, &lt;strong&gt;sacrificing features, never quality.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Embrace change. Ship. Never cut corners.&lt;/p&gt;

&lt;h2&gt;Quality is contagious&lt;/h2&gt;

&lt;p&gt;Which reminds me of the &lt;a href="http://en.wikipedia.org/wiki/Broken_windows_theory"&gt;broken windows theory&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Monitoring and maintaining urban environments in a well-ordered condition may prevent further vandalism as well as an escalation into more serious crime.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Broken windows are the reason most large software projects suck to work on. A little technical debt here, a few shortcuts there, and pretty soon you&amp;rsquo;ve got a codebase so full of broken windows that no one even cares if they throw another pile of broken glass on the heap.&lt;/p&gt;

&lt;p&gt;But just as broken windows are contagious, so is a dedication to quality. Carve out a little piece of a messy codebase and clean it up. Sharpen the edges, polish the surface and make it &lt;em&gt;shine&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The caveat here is that you can&amp;rsquo;t half-ass quality. Dedication to &amp;ldquo;semi-quality&amp;rdquo; isn&amp;rsquo;t dedication at all. High-end design coupled with mediocre engineering can only produce a mediocre result.&lt;/p&gt;

&lt;p&gt;And I don&amp;rsquo;t know about you, but I don&amp;rsquo;t dream of building mediocre. I dream of building the best. So I&amp;rsquo;m thankful to Alex for instilling this idea of relentless quality in me, even if I still have footer spacing related nightmares from time to time.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/dDtdof5RxUA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/relentless-quality</feedburner:origLink></entry>
 
 <entry>
   <title>Deploying: Then &amp; Now</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/KkIaHs5ppQ0/ops-art" />
   
   <updated>2011-08-02T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/ops-art</id>
   <content type="html">&lt;p&gt;A couple months ago I got up on stage during lightening talks  at &lt;a href="http://codeconf.com"&gt;CodeConf 2011&lt;/a&gt; to talk about our friendly robot, &lt;a href="http://hubot.github.com"&gt;Hubot&lt;/a&gt;.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/opsart/hubot-thinner.png" /&gt;&lt;/div&gt;


&lt;p&gt;Inside of five minutes I logged into our Campfire room with spotty WiFi, asked Hubot a favor, and he deployed a major new feature to our site — &lt;a href="https://github.com/blog/831-issues-2-0-the-next-generation"&gt;Issues 2.0&lt;/a&gt;. A deploy spanning around 30 servers that changed a major feature for 800,000 users. It was pretty awesome and kind of a ridiculous thing to do.&lt;/p&gt;

&lt;p&gt;Rewind the clock 7 years ago and I had just landed my first steady job in the tech industry — a front end developer for a big interactive agency.&lt;/p&gt;

&lt;p&gt;I remember one of our clients had a static HTML website that I was in charge of maintaining. We had a 45 minute window occurring once a week where we could deploy their site.&lt;/p&gt;

&lt;p&gt;Once a week, I generated a list of files I&amp;rsquo;d changed since the last week so a System Administrator could FTP the files over to production. Any changes to production I needed that occurred outside that 45 minute window required manager intervention.&lt;/p&gt;

&lt;p&gt;Recap time.&lt;/p&gt;

&lt;h3&gt;2004&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;System Administrator time required to deploy every website.&lt;/li&gt;
&lt;li&gt;Deploys scheduled by managers once a week.&lt;/li&gt;
&lt;li&gt;Manually generating lists of changed files.&lt;/li&gt;
&lt;li&gt;Simple deploys take 30+ minutes.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;2011&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Deploying on stage for the hell of it.&lt;/li&gt;
&lt;li&gt;System Administrator probably drinking whiskey.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;2011 is pretty fucking awesome.&lt;/p&gt;

&lt;p&gt;Deployment is an art. And the style in which you deploy impacts your company culture more than you think. &lt;strong&gt;Deploy with style.&lt;/strong&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/KkIaHs5ppQ0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/ops-art</feedburner:origLink></entry>
 
 <entry>
   <title>Designing GitHub for Mac</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/JZOhDKRtY4g/designing-github-mac" />
   
   <updated>2011-06-28T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/designing-github-mac</id>
   <content type="html">&lt;p&gt;A few days ago we lifted the curtains on a project I&amp;rsquo;ve been deep into for a long time now: &lt;a href="http://mac.github.com"&gt;GitHub for Mac&lt;/a&gt;. This is the first OS X app I&amp;rsquo;ve designed and thought it might be interesting to share some of the process and things I learned throughout development.&lt;/p&gt;

&lt;h2&gt;Why should we build  it?&lt;/h2&gt;

&lt;p&gt;For a long time I assumed OS X developers would see the immense market for an awesome Git application. Unfortunately for everyone involved, every OS X application that&amp;rsquo;s showed up over the years gave up and tried to turn CLI commands into buttons.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;img src="http://assets.warpspire.com/images/githubmac/tower.png" alt="Screenshot of Git Tower" /&gt;
&lt;/div&gt;


&lt;p&gt;Clients claiming to be &amp;ldquo;simple&amp;rdquo; choose to redefine &amp;ldquo;simple&amp;rdquo; as fewer supported Git commands rather than simplifying the interaction with Git.&lt;/p&gt;

&lt;p&gt;It blows my mind that no one tried to do anything special. Git (and its  DVCS cousins like Mercurial &amp;amp; Bazaar) provide an amazing platform to build next generation clients — and it&amp;rsquo;s like the entire OS X ecosystem left their imagination at home.&lt;/p&gt;

&lt;p&gt;Eventually, I (well, many of us) decided that better native clients (OSX, Windows, Linux, Eclipse, Visual Studio, etc) was the best way to grow GitHub. And since we all use Macs — we should start off with an OS X application. Build what you know/use, expand from there.&lt;/p&gt;

&lt;h2&gt;What are we building?&lt;/h2&gt;

&lt;p&gt;Personally, I had some big goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Death of the SSH key. People should be able to connect to GitHub with their GitHub username and password.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make it obvious that there &lt;em&gt;is&lt;/em&gt; a distinction between remote and local. Make it clear what commits need to be pushed before others can see them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplify the &lt;code&gt;git fetch, pull (--rebase), push&lt;/code&gt; interaction. Synchronize — don&amp;rsquo;t make the user figure out what they need to do to get their local commits remote and remote commits local.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix the local/remote branching problem. Get rid of this tracking idea — interact with local or remote branches as if they were no distinction between the two.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I didn&amp;rsquo;t want to replace the command line. &lt;strong&gt;I wanted to build an awesome version control client.&lt;/strong&gt; As it happens, Git is the perfect backend to do that — and GitHub is the perfect central server to collaborate.&lt;/p&gt;

&lt;h2&gt;Sketches &amp;amp; early ideas&lt;/h2&gt;

&lt;p&gt;The first thing we did was to start populating an internal wiki full of ideas. Lots of words, lots of sketches.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/githubmac/sketchbook-full.png"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/sketchbook.png" alt="My beloved sketchbook" /&gt;&lt;/a&gt;
  &lt;small&gt;Incomprehensible pages from my Moleskine&lt;/small&gt;
&lt;/div&gt;




&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/githubmac/scottmock-full.png"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/scottmock.png" alt="Scott's mockups" /&gt;&lt;/a&gt;
  &lt;small&gt;Scott created a bunch of mockups with Balsamiq&lt;/small&gt;
&lt;/div&gt;


&lt;h2&gt;Let&amp;rsquo;s get some designers on this&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;d been using OS X for years, but I didn&amp;rsquo;t feel comfortable designing a native app. My previous attempts at OS X design weren&amp;rsquo;t too fantastic…&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/githubmac/storia-full.png"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/storia.png" alt="An abandoned design direction." /&gt;&lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;In the end, we hired &lt;a href="http://eddit.com/"&gt;Eddie Wilson&lt;/a&gt; to come up with some wireframes and some comps while &lt;a href="https://twitter.com/#!/joericioppo"&gt;Joe&lt;/a&gt; and &lt;a href="https://twitter.com/#!/joshaber"&gt;Josh&lt;/a&gt; cranked away at the Cocoa backend. His first comps were a great start, and influenced the end product tremendously.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/githubmac/eddit1-full.png"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/eddit1.png" alt="Eddie's mockup" /&gt;&lt;/a&gt;
&lt;/div&gt;




&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/githubmac/eddit2-full.png"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/eddit2.png" alt="Eddie's mockup" /&gt;&lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Unfortunately right about this time is when we learned how much we suck at working with contractors. We&amp;rsquo;re extremely opinionated, really bad at expressing our opinions, and change our minds all the time. We asked Eddie to hold off while we re-grouped and figured out what we wanted from the app.&lt;/p&gt;

&lt;p&gt;We sat down and had a lot of discussions about how we wanted this thing to work. &lt;a href="http://www.brandonwalkin.com/blog/"&gt;Brandon Walkin&lt;/a&gt; helped out quite a bit, and even sketched up some wireframes &amp;amp; notes for us.&lt;/p&gt;

&lt;p&gt;Eventually we figured out what we wanted to design — but now we didn&amp;rsquo;t have anyone to design it. Eddie had since taken up other work and pretty much every Cocoa designer on the planet was inundated with work.&lt;/p&gt;

&lt;p&gt;In the end, I decided that GitHub for Mac was &lt;em&gt;the thing&lt;/em&gt; I wanted out of GitHub, and if I wanted it to happen I&amp;rsquo;d have to take the design reins. I picked up Eddie&amp;rsquo;s comps and ran with it.&lt;/p&gt;

&lt;h2&gt;A slow process&lt;/h2&gt;

&lt;p&gt;I tried my best to combine Eddie&amp;rsquo;s original comps with our internal feedback and match it up with a modern OS X look &amp;amp; feel. All in all I created 45 comps for 1.0 — each with about 5-10 unique states (with layer groups).&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/githubmac/comps-full.png"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/comps.png" alt="All my mockups" /&gt;&lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;After the first round of comps, I started writing down how I imagined everything to work.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://share.kyleneath.com/secrets/08bce2/"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/styleguide.png" alt="The styleguide" /&gt;&lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;My plan was to fully flesh out this styleguide — but as it happened, &lt;a href="https://twitter.com/#!/joshaber"&gt;Josh&lt;/a&gt; was able to implement my designs faster than I could explain them. Still, I think it was a good exercise to explain my thinking for the designs — if anything for my own personal benefit.&lt;/p&gt;

&lt;h2&gt;The aesthetic&lt;/h2&gt;

&lt;p&gt;Learning the OS X aesthetic wasn&amp;rsquo;t easy. And it probably didn&amp;rsquo;t help that I started to get serious about OS X design about the same time Lion screenshots started showing up. Like it or not, OS X app design is changing in drastic ways right now.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;img src="http://assets.warpspire.com/images/githubmac/lion.png" alt="Lion screenshot" /&gt;&lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Scrollbars are a thing of the past. Titlebars full of clickable areas. Buttons shedding themselves of borders. Custom graphics / buttons for every app. And Helvetica everywhere!&lt;/p&gt;

&lt;p&gt;I tried my best to weigh this new direction with a lot of my favorite designed apps — &lt;a href="http://itunes.apple.com/us/app/twitter/id409789998?mt=12"&gt;Twitter&lt;/a&gt;, &lt;a href="http://macrabbit.com/espresso/"&gt;Espresso&lt;/a&gt;, &lt;a href="http://sparrowmailapp.com/"&gt;Sparrow&lt;/a&gt;, and &lt;a href="http://www.panic.com/transmit/"&gt;Transmit&lt;/a&gt; to name a few.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/githubmac/onepointoh-full.png"&gt;&lt;img src="http://assets.warpspire.com/images/githubmac/onepointoh.png" alt="1.0" /&gt;&lt;/a&gt;
&lt;small&gt;Tweetie style side-tabs. No title in the window, instead a breadcrumb — always promoting a one-window experience.&lt;/small&gt;
&lt;/div&gt;




&lt;div class="figure"&gt;
  &lt;img src="http://assets.warpspire.com/images/githubmac/popover.png" alt="Popover" /&gt;
&lt;small&gt;We use a lot of popovers (borrowed from iOS / XCode) rather than modal windows throughout the app.&lt;/small&gt;
&lt;/div&gt;




&lt;div class="figure"&gt;
  &lt;img src="http://assets.warpspire.com/images/githubmac/sync.png" alt="Sync button" /&gt;
&lt;small&gt;Subtle buttons in the title bar.&lt;/small&gt;
&lt;/div&gt;


&lt;h2&gt;Lessons learned&lt;/h2&gt;

&lt;p&gt;Designing a native OS X app was definitely full of surprises. I&amp;rsquo;ve actually done quite a bit of native development before with WPF &amp;amp; Flex — but Cocoa is quite different.&lt;/p&gt;

&lt;h3&gt;Welcome to 2004 — everything is a sliced image&lt;/h3&gt;

&lt;p&gt;Remember web development in 2004? When you had to create pixel-perfect comps because every element on screen was an image? That&amp;rsquo;s what developing for Cocoa is. Drawing in code is &lt;em&gt;slow&lt;/em&gt; and &lt;em&gt;painful&lt;/em&gt;. Images are easier to work with and result in more performant code.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;img src="http://assets.warpspire.com/images/githubmac/slices.png" alt="All of the slices" /&gt;
&lt;small&gt;Remember these days?&lt;/small&gt;
&lt;/div&gt;


&lt;p&gt;This meant my Photoshop files had to be a &lt;em&gt;lot&lt;/em&gt; more fleshed out than I&amp;rsquo;ve been accustomed to in recent years. I usually get about 80% complete in Photoshop (using tons of screenshotting &amp;amp; layer flattening), then jump into code and tweak to completion. But with Cocoa, I ended up fleshing out that last 20% in Photoshop.&lt;/p&gt;

&lt;h3&gt;Change is painful&lt;/h3&gt;

&lt;p&gt;Want to move an element from the bottom of the screen to the top? A lot of times with Cocoa this involves rewriting your entire view. There is &lt;em&gt;no layout engine&lt;/em&gt; for Cocoa. If you want two elements to rest side to side, you&amp;rsquo;ll need to calculate the pixel size of the text, padding, borders, margins — then manually position the next element.&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;img src="http://assets.warpspire.com/images/githubmac/interfacebuilder.png" alt="A typical xib file" /&gt;
&lt;small&gt;What about Interface Builder? Pretty useless. Everything is a blue box on complex projects.&lt;/small&gt;
&lt;/div&gt;


&lt;p&gt;Want to change the background color of a button? You&amp;rsquo;re probably going to have to rewrite all of the drawing code for the button. There is no styling engine in Cocoa.&lt;/p&gt;

&lt;p&gt;This sucks. And it means that change is insanely painful in code. It&amp;rsquo;s much easier to prototype with HTML / CSS and see if the design is going to hold up.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://share.kyleneath.com/secrets/08bce2/changes.html"&gt;This proposed changes redesign&lt;/a&gt; is a good example of what I mean. I spent a long time creating a &amp;ldquo;clickable&amp;rdquo; prototype with animations. In the end, we decided a lot of the core ideas were wrong and decided not to go down that path. Creating this HTML/CSS/JS prototype took a couple days. Doing the same in code would have taken a lot longer — and been &lt;em&gt;much&lt;/em&gt; harder to throw away (due to the way project files work in Xcode, branching is not simple).&lt;/p&gt;

&lt;h3&gt;Objective-C is easy, Cocoa is hard&lt;/h3&gt;

&lt;p&gt;This was the first serious Cocoa project I&amp;rsquo;ve been involved with. I had dozens of little example projects, but never pushed through to ship anything.  As I went on and talked to people about my frustrations, they inevitably came up with the same response:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Why don&amp;rsquo;t you just use MacRuby?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Why? Because &lt;strong&gt;Objective-C is really easy.&lt;/strong&gt; The language was never a problem. You know what was? Cocoa. Learning the differences between layer-backed views, layer-hosted views — understanding that you have to subclass &lt;em&gt;everything&lt;/em&gt; — balancing delegates, weak connections, strong connections, KVC, view controllers, and notifications — understanding little intricacies like how AppKit flips &lt;code&gt;.xib&lt;/code&gt;s when it load them up or how hard it is to make one word in a sentence bold. I&amp;rsquo;m not going to lie: Cocoa (that is: AppKit, UIKit, Core Text, Core Animation, etc) is extremely difficult. The gap between simple example apps and a fully functional application is huge.&lt;/p&gt;

&lt;p&gt;Projects like &lt;a href="https://github.com/BigZaphod/Chameleon"&gt;Chameleon&lt;/a&gt; that give you a purely layer-backed environment to work with using a modern API (UIKit) matter &lt;em&gt;far&lt;/em&gt; more than the language you&amp;rsquo;re using. This isn&amp;rsquo;t to say MacRuby isn&amp;rsquo;t awesome —  it just means that it doesn&amp;rsquo;t make AppKit development any easier; you still have to learn Cocoa.&lt;/p&gt;

&lt;p&gt;Along those same lines, I think that &lt;strong&gt;Cocoa is dying for a framework.&lt;/strong&gt; Something that weighs on the simple defaults side rather than complex code generation side.&lt;/p&gt;

&lt;h3&gt;Secrecy is overrated&lt;/h3&gt;

&lt;p&gt;GitHub for Mac was in development for just under a year and there was never any leaked screenshots or blog posts. In fact, there were dozens of &lt;a href="http://dribbble.com/shots/54738-Desktop-UI"&gt;public&lt;/a&gt; &lt;a href="http://dribbble.com/shots/170535-Add-Repo-Local"&gt;screenshots&lt;/a&gt; of the &lt;a href="http://dribbble.com/shots/141734-Stars?list=103-Operation-08bce2"&gt;app&lt;/a&gt; on dribbble — but for the most part, people were surprised when we launched.&lt;/p&gt;

&lt;p&gt;We didn&amp;rsquo;t have beta testers sign NDAs or demand first-borns to get access to the early builds. How on earth did we keep something under wraps for so long?&lt;/p&gt;

&lt;p&gt;We asked people politely not to share it with the world. It&amp;rsquo;s really not that hard. Don&amp;rsquo;t send betas to douchebags. Politely ask people not to blog about it. Done.&lt;/p&gt;

&lt;h2&gt;Here&amp;rsquo;s to a bright future&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;m hoping that GitHub for Mac (and supporting projects, like &lt;a href="https://github.com/libgit2"&gt;libgit2&lt;/a&gt;) spurs a new round of creativity in source control clients. I&amp;rsquo;ve already seen some progress — like &lt;a href="https://github.com/kennethreitz/legit"&gt;legit&lt;/a&gt; — but I&amp;rsquo;m hoping to see a new generation of source control clients in the future. Git is immensely powerful, and it&amp;rsquo;s up to us to leverage that power into something awesome.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/JZOhDKRtY4g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/designing-github-mac</feedburner:origLink></entry>
 
 <entry>
   <title>Excellent embedding markup</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/stl6rTH8Irg/followbutton" />
   
   <updated>2011-06-15T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/twitter-embed-code</id>
   <content type="html">&lt;p&gt;I was playing around with Twitter&amp;rsquo;s new Follow Button and I couldn&amp;rsquo;t help but notice that the embedding markup is some of the best I&amp;rsquo;ve ever seen.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;a href="http://twitter.com/kneath" class="twitter-follow-button" data-show-count="false"&amp;gt;Follow @kneath&amp;lt;/a&amp;gt;
&amp;lt;script src="http://platform.twitter.com/widgets.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I love the idea of using regular HTML with feature-flags in &lt;code&gt;data&lt;/code&gt; attributes combined with a common script. Can&amp;rsquo;t wait to play around with this style on &lt;a href="https://gist.github.com"&gt;Gist&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/stl6rTH8Irg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>https://twitter.com/about/resources/followbutton</feedburner:origLink></entry>
 
 <entry>
   <title>Build your business around an idea</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/-BuPaMVn00s/idea-businesses" />
   
   <updated>2011-06-14T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/idea-businesses</id>
   <content type="html">&lt;p&gt;Living in San Francisco and working in tech right now is absolutely insane. Employers and recruiters battle for employees while VCs rain down millions of dollars &lt;a href="http://techcrunch.com/2011/01/28/yuri-milner-sv-angel-offer-every-new-y-combinator-startup-150k/"&gt;without meeting founders or even knowing what kind of company they&amp;rsquo;re building&lt;/a&gt;. It&amp;rsquo;s a crazy world to live in and can feel like money &lt;em&gt;is&lt;/em&gt; growing on trees and the only spending limit is your imagination. If you have just a little bit of initiative, you can take any idea and start a company with absolutely zero personal risk.&lt;/p&gt;

&lt;p&gt;And that&amp;rsquo;s one of the biggest reasons San Francisco is so special to me. Everyone out here &lt;em&gt;knows&lt;/em&gt; they can do anything. Spend a few weeks hanging out in bars and cafes asking what people do and you&amp;rsquo;ll hear some of the most idiotic business ideas in the world. A lot of journalists use this argument to call San Francisco an echo chamber whose sole purpose is burning money. And you know, they&amp;rsquo;re right.&lt;/p&gt;

&lt;p&gt;This city does burn through money on terrible ideas. But that&amp;rsquo;s a tradeoff for fostering a city of people who believe they can do anything. And that spawns an incredible number of amazing companies — so it doesn&amp;rsquo;t bother me. What does bother me is the &lt;em&gt;lack of imagination&lt;/em&gt; most startup founders have.&lt;/p&gt;

&lt;h2&gt;Build something incredible&lt;/h2&gt;

&lt;p&gt;Most founders I talk to are pretty complacent building something mediocre. They won&amp;rsquo;t admit if you flat out ask them — but try pressing them to describe what makes their company special. Most cop out and give you an answer like:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;We&amp;rsquo;re building [technology x] because [company y] hasn&amp;rsquo;t built it and [people z] need it.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Want a more concrete example? How about something like:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;We&amp;rsquo;re building a cloud sync solution for iOS because Apple hasn&amp;rsquo;t built it and almost every iOS application needs sync.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;There are thousands of people building products like this. They&amp;rsquo;re filling holes. Filling holes is mediocre and boring. Dare to build something incredible – something unique, something lasting, something special.&lt;/p&gt;

&lt;h2&gt;Ideas are lasting, products are not&lt;/h2&gt;

&lt;p&gt;The easiest way to build something incredible is to base your business around an idea. Products are just the manifestation of the idea.&lt;/p&gt;

&lt;p&gt;This is something I think about at GitHub a lot. We&amp;rsquo;ve built an amazing product (&lt;a href="https://github.com"&gt;github.com&lt;/a&gt;) — but when you ask us what the &lt;a href="https://github.com/about"&gt;company is about&lt;/a&gt; we say:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;We make it easier to collaborate with others and share your projects with the universe.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;There&amp;rsquo;s a lot of interesting things you &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; see it that description: Git, version control, issue tracking, wikis, or website. We know that our product (a website hosting git repositories with built-in issue tracking &amp;amp; wikis) is great — but if it doesn&amp;rsquo;t serve a higher purpose, it would be mediocre. So we focus on the idea.&lt;/p&gt;

&lt;p&gt;That means looking at version control, wikis, and issue tracking as tools for collaboration. It means that as important as it is for our website to be easy to use — it&amp;rsquo;s equally important for Git to be easy to use. Or to create tools that let people use Git without even knowing they&amp;rsquo;re using Git.&lt;/p&gt;

&lt;p&gt;If I look into the future, I know that the idea of collaboration is lasting — but Git? That&amp;rsquo;s a hard bet to make. I know that if we focus our business on collaboration we can build something lasting. If we focus our business on being a Git host we&amp;rsquo;re doomed.&lt;/p&gt;

&lt;h2&gt;Ideas are sexy&lt;/h2&gt;

&lt;p&gt;One of the more awesome things about building your business around an idea is how easy it is to pitch to others. Ideas are sexy and draw people in — they invite passion and commitment. And pitching people is all about displaying passion and commitment. It doesn&amp;rsquo;t matter if you&amp;rsquo;re pitching for VC funding, trying to land a new customer, or interviewing a prospective employee — having a good pitch is critical to any successful business.&lt;/p&gt;

&lt;p&gt;People want to be part of ideas. Being part of a company who builds a successful product is cool… but being part of an idea is a lot more attractive. If you can build a business where both your employees and your customers think they&amp;rsquo;re part of an idea, you&amp;rsquo;ve created something special.&lt;/p&gt;

&lt;h2&gt;Evolving ideas from products&lt;/h2&gt;

&lt;p&gt;The trouble is that founding a company around an idea doesn&amp;rsquo;t actually work. Apple &lt;del&gt;Computer&lt;/del&gt; is a great example. They take bleeding edge technology, marry it with exceptional design, and sell it at a premium price. But the company wasn&amp;rsquo;t always like that. It was founded around a product — the personal computer. Yet in 2011, Apple&amp;rsquo;s biggest business is mobile phones.&lt;/p&gt;

&lt;p&gt;You have to ask… how did a company founded around building personal computers come to generate most of its revenue from mobile phones? They &lt;em&gt;evolved&lt;/em&gt;. They found their strengths (design, technology), and evolved the company around those values. This manifested itself into new products — the iPod, iPhone, iPad, TV, MobileMe, Airport Expresses, Cinema Displays, etc. Some successes. Some failures.&lt;/p&gt;

&lt;p&gt;The core component of all these products is that they are manifestations of an idea. When the iPod took off in popularity, Apple didn&amp;rsquo;t rearrange the company around portable music devices. They kept focusing on building exceptionally designed hi-tech gadgets with bleeding edge technology.&lt;/p&gt;

&lt;p&gt;So it&amp;rsquo;s okay to focus on a product at first. But as soon as you find your strengths as a company, abstract it out into an idea and focus on that. Do that and you won&amp;rsquo;t have your entire business invalidated by a feature that Facebook or Apple rolled out at their last keynote. Because ideas will last, products won&amp;rsquo;t.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/-BuPaMVn00s" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/idea-businesses</feedburner:origLink></entry>
 
 <entry>
   <title>Infinite Scroll + HTML5 History API</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/Bj_Fwp85Pvw/" />
   
   <updated>2011-05-31T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/link-history-api</id>
   <content type="html">&lt;p&gt;Something I&amp;rsquo;ve been meaning to do for a while — here&amp;rsquo;s a little experiment using the HTML5 History API and infinite scrolling to kill off &amp;ldquo;next page&amp;rdquo; links and still maintain real URLs that persist across page views.&lt;/p&gt;

&lt;p&gt;In my perfect world, this is how Twitter, Facebook and Tumblr&amp;rsquo;s infinite scrolling would work.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/Bj_Fwp85Pvw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/experiments/history-api/</feedburner:origLink></entry>
 
 <entry>
   <title>Product design at GitHub</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/JBrdNZA2D64/product-design" />
   
   <updated>2011-03-30T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/product-design</id>
   <content type="html">&lt;p&gt;Product design is easily the hardest aspect of building software today. Technology, hiring, funding, aesthetic design, and press are all minuscule in comparison. When I talk about product design I&amp;rsquo;m referring to the process by which you decide what your product does and does not do. I happen to think we do a pretty good job of this at GitHub, and I&amp;rsquo;d like to give you a bit of an insight into our process and hopefully shed some light on why it works so well.&lt;/p&gt;

&lt;p&gt;I should warn you that I am not a &amp;ldquo;Product Designer.&amp;rdquo; We don&amp;rsquo;t have titles at GitHub — we let employees pick their own.  I like to call myself &lt;strong&gt;~designer&lt;/strong&gt; since I mostly focus on the look &amp;amp; feel of our product. But then again, I spent the past weekend building an application to track &amp;amp; distribute binaries and updating some of our reducing functions to support a newer version of MongoDB. So, yeah. I&amp;rsquo;m ~designer. But maybe that leads me to my next point…&lt;/p&gt;

&lt;h2&gt;Everyone is a product designer&lt;/h2&gt;

&lt;p&gt;Every employee at GitHub is a product designer. We only hire smart people we  trust to make our product better. We don&amp;rsquo;t have managers dictating what to work on. We don&amp;rsquo;t require executive signoff to ship features. Executives, system administrators, developers, and designers concieve, ship, and remove features alike.&lt;/p&gt;

&lt;p&gt;Having the role of &amp;ldquo;Product Designer&amp;rdquo; or having a CEO who says they&amp;rsquo;re going to &amp;ldquo;focus on product design now&amp;rdquo; never made much sense to me. Aren&amp;rsquo;t you hiring smart people who use your product? Don&amp;rsquo;t you trust your employees? Doesn&amp;rsquo;t everyone at your company want to make your product better? Doesn&amp;rsquo;t that make everyone product designers all of the time?&lt;/p&gt;

&lt;p&gt;Along these lines, my two favorite questions to ask in an interview (or to people who don&amp;rsquo;t know they&amp;rsquo;re interviewing) are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What would you like to see in GitHub?&lt;/li&gt;
&lt;li&gt;What feature do you think we messed up / should remove?&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;It brings out the passion in people and instantly highlights problems you might have with their decisions. Some people just don&amp;rsquo;t have the same vision for your product as you do, and that&amp;rsquo;s fine.&lt;/p&gt;

&lt;h2&gt;Write down ideas like crazy&lt;/h2&gt;

&lt;p&gt;Our internal wiki is filled with ideas. Old ideas. Bad ideas. Good ideas. Half-baked ideas. The point is that we have a place to share our crazy with each other. &lt;a href="https://gist.github.com/ad66d382a04c063b6861"&gt;This wiki page&lt;/a&gt; discussing compare view eventually became &lt;a href="https://github.com/blog/712-pull-requests-2-0"&gt;Pull Requests 2.0&lt;/a&gt; — arguably the best code review tool I&amp;rsquo;ve ever used.&lt;/p&gt;

&lt;p&gt;Most of the time when someone adds an idea it&amp;rsquo;s nothing original. It&amp;rsquo;s something we&amp;rsquo;ve discussed in person, seen in another product, or maybe thought about ourselves. But that&amp;rsquo;s really half the point — seeing someone else write down the same idea you&amp;rsquo;ve had makes you twice as excited about the idea. As others chime in saying they&amp;rsquo;d love to see the feature, excitement about it grows and grows. Eventually you&amp;rsquo;ve got 4 developers hacking on something at 11:30pm because they want to see it happen so badly.&lt;/p&gt;

&lt;h2&gt;Constantly experiment and iterate&lt;/h2&gt;

&lt;p&gt;Right now our main repository has 65 branches. This doesn&amp;rsquo;t count the dozen or so other repositories that collectively represent what is &lt;a href="https://github.com"&gt;https://github.com&lt;/a&gt; or the 139 repositories under our organization. Needless to say, there are a ton of features, anti-features and half ideas in these branches. Sometimes they&amp;rsquo;re really pretty features that aren&amp;rsquo;t functional and sometimes they&amp;rsquo;re really ugly features that are completely functional.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;re always sending pull requests, shipping them to staging and asking others what they think. Talking about a feature in a meeting and crafting a spec is one thing, but coding up a working prototype is way more effective. We&amp;rsquo;re always running experimental features in production to staff only. No better way to see if a feature is going to fit than to actually use it.&lt;/p&gt;

&lt;p&gt;Once a feature is out and ready for people to use there&amp;rsquo;s about a 100% chance that someone is going to want to change some aspect of it. So we iterate — tweak, deploy, discuss in a pull request — over and over until it&amp;rsquo;s good enough for public consumption.&lt;/p&gt;

&lt;p&gt;On that note, our pull requests are generally pretty &lt;em&gt;epic&lt;/em&gt;. It turns out that pull requests are perfect for experimenting with new features, discussing them with the team, and getting others to help you ship. &lt;a href="http://assets.warpspire.com/images/product-design/pull-request.png"&gt;Check out this pull request&lt;/a&gt; for shipping our org profiles.  (Funny anectdote: this pull request was created before we shipped pull requests 2.0 — we &lt;em&gt;constantly&lt;/em&gt; use experimental features)&lt;/p&gt;

&lt;h2&gt;Abandon features&lt;/h2&gt;

&lt;p&gt;You can&amp;rsquo;t run a product and pretend that every one of your ideas is perfect. You&amp;rsquo;re going to have bad ideas, ideas that don&amp;rsquo;t fit, and features that become abandoned. Don&amp;rsquo;t be afraid to abandon ideas. The amount of time you spend on something is meaningless. You&amp;rsquo;re not losing anything by throwing work away — you&amp;rsquo;re choosing not to make your product worse.&lt;/p&gt;

&lt;p&gt;The first version of &lt;a href="http://jobs.github.com"&gt;http://jobs.github.com&lt;/a&gt; that we built didn&amp;rsquo;t share a single piece of functionality with what shipped on day one. It wasn&amp;rsquo;t an iteration — we straight up threw away a few months of work because we realized it was a bad idea. We started using our creation and realized we couldn&amp;rsquo;t figure out how to make money without pissing off our customers. So we abandoned that idea and started anew — even though we could have shipped it and started making money immediately.&lt;/p&gt;

&lt;p&gt;Shipping features because you spent time or money on them is a coward&amp;rsquo;s excuse. It takes balls to abandon features — grow some.&lt;/p&gt;

&lt;h2&gt;Argue all the time&lt;/h2&gt;

&lt;p&gt;We do not have a quiet workplace. We argue in bars, in Campfire and in email. New hires and CEOs alike. But it&amp;rsquo;s not personal — it&amp;rsquo;s about making our product better. If you&amp;rsquo;re not forced to rationalize your product  choices, who&amp;rsquo;s to say you&amp;rsquo;re making good decisions?&lt;/p&gt;

&lt;p&gt;Arguing with your co-workers isn&amp;rsquo;t a bad thing. It&amp;rsquo;s not creating a negative work environment — it&amp;rsquo;s a tool to help you make good decisions. Being an empty cheerleader and telling everyone that their idea is great is harmful and short-sighted. Argue and make good decisions.&lt;/p&gt;

&lt;h2&gt;Talk to your customers&lt;/h2&gt;

&lt;p&gt;I spend a good portion of my day reading through our &lt;a href="http://support.github.com"&gt;support site&lt;/a&gt;, mailing lists, twitter feeds, and blog posts written about git and GitHub. Listening to your customers is supremely important — they&amp;rsquo;re full of great ideas. They&amp;rsquo;re also full of shockingly terrible ideas. As &lt;a href="http://tom.preston-werner.com/2011/03/29/ten-lessons-from-githubs-first-year.html"&gt;Tom&lt;/a&gt; puts it:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Don’t give your customers what they ask for; give them what they want.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;We also spend a lot of &lt;em&gt;physical&lt;/em&gt; time with our customers. We have monthly meetups here in San Francisco, and you can pretty much guarantee that anyone who&amp;rsquo;s traveling will host a meetup in whatever city they&amp;rsquo;re in.  People can get crazy online. It&amp;rsquo;s a lot harder to spout out that crazy when you&amp;rsquo;re talking to someone face to face. It forces people to really think about what they&amp;rsquo;re going to say and reminds them that there&amp;rsquo;s a living, breathing human being behind the product.&lt;/p&gt;

&lt;h2&gt;Product design is in the eye of the beholder&lt;/h2&gt;

&lt;p&gt;We know that product design isn&amp;rsquo;t just adding and removing features. It&amp;rsquo;s how our customers perceive the features. Who cares if some analyst thinks your company is doing well if your customers don&amp;rsquo;t?&lt;/p&gt;

&lt;p&gt;Having a great blog post explaining new features is absolutely killer. It allows us to frame features in a certain light and explain our thinking. It also shows a record of shipping — and we try hard to ship and tell people about it all of the time.&lt;/p&gt;

&lt;p&gt;If you redesign your entire product once every two years like Twitter does, it&amp;rsquo;s a &lt;em&gt;big deal&lt;/em&gt;. If your users don&amp;rsquo;t like 100% of it, they&amp;rsquo;re going to be pissed. But if you ship something every two months and they don&amp;rsquo;t like 10% of it — their overall perception is still positive.&lt;/p&gt;

&lt;p&gt;We also know that what we &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; do is just as important as what we &lt;em&gt;are&lt;/em&gt; doing. We don&amp;rsquo;t publish roadmaps or promise features within a timeframe — we &lt;a href="http://ozmm.org/posts/managing_expectations.html"&gt;under promise and over deliver&lt;/a&gt;. And really, I think that&amp;rsquo;s why our customers are so happy with our product design as a whole.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don&amp;rsquo;t give your customers what they ask for, give them what they want. Under promise, over deliver.&lt;/strong&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/JBrdNZA2D64" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/product-design</feedburner:origLink></entry>
 
 <entry>
   <title>Design hacks for the pragmatic minded</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/kbdop01lZMM/designhacks" />
   
   <updated>2011-03-24T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/link-designhacks-presentation</id>
   <content type="html">&lt;p&gt;Slides and references links from my presentation I gave at Ruby on Ales &amp;ndash; &lt;em&gt;Design hacks for the pragmatic minded&lt;/em&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/kbdop01lZMM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/talks/designhacks</feedburner:origLink></entry>
 
 <entry>
   <title>Documentation is freaking awesome</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/h7lkBMw3UXM/documentation" />
   
   <updated>2011-02-05T00:00:00-08:00</updated>
   <id>http://warpspire.com/posts/link-documentation-presentation</id>
   <content type="html">&lt;p&gt;Slides and references links from my presentation I gave at Magic Ruby &amp;ndash; &lt;em&gt;Documentation is freaking awesome&lt;/em&gt;. Check it out if you&amp;rsquo;re curious.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/h7lkBMw3UXM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/talks/documentation</feedburner:origLink></entry>
 
 <entry>
   <title>Speaking at Magic Ruby</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/4yo74SB-Uu8/" />
   
   <updated>2011-01-04T00:00:00-08:00</updated>
   <id>http://warpspire.com/posts/link-magic-ruby</id>
   <content type="html">&lt;p&gt;I&amp;rsquo;ll be giving a talk about documentation (no, not just code comments and RDoc) at Magic Ruby February 4th-5th. Oh, did I mention it&amp;rsquo;s in &lt;strong&gt;Disneyworld?&lt;/strong&gt; And it&amp;rsquo;s &lt;strong&gt;free?&lt;/strong&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/4yo74SB-Uu8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://magic-ruby.com/</feedburner:origLink></entry>
 
 <entry>
   <title>URL Design</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/2qo4oCys3fU/url-design" />
   
   <updated>2010-12-28T00:00:00-08:00</updated>
   <id>http://warpspire.com/posts/url-design</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;You should take time to design your URL structure.&lt;/strong&gt; If there&amp;rsquo;s one thing I hope you remember after reading this article it&amp;rsquo;s to take time to design your URL structure. Don&amp;rsquo;t leave it up to your framework. Don&amp;rsquo;t leave it up to chance. Think about it and craft an experience.&lt;/p&gt;

&lt;p&gt;URL Design is a complex subject. I can&amp;rsquo;t say there are any &amp;ldquo;right&amp;rdquo; solutions — it&amp;rsquo;s much like the rest of design. There&amp;rsquo;s good URL design, there&amp;rsquo;s bad URL design, and there&amp;rsquo;s everything in between — it&amp;rsquo;s subjective.&lt;/p&gt;

&lt;p&gt;But that doesn&amp;rsquo;t mean there aren&amp;rsquo;t best practices for creating great URLs. I hope to impress upon you some best practices in URL design I&amp;rsquo;ve learned over the years and explain why I think new HTML5 javascript history APIs are so exciting to work with.&lt;/p&gt;

&lt;h2&gt;Why you need to be designing your URLs&lt;/h2&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/urldesign/chrome.jpg" alt="Chrome's URL bar" /&gt;&lt;/div&gt;


&lt;p&gt;The URL bar has become a main attraction of modern browsers. And it&amp;rsquo;s not just a simple URL bar anymore — you can type partial URLs and browsers use dark magic to seemingly conjure up exactly the full URL you were looking for. When I type in &lt;strong&gt;&lt;code&gt;resque issues&lt;/code&gt;&lt;/strong&gt; into my URL bar, the first result is &lt;code&gt;https://github.com/defunkt/resque/issues&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;URLs are &lt;em&gt;universal&lt;/em&gt;. They work in Firefox, Chrome, Safari, Internet Explorer, cURL, wget, your iPhone, Android and even written down on sticky notes. They are the one universal syntax of the web. Don&amp;rsquo;t take that for granted.&lt;/p&gt;

&lt;p&gt;Any regular semi-technical user of your site should be able to navigate 90% of your app based off memory of the URL structure. In order to achieve this, your URLs will need to be &lt;em&gt;pragmatic.&lt;/em&gt; Almost like they were a math equation — many simple rules combined in a strategic fashion to get to the page they want.&lt;/p&gt;

&lt;h2&gt;Top level sections are gold&lt;/h2&gt;

&lt;p&gt;The most valuable aspect of any URL is what lies at the top level section. In my opinion, it should be the first discussion of any startup directly after the idea is solidified. Long before any technology discussion. Long before any code is written. This is top-level section is going to change the fundamentals of how your site functions.&lt;/p&gt;

&lt;p&gt;Do I seem dramatic? It may seem that way — but come 1,000,000 users later think about how big of an impact it will be. Think about how big of a deal Facebook&amp;rsquo;s rollout of usernames was. Available URLs are a lot like real estate and the top level section is the best property out there.&lt;/p&gt;

&lt;p&gt;Another quick tip — whenever you&amp;rsquo;re building a new site, think about &lt;a href="http://www.quora.com/How-do-sites-prevent-vanity-URLs-from-colliding-with-future-features?__snids__=4909005"&gt;blacklisting a set of vanity URLs&lt;/a&gt; (and maybe learn a little bit about bad URL design from Quora&amp;rsquo;s URLs).&lt;/p&gt;

&lt;h2&gt;Namespacing is a great tool to expand URLs&lt;/h2&gt;

&lt;p&gt;Namespaces can be a great way to build up a pragmatic URL structure that&amp;rsquo;s easy to remember with continued usage. What do I mean by a namespace? I mean a portion of a URL that dictates unique content. An example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;https://github.com/&lt;strong&gt;defunkt/resque&lt;/strong&gt;/issues&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;In the URL above, &lt;strong&gt;&lt;code&gt;defunkt/resque&lt;/code&gt;&lt;/strong&gt; is the namespace. Why is this useful? Because anything after that URL suddenly becomes a new top level section. So you can go to any &lt;strong&gt;&lt;code&gt;&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;&lt;/code&gt;&lt;/strong&gt; and then tack on &lt;code&gt;/issues&lt;/code&gt; or maybe &lt;code&gt;/wiki&lt;/code&gt; and get the same page, but under a different namespace.&lt;/p&gt;

&lt;p&gt;Keep that namespace clean. Don&amp;rsquo;t start throwing some content under &lt;code&gt;/feature/&lt;strong&gt;&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;&lt;/strong&gt;&lt;/code&gt; and some under &lt;code&gt;/&lt;strong&gt;&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;&lt;/strong&gt;/feature&lt;/code&gt;. For a namespace to be effective it has to be universal.&lt;/p&gt;

&lt;h2&gt;Querystrings are great for filters and sorts&lt;/h2&gt;

&lt;p&gt;The web has had a confused past with regards to querystrings. I&amp;rsquo;ve seen everything from every page of a site being served from one URL with different querystring parameters to sites who don&amp;rsquo;t use a single querystring parameter.&lt;/p&gt;

&lt;p&gt;I like to think of querystrings as the knobs of URLs — something to tweak your current view and fine tune it to your liking. That&amp;rsquo;s why they work so great for sorting and filtering actions. Stick to a uniform pattern (&lt;code&gt;sort=alpha&amp;amp;dir=desc&lt;/code&gt; for instance) and you&amp;rsquo;ll make sorting and filtering via the URL bar easy and rememberable.&lt;/p&gt;

&lt;p&gt;One last thing regarding querystrings: The page should work without the querystrings attached. It may show a different page, but the URL without querystrings should render.&lt;/p&gt;

&lt;h2&gt;Non-ASCII URLs are terrible for english sites&lt;/h2&gt;

&lt;p&gt;The world is a complicated place filled with ¿ümlåts?, ¡êñyés! and all sorts of awesome characters ☄. These characters have no place in the URL of any english site. They&amp;rsquo;re complicated to type with english keyboards and often times expand into confusing characters in browsers (ever see &lt;code&gt;xn--n3h&lt;/code&gt; in a url? That&amp;rsquo;s a ☃).&lt;/p&gt;

&lt;h2&gt;URLs are for humans — not for search engines&lt;/h2&gt;

&lt;p&gt;I grew up in this industry learning how to game search engines (well, Google) to make money off my affiliate sales, so I&amp;rsquo;m no stranger to the practice of keyword stuffing URLs. It was fairly common to end up with a URL like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://guitars.example.com/best-guitars/cheap-guitars/popular-guitar
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That kind of URL used to be great for SEO purposes. Fortunately Google&amp;rsquo;s hurricane updates of 2003 eliminated any ranking benefit of these URLs. Unfortunately the professional SEO industry is centered around extortion and still might advise you stuff your URLs with as many keywords as you can think of. They&amp;rsquo;re wrong — ignore them.&lt;/p&gt;

&lt;p&gt;Some additional points to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Underscores are just bad. Stick to dashes.&lt;/li&gt;
&lt;li&gt;Use short, full, and commonly known words. If a section has a dash or special character in it, the word is probably too long.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;URLs are for humans. &lt;strong&gt;Design them for humans.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;A URL is an agreement&lt;/h2&gt;

&lt;p&gt;A URL is an agreement to serve something from a predictable location for as long as possible. Once your first visitor hits a URL you&amp;rsquo;ve implicitly entered into an agreement that if they bookmark the page or hit refresh, they&amp;rsquo;ll see the same thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don&amp;rsquo;t change your URLs after they&amp;rsquo;ve been publicly launched.&lt;/strong&gt; If you absolutely must change your URLs, add redirects — it&amp;rsquo;s not that scary.&lt;/p&gt;

&lt;h2&gt;Everything should have a URL&lt;/h2&gt;

&lt;p&gt;In an ideal world, every single screen on your site should result in a URL that can be copy &amp;amp; pasted to reproduce the same screen in another tab/browser. In fairness, this wasn&amp;rsquo;t completely possible until very recently with some of the new HTML5 browser history Javascript APIs. Notably, there are two new methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;onReplaceState&lt;/code&gt;&lt;/strong&gt; — This method replaces the current URL in the browser history, leaving the back button unaffected.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;onPushState&lt;/code&gt;&lt;/strong&gt; &amp;ndash; This method pushes a new URL onto the browser&amp;rsquo;s history, replacing the URL in the URL bar &lt;em&gt;and&lt;/em&gt; adding it to the browser&amp;rsquo;s history stack (affecting the back button).&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;When to use &lt;code&gt;onReplaceState&lt;/code&gt; and when to use &lt;code&gt;onPushState&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;These new methods allow us to change the &lt;em&gt;entire&lt;/em&gt; path in the URL bar, not just the anchor element. With this new power, comes a new design responsibility — we need to craft the back button experience.&lt;/p&gt;

&lt;p&gt;To determine which to use, ask yourself this question: &lt;em&gt;Does this action produce new content or is it a different display of the same content?&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Produces new content&lt;/strong&gt; — you should use &lt;code&gt;onPushState&lt;/code&gt; (ex: pagination links)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Produces a different display of the same content&lt;/strong&gt; — you should use &lt;code&gt;onReplaceState&lt;/code&gt; (ex: sorting and filtering)&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Use your own judgement, but these two rules should get you 80% there. Think about what you want to see when you click the back button and make it happen.&lt;/p&gt;

&lt;h2&gt;A link should behave like a link&lt;/h2&gt;

&lt;p&gt;There&amp;rsquo;s a lot of awesome functionality built into linking elements like &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;.  If you middle click or command-click on them they&amp;rsquo;ll open in new windows. When you hover over an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; your browser tells you the URL in the status bar.  Don&amp;rsquo;t break this behavior when playing with &lt;code&gt;onReplaceState&lt;/code&gt; and &lt;code&gt;onPushState&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embed the location of AJAX requests in the &lt;code&gt;href&lt;/code&gt; attributes of anchor elements.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;return true&lt;/code&gt; from Javascript click handlers when people middle or command click.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;It&amp;rsquo;s fairly simple to do this with a quick conditional inside your click handlers. Here&amp;rsquo;s an example jQuery compatible snippet:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a.ajaxylink&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="c1"&gt;// Fallback for browser that don&amp;#39;t support the history API&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;replaceState&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="c1"&gt;// Ensure middle, control and command clicks act normally&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;which&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metaKey&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Do something awesome, then change the URL&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;New Title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/some/cool/url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Post-specific URLs need to die&lt;/h2&gt;

&lt;p&gt;In the past, the development community loved to create URLs which could never be re-used. I like to call them POST-specific URLs — they&amp;rsquo;re the URLs you see in your address bar after you submit a form, but when you try to copy &amp;amp; pasting the url into a new tab you get an error.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s no excuse for these URLs at all. Post-specific URLs are for redirects and APIs — not end-users.&lt;/p&gt;

&lt;h2&gt;A great example&lt;/h2&gt;

&lt;div class="figure"&gt;&lt;a href="https://github.com/defunkt/resque/pull/175#issuecomment-619615"&gt;&lt;img src="http://assets.warpspire.com/images/urldesign/urlparts.1.gif" alt="Example URL" /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;&lt;p&gt;ASCII-only user generated URL parts (defunkt, resque).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;ldquo;pull&amp;rdquo; is a short version of &amp;ldquo;pull request&amp;rdquo; — single word, easily associated to the origin word.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The pull request number is scoped to defunkt/resque (starts at &lt;strong&gt;one&lt;/strong&gt; there).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anchor points to a scrolling position, not hidden content.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;strong&gt;Bonus points:&lt;/strong&gt; This URL has many different formats as well — check out the &lt;a href="https://github.com/defunkt/resque/pull/175.patch"&gt;patch&lt;/a&gt; and &lt;a href="https://github.com/defunkt/resque/pull/175.diff"&gt;diff&lt;/a&gt; versions.&lt;/p&gt;

&lt;h2&gt;The beginning of an era&lt;/h2&gt;

&lt;p&gt;I hope that as usage of new Javascript APIs increases, designers and developers take time to design URLs.  It&amp;rsquo;s an important part of any site&amp;rsquo;s usability and too often I see URLs ignored. While it&amp;rsquo;s easy to redesign the look &amp;amp; feel of a site, it&amp;rsquo;s &lt;em&gt;much&lt;/em&gt; more difficult to redesign the URL structure.&lt;/p&gt;

&lt;p&gt;But I&amp;rsquo;m excited. I&amp;rsquo;ve watched URLs change over the years. At times hard-linking was sacrificed at the altar of AJAX while other times performance was sacrificed to generate real URLs for users. We&amp;rsquo;re finally at a point in time where we can have the performance and usability benefits of partial page rendering while designing a coherent and refined URL experience at the same time.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/2qo4oCys3fU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/url-design</feedburner:origLink></entry>
 
 <entry>
   <title>My TextMate Snippets &amp; Triggers</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/AI4kFT_NLSI/textmate-snippets" />
   
   <updated>2010-08-26T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/link-snippets</id>
   <content type="html">&lt;p&gt;A while ago I put up a collection of some of my handcrafted TextMate snippets. mostly focused on front-end stuff: HTML shortcuts, CSS gradients, jQuery plugin bases, commenting helpers, etc.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/AI4kFT_NLSI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://github.com/kneath/textmate-snippets</feedburner:origLink></entry>
 
 <entry>
   <title>The Geek Talk Interview</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/UA5E39usQO4/" />
   
   <updated>2010-08-23T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/link-geektalk</id>
   <content type="html">&lt;p&gt;A quick interview I did over at The Geek Talk. Mostly covering my daily routine and whatnot.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/UA5E39usQO4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://thegeektalk.com/interviews/kyle-neath/</feedburner:origLink></entry>
 
 <entry>
   <title>RSS Feeds for Warpspire</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/c_H3AiieTHY/warpspire" />
   
   <updated>2010-08-23T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/link-feeds</id>
   <content type="html">&lt;p&gt;I was going to try and fix some bugs in &lt;a href="http://pages.github.com"&gt;GitHub Pages&lt;/a&gt; (that&amp;rsquo;s how this site is hosted) — but I think I&amp;rsquo;m going to give up that fight. If you&amp;rsquo;d like to subscribe to Warpspire, you can find the feeds at &lt;a href="http://feeds.feedburner.com/warpspire"&gt;http://feeds.feedburner.com/warpspire&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/c_H3AiieTHY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://feeds.feedburner.com/warpspire</feedburner:origLink></entry>
 
 <entry>
   <title>Rethinking Warpspire</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/6eBmbN1deg0/rethinking" />
   
   <updated>2010-08-01T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/rethinking</id>
   <content type="html">&lt;p&gt;I think it&amp;rsquo;s always a good idea to take a step back and ask yourself why you&amp;rsquo;re doing something.  So right now I&amp;rsquo;m taking a step back to rethink Warpspire.&lt;/p&gt;

&lt;h2&gt;Getting rid of cruft&lt;/h2&gt;

&lt;p&gt;The other day I followed a link to a blog post on Mint. I was presented with this screen:&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/rethinking/mint_screen.jpg" alt="Screenshot of Mint blog post" /&gt;&lt;/div&gt;


&lt;p&gt;I hate what most designers have done to the web. You&amp;rsquo;d think people would be taking cues from things like &lt;a href="http://lab.arc90.com/experiments/readability/"&gt;Readability&lt;/a&gt; and Safari Reader, but they&amp;rsquo;re not. People are throwing more and more crap onto each page and making things harder and harder to read.&lt;/p&gt;

&lt;p&gt;Anyways, it got me to thinking about sites that I continue to enjoy reading in the browser. One site that immediately came to mind is &lt;a href="http://daringfireball.net"&gt;Daring Fireball&lt;/a&gt;. The format and presentation has lasted for years without feeling tired or hard to read. So it should come as no suprise that this new layout mirrors DF in a great number of ways. (Alas, my logo features the same unicode character as DF — something which has now turned from a funny coincidence to a long boring story. I hate logos.)&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/rethinking/warpspire_screen.jpg" alt="Screenshot of Warpspire" /&gt;&lt;/div&gt;


&lt;p&gt;This new layout is the simplest layout I&amp;rsquo;ve ever had on one of my sites. The goal was to create a focused place for my ideas.&lt;/p&gt;

&lt;h2&gt;Abandoning old baggage&lt;/h2&gt;

&lt;p&gt;There was a lot of crap on Warpspire. WordPress tells me the first post was published August 15, 2004. &lt;strong&gt;That&amp;rsquo;s six years ago.&lt;/strong&gt;  To say that the web is a different place now is an understatement. I remember debugging that initial site on IE5 &lt;em&gt;for Mac&lt;/em&gt;.  Six years ago, I was in my 2nd year of studying Civil Engineering at Cal Poly. I had no concept of the value of the web or how important it would be come.  I was also twenty years old, angsty and wrong about many things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;So I deleted most of my posts.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What&amp;rsquo;s left? The most popular posts (traffic wise) along with a couple of ones that I particularly enjoyed and still felt relevant.  I&amp;rsquo;ve also edited them all, and rewritten some.&lt;/p&gt;

&lt;p&gt;Almost certainly a bad idea for my traffic, but probably a good idea for my readership. And I&amp;rsquo;ll value readers over pageviews any day.&lt;/p&gt;

&lt;h2&gt;On the subject of comments&lt;/h2&gt;

&lt;p&gt;The thing about comments is that commentors tend to be a bunch of crazies wandering the internet like it&amp;rsquo;s a zombie apocolypse. It&amp;rsquo;s a striking contrast to the rational human beings whom I have sensible arguments with here in the meatspace.&lt;/p&gt;

&lt;p&gt;The thing is, I&amp;rsquo;ve met some of the smartest people on the planet through my site and I don&amp;rsquo;t want to lose that. So here&amp;rsquo;s the deal: you send me email, and I send you one back.  If I think others might be interested in what you have to say, I&amp;rsquo;ll post it here on Warpspire.&lt;/p&gt;

&lt;p&gt;A comment should mean something to you and it should mean something to me. Typical blog comments just stopped meaning anything to me a long time ago and that sucks. So I&amp;rsquo;m hoping this is a move toward fixing that.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/6eBmbN1deg0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/rethinking</feedburner:origLink></entry>
 
 <entry>
   <title>What's your focus?</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/tdbW9r_P65c/focus" />
   
   <updated>2010-03-29T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/focus</id>
   <content type="html">&lt;p&gt;Every great website has a focus.  If you can&amp;rsquo;t summarize the purpose of your website into one sentence, ten words or less &amp;mdash; your idea will almost certainly fail.  Talking to founders, I&amp;rsquo;d say this idea is pretty well established.  Now let me reveal a secret that is not so well established: your website&amp;rsquo;s design should follow this same focus.&lt;/p&gt;

&lt;h2&gt;Learn by example: source hosting sites&lt;/h2&gt;

&lt;p&gt;Let&amp;rsquo;s start off with a field I&amp;rsquo;m pretty familiar with: source hosting sites. I&amp;rsquo;m talking about &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt;, &lt;a href="http://bitbucket.org"&gt;BitBucket&lt;/a&gt;, &lt;a href="http://sourceforge.net"&gt;SourceForge&lt;/a&gt;, &lt;a href="http://code.google.com"&gt;Google Code&lt;/a&gt;, &lt;a href="http://launchpad.net"&gt;Launchpad&lt;/a&gt; and the likes.  These sites all have a common focus: &lt;strong&gt;sharing code.&lt;/strong&gt;  I&amp;rsquo;m going to show you why GitHub is the only site who&amp;rsquo;s design follows it&amp;rsquo;s focus.&lt;/p&gt;

&lt;p&gt;If your site&amp;rsquo;s focus is sharing code, the design should focus on sharing code. If you ever talk to any of us GitHubbers, we&amp;rsquo;ll always say that the site is &lt;em&gt;all about the code&lt;/em&gt;.  Let&amp;rsquo;s look at project landing pages in each of the above sites.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://github.com/facebook/three20"&gt;GitHub&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/github.gif" alt="GitHub" /&gt;&lt;/div&gt;


&lt;p&gt;When you visit a GitHub project page, the first thing you see is the source code. Right below is the README pulled straight from the code.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://bitbucket.org/jespern/django-piston/overview/"&gt;BitBucket&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/bitbucket.gif" alt="BitBucket" /&gt;&lt;/div&gt;


&lt;p&gt;BitBucket chose to highlight the shortlog (recent commits) on the project page.  If you want to see the code, you need to go to the 3rd tab.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://sourceforge.net/projects/junit/"&gt;SourceForge&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/sourceforge.gif" alt="SourceForge" /&gt;&lt;/div&gt;


&lt;p&gt;Sourceforge chose to highlight downloads (in this case, a compiled jar file &amp;mdash; not the code) on the project page.  If you want to see the code, you need to click Develop, and then fish around in the sidebar for the correct VCS and click browse.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://code.google.com/p/flot/"&gt;Google Code&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/googlecode.gif" alt="Google Code" /&gt;&lt;/div&gt;


&lt;p&gt;Google Code chose to highlight the wiki on the project page.  Getting to the code in Google Code is probably the most interesting of the bunch because many projects don&amp;rsquo;t even host their code there (example: &lt;a href="http://code.google.com/p/redis/wiki/UnstableSource?tm=4"&gt;redis&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;When you click the Source tab you actually get a wiki page which many projects use to point to another repository.  &lt;em&gt;If&lt;/em&gt; the project hosts it&amp;rsquo;s code there, there is a sub link under Source that is labeled Browse that you can finally see the code.&lt;/p&gt;

&lt;h3&gt;&lt;a href="https://launchpad.net/drizzle"&gt;Launchpad&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/launchpad.gif" alt="Launchpad" /&gt;&lt;/div&gt;


&lt;p&gt;Launchpad decided to highlight everything but the source code on the project page.  If you want to see the code, there is a tiny link in the middle of the page that says &amp;rsquo;View the branch content.&amp;rsquo;&lt;/p&gt;

&lt;h2&gt;Great examples from other fields&lt;/h2&gt;

&lt;p&gt;Source code hosting is just something that I&amp;rsquo;m extremely involved with. That doesn&amp;rsquo;t mean that focus is limited to code.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.flickr.com/photos/wcouch/4338090218/"&gt;Flickr&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/flickr.gif" alt="Flickr" /&gt;&lt;/div&gt;


&lt;p&gt;Flickr is all about sharing photos.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://facebook.com"&gt;Facebook&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/facebook.gif" alt="Facebook" /&gt;&lt;/div&gt;


&lt;p&gt;Facebook is all about connecting with your friends.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://daringfireball.net"&gt;Daring Fireball&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/fireball.gif" alt="Daring Fireball" /&gt;&lt;/div&gt;


&lt;p&gt;Daring Fireball is all about John Gruber&amp;rsquo;s writing.&lt;/p&gt;

&lt;h2&gt;Sites that have lost their focus&lt;/h2&gt;

&lt;p&gt;There is a huge genre of sites that seem to have completely forgotten their focus.  I&amp;rsquo;ll see if you can guess the genre.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://msnbc.com"&gt;MSNBC&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/msnbc.gif" alt="MSNBC" /&gt;&lt;/div&gt;


&lt;h3&gt;&lt;a href="http://nytimes.com"&gt;NYTimes&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/nytimes.gif" alt="NYTimes" /&gt;&lt;/div&gt;


&lt;h3&gt;&lt;a href="http://www.rollingstone.com/politics/story/32255149/wall_streets_bailout_hustle/p"&gt;Rolling Stone&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/rollingstone.gif" alt="Rolling Stone" /&gt;&lt;/div&gt;


&lt;p&gt;It&amp;rsquo;s no wonder news sites can&amp;rsquo;t get people to pay for their content. You need to focus on your content to get people to pay for it.&lt;/p&gt;

&lt;h2&gt;Charging for your focus&lt;/h2&gt;

&lt;p&gt;Many sites don&amp;rsquo;t want to give away their focus for free. That&amp;rsquo;s perfectly fine. But it doesn&amp;rsquo;t change a thing. Replace what people are going to pay for with an opportunity to pay you.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;img src="http://assets.warpspire.com/images/focus/peepcode.gif" alt="PeepCode" /&gt;&lt;/div&gt;


&lt;p&gt;PeepCode&amp;rsquo;s focus is great tutorials. But the tutorial is not the focus of the product page &amp;mdash; instead a teaser and a purchase button are.&lt;/p&gt;

&lt;p&gt;Lots of people think that replacing their paid focus content with advertising is the solution &amp;mdash; but that just redirects the focus on advertising &amp;mdash; not getting paid.&lt;/p&gt;

&lt;p&gt;Premium content is not about &lt;em&gt;removing access&lt;/em&gt;, it&amp;rsquo;s about &lt;em&gt;charging for access&lt;/em&gt;.  Don&amp;rsquo;t focus on removing content, focus on charging for it.&lt;/p&gt;

&lt;h2&gt;Find your focus and focus on it&lt;/h2&gt;

&lt;p&gt;If you work on a website for a living, you should be thinking about your focus every single day.  It doesn&amp;rsquo;t matter if you&amp;rsquo;re a copywriter, project manager, designer or sysadmin.  What&amp;rsquo;s the focus of your site? Does your design reflect this? Run that through your head for every decision.&lt;/p&gt;

&lt;p&gt;The beautiful thing about focus is that it&amp;rsquo;s not about the details. It doesn&amp;rsquo;t  matter if you add some advertising to a sidebar, links to your header, change the background color or add administrative debris &amp;mdash; these are all minor subjects.  Focus is more about aiming in the right direction. Worry about the details later &amp;mdash; but never aim in a different direction.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/tdbW9r_P65c" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/focus</feedburner:origLink></entry>
 
 <entry>
   <title>Optimizing asset bundling and serving with Rails</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/hbS2WYCFuJU/551-optimizing-asset-bundling-and-serving-with-rails" />
   
   <updated>2009-11-19T00:00:00-08:00</updated>
   <id>http://warpspire.com/posts/link-asset-bundling</id>
   <content type="html">&lt;p&gt;I wrote up a pretty lengthy post over at the GitHub blog explaining how we do asset bundling and serving. Well worth the read for anyone who&amp;rsquo;s interested in front end performance and works on ruby apps.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/hbS2WYCFuJU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://github.com/blog/551-optimizing-asset-bundling-and-serving-with-rails</feedburner:origLink></entry>
 
 <entry>
   <title>It's not about how many hours you work</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/c6kGRLUV6HI/work-life-balance" />
   
   <updated>2009-10-11T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/work-life-balance</id>
   <content type="html">&lt;p&gt;My favorite discussion amongst web professionals is when people start talking about work/life balance and how many hours they&amp;rsquo;re working.  There&amp;rsquo;s been no end of interesting ideas to pop out from this &amp;mdash; everything from 4 hour work weeks to 100 hour work weeks.  And everyone thinks that they&amp;rsquo;ve got the answer. But I think everyone&amp;rsquo;s just arguing about an irrelevant metric: the hour.&lt;/p&gt;

&lt;h2&gt;Let&amp;rsquo;s talk about that work/life balance thing&lt;/h2&gt;

&lt;p&gt;Most of this discussion always seem to revolve around the idea of a work/life balance.  The basic idea is to keep yourself sane.  Don&amp;rsquo;t abandon your real life for your work.  That makes sense, until people start attaching hours to it.  I&amp;rsquo;ve had discussions with people where they try and argue to me that 40 hour work weeks keep them balanced.  But I have to wonder, where does that magical number 40 come from?&lt;/p&gt;

&lt;p&gt;The fallacy here is that people are thinking in black and white terms of &amp;ldquo;work&amp;rdquo; and &amp;ldquo;life.&amp;rdquo;  I never really understood that, and I think I&amp;rsquo;ve gotten to a point in my life where I can see why: it&amp;rsquo;s a bunch of bullshit that employers made up to promote 40 hour work weeks.  If you really think that there is a certain number of hours you can work a week to balance your life, you&amp;rsquo;re doing it wrong. So let&amp;rsquo;s ditch this idea of a work/life balance, because it just doesn&amp;rsquo;t make sense.&lt;/p&gt;

&lt;h2&gt;It&amp;rsquo;s about creating a creative environment in your life&lt;/h2&gt;

&lt;p&gt;It&amp;rsquo;s just that simple.  If you&amp;rsquo;re in the creative field, you need to make sure your life promotes a creative environment.  There isn&amp;rsquo;t one catch-all formula to do this.  There isn&amp;rsquo;t a number of hours you need to work.  You just need to experiment and find out what works for you.  What I will do is try and offer some advice.&lt;/p&gt;

&lt;h3&gt;Find your passion in life and try to make money from it&lt;/h3&gt;

&lt;p&gt;If you hate your job, it&amp;rsquo;s unlikely that you&amp;rsquo;ll be successful in fostering a creative environment.  Try your best to fix this.  Find out what you&amp;rsquo;re good at, and try to make money from it.  You&amp;rsquo;ll be producing better (more valuable) work and enjoying life more.&lt;/p&gt;

&lt;h3&gt;Explore projects that are explicitly not for profit&lt;/h3&gt;

&lt;p&gt;Money taints things, there is no denying this.  So I suggest to find an outlet that you purposefully can&amp;rsquo;t/don&amp;rsquo;t make money from to help exercise your brain.  That might mean creating websites, making music, or hacking on an epic perl script that no one but yourself will use.  It doesn&amp;rsquo;t have to be something different from your work &amp;mdash; it just has to be separated from your work.  Something you can change or destroy without worrying about what others think.&lt;/p&gt;

&lt;h3&gt;Stop working if you&amp;rsquo;re producing crap&lt;/h3&gt;

&lt;p&gt;The only thing worse than being unproductive at work is forcing false productivity.  If you find yourself at your desk and you can&amp;rsquo;t come up with anything useful, just stop trying.  Leave your desk and go do something else.  Maybe for a few hours, maybe for a week, maybe &lt;a href="http://www.fastcompany.com/blog/cliff-kuang/design-innovation/design-geniuss-secret-time-and-lots-it"&gt;for a year&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Accept that there is no way you can be productive for 40 hours a week&lt;/h3&gt;

&lt;p&gt;The 40 hour work week is completely unsustainable.  Human beings are not meant to sit down and &lt;em&gt;really&lt;/em&gt; focus for 40 hours a week, 50 weeks a year.  Our brains can&amp;rsquo;t handle it.  I&amp;rsquo;m sure startup founders will come in here exclaiming how they&amp;rsquo;ve been working 100 hour work weeks for 6 months now and every hour was well spent.  They&amp;rsquo;re lying.&lt;/p&gt;

&lt;p&gt;Your brain &lt;em&gt;needs&lt;/em&gt; to purposefully not think in order to come up with creative ideas.  That might mean relaxing to your favorite book or movie while your subconscious attacks your latest project.  You&amp;rsquo;re not working in the strict sense&amp;mdash;but you&amp;rsquo;re getting work done.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s not to say you can&amp;rsquo;t have weeks where you get hundreds of hours of work done.  But in my experience, after a week like that, I need another week or two to decompress.&lt;/p&gt;

&lt;h2&gt;Focus on what matters&lt;/h2&gt;

&lt;p&gt;My goal with this post is to hopefully get people to stop thinking in hours.  Start focusing on making great things.  It&amp;rsquo;s about the things you produce, not the hours required to make them.&lt;/p&gt;

&lt;p&gt;Once you realize you&amp;rsquo;ve been focused on the wrong metric I think you&amp;rsquo;ll realize  arguing about a work/life balance is just ridiculous.  Spend time on your life. Spend time on your work. But always strive to do better. That&amp;rsquo;s all you need.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/c6kGRLUV6HI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/work-life-balance</feedburner:origLink></entry>
 
 <entry>
   <title>Joining GitHub</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/TSIVMRvJLAo/joining-github" />
   
   <updated>2009-10-01T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/joining-github</id>
   <content type="html">&lt;p&gt;I still feel like it was last week I decided to &lt;a href="/features/ch-ch-ch-changes/"&gt;give up my &amp;ldquo;safe&amp;rdquo; job at &lt;strike&gt;Web Associates&lt;/strike&gt; Level Studios&lt;/a&gt; to play around with the &lt;a href="http://entp.com"&gt;ENTP&lt;/a&gt; crew.  Well, it&amp;rsquo;s time for another move.  Last week I was given an offer I just couldn&amp;rsquo;t refuse&amp;mdash;to join the amazing &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; team (&lt;a href="http://github.com/kneath"&gt;my GitHub profile&lt;/a&gt;.  For those of you who don&amp;rsquo;t know who GitHub is: shame on you.  GitHub has taken something as boring as source control and made it something that &lt;em&gt;brings people together&lt;/em&gt;.  Social coding, indeed.&lt;/p&gt;

&lt;h2&gt;A brief look at the past couple years&lt;/h2&gt;

&lt;p&gt;The past couple of years have been a crazy blur of projects for me.  Most of what I did for ENTP was for [redacted], so you won&amp;rsquo;t be seeing most of what I did, but I thought I&amp;rsquo;d spend a few minutes to archive (for my own good) some of the public-facing projects I completed.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://tenderapp.com"&gt;Tender&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;a href="http://tenderapp.com"&gt;&lt;img src="http://assets.warpspire.com/images/github/tender_marketing.jpg" alt="Tender's Marketing Site" /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;p&gt;By in large, the biggest project I worked on ENTP was &lt;a href="http://tenderapp.com"&gt;Tender&lt;/a&gt; &amp;mdash; and I&amp;rsquo;ll be honest, it&amp;rsquo;s going to hurt to let this go.  Tender was my baby, and I did all of the IA, design and front-end work for the site as well as some marketing and analytical work.  The shining side of that tunnel is that of course GitHub &lt;a href="http://support.github.com"&gt;uses Tender&lt;/a&gt; for their support, so I&amp;rsquo;ll at least get to use it and see how ENTP shapes the product.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://iphone.lighthouseapp.com"&gt;Lighthouse iPhone&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;a href="http://iphone.lighthouseapp.com"&gt;&lt;img src="http://assets.warpspire.com/images/github/lighthouse_iphone.jpg" alt="Lighthouse iPhone Screenshots" /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;p&gt;Designing an iPhone optimized interface was one of my first projects at ENTP.  It doesn&amp;rsquo;t benefit from any of the OS 2.0+ features (HTML5, CSS Animations, Etc) since the code was created before these came along, but it gets the job done.  It was a great exploration in turning a complicated interface and trimming it down to the bare essentials.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://entp.com"&gt;ENTP.com&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;a href="http://entp.com"&gt;&lt;img src="http://assets.warpspire.com/images/github/entp.jpg" alt="ENTP.com Screenshot" /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;p&gt;I designed this in collaboration with Justin Palmer when ENTP decided they needed a new site.  It&amp;rsquo;s got a few interesting features (like pulling in our current GitHub projects on demand in the footer), but it&amp;rsquo;s mostly just a brochure site for the agency.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://hoth.entp.com"&gt;Hoth&lt;/a&gt;&lt;/h3&gt;

&lt;div class="figure"&gt;&lt;a href="http://hoth.entp.com"&gt;&lt;img src="http://assets.warpspire.com/images/github/entp_hoth.jpg" alt="Hoth Screenshot" /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;p&gt;Hoth is ENTP&amp;rsquo;s blog.  This design accompanied the new ENTP.com design and added in a bit of tumble-like functionality to the templates.&lt;/p&gt;

&lt;h2&gt;On to the next chapter&lt;/h2&gt;

&lt;p&gt;So now I enter the third dream job I&amp;rsquo;ve had in the 4 years since I graduated college (none of which have been slightly related to my degree). I&amp;rsquo;ll be diving into a design/front-end role for the team and help clean up and take the product to the next level.&lt;/p&gt;

&lt;div class="figure"&gt;&lt;a href="http://github.com"&gt;&lt;img src="http://assets.warpspire.com/images/github/octocat.png" alt="OctoCat" /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;p&gt;I&amp;rsquo;ll see ya&amp;rsquo;ll at the next GitHub drinkup.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/TSIVMRvJLAo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/joining-github</feedburner:origLink></entry>
 
 <entry>
   <title>Installable apps</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/z6w1ZTfCn3s/installable-apps" />
   
   <updated>2009-05-03T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/installable-apps</id>
   <content type="html">&lt;p&gt;I&amp;rsquo;m getting kind of tired of all these &lt;em&gt;web&lt;/em&gt; developers complaining about the time it takes to get updates to their apps up on the iTunes App Store.  The truth is this complaining has some merit.  But you have to realize that these people are not making &lt;em&gt;web&lt;/em&gt; applications, they&amp;rsquo;re making &lt;em&gt;installable&lt;/em&gt; applications.  The problem is not Apple. The problem is lack of QA testing.&lt;/p&gt;

&lt;h2&gt;Your application will have many bugs&lt;/h2&gt;

&lt;p&gt;The first rule of development: your code is going to have a lot of bugs. I don&amp;rsquo;t care if you&amp;rsquo;ve got 3 days experience or 30 years experience in the industry. &lt;strong&gt;Your code will have bugs.&lt;/strong&gt; This isn&amp;rsquo;t a pride issue, it&amp;rsquo;s a fact of life. Good developers know this and rely on testing (code, user-acceptance, performance) to expose bugs so they can fix them.&lt;/p&gt;

&lt;h2&gt;Bugs will appear after your code is deployed&lt;/h2&gt;

&lt;p&gt;Whether it&amp;rsquo;s the Y2k bug, deprecation of a technology, or your application getting blacklisted from a web service &amp;mdash; some bugs are going to show up after your code is deployed.  This is something you should expect.  Again, this is not negotiable. It is going to happen.&lt;/p&gt;

&lt;h2&gt;The web makes us lazy&lt;/h2&gt;

&lt;p&gt;The truth is, developing web applications makes us lazy.  I can fix a bug, deploy, and it&amp;rsquo;s fixed in about 15 seconds.  This is why I &lt;em&gt;love&lt;/em&gt; working on hosted web applications.  You&amp;rsquo;ve got such immense power over the deployment process.  Some things that rock about web apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can be &lt;em&gt;really lazy&lt;/em&gt; with UAT (User Acceptance Testing).  Users will do your UAT for your and you can fix it on the fly.&lt;/li&gt;
&lt;li&gt;You can be &lt;em&gt;really lazy&lt;/em&gt; with bugs that will appear after deploy.  If a web service changes, you fix it and redeploy. Done.&lt;/li&gt;
&lt;li&gt;You only need &lt;em&gt;one computer&lt;/em&gt; to test your application.  No need to purchase multiple hardware platforms, video cards, or install multiple operating systems!&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;You can&amp;rsquo;t be lazy with installable applications&lt;/h2&gt;

&lt;p&gt;I once worked on a desktop application that was being sent out on millions of machines.  This application was going to be the first thing that started up when the user booted the machine.  It also meant we didn&amp;rsquo;t have the option to issue updates for the application after deployment.  We spent &lt;em&gt;tons&lt;/em&gt; of time doing user testing on dozens of machines.  And then the client did user testing.  And then the client&amp;rsquo;s QA department did even more testing.  And then the client&amp;rsquo;s QA department did more testing throughout the whole time they were writing hard drives.&lt;/p&gt;

&lt;p&gt;Remember the days when you updated applications with &lt;em&gt;CDs&lt;/em&gt; or &lt;em&gt;floppy disks&lt;/em&gt;?  My god, for a while there it just &lt;em&gt;wasn&amp;rsquo;t feasible&lt;/em&gt; to update installable applications over the internet.  The end result? Software development firms spent a lot of time and money on QA.  Same goes for game development companies.&lt;/p&gt;

&lt;p&gt;My point is: if you know that one of your restraints is updating can be slow or impossible, you &lt;em&gt;spend more time testing the application.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;The App Store is slow&lt;/h2&gt;

&lt;p&gt;It&amp;rsquo;s true the App Store is slow when it comes to delivering updates.  To me, this is just a known variable.  Wouldn&amp;rsquo;t it be awesome if they had 24 hour turnaround? Sure would be.  But it&amp;rsquo;s one of those tradeoffs you get with a closed system.  If you want to trade it for an open system &amp;mdash; build a web application.  It&amp;rsquo;s not that hard.&lt;/p&gt;

&lt;p&gt;I know it sucks testing your application.  I know as a lone developer you don&amp;rsquo;t have the money to hire testers.&lt;/p&gt;

&lt;p&gt;But think of the rewards.  The App Store is something of a gold rush right now.  A small group of people have made obnoxious profits off very little effort.  There&amp;rsquo;s almost no overhead ($100 application fee? psh) &amp;mdash; and anyone can submit apps.  It&amp;rsquo;s a shitty closed ecosystem controlled by Apple. But it&amp;rsquo;s a shitty closed ecosystem of chocolate-filled pools lined with gold and supermodels dressed in nothing but $100 bills if you strike it rich.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/z6w1ZTfCn3s" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/installable-apps</feedburner:origLink></entry>
 
 <entry>
   <title>Xcode window management sucks</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/BFl0RB5CKCk/xcode-window-management" />
   
   <updated>2009-02-23T00:00:00-08:00</updated>
   <id>http://warpspire.com/posts/xcode-window-management</id>
   <content type="html">&lt;div class="infobox"&gt;
&lt;p&gt;&lt;strong&gt;Hi, did you come here to tell me that Xcode offers "all-in-one" editing?&lt;/strong&gt; Please, don't send me an email. This is addressed in this article if you take time to read it.&lt;/p&gt;
&lt;/div&gt;


&lt;p&gt;I posted some thoughts to twitter last night about how much the Xcode window management drives me insane.  What I got back was a huge reaction of &amp;ldquo;it&amp;rsquo;s perfect&amp;rdquo; and &amp;ldquo;this is how OSX works&amp;rdquo;  Suddenly I was wondering, am I just insane for thinking the window management is absolutely horrible?&lt;/p&gt;

&lt;p&gt;No, no. I&amp;rsquo;m not. It&amp;rsquo;s horrible.  Just because Apple built it, does not make it perfect.&lt;/p&gt;

&lt;h2&gt;Tabs are the future (actually it&amp;rsquo;s been the standard for years)&lt;/h2&gt;

&lt;p&gt;Tabs have clearly proven themselves to be a superior method for editing multiple code files.  Why? Because the most recognizable thing about code file is it&amp;rsquo;s &lt;em&gt;filename&lt;/em&gt;.  Not the look of the text.  Let&amp;rsquo;s look at this through some examples.&lt;/p&gt;

&lt;h3&gt;Case #1: Window-based management FTW, Photoshop&lt;/h3&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/xcode-windows/photoshop_full.jpg"&gt;&lt;img src="http://assets.warpspire.com/images/xcode-windows/photoshop.jpg" /&gt;&lt;/a&gt;
  &lt;small&gt;Example of window management in Photoshop&lt;/small&gt;
&lt;/div&gt;


&lt;p&gt;Window management in OSX defaults to a new window for each document. This works wonderfully for most applications when you can see the differences visually.  Photoshop is a great example.  Using Exposé, I can see which document I mean to be working on at a glance  The &lt;em&gt;visual representation&lt;/em&gt; of the document is the unique identifier.&lt;/p&gt;

&lt;p&gt;Some more points on why this works so well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image documents are the &lt;em&gt;only windows&lt;/em&gt; you will ever see in Photoshop. Everything else is a panel. This functionality is the same for all five-star document-based apps. iWork, iLife, etc.  There is a really good reason Apple chose to hide panels when activating Exposé.&lt;/li&gt;
&lt;li&gt;Photoshop is a document immersive program. It&amp;rsquo;s unlikely you&amp;rsquo;ll be working on more than one PSD at a time.  The document is all that matters. Conversely with code, the project is all that matters (not one code file).&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Case #2: Tab-based management FTW, Texmtate&lt;/h3&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/xcode-windows/textmate_full.jpg"&gt;&lt;img src="http://assets.warpspire.com/images/xcode-windows/textmate.jpg" /&gt;&lt;/a&gt;
  &lt;small&gt;Example of window management in Texmate&lt;/small&gt;
&lt;/div&gt;


&lt;p&gt;Window management for Textmate is handled via tabs and a persistent sidebar.  At a glance, you can see all files you&amp;rsquo;re currently working on.  In the case of Cocoa, you are often switching between interface &amp;amp; implementation files, but this is easily handled via cmd-opt-up, so long as you have the name of the class right, you&amp;rsquo;ve got the right file.&lt;/p&gt;

&lt;p&gt;Some points on why this works so well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows provide a way to group files in a meaningful manner. Each window is a unique project. Remember, the project is the important thing &amp;mdash; when coding in Cocoa, you&amp;rsquo;ll need to edit multiple files at once to make them work with one another.&lt;/li&gt;
&lt;li&gt;I can quickly move between individual files via the keyboard. Considering coding is almost purely typing, keeping my hands on the keyboard is &lt;em&gt;killer&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Case #3: WTF-based management FTL, Xcode&lt;/h3&gt;

&lt;div class="figure"&gt;
  &lt;a href="http://assets.warpspire.com/images/xcode-windows/xcode_full.jpg"&gt;&lt;img src="http://assets.warpspire.com/images/xcode-windows/xcode.jpg" /&gt;&lt;/a&gt;
  &lt;small&gt;Example of window management in Xcode&lt;/small&gt;
&lt;/div&gt;


&lt;p&gt;Window management for Xcode is handled via a combination of this thing called a Project window, which morphs depending on it&amp;rsquo;s toolbar state, windows for each document, and windows for ancillary programs (like the model editor).  Please note I have the same number of windows open in this screenshot as I did in Textmate (7).  It&amp;rsquo;s actually a pretty small program,  but completely overwhelming.&lt;/p&gt;

&lt;p&gt;Some points on why this doesn&amp;rsquo;t work so well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows mean different things.  Some mean code documents, some mean visual aid, some mean a kind of &amp;ldquo;project&amp;rdquo; that groups all things.&lt;/li&gt;
&lt;li&gt;The project window continually morphs it&amp;rsquo;s state as you enter and exit debugging. It&amp;rsquo;s appearance is different, not upon your application&amp;rsquo;s state, but rather the toolbar button in the upper left, that automatically changes (one-way).&lt;/li&gt;
&lt;li&gt;All the code looks the same. There is no unique identifier in Exposé mode. I must selectively hover over each file and read it&amp;rsquo;s filename. Or, I can exposé to try and find the project window (which can look much like a code window too), and then open a new document.&lt;/li&gt;
&lt;li&gt;If I accidentally Cmd-W the Project window, I have to start from scratch, opening the whole project and each document again. This often happens as you accidentally open windows and want to immediately close them.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Some may counter, telling me that Xcode offers editing inside the project window. Sure, this works, but offers just as many frustrations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You &lt;em&gt;must&lt;/em&gt; single click on files to open them. Double-clicking them still opens them in a new document.&lt;/li&gt;
&lt;li&gt;Because of the above, and the last bullet on the previous list, I constantly find myself accidentally closing the project because I was trying to close an accidentally opened window.&lt;/li&gt;
&lt;li&gt;Unless I choose not to run my program, I constantly have to switch out of debug mode and back into editing mode via the toolbar.&lt;/li&gt;
&lt;li&gt;Every single time I open Xcode I have to force it into editor mode.&lt;/li&gt;
&lt;li&gt;There is a delay in single clicking a document.  You click the file on the sidebar, the sidebar highlights, but the new document doesn&amp;rsquo;t open in the editing window for a second or two. When trying to scan documents for some code, this results in endless confusion.&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s no idea of &amp;ldquo;open files&amp;rdquo; in this mode. No context for which I&amp;rsquo;m working. I can&amp;rsquo;t say, work on the View Controllers by opening each of them. Each time I must select the unique view controller in the sidebar, ordered alphabetically.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;It&amp;rsquo;s a shame&lt;/h2&gt;

&lt;p&gt;It&amp;rsquo;s a shame, because other than the window management, Xcode is really an awesome IDE. The actual text editing is great as is debugging, scriptability, and file management. It really helps solve all the problems that Cocoa apps force upon mere text editors (long method names, class names, files being in one directory, different types of files in the same directory, etc).&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s the program&amp;rsquo;s fatal flaw in my mind.  It isn&amp;rsquo;t that it&amp;rsquo;s sub-par, or not good enough &amp;mdash; it&amp;rsquo;s downright infuriating to use. I want to do mean things to cute kittens whenever I use it.  So I don&amp;rsquo;t. I use TextMate. Which actually is very good at Cocoa &amp;amp; Objective-C. But it means much more typing (especially with the shift key) since TextMate favors tab-triggers rather than tab-completion.&lt;/p&gt;

&lt;p&gt;At the end of the day, this is the kind of stuff I hope Mac developers care about.  It&amp;rsquo;s about making the user experience the #1 priority in software development.  And it&amp;rsquo;s something that I&amp;rsquo;m confident Apple knows about and intends to fix in future versions of Xcode. Because they care about the user experience.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/BFl0RB5CKCk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/xcode-window-management</feedburner:origLink></entry>
 
 <entry>
   <title>Top reasons your CSS columns are messed up</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/joLnjlBWxcE/css-column-tricks" />
   
   <updated>2008-05-12T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/css-column-tricks</id>
   <content type="html">&lt;p&gt;I believe the recent surge in popularity of CSS frameworks comes from a lack of basic understanding of the CSS box model and how it&amp;rsquo;s implemented across browsers.  I wanted to share with you some quick tips on how to avoid easy pitfalls so you can create your own CSS framework in no time flat, without all the cruft of having ten thousand column combinations available.  Keeping these quick tips in mind at all times will allow you to do something I like to call &lt;em&gt;defensive coding&lt;/em&gt; &amp;mdash; and really that&amp;rsquo;s all CSS frameworks are: defensively coded snippets of CSS.&lt;/p&gt;

&lt;h2&gt;Your margins are doubled in IE6&lt;/h2&gt;

&lt;div class="figure"&gt;
&lt;img src="http://assets.warpspire.com/images/css-column-tricks/ie6doublefloat.gif" /&gt;
&lt;/div&gt;


&lt;p&gt;Here&amp;rsquo;s a super common pitfall: IE6 will double margins facing the direction of the float.  Example problematic code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nc"&gt;.sidebar&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;margin-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This sidebar will have a 40px left margin in IE6 &amp;mdash; almost certainly throwing the sidebar down below the content, and not next to the content as it should be.  Easy fix: add &lt;code&gt;display:inline;&lt;/code&gt;  No side effects in any browser, and IE6 obeys margins perfectly.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nc"&gt;.sidebar&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;margin-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;inline&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt; By declaring &lt;code&gt;float&lt;/code&gt; on an element, you implicitly demand that it must be rendered as a block element &amp;mdash; thus rendering the &lt;code&gt;display:inline&lt;/code&gt; inert.  However, due to IE6&amp;rsquo;s awesome CSS engine, it fixes a bizarre bug that is the #2 reason I see CSS columns fail in IE6.&lt;/p&gt;

&lt;h2&gt;Your content is wider than your column&lt;/h2&gt;

&lt;div class="figure"&gt;
&lt;img src="http://assets.warpspire.com/images/css-column-tricks/extendingcolumns.gif" /&gt;
&lt;/div&gt;


&lt;p&gt;Let&amp;rsquo;s pretend you&amp;rsquo;ve got this simplistic setup of code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nc"&gt;.columns&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.columns&lt;/span&gt; &lt;span class="nc"&gt;.main&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.columns&lt;/span&gt; &lt;span class="nc"&gt;.sidebar&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;HTML:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;columns&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/images/awesome.gif&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- /.main --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;sidebar&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Sidebar rules!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- /.sidbear --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- /.columns --&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Harmless right? You might view this in Firefox and everything will be fine. But then you look at it in IE6 and your sidebar has mysteriously dissapeared below &lt;code&gt;.main&lt;/code&gt;.  WTF? You look at the HTML, the CSS, and everything&amp;rsquo;s fine.  &lt;strong&gt;What could possibly be wrong?&lt;/strong&gt;  A common problem here is if &lt;code&gt;awesome.gif&lt;/code&gt; is 510px wide.  What this does is push out &lt;code&gt;.main&lt;/code&gt; to 510px, and suddenly there&amp;rsquo;s not enough room for &lt;code&gt;.sidebar&lt;/code&gt; inside &lt;code&gt;.columns&lt;/code&gt; any longer.  Ack!&lt;/p&gt;

&lt;p&gt;Easy fix: add &lt;code&gt;overflow:hidden&lt;/code&gt; to your columns.  This forces the width restriction to crop any extruding content.  New magical CSS:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nc"&gt;.columns&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.columns&lt;/span&gt; &lt;span class="nc"&gt;.main&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;overflow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.columns&lt;/span&gt; &lt;span class="nc"&gt;.sidebar&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;right&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;overflow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Your margins extend past your container&lt;/h2&gt;

&lt;div class="figure"&gt;
&lt;img src="http://assets.warpspire.com/images/css-column-tricks/negativemargin.gif" /&gt;
&lt;/div&gt;


&lt;p&gt;So you&amp;rsquo;re building out a simple product listing template out, and you throw it in an unordered list:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="nc"&gt;.listing&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="nc"&gt;.listing&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;list-style-type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;85px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;HTML:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;listing&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Product #1&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Product #2&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Product #3&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Product #4&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This CSS will work just fine in something like Firefox, but for mysterious reasons you&amp;rsquo;ll see that Product #4 appears on it&amp;rsquo;s own line in IE6.  What&amp;rsquo;s happening here? I mean 4 columns x 85px + 3 gaps x 20px = 400px, right? Except that your 4th gap is hanging over the right edge &amp;mdash; pushing the true width of the blocks to 420px.  Firefox is smart and lets that margin just hang out there &amp;mdash; but IE6 will apply that margin within the parent wrapper &amp;mdash; throwing the 4th item down since it takes up 20px more than it should have.&lt;/p&gt;

&lt;p&gt;The fix? Apply a left margin to each item, with a negative margin to the wrapper.  This means that every item has a visible margin, but the whole block of elements are yanked back by the negative margin:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="nc"&gt;.listing&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;-20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;420px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="nc"&gt;.listing&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;list-style-type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;85px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This gets around the nasty solution of adding a class to the first or last item in every row &amp;mdash; something I&amp;rsquo;ve seen with abundance around the web.&lt;/p&gt;

&lt;h2&gt;Building a CSS framework in no time&lt;/h2&gt;

&lt;p&gt;Wev'e got to start out with some basic HTML.  Here&amp;rsquo;s what I&amp;rsquo;ve been using lately:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;columns col2&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;column first&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- /.first --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;column last&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- /.last --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- /.columns --&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;For different column widths, I&amp;rsquo;ve been changing out the &lt;code&gt;col2&lt;/code&gt; declaration to things like &lt;code&gt;col2A, col2B, col2C&lt;/code&gt; and so on. You could easily give them more semantic names like &lt;code&gt;products-columns&lt;/code&gt; too.&lt;/p&gt;

&lt;h3&gt;Self clearing is the future&lt;/h3&gt;

&lt;p&gt;The first step for any column framework is self-clearing. It&amp;rsquo;s easy, practical, and reduces all those damn clearing divs.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nc"&gt;.columns&lt;/span&gt;&lt;span class="nd"&gt;:after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;content&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;clear&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;both&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;visibility&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="nc"&gt;.columns&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1%&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="nc"&gt;.columns&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.columns&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;Float those columns&lt;/h3&gt;

&lt;p&gt;Next step is to actually float those columns. So let&amp;rsquo;s add a couple more declarations:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nc"&gt;.columns&lt;/span&gt; &lt;span class="nc"&gt;.column&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;overflow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.columns&lt;/span&gt; &lt;span class="nc"&gt;.last&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.col2&lt;/span&gt; &lt;span class="nc"&gt;.first&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.col2&lt;/span&gt; &lt;span class="nc"&gt;.last&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.col2A&lt;/span&gt; &lt;span class="nc"&gt;.first&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.col2B&lt;/span&gt; &lt;span class="nc"&gt;.last&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.col3&lt;/span&gt; &lt;span class="nc"&gt;.first&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.col3&lt;/span&gt; &lt;span class="nc"&gt;.second&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;280px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;margin-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.col3&lt;/span&gt; &lt;span class="nc"&gt;.last&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;Done&amp;hellip; uh, what?&lt;/h3&gt;

&lt;p&gt;Oh, yeah. That&amp;rsquo;s it. That&amp;rsquo;s all it takes to create reliable columns in CSS. Really.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s an &lt;a href="http://assets.warpspire.com/images/css-column-tricks/example.html"&gt;example page&lt;/a&gt; to prove it!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/joLnjlBWxcE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/css-column-tricks</feedburner:origLink></entry>
 
 <entry>
   <title>Why I don't use CSS Frameworks</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/AMtPUDSn9U4/css-frameworks" />
   
   <updated>2007-08-17T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/css-frameworks</id>
   <content type="html">&lt;p&gt;CSS Frameworks seem like an awesome advancement at first glance: speed up your development, normalize your code base, and eliminate those nasty browser bugs!  Hot damn, where do I sign up?  Unfortunately there&amp;rsquo;s some pretty strong caveats that go with those statements.&lt;/p&gt;

&lt;h2&gt;The frameworks themselves are very good&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;d like to start this off by saying there&amp;rsquo;s nothing inheritly wrong with any of the CSS, HTML, or ideas put into these frameworks.  I also think it&amp;rsquo;s an absolutely fabulous idea that people are writing them &amp;mdash; it gives newcomers an easy way out to create professional looking designs using semantic XHTML and CSS.&lt;/p&gt;

&lt;h2&gt;Advantages of Frameworks&lt;/h2&gt;

&lt;p&gt;Most CSS frameworks offer three primary selling points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed up your develoment (don&amp;rsquo;t have to write all that HTML/CSS)&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t worry about those nasty IE bugs!&lt;/li&gt;
&lt;li&gt;Normalize your code/class base&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Speeding up your development&lt;/h3&gt;

&lt;p&gt;For those who have intimate knowledge of the framework, I do believe the frameworks will speed up development.  But for the average user, I think that the time required to understand the architecture of the framework far outweighs the menial task of coding it from scratch.&lt;/p&gt;

&lt;p&gt;Over the past three years, I&amp;rsquo;ve built unknown dozens of layouts, with most of them being extremely visually complex.  On average, it takes me about 8 hours to build out a Master design into a functioning bug-free template.  Of that time, I would have to say that doing the basic layout &amp;amp; typography (framework material) takes less than 20 minutes.  That&amp;rsquo;s &lt;strong&gt;less than 5% of development time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You may save time, but the question quickly becomes how much time, and at what cost?  We&amp;rsquo;ll cover that later.  My point being that frameworks do not solve the hard problems in CSS &amp;mdash; the ones that pop up when you&amp;rsquo;re knee-deep in HTML and suddenly the goddamn box doesn&amp;rsquo;t show up in IE6.  These are the problems that take the majority of time when developing a website.&lt;/p&gt;

&lt;h3&gt;Don&amp;rsquo;t worry about  IE bugs&lt;/h3&gt;

&lt;p&gt;Well, gee that sure would be a wonderful thing if that were the case, wouldn&amp;rsquo;t it?  The truth is the frameworks do eliminate some bugs &amp;mdash; but they&amp;rsquo;re the easy ones to pick off.  The ones solved by a quick &lt;code&gt;display:inline&lt;/code&gt; or &lt;code&gt;height:1%&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The frameworks don&amp;rsquo;t solve bugs where none of the public hacks work.  Or where IE inexplicably adds a 30px top margin to your element, but then dissolves in when you hover over your main navigation.  It doesn&amp;rsquo;t solve the problems when IE displays the same HTML and CSS differently on two different computers.&lt;/p&gt;

&lt;p&gt;It doesn&amp;rsquo;t solve the hard problems.&lt;/p&gt;

&lt;h3&gt;Normalize your code base&lt;/h3&gt;

&lt;p&gt;This is one area I think frameworks are great at: getting a large team of people all using the same code structure.  But then again, I think this can be solved by an internal styleguide just the same.&lt;/p&gt;

&lt;h2&gt;Disadvantages of frameworks&lt;/h2&gt;

&lt;p&gt;There are a few pretty severe disadvantages of frameworks in my eyes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Familiarity with your code&amp;rsquo;s architecture&lt;/li&gt;
&lt;li&gt;Inheriting someone else&amp;rsquo;s bugs&lt;/li&gt;
&lt;li&gt;Not learning&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Familiarity with your code&amp;rsquo;s architecture&lt;/h3&gt;

&lt;p&gt;This is the largest reason I&amp;rsquo;ve never built or used a CSS framework.  By building a site from the ground up, you gain a knowledge of your site&amp;rsquo;s architecture that can&amp;rsquo;t be learned through any study or documentation.  When a programmer asks you a question about restructuring the HTML, you can answer right away.  You know where the CSS styles are (hopefully) and you know &lt;em&gt;how&lt;/em&gt; the layout works.&lt;/p&gt;

&lt;p&gt;This is increasingly relevant in today&amp;rsquo;s Javascript-out-the-ass world.  Once you start manipulating the XHTML/CSS of your site through dynamic scripting: you better know how it&amp;rsquo;s laid out.  Javascript-based effects are tied very closely to the CSS structure of the site.  You&amp;rsquo;ll have to know when you can use &lt;code&gt;float&lt;/code&gt; and when you can use &lt;code&gt;position&lt;/code&gt; to lay out elements.  Should you use &lt;code&gt;line-height&lt;/code&gt;, &lt;code&gt;margin&lt;/code&gt;, &lt;code&gt;padding&lt;/code&gt;, or &lt;code&gt;height&lt;/code&gt; to get that container to extend?  It&amp;rsquo;s a very important decision: and laying out the architecture helps you achieve this.&lt;/p&gt;

&lt;h3&gt;Inheriting someone else&amp;rsquo;s bugs&lt;/h3&gt;

&lt;p&gt;At the end of the day, no framework is perfect. No design is perfect.  But instead of fixing your bugs, you&amp;rsquo;re fixing someone else&amp;rsquo;s bugs.  Do you know how much it sucks fixing your own bugs?  It sucks 10,000x worse fixing someone else&amp;rsquo;s bugs.&lt;/p&gt;

&lt;h3&gt;Not learning&lt;/h3&gt;

&lt;p&gt;Again, on my mantra of why I wouldn&amp;rsquo;t recommend frameworks comes the lack of knowledge gained by fixing those problems frameworks solve.  I&amp;rsquo;ve &lt;a href="/tipsresources/web-production/most-amazing-css-tip-youll-ever-read-in-your-life/"&gt;advocated before&lt;/a&gt; how important it is to build websites.  I can guarantee you that if you keep building sites from the ground-up, you&amp;rsquo;ll learn new things each time.  You&amp;rsquo;ll learn not only how to fix and avoid browser bugs, but how to make your markup more elegant.  You&amp;rsquo;ll transform the act of building websites from a job into an art.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Hopefully this clears up a bit of why I don&amp;rsquo;t like CSS frameworks.  It&amp;rsquo;s not that they&amp;rsquo;re bad &amp;mdash; it&amp;rsquo;s just that I don&amp;rsquo;t think they offer enough value for the drawbacks.  It all comes down to intelligently analyzing your situation before you jump head-first into someone else&amp;rsquo;s code.&lt;/p&gt;

&lt;h3&gt;The one &amp;ldquo;framework&amp;rdquo; I do use&lt;/h3&gt;

&lt;p&gt;On that note, there is one framework I do use.  It&amp;rsquo;s the CSS reset &amp;mdash; not that I&amp;rsquo;d even call it a framework.  Here it is in all its glory:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="c"&gt;/*------------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c"&gt;  Global Styles&lt;/span&gt;
&lt;span class="c"&gt;------------------------------------------------------------------------------------*/&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h6&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;blockquote&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;dl&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;fieldset&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;address&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;1em&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;dd&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;margin-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;5%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;fieldset&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.hide&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.print-logo&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.close-button&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.left&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.right&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;float&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.clear&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;clear&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;both&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;line-height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;border&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;What&amp;rsquo;s your take on frameworks? Do you use them? If so, what other benefits have you gained from using them?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/AMtPUDSn9U4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/css-frameworks</feedburner:origLink></entry>
 
 <entry>
   <title>MooTools Javascript Classes</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/KgumPKffnnw/mootools-javascript-classes" />
   
   <updated>2007-07-16T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/mootools-javascript-classes</id>
   <content type="html">&lt;p&gt;One of Javascript&amp;rsquo;s major blunders when it comes to Object-Oriented design is the lack of true classes.  Lucky for us, we&amp;rsquo;ve had every library author out there have their whack at creating a class structure.&lt;/p&gt;

&lt;h2&gt;What is a class?&lt;/h2&gt;

&lt;p&gt;A class is kind of a template.  One of the big concepts of OO is treating your code as real world objects.  Let&amp;rsquo;s say you want to have three variables for different dogs: ollie, rowdy, and killer.  Each of these variables should be an &lt;em&gt;instance&lt;/em&gt; of a &lt;em&gt;class&lt;/em&gt;.  That class&amp;rsquo;s name would be Dog. Each particular dog is an instance of the generic Dog class.  I won&amp;rsquo;t go into much more detail here: there&amp;rsquo;s plenty of reading to do on what classes really are, and how to use them best.&lt;/p&gt;

&lt;h2&gt;MooTools = &amp;lt;3&lt;/h2&gt;

&lt;p&gt;Out of all the class systems I&amp;rsquo;ve used, I&amp;rsquo;d have to say MooTool&amp;rsquo;s class system (spanwed from Dean Edward&amp;rsquo;s Base) is the cleanest, most extensible system yet.  Creating and extending classes is ridiculously easy.&lt;/p&gt;

&lt;h3&gt;Create a class&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Animal Runs!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;pet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ==&amp;gt; &amp;quot;Animal Runs!&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;(It&amp;rsquo;s also fair to note that MooTools supports Prototype&amp;rsquo;s &lt;code&gt;Class.create&lt;/code&gt; method as well)&lt;/p&gt;

&lt;h3&gt;Extend a class&lt;/h3&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;bark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Woof! Woof!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;pet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bark&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ==&amp;gt; &amp;quot;Animal Runs!&amp;quot;&lt;/span&gt;
&lt;span class="c1"&gt;// ==&amp;gt; &amp;quot;Woof! Woof!&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You&amp;rsquo;ll notice you still get access to parent methods (through &lt;code&gt;this.parent()&lt;/code&gt;), as you can see where this.text gets initialized when a new instance of Dog is created.&lt;/p&gt;

&lt;p&gt;The syntax is short, sweet, and to the point.  Furthermore it allows me all the flexibility I need&amp;hellip; well, almost.  MooTools team gets bonus points for the next section.&lt;/p&gt;

&lt;h2&gt;Javascript mixins&amp;hellip; kinda&lt;/h2&gt;

&lt;p&gt;There are two common actions that many Javascript actions have: options, and callbacks.  MooTools have created a sort of ruby-style mixin for classes to handle these functions.  MooTools calls these mixins Utility Classes.  To enable these, add this line to the code above:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;implement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Events&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Options&lt;/h2&gt;

&lt;p&gt;What does this do?  First off, it allows for quick, easy, extendible options.  All you do is set your default options in an options property, and then call the &lt;code&gt;setOptions&lt;/code&gt; method inside your class.  Here&amp;rsquo;s an example:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Jack Russel Terrier&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="c1"&gt;// Here&amp;#39;s the magic!&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="nx"&gt;bark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;My name is &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; and I am &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; years old&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;afterBark&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;implement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Events&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ollie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Ollie&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ollie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bark&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ==&amp;gt; &amp;quot;My name is Ollie and I am 5 years old&amp;quot;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;rowdy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Rowdy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;rowdy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bark&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ==&amp;gt; &amp;quot;My name is Rowdy and I am 15 years old&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;By mixing in the Options methods, you now have access to setOptions, which either uses user-defined options or class-based defaults (with one line of code).&lt;/p&gt;

&lt;h3&gt;Events&lt;/h3&gt;

&lt;p&gt;You can also define custom events (usually called callbacks).  Notice the &lt;code&gt;this.fireEvent('afterBark')&lt;/code&gt; bit in the Dog class above?  Check it out:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;killer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Killer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;killer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;afterBark&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; just barked!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;killer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bark&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ==&amp;gt; &amp;quot;My name is Killer and I am 5 years old&amp;quot;&lt;/span&gt;
&lt;span class="c1"&gt;// ==&amp;gt; &amp;quot;Killer just barked!&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It allows you to tie into the &lt;em&gt;same&lt;/em&gt; event functionality used for the DOM, but with your own methods you create in your classes. I&amp;rsquo;m in love with this easy functionality &amp;mdash; sure there&amp;rsquo;s been other ways to do this, but none so elegant as what the Moo team has come up with.&lt;/p&gt;

&lt;h3&gt;Chain&lt;/h3&gt;

&lt;p&gt;The last utility class is the Chain class.  This allows for some nice chaining of classes: I&amp;rsquo;ll leave it up to you to explore this one since I haven&amp;rsquo;t used it in great detail yet.  In a nutshell: it allows for time-dependent chains (so that events fire after another one is complete).&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Every good Javascript developer knows that there&amp;rsquo;s 50 ways to skin a cat when it comes to classes and Javascript.  But for me, one of the largest reasons MooTools is my framework of choice is the underlying class system.  No extending &lt;code&gt;Object&lt;/code&gt;, and no overriding of parent methods.  The syntax is clean and easy to remember, giving it huge bonus points in my book.&lt;/p&gt;

&lt;p&gt;Personally, I would like to thank the smarter developers who have taken the hard hits with Javascript to implement these nice OO techniques.  Without them, my Javascript would still be procedural-based with tons of global variables thrown about.  Yay for frameworks!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/KgumPKffnnw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/mootools-javascript-classes</feedburner:origLink></entry>
 
 <entry>
   <title>Using TextMate's TODO bundle</title>
   
     <link href="http://feedproxy.google.com/~r/warpspire/~3/hOpvfnHG6GU/textmate-todos" />
   
   <updated>2007-06-25T00:00:00-07:00</updated>
   <id>http://warpspire.com/posts/textmate-todos</id>
   <content type="html">&lt;p&gt;If you use TextMate, you should really think about using the TODO bundle more often.  It&amp;rsquo;s a simple, low-maintenance bundle that adds tremendous value to your code.&lt;/p&gt;

&lt;h2&gt;Setting TODO, FIXME, and CHANGELOG&lt;/h2&gt;

&lt;p&gt;Using the bundle is pretty easy.  In any language, just type in a quick comment with the prefix TODO, FIXME or CHANGED like so:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;
  &lt;span class="c1"&gt;# TODO: different display for different types of clips: active, processing, etc&lt;/span&gt;
  &lt;span class="vi"&gt;@clip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Clip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# TODO: Make a real related clips dealieo&lt;/span&gt;
  &lt;span class="vi"&gt;@related_clips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Clip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:limit&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:conditions&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;clips.status = &amp;#39;processed&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Using this syntax lets you keep pushing ahead at full steam and leave the hard stuff for later.  For example, in the above example I wanted to get a quick functional prototype out the door.  It wasn&amp;rsquo;t mandatory that the Related Clips &lt;em&gt;actually&lt;/em&gt; be related: it was only mandatory that there was content present.&lt;/p&gt;

&lt;p&gt;You can also use the keywords FIXME or CHANGED throughout your code, like so:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;
  &lt;span class="c1"&gt;# FIXME: This totally breaks if an invalid ID is given&lt;/span&gt;
  &lt;span class="vi"&gt;@clip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Clip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# CHANGED: @related_clips now uses a model method related_clips&lt;/span&gt;
  &lt;span class="vi"&gt;@related_clips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Clip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;related_clips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This lets others working on the code let you know that you &lt;em&gt;know&lt;/em&gt; something is broken and/or changed, but you just don&amp;rsquo;t have time to get to it.&lt;/p&gt;

&lt;h2&gt;Getting the information back&lt;/h2&gt;

&lt;p&gt;Well, that&amp;rsquo;s all fine and well.. but how do you know what needs to be fixed/changed/done ?  Just hit Ctr+Shift+T  and TextMate will pop up with a pretty little list, hyperlinked and all&lt;/p&gt;

&lt;div class="figure"&gt;
  &lt;img src="http://assets.warpspire.com/images/textmate-todo-bundle/list.gif" alt="Screenshot of the TODO list" /&gt;
  &lt;small&gt;&lt;em&gt;Ctrl + Shift + T&lt;/em&gt; brings up a list of all your todo's&lt;/small&gt;
&lt;/div&gt;


&lt;p&gt;I use this bundle practically every time I open up Textmate.  It allows me to keep on a focused track of development, while still keeping a lot of &amp;ldquo;ooh, I need to do that sometime&amp;rdquo; kind of tasks on the radar.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/warpspire/~4/hOpvfnHG6GU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://warpspire.com/posts/textmate-todos</feedburner:origLink></entry>
 

</feed>

