<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
  <title type="html">ReinH Blog</title>
  <subtitle>Ruby and Rails Best Practices</subtitle>
  <link href="http://reinh.com/feed/atom.xml" rel="self" />
  <link href="http://reinh.com/" />
  <updated>2009-09-23T14:14:17-04:00</updated>
  <author>
    <name>Rein Henrichs</name>
    <email>reinh@reinh.com</email>
  </author>
  <id>http://reinh.com/</id>
  
  <entry>
    <title type="html">Ch-Ch-Ch-Changes</title>
    <link href="http://reinh.com/blog/2009/09/21/ch-ch-ch-changes.html" />
    <id>tag:reinh.com,2009-09-21:1253554876</id>
    <published>2009-09-21T13:41:16-04:00</published>
    <updated>2009-09-21T13:41:16-04:00</updated>
    <content type="html">&lt;p&gt;A couple months ago, I resigned my position at Hashrocket. This was not an easy decision for me. Working with the rocketeers has been a very fulfilling and edifying experience. The people at Hashrocket are passionate about what they do and extremely competent. I was given challenging and rewarding responsibilities. Hashrocket was a great job and I would recommend it to anyone. Why, then, did I chose to leave?&lt;/p&gt;

&lt;p&gt;In the end, it came down to a need for personal growth. At Hashrocket, I have had the opportunity to work with interesting clients on interesting projects, to lead a number of talented development teams and to consult on Rails development and Agile methodologies to large businesses. Thanks to Hashrocket, I have expanded my core competencies and matured as a developer. Certainly I could have stayed with Hashrocket and continued this process. There was more to do and more to learn. In the end, though, I felt that it was time to for me to take on a new set of challenges. My friend and former boss, Obie Fernandez, has been wonderfully supportive of me in this and I owe him a great debt of gratitude. I am happy to say that my departure from Hashrocket has been entirely amicable. They are a great bunch, one and all, and I am fortunate to have worked with them.&lt;/p&gt;

&lt;p&gt;As a consultant for the past eight years, both freelance and with Hashrocket, I have worked with many clients. This work has been more or less successful, my clients have been more or less happy, and the work has been more or less satisfying, but there is a common factor in its transient nature. I work on a project for weeks or months, provide as much value as my abilities allow, and then move on to another project once my role is complete. Consultants rarely experience the satisfaction and sense of accomplishment of a job well done, the rewards of the successful completion of a long and often arduous project life cycle.&lt;/p&gt;

&lt;p&gt;So, to make a long story short, I wanted to find a project that I could call home. I wanted to feel a sense of ownership in the project and its outcome. I also wanted to learn new skills and develop new competencies. The problem is that I didn't yet know where home was, so I decided to start by taking some time off and then sort of figure things out from there. This was risky, especially in our current economic climate. Luckily, I've never been shy about making such decisions. After all, I love a good adventure, and adventures always entail a certain amount of risk.&lt;/p&gt;

&lt;p&gt;During my vacation, I spent a lot of time playing piano and writing music. It felt good to give my creative muscles some much-needed exercise. I assessed my career and my goals. I read a lot. I played some video games. I quickly found, however, that living without a &quot;&lt;a href=&quot;http://37signals.com/svn/posts/1930-mojito-island-is-a-mirage&quot;&gt;dedicated purpose&lt;/a&gt;&quot; was less than satisfying. I was not happy leaving my tools in the corner to gather dust: they needed to be used. So, how best to use them?&lt;/p&gt;

&lt;p&gt;I decided, after some consideration, that what I wanted was the opportunity to shape the destiny of a project that I believed in. I wanted to do more than sit behind a desk and code. Luckily, I was presented with just such an opportunity only a few weeks after leaving Hashrocket. Rick Bradley, a good friend of mine and an excellent developer, had a client who was looking for a full-time hire. I was reluctant to become Yet Another Developer but I decided to look into it. I'm sure glad I did: the position turned out to be just what I was looking for.&lt;/p&gt;

&lt;p&gt;The client was &lt;a href=&quot;http://reductivelabs.com/&quot;&gt;Reductive Labs&lt;/a&gt;, the company behind &lt;a href=&quot;http://reductivelabs.com/trac/puppet/&quot; title=&quot;puppet - Trac&quot;&gt;Puppet&lt;/a&gt;, the Ruby-based configuration management tool. This in and of itself was interesting. The Puppet codebase covers a large area both topographically and conceptually. It has a significant installation base and a large open source community. It would be a challenging project to work on and a welcome test of my abilities.&lt;/p&gt;

&lt;p&gt;I don't have a Computer Science background. I've never taken any courses in programming. I am entirely self-taught. Puppet, on the other hand, has a lot of Serious Business going on: a parser-compiler, a graphing library, client-server systems, and so on. I have experience in some of these areas, but in others I have only a basic theoretical knowledge gleaned by way of an intense curiosity and a love of reading. I had read the &lt;a href=&quot;http://dragonbook.stanford.edu/&quot;&gt;Dragon Book&lt;/a&gt;, for instance, but I had no experiential background in language design or writing parsers and compilers. Luckily, my lack of a formal education was not a barrier to entry (nor should it be if you have the skills needed to execute or the ability to acquire them, but that's a topic for another post).&lt;/p&gt;

&lt;p&gt;I spent a week in Portland getting to know the code and the company. While Puppet is older than Rails, the code has until recently been under the sole stewardship of Reductive founder and CEO Luke Kanies. As a company, Reductive is small and young, but the technology is relatively mature. This is an interesting combination of both the pioneering spirit of a startup and the stability of an established open source project.&lt;/p&gt;

&lt;p&gt;During the day, I spent my time pairing with Luke and talking with the founders about their plans for Reductive Labs and Puppet. Luke has a piercing intelligence and a compelling vision for the future of both Puppet and Reductive Labs itself. I quickly saw that I would not just be yet another a developer, rather that I would also have the opportunity to lead teams, collaborate with a large and active open source community, and even more importantly, to help Luke and the rest of the Reductive team make design and strategy decisions that would inform the growth of both Puppet and the company. Plus, I would be &quot;forced&quot; to relocate to Portland, one of my favorite cities. Bonus.&lt;/p&gt;

&lt;p&gt;Apparently my visit was a success: I'm pleased to say that Luke offered me a position immediately after my trip and I accepted just as quickly. As I grow into my new responsibilities at Reductive, I find that they scale well with my abilities. Luke seems happy to let me do what I'm good at and I enjoy the opportunity to carve out my own role within a growing company. Most importantly, I feel like I have the opportunity to accomplish something significant. Nothing matters more to my sense of fulfillment and satisfaction.&lt;/p&gt;

&lt;p&gt;My faithful readers have most likely been lamenting this blog's recent lack of content. Hopefully my little story helps explain this conspicuous absence. Expect more posts in the near future. I've got plenty to talk about.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Custom FiveRuns TuneUp&amp;nbsp;Instrumentation</title>
    <link href="http://reinh.com/blog/2009/04/21/custom-fiveruns-tuneup-instrumentation.html" />
    <id>tag:reinh.com,2009-04-21:1240327823</id>
    <published>2009-04-21T11:30:23-04:00</published>
    <updated>2009-04-21T11:30:23-04:00</updated>
    <content type="html">&lt;p&gt;&lt;img src=&quot;http://reinh.com/images/product_tuneup.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.fiveruns.com/products/tuneup&quot;&gt;TuneUp&lt;/a&gt; is a development performance monitoring tool from &lt;a href=&quot;http://www.fiveruns.com&quot;&gt;FiveRuns&lt;/a&gt;. It can help you catch poorly performing actions and queries early and is a great tool to add to your performance monitoring toolbelt. TuneUp also makes it very simple to add custom instrumentation to your Rails app, which came in handy when we needed to report on web service queries made by our Endeca client.&lt;/p&gt;
&lt;p&gt;A brief chat with &lt;a href=&quot;http://codefluency.com&quot;&gt;Bruce Williams&lt;/a&gt; helped point the way to TuneUp&amp;#8217;s &lt;code&gt;FiveRuns::TuneUp.step&lt;/code&gt;, the jumping-off point for its instrumentation of your model, view and controller activity. We were able to write a simple plugin that adds instrumentation to calls made by the &lt;a href=&quot;http://github.com/primedia/endeca&quot;&gt;Primedia Endeca gem&lt;/a&gt; (a gem used to consume Endeca&amp;#8217;s RESTful JSON bridge API).&lt;/p&gt;
&lt;p&gt;The plugin takes advantage of &lt;code&gt;alias_method_chain&lt;/code&gt; to add instrumentation to the Endeca query methods. This solution is very clean and is idiomatic to Rails itself as Rails uses &lt;code&gt;alias_method_chain&lt;/code&gt; to &amp;#8220;embellish&amp;#8221; many parts of the request response cycle for things like benchmarking and caching, as &lt;a href=&quot;http://www.loudthinking.com/posts/33-myth-4-rails-is-a-monolith&quot;&gt;David mentions&lt;/a&gt; in a blog post from his Rails Myths series&lt;/p&gt;
&lt;p&gt;If you want to look at the code, you can find the plugin at its &lt;a href=&quot;http://github.com/primedia/endeca_tuneup&quot;&gt;github repo&lt;/a&gt;. All the code is in the &lt;a href=&quot;http://github.com/primedia/endeca_tuneup/blob/0e59b0c1f2bdac7f09bb07649b6aab5541aebd7d/init.rb&quot;&gt;&lt;code&gt;init.rb&lt;/code&gt;&lt;/a&gt; but I&amp;#8217;ll reprint it here for convenience. Note that we could have refactored these similar method definitions using metaprogramming techniques but chose not to do so for reasons of simplicity and clarity.&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;defined?&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;FiveRuns&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class=&quot;r&quot;&gt;defined?&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;Endeca&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class=&quot;r&quot;&gt;defined?&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;Endeca&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Document&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Tuneup instrumentation&lt;/span&gt;
  &lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class=&quot;cl&quot;&gt;Endeca::Document&lt;/span&gt;
    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;all_with_tuneup&lt;/span&gt;(*args)
      &lt;span class=&quot;co&quot;&gt;Fiveruns&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Tuneup&lt;/span&gt;.step &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;name&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.all&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:model&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;
        all_without_tuneup(*args)
      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
    alias_method_chain &lt;span class=&quot;sy&quot;&gt;:all&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:tuneup&lt;/span&gt;

    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;first_with_tuneup&lt;/span&gt;(*args)
      &lt;span class=&quot;co&quot;&gt;Fiveruns&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Tuneup&lt;/span&gt;.step &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;name&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.first&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:model&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;
        first_without_tuneup(*args)
      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
    alias_method_chain &lt;span class=&quot;sy&quot;&gt;:first&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:tuneup&lt;/span&gt;

    &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;by_id_with_tuneup&lt;/span&gt;(*args)
      &lt;span class=&quot;co&quot;&gt;Fiveruns&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Tuneup&lt;/span&gt;.step &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;name&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.by_id&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:model&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;
        by_id_without_tuneup(*args)
      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
    alias_method_chain &lt;span class=&quot;sy&quot;&gt;:by_id&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:tuneup&lt;/span&gt;
  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title type="html">Simplify Your Dev Environment With Passenger&amp;nbsp;Pane</title>
    <link href="http://reinh.com/blog/2009/04/17/simplify-your-dev-environment-with-passenger-pane.html" />
    <id>tag:reinh.com,2009-04-17:1239977051</id>
    <published>2009-04-17T10:04:11-04:00</published>
    <updated>2009-04-17T10:04:11-04:00</updated>
    <content type="html">&lt;p&gt;&lt;img src=&quot;http://reinh.com/images/phusion-logo.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;


&lt;p&gt;On OS X? Develop web applications with Rails? Or Merb? Or Sinatra? Or any other Rack compatible framework? Want drag-and-drop and point-and-click development server management? Then you need Passenger Pane. We&amp;#8217;ll walk you through the installation process and show you how to get a simple Rack application up and running. Thanks to &lt;a href=&quot;http://jasonnoble.org&quot;&gt;Jason Noble&lt;/a&gt; for his help getting everything working.&lt;/p&gt;


&lt;p&gt;Passenger Pane is an OS X preference pane designed to work in concert with Phusion Passenger and your OS X Leopard's default Apache2 installation (the same one that serves your Web Sharing). Setup is pretty simple and will probably take about 10 minutes. Here's what we're going to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install Phusion Passenger&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Passenger Pane&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Serve a &quot;Hello World!&quot; Rack endpoint&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Profit!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;Install Phusion Passenger&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.modrails.com&quot;&gt;Phusion Passenger&lt;/a&gt; is the (not so) new hotness in the Rails deployment world. Phusion is great for serving Rails applications via Apache in production (especially in concert with Rails Enterprise Edition, which provides a 33% memory savings over standard MRI Ruby), but it's also great for simplifying your development environment.&lt;/p&gt;

&lt;p&gt;The Phusion team have done a great job on the passenger install. Here are the &lt;a href=&quot;http://www.modrails.com/install.html&quot;&gt;official installation instructions&lt;/a&gt;. We'll repeat them here for the sake of convenience.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open a Terminal window.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the passenger gem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install passenger
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the passenger apache2 module:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Include the module and some supporting configuration settings into an apache conf file. The code will be provided by the passenger install script.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, add a &lt;code&gt;Directory&lt;/code&gt; directive to your apache2 config that allows access to the directory where your app source codes are located. You can put this at the bottom of your &lt;code&gt;passenger.conf&lt;/code&gt; file (replace my source directory with yours):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Directory /Users/reinh/code/&amp;gt;
  Order Allow,Deny
  Allow from all
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p class=&quot;note&quot;&gt;&lt;strong&gt;Note:&lt;/strong&gt; We put the passenger apache configuration in &lt;code&gt;/etc/apach2/other/passenger.conf&lt;/code&gt; (a file we created). The default apache2 &lt;code&gt;httpd.conf&lt;/code&gt; imports all &lt;code&gt;.conf&lt;/code&gt; files in &lt;code&gt;/etc/apache2/other&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;Install Passenger Pane&lt;/h3&gt;

&lt;p class=&quot;right&quot;&gt;
    &lt;a href=&quot;http://www.fngtps.com/2008/06/putting-the-pane-back-into-deployment&quot; alt=&quot;Passenger Pane&quot;&gt;
        &lt;img src=&quot;http://reinh.com/images/passenger_icon.png&quot;&gt;
    &lt;/a&gt;
&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://www.fngtps.com/2008/06/putting-the-pane-back-into-deployment&quot;&gt;Passenger Pane&lt;/a&gt; gives you a Preference Pane that lets you add, remove and manage apps deployed on Phusion Passenger. Drag-and-drop to serve a new app and restart with a single click &amp;mdash; it even provides host entries for each app so you don't have to mess with virtual hosts or your hosts file. This is great for serving multiple applications simultaneously or just generally being awesome.&lt;/p&gt;

&lt;p&gt;Installation is simple. Download the preference pane from &lt;a href=&quot;http://www.fngtps.com/2008/06/putting-the-pane-back-into-deployment&quot;&gt;their homepage&lt;/a&gt; and double-click to install. If you installed Passenger correctly (as above), this should just work. If not, look for errors in Console.app or a helpful notice in the preference pane and ask for help on the &lt;a href=&quot;http://groups.google.com/group/phusion-passenger&quot;&gt;Passenger forums&lt;/a&gt; or in the &lt;code&gt;#passenger&lt;/code&gt; channel on &lt;code&gt;irc.freenode.net&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After installing Passenger Pane, you will need to restart Apache. The simplest way to do this on OS X is to open the Sharing preference pane and uncheck and recheck Web Sharing.&lt;/p&gt;

&lt;h3&gt;Serve A &quot;Hello World!&quot; Rack Endpoint&lt;/h3&gt;

&lt;p&gt;Let's test that everything is working by creating a simple &lt;a href=&quot;http://rack.rubyforge.org/&quot;&gt;Rack&lt;/a&gt; &quot;Hello World!&quot; endpoint.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install &lt;code&gt;rack&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install rack
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new directory called &lt;code&gt;rack-hello-world&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a file inside it called &lt;code&gt;config.ru&lt;/code&gt; with these contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;run lambda{|env| [200, {&quot;Content-Type&quot; =&amp;gt; &quot;text/plain&quot;}, [&quot;Hello World!&quot;]]}
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;public&lt;/code&gt; directory inside &lt;code&gt;rack-hello-world&lt;/code&gt; (you'll see why later).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drag the &lt;code&gt;rack-hello-world&lt;/code&gt; folder into your Passenger Pane panel (if you're using TextMate, you can drag it from the project panel). You will probably need to click the lock first to allow modifications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browse to &lt;code&gt;&lt;a href=&quot;http://rack-hello-world.local&quot;&gt;http://rack-hello-world.local&lt;/a&gt;&lt;/code&gt; and behold the awesome!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Profit!!!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;If you've done this correctly, your Passenger Pane should look similar to this:&lt;/p&gt;

&lt;p class=&quot;screenshot&quot;&gt;
    &lt;img src=&quot;http://reinh.com/images/passenger_pane.png&quot;&gt;
&lt;/p&gt;


&lt;p&gt;Your browser should be showing you your glorious &quot;Hello World!&quot; homepage.&lt;/p&gt;

&lt;p&gt;Now you can drag in the app folders of any Rails, Merb, Sinatra or Ramaze applications and have them instantly served by Passenger. In fact, any Ruby web application that can run on Rack can be run in Passenger Pane. How's that for a painless local development environment?&lt;/p&gt;

&lt;p class=&quot;note&quot;&gt;&lt;strong&gt;Note:&lt;/strong&gt; Why (I hear you asking) did we create a public directory? The answer is that Apache expects to serve a public directory and will fail if one is not found under the root of the app you're serving. If you had not created the directory, you would have to look at your apache error log (usually located at &lt;code&gt;/var/log/apache2/error_log&lt;/code&gt;) to find out what went wrong.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title type="html">Simple Git Continuous&amp;nbsp;Integration</title>
    <link href="http://reinh.com/blog/2008/02/21/git-pre-commit-hook.html" />
    <id>tag:reinh.com,2008-02-21:1203628588</id>
    <published>2008-02-21T16:16:28-05:00</published>
    <updated>2008-02-21T16:16:28-05:00</updated>
    <content type="html">&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; It looks like Chris Wanstrath (of &lt;a href=&quot;http://github.com&quot; title=&quot;Secure Git hosting and collaborative development &amp;mdash; GitHub&quot;&gt;Github&lt;/a&gt; fame) &lt;a href=&quot;http://ozmm.org/posts/git_post_commit_for_profit.html&quot; title=&quot;Git post-commit for profit &amp;mdash; ones zeros majors and minors&quot;&gt;beat me to it&lt;/a&gt;. Clearly, the git is strong with this one.&lt;/p&gt;

&lt;p&gt;Preventing your developers (and yourself) from breaking the build is as simple as putting this in your .git/hooks/pre-commit and making it executable (&lt;code&gt;chmod +x .git/hooks/pre-commit&lt;/code&gt;).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
rake spec 2&amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will stop the commit if the specs don’t pass.&lt;/p&gt;

&lt;p&gt;This isn’t a replacement for a more robust CI system but it does make it a lot harder to do something stupid. Redirecting STDERR to /dev/null is optional but recommended since the STDERR output of failing specs isn’t useful. It you use Test::Unit instead of RSpec (for shame), use rake test instead. Likewise, anything that returns proper error codes (0 for success, &gt; 0 for failure) can be used.&lt;/p&gt;

&lt;p&gt;This is mainly useful if your specs take under a minute to run, otherwise it becomes tedious. If you have long-running specs, I suggest using a special task that runs an abridged set of core specs instead.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">REST &amp;&amp;nbsp;Rails</title>
    <link href="http://reinh.com/blog/2007/11/13/rest-and-rails.html" />
    <id>tag:reinh.com,2007-11-13:1194974956</id>
    <published>2007-11-13T12:29:16-05:00</published>
    <updated>2007-11-13T12:29:16-05:00</updated>
    <content type="html">&lt;p&gt;I am giving a presentation on Rails, REST, and the Resource Oriented Architecture today entitled &amp;#8220;REST &amp;amp; Rails: Web Services for the Rails World&amp;#8221;. Check out &lt;a href=&quot;http://assets.reinh.com/talks/REST-and-Rails.pdf&quot;&gt;the slides&lt;/a&gt;.&lt;/p&gt;
    &lt;a href=&quot;http://assets.reinh.com/talks/REST-and-Rails.pdf&quot; title=&quot;REST &amp;amp; Rails&quot;&gt;&lt;img src=&quot;http://assets.reinh.com/images/REST-and-Rails.gif&quot; title=&quot;REST &amp;amp; Rails&quot;&gt;&lt;/a&gt;</content>
  </entry>
  
  <entry>
    <title type="html">Custom Textile Tags For Great&amp;nbsp;Justice</title>
    <link href="http://reinh.com/blog/2008/04/09/customize-textile-tags-for-great-justice.html" />
    <id>tag:reinh.com,2008-04-09:1207788961</id>
    <published>2008-04-09T20:56:01-04:00</published>
    <updated>2008-04-09T20:56:01-04:00</updated>
    <content type="html">&lt;p&gt;fig. 1.1 | elem-typo-style.png&lt;/p&gt;
&lt;p&gt;Taking some inspiration (and code) from the quirky but lovable _why&amp;#8217;s original post on &lt;a href=&quot;http://redhanded.hobix.com/inspect/usingRedcloth3.html&quot;&gt;adding yer custom blocks&lt;/a&gt; to RedCloth and the inimitable Geoff Grosenbach&amp;#8217;s foray into the world of &lt;a href=&quot;http://nubyonrails.com/articles/about-this-blog-custom-textile&quot; title=&quot;About This Blog: Custom Textile | Ruby on Rails for Newbies&quot;&gt;custom textile figure tags&lt;/a&gt;, we&amp;#8217;ve build a custom tag (or prefix) for this blog&amp;#8217;s own figures, like &lt;a href=&quot;/images/elem-typo-style.png&quot; class=&quot;fig&quot; title=&quot;figure-1-1&quot;&gt;(Fig. 1.1)&lt;/a&gt; there on the right.&lt;/p&gt;
&lt;p&gt;RedCloth&amp;#8217;s textile implementation uses some simple metaprogramming to create its own tags, which allows you to (more or less) easily create new tags to suit your own needs. The basic formula is: write a &lt;code&gt;textile_#{ tag }&lt;/code&gt; method, where &lt;code&gt;tag&lt;/code&gt; is the name of the tag you want to create. This method takes four arguments, tag, atts, cite and content, which are parsed from the textile by the RedCloth engine.&lt;/p&gt;
&lt;p&gt;For our purposes, we&amp;#8217;re only concerned with content and atts, so I&amp;#8217;ll leave the rest as an exercise for the gentle reader. The html we&amp;#8217;re trying to create looks like this:&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
&lt;pre&gt;&lt;span class=&quot;ta&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;figure-1-1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;ta&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fig&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;/images/image.jpb&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;ta&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;ta&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;/images/thumbs/image.jpg&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;an&quot;&gt;alt&lt;/span&gt;=&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Figure 1.1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;ta&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;ta&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;ta&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Figure 1.1&lt;span class=&quot;ta&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;ta&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The tag we want to use to create it looks like this:&lt;/p&gt;
&lt;code&gt;fig. 1.1 | image.jpg&lt;/code&gt;&lt;p&gt;That&amp;#8217;s quite a bit shorter and more elegant. Jumping right in to the good stuff, the method definition for our new tag looks like this:&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;textile_fig&lt;/span&gt;(tag, atts, cite, content)
  span_class = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;img &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; atts =~ &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class=&amp;quot;([^&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]+)&amp;quot;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;
    span_class += &lt;span class=&quot;gv&quot;&gt;$1&lt;/span&gt;
  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
  (figure_number, img_url) = content.split(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).map { |w| w.strip }
  figure_name = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Figure &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;figure_number&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  figure_id = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;figure-&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;figure_number&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;.tr(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)

  &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;
  &amp;lt;div class=&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;span_class&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot; id=&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;figure_id&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot;&amp;gt;
    &amp;lt;a class=&amp;quot;fig&amp;quot; href=&amp;quot;/images/&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;img_url&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot;&amp;gt;
      &amp;lt;img src=&amp;quot;/images/thumbs/&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;img_url&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot; alt=&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;figure_name&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot; /&amp;gt;
    &amp;lt;/a&amp;gt;
    &amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;figure_name&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s break that down.&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
&lt;pre&gt;span_class = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;img &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; atts =~ &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class=&amp;quot;([^&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]+)&amp;quot;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;
  span_class += &lt;span class=&quot;gv&quot;&gt;$1&lt;/span&gt;
&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This adds any classes in atts (in the form of &lt;code&gt;class=&quot;foo&quot;&lt;/code&gt;) to the base class, img.&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
&lt;pre&gt;(figure_number, img_url) = content.split(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).map { |w| w.strip }
figure_name = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Figure &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;figure_number&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
figure_id = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;figure-&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;figure_number&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;.tr(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This breaks &amp;#8220;fig 1.1 | image.jpg&amp;#8221; down into two parts by splitting on the &amp;#8220;|&amp;#8221; and then normalizes them a bit to be used later.&lt;/p&gt;
&lt;p&gt;Finally, the relevant parts are jammed into the html prototype and spit back as the method&amp;#8217;s return value for insertion into your textile document (and for great justice, of course).&lt;/p&gt;
&lt;p&gt;fig. 1.2 | ReinH-07.png&lt;/p&gt;
&lt;p&gt;A later post might show the way &lt;code&gt;__END__&lt;/code&gt;, &lt;code&gt;DATA&lt;/code&gt; and &lt;code&gt;if __FILE__ == $PROGRAM_NAME&lt;/code&gt; were used with the TextMate Ruby Bundle&amp;#8217;s &amp;amp;#x2318;R command to preview the output of the textile tag as it was being written for a faster workflow or the jQuery used to activate the thumbnail&amp;#8217;s hover effect while an inline link like &lt;a href=&quot;/images/ReinH-07.png&quot; class=&quot;fig&quot; title=&quot;figure-1-2&quot;&gt;(Fig. 1.2)&lt;/a&gt; is hovered. But I wouldn&amp;#8217;t hold your breath.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title type="html">To Design A Blog (act&amp;nbsp;1)</title>
    <link href="http://reinh.com/blog/2008/02/25/to-design-a-blog.html" />
    <id>tag:reinh.com,2008-02-25:1203970944</id>
    <published>2008-02-25T15:22:24-05:00</published>
    <updated>2008-02-25T15:22:24-05:00</updated>
    <content type="html">&lt;p&gt;Your blog&amp;#8217;s role as personal soapbox is obvious; its role in establishing identity is often overlooked. As a designer, your blog speaks volumes not only by what it says, but also by how it says it. If you can&amp;#8217;t design your own blog &amp;ndash; they will say &amp;ndash; how can you design anything else? It was with this in mind that I set out to redesign my own blog.&lt;/p&gt;
&lt;p&gt;As an entry point for colleagues and potential clients, your blog&amp;#8217;s first impression is crucial. Snap judgements will be made that you may never be able to escape. Your design must inform your readers as to your abilities with grace and flair. It must establish your visual style distinctly and succinctly. It must be both well orchestrated and well rehearsed. It must, in short, be great.&lt;/p&gt;
&lt;h3&gt;The Design Process&lt;/h3&gt;
&lt;p&gt;Before setting pen to paper, hand to mouse or fingers to keyboard, I began by thinking about what kind of response I wanted to elicit from my readers. I decided that want it to be warm and inviting, rich in information, and clean and elegant; it should be visually consistent, easy to read, and easy to navigate; most importantly, it should look like me.&lt;/p&gt;
&lt;p&gt;This lead to a few clear design goals:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Strong, consistent typography&lt;/li&gt;
	&lt;li&gt;Simple, uncomplicated layout&lt;/li&gt;
	&lt;li&gt;Minimal but effective use of color&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The design itself went through a number of iterations, beginning with simple pen-and-paper sketches. At the beginning, I imposed a few constraints to help focus my efforts: Single column, 800px width, gridded layout, three fonts. The content would reign supreme. Consistent typography would establish a visual hierarchy.&lt;/p&gt;
&lt;h3&gt;In The Beginning Was The Typography&lt;/h3&gt;
&lt;div class=&quot;img&quot;&gt;
&lt;a href=&quot;/images/redesign/ReinH-01.png&quot;&gt;&lt;img src=&quot;/images/redesign/thumbs/ReinH-01.png&quot; id=&quot;figure-1-1&quot; alt=&quot;&quot;&gt;&lt;/a&gt;
    &lt;p&gt;(Figure 1.1)&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Sorting out the typography goes a long way towards giving your design a strong, cohesive style. It is important to chose two or three fonts (and no more) and to use them consistently. It is also important to use consistent font sizing to establish a visual hierarchy.&lt;/p&gt;
&lt;p&gt;I decided on Helvetica (specifically Helvetica Neue when available) for headers and Verdana for body text. Helvetica was chosen for its readability at medium to large point sizes and flat out gorgeousness. Verdana was chosen for its ubiquity and readability on screen at small to medium point sizes.&lt;/p&gt;
&lt;h3&gt;Rock Out With Your Layout&lt;/h3&gt;
&lt;p&gt;Most blogs use a two-column layout with a sidebar on the right to display subordinate information. Here, I choose a more minimal approach: a single column with information presented serially according to importance. The home page is streamlined to encourage the reader to discover subordinate content, as will navigation links at the top.&lt;/p&gt;
&lt;p&gt;Also, the typography was further refined. A serif font is added for subtitles and meta information (like post date). Finally. the main heading font is pumped a bit to help the major sections pop.&lt;/p&gt;
&lt;div class=&quot;img&quot;&gt;    &lt;a href=&quot;/images/redesign/ReinH-02.png&quot;&gt;&lt;img src=&quot;/images/redesign/thumbs/ReinH-02.png&quot; id=&quot;figure-1-2&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;br&gt;
    &lt;p&gt;(Figure 1.2)&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A quick look at &lt;a href=&quot;/images/redesign/ReinH-02.png&quot;&gt;Figure 1.2&lt;/a&gt; will reveal that the initial read is much improved. The main content sections (the latest post and the list of recent posts) stand out as clearly differentiated. There remain, however, some issues with the font sizing and the spacing of elements. Also, the footer&amp;#8217;s columns appear rather haphazardly placed.&lt;/p&gt;
&lt;p&gt;Coming up in act two, the layout and typography get cleaned up and we add a splash of color. Don&amp;#8217;t miss it!&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title type="html">To Design A Blog (act&amp;nbsp;2)</title>
    <link href="http://reinh.com/blog/2008/02/26/to-design-a-blog-2.html" />
    <id>tag:reinh.com,2008-02-26:1204079296</id>
    <published>2008-02-26T21:28:16-05:00</published>
    <updated>2008-02-26T21:28:16-05:00</updated>
    <content type="html">&lt;p&gt;fig. 1.1 | ReinH-02.png&lt;/p&gt;
&lt;p&gt;In our &lt;a href=&quot;http://reinh.com/2008/02/25/to-design-a-blog-1.html&quot;&gt;first installment&lt;/a&gt;, the typography and layout of the blog were mostly decided. With this ground work in place, it&amp;#8217;s time to start focusing on the details. But first, it&amp;#8217;s time to give our eyes and brain a chance to relax and reset. Staring at the same design for hours tends to give you tunnel-vision and we want to be able to look at the site afresh.&lt;/p&gt;
&lt;p&gt;Now that we&amp;#8217;re ready to continue, the most obvious issue is the arrangement of the sections in the footer. The rest of the design follows a strict grid system but the haphazard placement of the bottom columns is jarring to the eye and the whitespace between them is also problematic. &lt;a href=&quot;/images/ReinH-02.png&quot; class=&quot;fig&quot; title=&quot;figure-1-1&quot;&gt;(Fig. 1.1)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;fig. 1.2 | ReinH-03.png&lt;/p&gt;
&lt;p&gt;A third column is added and the columns are properly aligned with the grid layout once again &lt;a href=&quot;/images/ReinH-03.png&quot; class=&quot;fig&quot; title=&quot;figure-1-2&quot;&gt;(Fig. 1.2)&lt;/a&gt;. Great success! The remaining changes are all relatively minor and mainly involve tweaks to font size, color, and spacing. Bonus points if you can spot them.&lt;/p&gt;
&lt;p&gt;Now then: Welcome to the new blog! Enjoy your stay.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title type="html">Git It, Got It?&amp;nbsp;Good!</title>
    <link href="http://reinh.com/blog/2008/02/19/git-it-got-it-good.html" />
    <id>tag:reinh.com,2008-02-19:1203458828</id>
    <published>2008-02-19T17:07:08-05:00</published>
    <updated>2008-02-19T17:07:08-05:00</updated>
    <content type="html">
&lt;p&gt;Last week, I gave a presentation on the &lt;a href=&quot;http://git.or.cz&quot;&gt;git&lt;/a&gt; version control system. Apparently it went pretty well. The &lt;a href=&quot;http://assets.reinh.com/talks/GIT.pdf&quot;&gt;slides are available&lt;/a&gt; for those who are interested.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">A&amp;nbsp;Retraction</title>
    <link href="http://reinh.com/blog/2008/12/05/a-retraction.html" />
    <id>tag:reinh.com,2008-12-05:1228500630</id>
    <published>2008-12-05T13:10:30-05:00</published>
    <updated>2008-12-05T13:10:30-05:00</updated>
    <content type="html">&lt;p&gt;The folks over at &lt;a href=&quot;https://www.woobius.com/&quot;&gt;Woobius&lt;/a&gt; have offered their sincere apology over what I believe was a simple misunderstanding and have made several changes to their blog design in response to my last post. I appreciate the professional way that they have handled the situation and have decided to retract said post in response to their request.&lt;/p&gt;
&lt;p&gt;I am not changing my stance on whether or not my design and content are open source and open to reuse (they are not). I will include a more explicit license to try to prevent such issues in the future. I would very much like to keep my blog&amp;#8217;s source publicly viewable on Github. I may need to discuss with the Github team the legal implications of their &lt;acronym title=&quot;Terms of Service&quot;&gt;TOS&lt;/acronym&gt; for public repositories.&lt;/p&gt;
&lt;p&gt;I would also like to find a licensing solution that would allow me to open certain parts of the source (my customizations of Webby and the various helpers and tools in my &lt;code&gt;lib&lt;/code&gt; directory, for instance) but still allow me to keep the design and content proprietary. I welcome any suggestions in the comment section below.&lt;/p&gt;
&lt;p&gt;I wish the Woobius team the best and look forward to seeing the direction that they take with their blog now that this misunderstanding has been cleared up. I hereby officially remove their evildoer status and downgrade them to unfortunate-misunderstanding-doers. I have also called off my Lawyers of Justice.&lt;/p&gt;</content>
  </entry>
  
</feed>
