<?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>remi</title>
  
  <link href="http://remi.org" />
  <updated>2009-09-28T00:00:00-07:00</updated>
  <id>http://remi.org</id><author>
    <name>remi Taylor</name>
    <email>remi@remitaylor.com</email>
  </author><link rel="self" href="http://feeds.feedburner.com/remitaylor" type="application/atom+xml" /><feedburner:browserFriendly></feedburner:browserFriendly><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
    <title>jQuery AJAX</title>
    <link href="http://remi.org/2009/09/28/jquery-ajax.html" />
    <updated>2009-09-28T00:00:00-07:00</updated>
    <id>http://remi.org//2009/09/28/jquery-ajax.html</id>
    <content type="html">
      &lt;p&gt;A few years back, I watched the &lt;a href='http://peepcode.com'&gt;Peepcode&lt;/a&gt; episode &lt;a href='https://peepcode.com/products/ajax-with-prototypejs'&gt;Ajax with Prototype.js&lt;/a&gt;. I thought it was the coolest thing ever!&lt;br /&gt;Compared to having to deal directly with XMLHttpRequest objects, it was &lt;em&gt;so&lt;/em&gt; easy. But that was way back in 2007.&lt;/p&gt;
      
      &lt;p&gt;Now, &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; is where it&amp;#8217;s at. And doing AJAX with &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; is even easier! Trivial, even!&lt;/p&gt;
      
      &lt;p&gt;In this episode, I&amp;#8217;ll show you how to:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;make arbitrary GET/POST/PUT/etc requests to your server and get the response&lt;/li&gt;
      
      &lt;li&gt;easily refresh part of the page with HTML rendered by your server&lt;/li&gt;
      
      &lt;li&gt;get JSON data from local &lt;em&gt;and&lt;/em&gt; remote servers (we demo getting tweets from Twitter)&lt;/li&gt;
      
      &lt;li&gt;get and run remote JavaScript&lt;/li&gt;
      
      &lt;li&gt;make sure your jQuery event handlers effect newly created DOM elements (eg. added via AJAX)&lt;/li&gt;
      
      &lt;li&gt;and more &lt;code&gt;:)&lt;/code&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt; 1 &lt;/span&gt;$.post(&lt;span class='Constant'&gt;'/dogs'&lt;/span&gt;, &lt;span class='Identifier'&gt;{&lt;/span&gt; &lt;span class='Constant'&gt;'dog[name]'&lt;/span&gt;: &lt;span class='Constant'&gt;'Rover'&lt;/span&gt; &lt;span class='Identifier'&gt;}&lt;/span&gt;);
      &lt;span class='lnr'&gt; 2 &lt;/span&gt;
      &lt;span class='lnr'&gt; 3 &lt;/span&gt;&lt;span class='Comment'&gt;// you can actually try the following snippets right here, on the blog!  just open Firebug  :) &lt;/span&gt;
      &lt;span class='lnr'&gt; 4 &lt;/span&gt;
      &lt;span class='lnr'&gt; 5 &lt;/span&gt;$.get(&lt;span class='Constant'&gt;'/index.html'&lt;/span&gt;, &lt;span class='Identifier'&gt;function&lt;/span&gt;(html)&lt;span class='Identifier'&gt;{&lt;/span&gt; &lt;span class='Statement'&gt;alert&lt;/span&gt;(&lt;span class='Constant'&gt;'got html: '&lt;/span&gt; + html); &lt;span class='Identifier'&gt;}&lt;/span&gt;);
      &lt;span class='lnr'&gt; 6 &lt;/span&gt;
      &lt;span class='lnr'&gt; 7 &lt;/span&gt;$(&lt;span class='Constant'&gt;'#content'&lt;/span&gt;).load(&lt;span class='Constant'&gt;'/index.html #header'&lt;/span&gt;);
      &lt;span class='lnr'&gt; 8 &lt;/span&gt;
      &lt;span class='lnr'&gt; 9 &lt;/span&gt;$.getJSON(&lt;span class='Constant'&gt;'&lt;a href='http://search.twitter.com/search.json?q=remitaylor&amp;amp;callback=?'&gt;http://search.twitter.com/search.json?q=remitaylor&amp;amp;callback=?&lt;/a&gt;'&lt;/span&gt;,
      &lt;span class='lnr'&gt;10 &lt;/span&gt;          &lt;span class='Identifier'&gt;function&lt;/span&gt;(tweets)&lt;span class='Identifier'&gt;{&lt;/span&gt; console.log(tweets.results) &lt;span class='Identifier'&gt;}&lt;/span&gt;);
      &lt;span class='lnr'&gt;11 &lt;/span&gt;
      &lt;span class='lnr'&gt;12 &lt;/span&gt;$(&lt;span class='Constant'&gt;'a'&lt;/span&gt;).live(&lt;span class='Constant'&gt;'click'&lt;/span&gt;, &lt;span class='Identifier'&gt;function&lt;/span&gt;()&lt;span class='Identifier'&gt;{&lt;/span&gt; &lt;span class='Statement'&gt;alert&lt;/span&gt;(&lt;span class='Constant'&gt;&amp;quot;I get bound to new DOM elements&amp;quot;&lt;/span&gt;); &lt;span class='Statement'&gt;return&lt;/span&gt; &lt;span class='Constant'&gt;false&lt;/span&gt;; &lt;span class='Identifier'&gt;}&lt;/span&gt;);&lt;/pre&gt;
    </content>
  </entry>
<entry>
    <title>jQuery Plugin Development</title>
    <link href="http://remi.org/2009/09/25/jquery-plugin-development.html" />
    <updated>2009-09-25T00:00:00-07:00</updated>
    <id>http://remi.org//2009/09/25/jquery-plugin-development.html</id>
    <content type="html">
      &lt;p&gt;Creating plugins for &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; is trivially easy and can help you:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;clean up your javascript in individual applications&lt;/li&gt;
      
      &lt;li&gt;share re-used javascript between multiple applications&lt;/li&gt;
      
      &lt;li&gt;share your snazzy &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; voodoo with others!&lt;/li&gt;
      &lt;/ul&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;$.fn.color = &lt;span class='Identifier'&gt;function&lt;/span&gt;(color)&lt;span class='Identifier'&gt;{&lt;/span&gt;
      &lt;span class='lnr'&gt;2 &lt;/span&gt;  &lt;span class='Statement'&gt;return&lt;/span&gt; &lt;span class='Identifier'&gt;this&lt;/span&gt;.each(&lt;span class='Identifier'&gt;function&lt;/span&gt;()&lt;span class='Identifier'&gt;{&lt;/span&gt;
      &lt;span class='lnr'&gt;3 &lt;/span&gt;    $(&lt;span class='Identifier'&gt;this&lt;/span&gt;).css(&lt;span class='Constant'&gt;'color'&lt;/span&gt;, color);
      &lt;span class='lnr'&gt;4 &lt;/span&gt;  &lt;span class='Identifier'&gt;}&lt;/span&gt;);
      &lt;span class='lnr'&gt;5 &lt;/span&gt;&lt;span class='Identifier'&gt;}&lt;/span&gt;;
      &lt;span class='lnr'&gt;6 &lt;/span&gt;
      &lt;span class='lnr'&gt;7 &lt;/span&gt;$(&lt;span class='Constant'&gt;'a'&lt;/span&gt;).color(&lt;span class='Constant'&gt;'red'&lt;/span&gt;).css(&lt;span class='Constant'&gt;'font-weight'&lt;/span&gt;, &lt;span class='Constant'&gt;'bold'&lt;/span&gt;);
      &lt;span class='lnr'&gt;8 &lt;/span&gt;
      &lt;span class='lnr'&gt;9 &lt;/span&gt;(&lt;span class='Identifier'&gt;function&lt;/span&gt;($)&lt;span class='Identifier'&gt;{&lt;/span&gt; ... &lt;span class='Identifier'&gt;}&lt;/span&gt;)&lt;span class='Identifier'&gt;{&lt;/span&gt;jQuery)&lt;/pre&gt;
    </content>
  </entry>
<entry>
    <title>Ruby Basics</title>
    <link href="http://remi.org/2009/09/13/ruby-basics.html" />
    <updated>2009-09-13T00:00:00-07:00</updated>
    <id>http://remi.org//2009/09/13/ruby-basics.html</id>
    <content type="html">
      &lt;p&gt;People often ask me how to get started programming &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;Whether you&amp;#8217;re an experienced programmer, or you&amp;#8217;ve never programmed before, this screencast will hopefully give you a good introduction to how to program with &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;(see &lt;a href='#screencast-video-player'&gt;screencast&lt;/a&gt; below)&lt;/p&gt;
      
      &lt;h2 id='try_ruby'&gt;Try Ruby!&lt;/h2&gt;
      
      &lt;p&gt;One of my favorite resources for learning &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; is &lt;a href='http://tryruby.sophrinix.com'&gt;Try Ruby!&lt;/a&gt;, a web site that has a built-in Ruby console and it walks you through tutorials. It&amp;#8217;s really quite ingenious. It tells you things to try and detects when you&amp;#8217;ve tried that bit of code, at which point it brings you to the next page of the tutorial.&lt;/p&gt;
      
      &lt;p&gt;&lt;img src='/images/try-ruby.png' alt='Screenshot of Try Ruby!' /&gt;&lt;/p&gt;
      
      &lt;p&gt;The &lt;a href='http://tryruby.sophrinix.com'&gt;Try Ruby!&lt;/a&gt; that&amp;#8217;s currently online is slightly different from the original, and may currently have a few bugs, but it should be good enough to get you started.&lt;/p&gt;
      
      &lt;p&gt;Unfortunately, one of the &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; community&amp;#8217;s most beloved programmers recently mysteriously vanished, and he was the one that hosted the original &lt;a href='http://tryruby.sophrinix.com'&gt;Try Ruby!&lt;/a&gt;, so &lt;a href='http://github.com/Sophrinix'&gt;someone&lt;/a&gt; is trying to get it fully back up and running.&lt;/p&gt;
      
      &lt;h2 id='installing_and_playing'&gt;Installing and Playing&lt;/h2&gt;
      
      &lt;p&gt;Really, the best way to learn any programming language is to download it and start playing around with it. Come up with some small task that you&amp;#8217;d like to try to accomplish with the language and see if you can do it. Also, read other people&amp;#8217;s code!&lt;/p&gt;
      
      &lt;p&gt;Luckily, &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; is installed out-of-the-box on Mac OSX. It&amp;#8217;s trivially easy to install on Linux (use your distro&amp;#8217;s package manager). And there&amp;#8217;s an &lt;a href='/2009/04/14/ruby-on-windows-quick-and-dirty.html'&gt;installer for Windows&lt;/a&gt; that you can download and double-click to install (&lt;a href='/2009/04/15/ruby-on-windows-cygwin-git-rvxt-and-more.html'&gt;or use cygwin&lt;/a&gt;).&lt;/p&gt;
      
      &lt;h2 id='additional_references'&gt;Additional References&lt;/h2&gt;
      
      &lt;p&gt;There&amp;#8217;s an &lt;a href='http://mislav.uniqpath.com/poignant-guide/'&gt;online book&lt;/a&gt; available for learning &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; that walks you through learning the whole language, from the very basics (for total beginners) to hardcore programming. Oh. And it has cartoon foxes.&lt;/p&gt;
      
      &lt;p&gt;&lt;img src='http://upload.wikimedia.org/wikipedia/en/thumb/0/04/Why%27s_foxes.png/350px-Why%27s_foxes.png' alt='Cartoon Foxed from Whys Poignant Guide to Ruby' /&gt;&lt;/p&gt;
      
      &lt;p&gt;It&amp;#8217;s not for everyone and, a few chapters in, you might start to feel dizzy (or like you&amp;#8217;re on an acid trip), but it&amp;#8217;s a &lt;em&gt;magnificent&lt;/em&gt; way to learn the basics. Every experienced &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; programmer has read atleast the beginning of the book and it&amp;#8217;s become a part of the community. It was created by &lt;a href='http://en.wikipedia.org/wiki/Why_the_lucky_stiff'&gt;Why the Lucky Stiff&lt;/a&gt; (aka _why), the programmer who recently disappeared.&lt;/p&gt;
      
      &lt;p&gt;If you prefer the usual boring programming language books, I recommend the &lt;a href='http://www.pragprog.com/titles/ruby/programming-ruby'&gt;Pickaxe&lt;/a&gt; book, which you&amp;#8217;ll likely find on every &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; programmer&amp;#8217;s bookshelf.&lt;/p&gt;
      
      &lt;p&gt;&lt;img src='http://assets0.pragprog.com/images/covers/190x228/ruby.jpg?1184184147' alt='Pickaxe' /&gt;&lt;/p&gt;
      
      &lt;p&gt;Anyway, enjoy the screencast! I hope you enjoy learning to program with &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; &lt;code&gt;:)&lt;/code&gt;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Dev Fu!</title>
    <link href="http://remi.org/2009/09/13/devfu.html" />
    <updated>2009-09-13T00:00:00-07:00</updated>
    <id>http://remi.org//2009/09/13/devfu.html</id>
    <content type="html">
      &lt;p&gt;It&amp;#8217;s been a few months since I&amp;#8217;ve regularly posted new screencasts. In that time, I&amp;#8217;ve gotten lots and lots of requests for screencasts and I can&amp;#8217;t wait to record and release as many as I can.&lt;/p&gt;
      
      &lt;p&gt;The fact is: I&amp;#8217;ve been busy!&lt;/p&gt;
      
      &lt;p&gt;The reason?&lt;/p&gt;
      
      &lt;h2 id='i_started_my_own_company'&gt;I Started My Own Company&lt;/h2&gt;
      
      &lt;p&gt;For those that don&amp;#8217;t know, my good friend &lt;a href='http://me.bm5k.com'&gt;@bm5k&lt;/a&gt; and I co-founded &lt;a href='http://devfu.com'&gt;Dev Fu!&lt;/a&gt; a few months ago, a Phoenix-based Ruby on Rails company. And it&amp;#8217;s been &lt;em&gt;crazy!&lt;/em&gt;&lt;/p&gt;
      
      &lt;p&gt;Crazy &lt;em&gt;fun&lt;/em&gt;, that is &lt;code&gt;:)&lt;/code&gt;&lt;/p&gt;
      
      &lt;p&gt;Over the years, I&amp;#8217;ve seen more and more of my developer &amp;amp; designer friends go freelance or start their own companies. I was always envious of them and hoped to go freelance myself, one day. Work from home? Set your own hours? Sounds like a dream!&lt;/p&gt;
      
      &lt;p&gt;Well, anyway &amp;#8230; I did it. Turns out that it&amp;#8217;s not hard at all to go out on your own!&lt;/p&gt;
      &lt;ol&gt;
        &lt;li&gt;Quit your day job&lt;/li&gt;
        &lt;li&gt;Setup your own company&lt;/li&gt;
        &lt;li&gt;?&lt;/li&gt;
        &lt;li&gt;Profit!&lt;/li&gt;
      &lt;/ol&gt;
      &lt;p&gt;Steps 1 and 2 are easy, you can do both of them in 1 day! Step 3 is where all of the mystery lies. Inotherwords, it&amp;#8217;s where all of the &lt;strong&gt;fun&lt;/strong&gt; is &lt;code&gt;:P&lt;/code&gt;&lt;/p&gt;
      
      &lt;h2 id='screencasts'&gt;Screencasts&lt;/h2&gt;
      
      &lt;p&gt;Anyway, I&amp;#8217;ve been so busy that I haven&amp;#8217;t had time to think much about screencasting. I really miss screencasting, though, and I have a good list of suggested screencast topics that I would love to start digging into.&lt;/p&gt;
      
      &lt;p&gt;Starting this week, I&amp;#8217;m going to try to release atleast 1 screencast a week.&lt;/p&gt;
      
      &lt;p&gt;For now, I&amp;#8217;m not releasing on a particular day. Very soon, however, I&amp;#8217;ll probably pick a day of the week that I&amp;#8217;ll always release a screencast on, so you&amp;#8217;ll know which days to check my RSS feed &lt;code&gt;:P&lt;/code&gt;&lt;/p&gt;
      
      &lt;p&gt;Watch for new screencasts! Hope you enjoy!&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Streaming Screencasts with Viddler</title>
    <link href="http://remi.org/2009/07/01/streaming-screencasts-with-viddler.html" />
    <updated>2009-07-01T00:00:00-07:00</updated>
    <id>http://remi.org//2009/07/01/streaming-screencasts-with-viddler.html</id>
    <content type="html">
      &lt;p&gt;You asked for it, so here it is!&lt;/p&gt;
      
      &lt;p&gt;Finally, if you don&amp;#8217;t want to wait for my screencasts to fully download, you can watch them streamed!&lt;/p&gt;
      
      &lt;p&gt;I tried out &lt;a href='http://www.viddler.com'&gt;Viddler&lt;/a&gt;, &lt;a href='http://www.vimeo.com'&gt;Vimeo&lt;/a&gt;, &lt;a href='http://www.viddyou.com'&gt;Viddyou&lt;/a&gt;, and &lt;a href='http://www.youtube,com'&gt;YouTube&lt;/a&gt; - all good services. &lt;a href='http://www.viddler.com'&gt;Viddler&lt;/a&gt; has treated me the best, so far, so I&amp;#8217;m starting to upload my screencasts to &lt;a href='http://www.viddler.com'&gt;Viddler&lt;/a&gt; and start embedding them in my blog posts.&lt;/p&gt;
      
      &lt;p&gt;Ofcourse, you&amp;#8217;ll still be able to download the full screencasts in the formats that I currently support:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Xvid'&gt;xvid&lt;/a&gt; encoded &lt;a href='http://en.wikipedia.org/wiki/Audio_Video_Interleave'&gt;avi&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/X264'&gt;x264&lt;/a&gt; encoded &lt;a href='http://en.wikipedia.org/wiki/Mp4'&gt;mp4&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Ogg'&gt;ogg&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;Let me know (in the comments) how you like the streaming &lt;a href='http://www.viddler.com'&gt;Viddler&lt;/a&gt; videos. I&amp;#8217;ve actually found that the videos looks better if you click the &lt;img src='/images/viddler-full-screen-button.png' alt='Full Screen button' /&gt; full screen button (atleast on my tiny 1280x800 laptop screen).&lt;/p&gt;
      
      &lt;p&gt;Are the available formats working well for everyone? The &lt;a href='http://www.viddler.com'&gt;Viddler&lt;/a&gt; streams? Let me know!&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Enjoy!&lt;/strong&gt;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Rack::OpenID::Proxy</title>
    <link href="http://remi.org/2009/06/30/rack-openid-proxy.html" />
    <updated>2009-06-30T00:00:00-07:00</updated>
    <id>http://remi.org//2009/06/30/rack-openid-proxy.html</id>
    <content type="html">
      &lt;h2 id='why'&gt;Why?&lt;/h2&gt;
      
      &lt;p&gt;If you have a Ruby web application that you want to use OpenID in, check out &lt;a href='http://remi.org/2009/06/26/rack-openid.html'&gt;Rack::OpenID&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;If you &amp;#8230;&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;have lots of applications and you only want to implement one OpenID consumer &lt;strong&gt;OR&lt;/strong&gt; &amp;#8230;&lt;/li&gt;
      
      &lt;li&gt;you have a web app running in an environment (like Google AppEngine) where OpenID consumers don&amp;#8217;t work properly&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;&amp;#8230; check out &lt;a href='http://github.com/devfu/rack-openid-proxy'&gt;Rack::OpenID::Proxy&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;If you don&amp;#8217;t need a proxy to be an OpenID consumer, this likely isn&amp;#8217;t for you. I created this because we&amp;#8217;ve been using Google AppEngine and OpenID doesn&amp;#8217;t work very well on AppEngine.&lt;/p&gt;
      
      &lt;h2 id='how'&gt;How?&lt;/h2&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/devfu/rack-openid-proxy'&gt;Rack::OpenID::Proxy&lt;/a&gt; runs as a standalone Rack application (or it can be run as middleware).&lt;/p&gt;
      
      &lt;p&gt;Let&amp;#8217;s say you run this proxy on &lt;a href='http://heroku.com'&gt;Heroku&lt;/a&gt; at &lt;code&gt;http://openid-proxy.heroku.com&lt;/code&gt;.&lt;/p&gt;
      
      &lt;p&gt;From a different web application, when you want to authenticate a user against OpenID, redirect them to &lt;code&gt;http://openid-proxy.heroku.com/openid?url=the-users.open-id-provider.com&lt;/code&gt;. This will redirect the user to the OpenID providers&amp;#8217; login and then redirect &lt;em&gt;back&lt;/em&gt; to whatever URL your request originally came from (via the referer) with an extra querystring, eg: &lt;code&gt;http://yoursite.com/original-path?token=1234abcd&lt;/code&gt;&lt;/p&gt;
      
      &lt;p&gt;Now the user is back on your site and has been through the OpenID process (via 1 simple redirect). To get the OpenID response (to find out if the login was successful), you can fetch the response via: &lt;code&gt;http://openid-proxy.heroku.com/openid.json?token=1234abcd&lt;/code&gt;&lt;/p&gt;
      
      &lt;p&gt;Here&amp;#8217;s an example consumer implementation written in Sinatra:&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt; 1 &lt;/span&gt;&lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;sinatra&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt; 2 &lt;/span&gt;&lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;open-uri&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt; 3 &lt;/span&gt;
      &lt;span class='lnr'&gt; 4 &lt;/span&gt;&lt;span class='Type'&gt;PROXY&lt;/span&gt; = &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;&lt;a href='http://my-open-id-proxy.com'&gt;http://my-open-id-proxy.com&lt;/a&gt;&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt; 5 &lt;/span&gt;
      &lt;span class='lnr'&gt; 6 &lt;/span&gt;get &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;/&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; &lt;span class='Statement'&gt;do&lt;/span&gt;
      &lt;span class='lnr'&gt; 7 &lt;/span&gt;  &lt;span class='Statement'&gt;if&lt;/span&gt; params[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;token&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;]
      &lt;span class='lnr'&gt; 8 &lt;/span&gt;    &lt;span class='Comment'&gt;# this is the redirect coming back from the proxy.&lt;/span&gt;
      &lt;span class='lnr'&gt; 9 &lt;/span&gt;    &lt;span class='Comment'&gt;# the OpenID response is accessible using the token we were given.&lt;/span&gt;
      &lt;span class='lnr'&gt;10 &lt;/span&gt;    response = open(&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; &lt;span class='Type'&gt;PROXY&lt;/span&gt; &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Constant'&gt;/openid?token=&lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; params[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;token&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;] &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;)
      &lt;span class='lnr'&gt;11 &lt;/span&gt;    &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;OpenID response: &lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; response &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='lnr'&gt;12 &lt;/span&gt;  &lt;span class='Statement'&gt;else&lt;/span&gt;
      &lt;span class='lnr'&gt;13 &lt;/span&gt;    haml &lt;span class='Constant'&gt;:openid_login_form&lt;/span&gt;
      &lt;span class='lnr'&gt;14 &lt;/span&gt;  &lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;15 &lt;/span&gt;&lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;16 &lt;/span&gt;
      &lt;span class='lnr'&gt;17 &lt;/span&gt;post &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;/login&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; &lt;span class='Statement'&gt;do&lt;/span&gt;
      &lt;span class='lnr'&gt;18 &lt;/span&gt;  &lt;span class='Comment'&gt;# redirect to the proxy to do the OpenID authentication for us.&lt;/span&gt;
      &lt;span class='lnr'&gt;19 &lt;/span&gt;  &lt;span class='Comment'&gt;# the proxy will redirect back to this app with a token param.&lt;/span&gt;
      &lt;span class='lnr'&gt;20 &lt;/span&gt;  redirect &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; &lt;span class='Type'&gt;PROXY&lt;/span&gt; &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Constant'&gt;/openid?url=&lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; params[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;openid-url&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;] &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='lnr'&gt;21 &lt;/span&gt;&lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;22 &lt;/span&gt;
      &lt;span class='lnr'&gt;23 &lt;/span&gt;&lt;span class='Special'&gt;__END__&lt;/span&gt;
      &lt;span class='lnr'&gt;24 &lt;/span&gt;
      &lt;span class='lnr'&gt;25 &lt;/span&gt;&lt;span class='Comment'&gt;@@ openid_login_form&lt;/span&gt;
      &lt;span class='lnr'&gt;26 &lt;/span&gt;
      &lt;span class='lnr'&gt;27 &lt;/span&gt;&lt;span class='Comment'&gt;%form{ :action =&amp;gt; '/login', :method =&amp;gt; 'post' }&lt;/span&gt;
      &lt;span class='lnr'&gt;28 &lt;/span&gt;&lt;span class='Comment'&gt;  %label&lt;/span&gt;
      &lt;span class='lnr'&gt;29 &lt;/span&gt;&lt;span class='Comment'&gt;    OpenID URL: &lt;/span&gt;
      &lt;span class='lnr'&gt;30 &lt;/span&gt;&lt;span class='Comment'&gt;    %input{ :type =&amp;gt; 'text', :name =&amp;gt; 'openid-url' }&lt;/span&gt;
      &lt;span class='lnr'&gt;31 &lt;/span&gt;&lt;span class='Comment'&gt;  %input{ :type =&amp;gt; 'submit', :value =&amp;gt; 'Login via OpenID' }&lt;/span&gt;&lt;/pre&gt;
      &lt;p&gt;&lt;a href='http://github.com/devfu/rack-openid-proxy' class='center'&gt;http://github.com/devfu/rack-openid-proxy&lt;/a&gt;&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Rack::OpenID</title>
    <link href="http://remi.org/2009/06/26/rack-openid.html" />
    <updated>2009-06-26T00:00:00-07:00</updated>
    <id>http://remi.org//2009/06/26/rack-openid.html</id>
    <content type="html">
      &lt;p&gt;I was looking for an easy way to add &lt;a href='http://openid.net'&gt;OpenID&lt;/a&gt; authentication to Rack applications and I found &lt;a href='http://github.com/josh/rack-openid'&gt;Rack::OpenID&lt;/a&gt;, a Rack middleware for &lt;a href='http://openid.net'&gt;OpenID&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;If you want to have a user redirected to their &lt;a href='http://openid.net'&gt;OpenID&lt;/a&gt; login, simply return:&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;[ &lt;span class='Constant'&gt;401&lt;/span&gt;, { &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;WWW-Authenticate&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;OpenID identity=&amp;quot;my-open-id-url.com&amp;quot;&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; }, [] ]&lt;/pre&gt;
      &lt;p&gt;If you &lt;code&gt;use Rack::OpenID&lt;/code&gt;, that will redirect the user to login via &lt;a href='http://openid.net'&gt;OpenID&lt;/a&gt;, after which they&amp;#8217;ll be redirected back to the URL they were redirected from with &lt;code&gt;env[&amp;quot;rack.openid.response&amp;quot;]&lt;/code&gt; set to an &lt;a href='http://openid.net'&gt;OpenID&lt;/a&gt; Response object.&lt;/p&gt;
      
      &lt;p&gt;Here&amp;#8217;s a simple Rack app that using &lt;a href='http://github.com/josh/rack-openid'&gt;Rack::OpenID&lt;/a&gt; &amp;#8230;&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt; 1 &lt;/span&gt;&lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;rack/openid&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt; 2 &lt;/span&gt;
      &lt;span class='lnr'&gt; 3 &lt;/span&gt;use &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Session&lt;/span&gt;::&lt;span class='Type'&gt;Cookie&lt;/span&gt;
      &lt;span class='lnr'&gt; 4 &lt;/span&gt;use &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;OpenID&lt;/span&gt;
      &lt;span class='lnr'&gt; 5 &lt;/span&gt;
      &lt;span class='lnr'&gt; 6 &lt;/span&gt;run &lt;span class='Statement'&gt;lambda&lt;/span&gt; {|&lt;span class='Identifier'&gt;env&lt;/span&gt;|
      &lt;span class='lnr'&gt; 7 &lt;/span&gt;  request = &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Request&lt;/span&gt;.new env
      &lt;span class='lnr'&gt; 8 &lt;/span&gt;  session = env[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;rack.session&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;]
      &lt;span class='lnr'&gt; 9 &lt;/span&gt;
      &lt;span class='lnr'&gt;10 &lt;/span&gt;  &lt;span class='Comment'&gt;# /logout should clear the session and redirect back to /&lt;/span&gt;
      &lt;span class='lnr'&gt;11 &lt;/span&gt;  &lt;span class='Statement'&gt;if&lt;/span&gt; env[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;PATH_INFO&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;] == &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;/logout&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;12 &lt;/span&gt;    session.clear
      &lt;span class='lnr'&gt;13 &lt;/span&gt;    [ &lt;span class='Constant'&gt;302&lt;/span&gt;, { &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;Location&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;/&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; }, [] ]
      &lt;span class='lnr'&gt;14 &lt;/span&gt;
      &lt;span class='lnr'&gt;15 &lt;/span&gt;  &lt;span class='Comment'&gt;# if we got a response from OpenID, save it in the session and redirect back to /&lt;/span&gt;
      &lt;span class='lnr'&gt;16 &lt;/span&gt;  &lt;span class='Statement'&gt;elsif&lt;/span&gt; openid_response = env[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;rack.openid.response&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;]
      &lt;span class='lnr'&gt;17 &lt;/span&gt;    session[&lt;span class='Constant'&gt;:openid&lt;/span&gt;] = openid_response
      &lt;span class='lnr'&gt;18 &lt;/span&gt;    [ &lt;span class='Constant'&gt;302&lt;/span&gt;, { &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;Location&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;/&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; }, [] ]
      &lt;span class='lnr'&gt;19 &lt;/span&gt;
      &lt;span class='lnr'&gt;20 &lt;/span&gt;  &lt;span class='Comment'&gt;# if we POST the form (with an openid_url field), redirect the user to login via OpenID&lt;/span&gt;
      &lt;span class='lnr'&gt;21 &lt;/span&gt;  &lt;span class='Statement'&gt;elsif&lt;/span&gt; openid_url = request.params[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;openid_url&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;]
      &lt;span class='lnr'&gt;22 &lt;/span&gt;    [ &lt;span class='Constant'&gt;401&lt;/span&gt;, { &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;WWW-Authenticate&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;OpenID identifier=\&amp;quot;&lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; openid_url &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Constant'&gt;\&amp;quot;&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;}, [] ]
      &lt;span class='lnr'&gt;23 &lt;/span&gt;
      &lt;span class='lnr'&gt;24 &lt;/span&gt;  &lt;span class='Comment'&gt;# display a page with a login form and the user's current logged in status&lt;/span&gt;
      &lt;span class='lnr'&gt;25 &lt;/span&gt;  &lt;span class='Statement'&gt;else&lt;/span&gt;
      &lt;span class='lnr'&gt;26 &lt;/span&gt;    &lt;span class='Statement'&gt;if&lt;/span&gt; session[&lt;span class='Constant'&gt;:openid&lt;/span&gt;]
      &lt;span class='lnr'&gt;27 &lt;/span&gt;      &lt;span class='Statement'&gt;if&lt;/span&gt; session[&lt;span class='Constant'&gt;:openid&lt;/span&gt;].status == &lt;span class='Constant'&gt;:failure&lt;/span&gt;
      &lt;span class='lnr'&gt;28 &lt;/span&gt;        login_status = &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;Login Failed: &lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; session[&lt;span class='Constant'&gt;:openid&lt;/span&gt;].message &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='lnr'&gt;29 &lt;/span&gt;      &lt;span class='Statement'&gt;else&lt;/span&gt;
      &lt;span class='lnr'&gt;30 &lt;/span&gt;        login_status = &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;Logged in as: &lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; session[&lt;span class='Constant'&gt;:openid&lt;/span&gt;].identity_url &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='lnr'&gt;31 &lt;/span&gt;      &lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;32 &lt;/span&gt;    &lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;33 &lt;/span&gt;    [ &lt;span class='Constant'&gt;200&lt;/span&gt;, { &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;Content-Type&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;text/html&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; }, &lt;span class='Special'&gt;%{&lt;/span&gt;
      &lt;span class='lnr'&gt;34 &lt;/span&gt;&lt;span class='Constant'&gt;      &amp;lt;a href=&amp;quot;/logout&amp;quot;&amp;gt;Logout&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class='lnr'&gt;35 &lt;/span&gt;&lt;span class='Constant'&gt;      &amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt; login_status &lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Constant'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class='lnr'&gt;36 &lt;/span&gt;&lt;span class='Constant'&gt;      &amp;lt;form action=&amp;quot;/&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;/span&gt;
      &lt;span class='lnr'&gt;37 &lt;/span&gt;&lt;span class='Constant'&gt;        OpenID URL: &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;openid_url&amp;quot; /&amp;gt;&lt;/span&gt;
      &lt;span class='lnr'&gt;38 &lt;/span&gt;&lt;span class='Constant'&gt;        &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Login&amp;quot; /&amp;gt;&lt;/span&gt;
      &lt;span class='lnr'&gt;39 &lt;/span&gt;&lt;span class='Constant'&gt;      &amp;lt;/form&amp;gt;&lt;/span&gt;
      &lt;span class='lnr'&gt;40 &lt;/span&gt;&lt;span class='Constant'&gt;    &lt;/span&gt;&lt;span class='Special'&gt;}&lt;/span&gt; ]
      &lt;span class='lnr'&gt;41 &lt;/span&gt;  &lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;42 &lt;/span&gt;}&lt;/pre&gt;
      &lt;p&gt;&lt;a href='http://github.com/josh/rack-openid' class='center'&gt;http://github.com/josh/rack-openid&lt;/a&gt;&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Rack::OAuth</title>
    <link href="http://remi.org/2009/06/23/rack-oauth.html" />
    <updated>2009-06-23T00:00:00-07:00</updated>
    <id>http://remi.org//2009/06/23/rack-oauth.html</id>
    <content type="html">
      &lt;p&gt;&lt;a href='http://github.com/remi/rack-oauth'&gt;Rack::OAuth&lt;/a&gt; is a Rack middleware for easily integrating OAuth into your Ruby web applications.&lt;/p&gt;
      
      &lt;p&gt;If you&amp;#8217;re using a Sinatra application or Rackup file, all you need to do is:&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;use &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;OAuth&lt;/span&gt;, &lt;span class='Constant'&gt;:key&lt;/span&gt;    =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;your-oauth-app-key&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;,
      &lt;span class='lnr'&gt;2 &lt;/span&gt;                 &lt;span class='Constant'&gt;:secret&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;your-oauth-app-secret&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;,
      &lt;span class='lnr'&gt;3 &lt;/span&gt;                 &lt;span class='Constant'&gt;:site&lt;/span&gt;   =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;&lt;a href='http://twitter-or-whatever.com'&gt;http://twitter-or-whatever.com&lt;/a&gt;&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;&lt;/pre&gt;
      &lt;p&gt;If you&amp;#8217;re using Rails, all you need to do is:&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;config.middleware.use &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;OAuth&lt;/span&gt;, &lt;span class='Constant'&gt;:key&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;...&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;, &lt;span class='Constant'&gt;:secret&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;...&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;, &lt;span class='Constant'&gt;:site&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;...&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;&lt;/pre&gt;
      &lt;p&gt;Then, whenever you want to have your user redirected to authorize OAuth access, redirect them to &lt;code&gt;/oauth_login&lt;/code&gt;.&lt;/p&gt;
      
      &lt;p&gt;After the OAuth authorization is complete, they&amp;#8217;ll be redirected back to &lt;code&gt;/oauth_complete&lt;/code&gt;.&lt;/p&gt;
      
      &lt;p&gt;Ofcourse all of these paths are configurable and there are more configration options available. To find out more, check out the screencast or checkout the code at:&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/remi/rack-oauth' class='center'&gt;http://github.com/remi/rack-oauth&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>jQuery Basics</title>
    <link href="http://remi.org/2009/06/16/jquery-basics.html" />
    <updated>2009-06-16T00:00:00-07:00</updated>
    <id>http://remi.org//2009/06/16/jquery-basics.html</id>
    <content type="html">
      &lt;p&gt;I was about to make a short screencast showing how to use a jQuery plugin I created when I realized &amp;#8230; there are still web developers out there who haven&amp;#8217;t used &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt;!&lt;/p&gt;
      
      &lt;p&gt;So &amp;#8230; developers who aren&amp;#8217;t yet fully comfortable with &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; &amp;#8230; this one is for you!&lt;/p&gt;
      
      &lt;p&gt;I show you how to:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;Download jQuery to use in your apps (or just the &lt;a href='http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery'&gt;Google Ajax Libraries&lt;/a&gt; version)&lt;/li&gt;
      
      &lt;li&gt;Browse the jQuery API via &lt;a href='http://visualjquery.com'&gt;Visual jQuery&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;Select elements on the page, eg. &lt;code&gt;$(&amp;#39;a&amp;#39;)&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;Do stuff with elements on the page, eg. &lt;code&gt;$(&amp;#39;a&amp;#39;).css(&amp;#39;color&amp;#39;, &amp;#39;blue&amp;#39;)&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;Method chaining, eg. &lt;code&gt;$(&amp;#39;a&amp;#39;).css(&amp;#39;color&amp;#39;, &amp;#39;blue&amp;#39;).text(&amp;#39;foo&amp;#39;)&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_JavaScript'&gt;Unobtrusive JavaScript&lt;/a&gt; (UJS) with &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt;, ie. event handling with &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;Running stuff once the DOM is fully loaded, eg. &lt;code&gt;$(document).ready(function(){ ... })&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;Writing your own &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; functions so you can say &lt;code&gt;$(&amp;#39;a&amp;#39;).myCoolFunction()&lt;/code&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;I think I&amp;#8217;ll do another screencast on Ajax with &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; &amp;#8230; but I hope this shows you the basics!&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;$(&lt;span class='Statement'&gt;document&lt;/span&gt;).ready(&lt;span class='Identifier'&gt;function&lt;/span&gt;()&lt;span class='Identifier'&gt;{&lt;/span&gt;
      &lt;span class='lnr'&gt;2 &lt;/span&gt;
      &lt;span class='lnr'&gt;3 &lt;/span&gt;  $(&lt;span class='Constant'&gt;'li'&lt;/span&gt;).css(&lt;span class='Constant'&gt;'color'&lt;/span&gt;, &lt;span class='Constant'&gt;'red'&lt;/span&gt;);
      &lt;span class='lnr'&gt;4 &lt;/span&gt;
      &lt;span class='lnr'&gt;5 &lt;/span&gt;  $(&lt;span class='Constant'&gt;'h1'&lt;/span&gt;).click(&lt;span class='Identifier'&gt;function&lt;/span&gt;()&lt;span class='Identifier'&gt;{&lt;/span&gt;
      &lt;span class='lnr'&gt;6 &lt;/span&gt;    &lt;span class='Statement'&gt;alert&lt;/span&gt;(&lt;span class='Constant'&gt;'clicked on header with text: '&lt;/span&gt; + $(&lt;span class='Identifier'&gt;this&lt;/span&gt;).text());
      &lt;span class='lnr'&gt;7 &lt;/span&gt;  &lt;span class='Identifier'&gt;}&lt;/span&gt;);
      &lt;span class='lnr'&gt;8 &lt;/span&gt;
      &lt;span class='lnr'&gt;9 &lt;/span&gt;&lt;span class='Identifier'&gt;}&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Rack::Staticifier - Rack middleware for static caching</title>
    <link href="http://remi.org/2009/06/15/rack-staticifier.html" />
    <updated>2009-06-15T00:00:00-07:00</updated>
    <id>http://remi.org//2009/06/15/rack-staticifier.html</id>
    <content type="html">
      &lt;p&gt;While at &lt;a href='http://railsconf.com'&gt;RailsConf&lt;/a&gt; this year, I got bored and coded up a &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; &lt;a href='/2009/02/28/rack-part-3-middleware.html'&gt;middleware&lt;/a&gt; for static caching.&lt;/p&gt;
      
      &lt;p&gt;&lt;span&gt;Rails&lt;/span&gt; has a way to staticly cache pages built-in but not all Ruby web frameworks do, so I figured this would make a good piece of &lt;a href='/2009/02/28/rack-part-3-middleware.html'&gt;middleware&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;( Also, I knew that I wanted to create &lt;a href='/2009/06/15/staticify.html'&gt;Staticify&lt;/a&gt; and it would require &lt;a href='http://github.com/remi/rack-staticifier'&gt;Rack::Staticifier&lt;/a&gt; )&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt; 1 &lt;/span&gt;&lt;span class='Comment'&gt;# this will cache ALL responses in a 'cache' directory&lt;/span&gt;
      &lt;span class='lnr'&gt; 2 &lt;/span&gt;use &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Staticifier&lt;/span&gt;
      &lt;span class='lnr'&gt; 3 &lt;/span&gt;
      &lt;span class='lnr'&gt; 4 &lt;/span&gt;&lt;span class='Comment'&gt;# this will cache ALL responses in a 'public/my/cached/stuff' directory&lt;/span&gt;
      &lt;span class='lnr'&gt; 5 &lt;/span&gt;use &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Staticifier&lt;/span&gt;, &lt;span class='Constant'&gt;:root&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;public/my/cached/stuff&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt; 6 &lt;/span&gt;
      &lt;span class='lnr'&gt; 7 &lt;/span&gt;&lt;span class='Comment'&gt;# this will only cache requests with 'foo' in the URL&lt;/span&gt;
      &lt;span class='lnr'&gt; 8 &lt;/span&gt;use &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Staticifier&lt;/span&gt; &lt;span class='Statement'&gt;do&lt;/span&gt; |&lt;span class='Identifier'&gt;env&lt;/span&gt;, &lt;span class='Identifier'&gt;response&lt;/span&gt;|
      &lt;span class='lnr'&gt; 9 &lt;/span&gt;  env[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;PATH_INFO&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;].include?(&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;foo&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;)
      &lt;span class='lnr'&gt;10 &lt;/span&gt;&lt;span class='Statement'&gt;end&lt;/span&gt;&lt;/pre&gt;
      &lt;p&gt;&lt;a href='http://github.com/remi/rack-staticifier' class='center'&gt;http://github.com/remi/rack-staticifier&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Staticify - static caching for Ruby web applications</title>
    <link href="http://remi.org/2009/06/14/staticify.html" />
    <updated>2009-06-14T00:00:00-07:00</updated>
    <id>http://remi.org//2009/06/14/staticify.html</id>
    <content type="html">
      &lt;p&gt;After the &lt;a href='http://devfu.com'&gt;Dev Fu!&lt;/a&gt; site was launched, one of the first responses the site received from &lt;a href='http://twitter.com'&gt;Twitter&lt;/a&gt; was from fellow Phoenix Rubyist &lt;a href='http://jamesbritt.com'&gt;James Britt&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://twitter.com/jamesbritt/status/1928272835' class='snippet'&gt;&lt;img src='/images/staticify/tweet1.png' alt='Tweet from James Britt' /&gt;&lt;/a&gt; &lt;a href='http://twitter.com/jamesbritt/status/1928300706' class='snippet'&gt;&lt;img src='/images/staticify/tweet2.png' alt='Tweet from James Britt' /&gt;&lt;/a&gt; &lt;a href='http://twitter.com/jamesbritt/status/1928562670' class='snippet'&gt;&lt;img src='/images/staticify/tweet3.png' alt='Tweet from James Britt' /&gt;&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://jamesbritt.com'&gt;James&lt;/a&gt; makes some really interesting and valid points.&lt;/p&gt;
      
      &lt;p&gt;We chose &lt;a href='http://wordpress.org'&gt;Wordpress&lt;/a&gt; for &lt;a href='http://devfu.com'&gt;Dev Fu&lt;/a&gt; because there are bagillions of free &lt;a href='http://wordpress.org'&gt;Wordpress&lt;/a&gt; templates available online and we wanted to use one to get the site up and running quickly.&lt;/p&gt;
      
      &lt;p&gt;That said, I&amp;#8217;m not personally a big fan of &lt;a href='http://wordpress.org'&gt;WordPress&lt;/a&gt;. Atleast not for my personal sites.&lt;/p&gt;
      
      &lt;p&gt;As &lt;a href='http://jamesbritt.com'&gt;James&lt;/a&gt; pointed out, there are a number of Ruby-based tools for making static websites:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://jekyllrb.com'&gt;Jekyll&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://webby.rubyforge.org'&gt;Webby&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://staticmatic.rubyforge.org'&gt;StaticMatic&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://webgen.rubyforge.org'&gt;webgen&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;Up until yesterday, &lt;a href='/'&gt;remi.org&lt;/a&gt; was running on &lt;a href='http://jekyllrb.com'&gt;Jekyll&lt;/a&gt; and I&amp;#8217;ve used &lt;a href='http://staticmatic.rubyforge.org'&gt;StaticMatic&lt;/a&gt; for client sites before.&lt;/p&gt;
      
      &lt;p&gt;My problem with these tools is that they all require you to learn their framework. They all have their own ways for how you&amp;#8217;re supposed to organize your views and static assets. Some use different templating languages. Some have special ways to manage navigation. And more.&lt;/p&gt;
      
      &lt;p&gt;I love the idea of generating static HTML sites in Ruby, but I like to code my sites myself. I have my own preferences and ways I want to keep things laid out. Some of these tools are overkill for what I want. Others have to be hacked to get them to work the way I want them to.&lt;/p&gt;
      
      &lt;p&gt;So &amp;#8230; I made &lt;a href='http://github.com/remi/staticify'&gt;Staticify&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/remi/staticify'&gt;Staticify&lt;/a&gt; isn&amp;#8217;t a framework. It does nothing more than staticly cache URLs for you from any Ruby web framework, eg. &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; or &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/remi/staticify' class='center'&gt;http://github.com/remi/staticify&lt;/a&gt;&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>FollowLists: a better way to #FollowFriday?</title>
    <link href="http://remi.org/2009/04/24/followlists-a-better-way-to-followfriday.html" />
    <updated>2009-04-24T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/24/followlists-a-better-way-to-followfriday.html</id>
    <content type="html">
      &lt;p&gt;&lt;a href='http://search.twitter.com/search?q=%23followfriday'&gt;#FollowFriday&lt;/a&gt; is a neat use of a #hashtag to share the names of good tweeps to follow with your fellow tweeps.&lt;/p&gt;
      
      &lt;p&gt;That said, lately my timeline has looked more like this on Fridays &amp;#8230;&lt;/p&gt;
      
      &lt;p&gt;&lt;img src='/images/followfriday-spam.png' alt='Lots of #FollowFriday tweets' /&gt;&lt;/p&gt;
      
      &lt;p&gt;&amp;#8230; and that&amp;#8217;s more like spam!&lt;/p&gt;
      
      &lt;p&gt;What we really need is a way to create and manage lists of twitter users and then share those lists with others.&lt;/p&gt;
      
      &lt;p&gt;Enter &lt;a href='http://followlists.com'&gt;FollowLists&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://followlists.com'&gt;FollowLists&lt;/a&gt; is basically like &lt;a href='http://tinyurl.com'&gt;TinyURL&lt;/a&gt;, but for sharing tweeps instead of websites :)&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Deploying Ruby Web Applications to Heroku</title>
    <link href="http://remi.org/2009/04/23/deploying-rails-and-rack-applications-to-heroku.html" />
    <updated>2009-04-23T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/23/deploying-rails-and-rack-applications-to-heroku.html</id>
    <content type="html">
      &lt;p&gt;Tonight, at the &lt;a href='http://phoenixandroid.com'&gt;Phoenix Android&lt;/a&gt; meeting, someone asked if I knew any good Ruby / Rails web hosts. Something easy for someone who&amp;#8217;s just learning Rails and wants to be able to essentially copy/paste their code to a server and have it &amp;#8220;just work.&amp;#8221;&lt;/p&gt;
      
      &lt;p&gt;The first (and only) service that came to mind was: &lt;a href='http://heroku.com'&gt;Heroku&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://heroku.com'&gt;Heroku&lt;/a&gt; is a sweet Ruby web application host that makes it &lt;em&gt;ridiculously&lt;/em&gt; easy to host your applications. Basically, you can take any existing Ruby / Rails web application you have and git push it to heroku &amp;#8230; and it gets automagically deployed. That&amp;#8217;s &lt;strong&gt;it&lt;/strong&gt;.&lt;/p&gt;
      
      &lt;p&gt;Up until recently (maybe even today?), &lt;a href='http://heroku.com'&gt;Heroku&lt;/a&gt; was in Beta and 100% free. It looks like they&amp;#8217;ve finally released some &lt;a href='http://heroku.com/pricing'&gt;pricing information&lt;/a&gt; but there is still a free plan so &lt;a href='http://heroku.com'&gt;Heroku&lt;/a&gt; is still a great choice for quickly and easily deploying a Ruby web app.&lt;/p&gt;
      
      &lt;p&gt;Anyway, that&amp;#8217;s all. I have a bit of a head cold so I sound a little funny and I&amp;#8217;m doing 100 times more &amp;#8220;ummmm&amp;#8221; than usual &amp;#8230; but, otherwise, I hope folks will find this useful. In the first 5 minutes, we create &lt;em&gt;AND&lt;/em&gt; deploy and Rails application :D&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>How I Record My Screencasts</title>
    <link href="http://remi.org/2009/04/16/how-i-record-my-screencasts.html" />
    <updated>2009-04-16T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/16/how-i-record-my-screencasts.html</id>
    <content type="html">
      &lt;p&gt;Someone recently asked me how I record my screencasts. Instead of answering him directly, I figured I would make a post to let everyone know :)&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='/images/screencasting-screenshot.png'&gt;&lt;img src='/images/screencasting-screenshot.png' alt='Screenshot of my Screencasting Setup' style='width: 100%;' /&gt;&lt;/a&gt;&lt;/p&gt;
      
      &lt;h2 id='my_setup'&gt;My Setup&lt;/h2&gt;
      
      &lt;p&gt;My screencasting setup is relatively simple, I use:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://recordmydesktop.sourceforge.net'&gt;recordMyDesktop&lt;/a&gt; for recording the screen and audio capture to an &lt;a href='http://en.wikipedia.org/wiki/Ogg'&gt;ogg&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;a cheap &lt;a href='http://www.logitech.com/index.cfm/webcam_communications/internet_headsets_phones/devices/3622&amp;amp;cl=US,EN'&gt;USB headset&lt;/a&gt; (which I bought for using &lt;a href='http://skype.com'&gt;Skype&lt;/a&gt;) for the audio capture&lt;/li&gt;
      
      &lt;li&gt;a VM instead of my actual local desktop (currently using &lt;a href='http://virtualbox.org'&gt;VirtualBox&lt;/a&gt; but I&amp;#8217;ve used &lt;a href='http://www.vmware.com/products/server/'&gt;VMware Server&lt;/a&gt; too)&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;I don&amp;#8217;t record my local desktop because:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;It&amp;#8217;s not optimized for a smaller resolution, eg. 800x600 (which I currently record at)&lt;/li&gt;
      
      &lt;li&gt;I can guarantee its state. It&amp;#8217;s very easy to screencast then revert the VM back to an old state&lt;/li&gt;
      
      &lt;li&gt;Easier to not accidentally record private personal / client projects and whatnot&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;h2 id='recording_software'&gt;Recording Software&lt;/h2&gt;
      
      &lt;p&gt;Way back when, I used to use &lt;a href='http://www.unixuser.org/~euske/vnc2swf/'&gt;vnc2swf&lt;/a&gt; for screencasting. It&amp;#8217;s &lt;em&gt;awesome&lt;/em&gt; for making a quick and dirty screencast because, when you&amp;#8217;re done, it&amp;#8217;s ready to view online. It also works very well, in my experience, on older computers (&lt;a href='http://recordmydesktop.sourceforge.net'&gt;recordMyDesktop&lt;/a&gt; dropped too many frames to be usable on &lt;a href='http://www.google.com/search?q=dell+inspiron+8200'&gt;my last laptop&lt;/a&gt;). It has a few problems though &amp;#8230; it doesn&amp;#8217;t work well if you&amp;#8217;re using &lt;a href='http://www.compiz-fusion.org'&gt;Compiz&lt;/a&gt; and converting from the generated swf to other formats is &lt;em&gt;really&lt;/em&gt; &lt;strong&gt;insanely&lt;/strong&gt; difficult and CPU / hard drive intensive.&lt;/p&gt;
      
      &lt;p&gt;Once I got my &lt;a href='http://www.dell.com/content/products/productdetails.aspx/xpsnb_m1330?c=us&amp;amp;l=en&amp;amp;s=dhs&amp;amp;cs=19'&gt;new laptop&lt;/a&gt; (from this decade :P), I discovered that &lt;a href='http://recordmydesktop.sourceforge.net'&gt;recordMyDesktop&lt;/a&gt; runs great on it, so I switched. I also like &lt;a href='http://recordmydesktop.sourceforge.net'&gt;recordMyDesktop&lt;/a&gt; because &lt;a href='http://en.wikipedia.org/wiki/Ogg'&gt;ogg&lt;/a&gt;&amp;#8217;s are pretty easy to convert from and conversions look pretty good!&lt;/p&gt;
      
      &lt;p&gt;My favorite thing about my setup is that I created keyboard shortcuts that run &lt;a href='http://github.com/remi/home/blob/43203289aa3d13af3be7d564e7503849f38475a9/bin/record-vm-screencast'&gt;scripts&lt;/a&gt; which start &amp;amp; stop recording so I never have to worry about booting up apps or anything. I just press a combination of keys and the recording starts. It even finds the VM on my desktop and draws a black box around it so I know that it&amp;#8217;s recording the right part of the screen :)&lt;/p&gt;
      
      &lt;h2 id='conversion__web_hosting'&gt;Conversion &amp;amp; Web Hosting&lt;/h2&gt;
      
      &lt;p&gt;The thing that took the longest with my screencasting setup was getting video conversions working just right &amp;#8230; and I&amp;#8217;m pretty happy with the way they&amp;#8217;re currently working. I have a &lt;a href='http://github.com/remi/home/tree/43203289aa3d13af3be7d564e7503849f38475a9/bin'&gt;set of scripts&lt;/a&gt; for converting a video to an &lt;a href='http://en.wikipedia.org/wiki/X264'&gt;x264&lt;/a&gt; encoded &lt;a href='http://en.wikipedia.org/wiki/Mp4'&gt;mp4&lt;/a&gt; or to a &lt;a href='http://en.wikipedia.org/wiki/Xvid'&gt;xvid&lt;/a&gt; encoded &lt;a href='http://en.wikipedia.org/wiki/Audio_Video_Interleave'&gt;avi&lt;/a&gt;, as well as a &lt;a href='http://github.com/remi/home/blob/43203289aa3d13af3be7d564e7503849f38475a9/bin/ogg2png'&gt;script for grabbing the first frame of the video&lt;/a&gt; to use as a thumbnail. I actually don&amp;#8217;t use these scripts manually anymore, but getting them working the way I wanted to took a bit of tweaking.&lt;/p&gt;
      
      &lt;p&gt;Once I finish recording a screencast and I&amp;#8217;m ready to convert it and deploy it online, I run &lt;a href='http://github.com/remi/home/blob/43203289aa3d13af3be7d564e7503849f38475a9/bin/ogg2deploy'&gt;a script&lt;/a&gt; that does all of the conversions then uploads all of them to &lt;a href='https://s3.amazonaws.com'&gt;Amazon S3&lt;/a&gt;.&lt;/p&gt;
      
      &lt;h2 id='thats_it'&gt;That&amp;#8217;s It&lt;/h2&gt;
      
      &lt;p&gt;That&amp;#8217;s pretty much it. I created a little macro-type thing on my blog that embeds screencasts in a blog post if I just give it a header like &lt;code&gt;video: rack-middleware&lt;/code&gt;. Sometime soon-ish, I plan on redesigning my blog and specifically creating it with screencasts in mind. I didn&amp;#8217;t know I would be screencasting as much as I am when I created my current blog.&lt;/p&gt;
      
      &lt;p&gt;Hope someone finds this useful! Enjoy.&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Ruby on Windows: Cygwin, Git, Rvxt, and more</title>
    <link href="http://remi.org/2009/04/15/ruby-on-windows-cygwin-git-rvxt-and-more.html" />
    <updated>2009-04-15T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/15/ruby-on-windows-cygwin-git-rvxt-and-more.html</id>
    <content type="html">
      &lt;p&gt;In my &lt;a href='/2009/04/14/ruby-on-windows-quick-and-dirty.html'&gt;previous screencast&lt;/a&gt;, I showed you how you can get up and running &lt;em&gt;quickly&lt;/em&gt; with &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; on Windows.&lt;/p&gt;
      
      &lt;p&gt;In this screencast, I show you how I think you can get up and running &lt;em&gt;correctly&lt;/em&gt; with &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; on Windows.&lt;/p&gt;
      
      &lt;p&gt;With &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; development, it&amp;#8217;s generally assumed that the developer is on some kindof a unix-style environment. This generally means developing on:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;Apple OS X&lt;/li&gt;
      
      &lt;li&gt;Linux&lt;/li&gt;
      
      &lt;li&gt;Windows Cygwin&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;Windows has some seriously shortcomings as a development platform. The &lt;a href='http://en.wikipedia.org/wiki/Cmd.exe'&gt;cmd.exe&lt;/a&gt; shell is not &lt;em&gt;nearly&lt;/em&gt; as powerful as the shells that are typically used by unix-y systems, eg. &lt;a href='http://en.wikipedia.org/wiki/Bash'&gt;BASH&lt;/a&gt;. Also, Windows doesn&amp;#8217;t come out-of-the-box with the tools needed for compiling code nor does it come with a package manager or something to make it easy to install these tools and their dependencies.&lt;/p&gt;
      
      &lt;p&gt;Enter &lt;a href='http://www.cygwin.com'&gt;Cygwin&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://www.cygwin.com'&gt;Cygwin&lt;/a&gt; provides a Linux-like environment for Windows. It can give you all of the commands that developers generally assume you have like:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;code&gt;ssh&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;code&gt;make&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;code&gt;gcc&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;code&gt;git&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;and much, much, much more&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;In this screencast, I show you &amp;#8230;&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;how to download &amp;amp; install &lt;a href='http://www.cygwin.com'&gt;Cygwin&lt;/a&gt; and install some packages, eg. &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; and &lt;a href='http://git-scm.org'&gt;Git&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;how to download &amp;amp; install &lt;a href='http://rubygems.org'&gt;RubyGems&lt;/a&gt; and install some gems, eg. &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; and &lt;span&gt;Rails&lt;/span&gt;&lt;/li&gt;
      
      &lt;li&gt;how to generate an ssh key, associate it with a &lt;a href='http://github.com'&gt;GitHub&lt;/a&gt; account, clone a &lt;a href='http://github.com'&gt;GitHub&lt;/a&gt; project, &amp;amp; update it&lt;/li&gt;
      
      &lt;li&gt;BONUS: how to update &lt;a href='http://www.cygwin.com'&gt;Cygwin&lt;/a&gt; to use the &lt;a href='http://en.wikipedia.org/wiki/Rxvt'&gt;Rxvt&lt;/a&gt; terminal (instead of &lt;a href='http://www.cygwin.com'&gt;Cygwin&lt;/a&gt; running in &lt;a href='http://en.wikipedia.org/wiki/Cmd.exe'&gt;cmd.exe&lt;/a&gt;)&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; In the screencast, I clone a &lt;a href='http://git-scm.org'&gt;git&lt;/a&gt; repository from &lt;a href='http://github.com'&gt;GitHub&lt;/a&gt; &lt;em&gt;before&lt;/em&gt; showing you how to associate your &lt;a href='http://git-scm.org'&gt;git&lt;/a&gt; with your &lt;a href='http://github.com'&gt;github&lt;/a&gt; account &amp;#8230; keep watching. I realize this mistake later in the screencast and show you how to do that.&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Ruby on Windows: Quick and Dirty</title>
    <link href="http://remi.org/2009/04/14/ruby-on-windows-quick-and-dirty.html" />
    <updated>2009-04-14T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/14/ruby-on-windows-quick-and-dirty.html</id>
    <content type="html">
      &lt;p&gt;I&amp;#8217;ve coded up some &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; web applications, eg. little &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; apps / prototypes, for some developer friends of mine who are on Windows and haven&amp;#8217;t used &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; before.&lt;/p&gt;
      
      &lt;p&gt;I wanted to show how easy it is to get up and running with &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; &lt;em&gt;quickly&lt;/em&gt; on Windows.&lt;/p&gt;
      
      &lt;p&gt;NOTE: this isn&amp;#8217;t the prefered way to do &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; development on Windows, in my opinion. Instead, I personally think you should use &lt;a href='http://www.cygwin.com'&gt;Cygwin&lt;/a&gt;. But, if you just want to get a &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; app up and running and you won&amp;#8217;t be doing too much development, this should work fine for you.&lt;/p&gt;
      
      &lt;p&gt;In this video I show you how to:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://www.ruby-lang.org/en/downloads/'&gt;Download&lt;/a&gt; and Install &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; on Windows&lt;/li&gt;
      
      &lt;li&gt;Install some &lt;a href='http://rubygems.org'&gt;RubyGems&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;Create and run a simple &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; application&lt;/li&gt;
      
      &lt;li&gt;Download a &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; application from &lt;a href='http://github.com'&gt;GitHub&lt;/a&gt; and run it&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;I &lt;em&gt;don&amp;#8217;t&lt;/em&gt; show you how to get &lt;a href='http://git-scm.org'&gt;git&lt;/a&gt; up and running on Windows, because I prefer &lt;a href='http://www.cygwin.com'&gt;Cygwin&lt;/a&gt; for doing that.&lt;/p&gt;
      
      &lt;p&gt;If you want to see howto get up and running with &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt;, &lt;a href='http://rubygems.org'&gt;RubyGems&lt;/a&gt;, &lt;a href='http://git-scm.org'&gt;git&lt;/a&gt; and more on Windows, checkout out my next screencast: &lt;a href='/2009/04/15/ruby-on-windows-cygwin-git-rvxt-and-more.html'&gt;Ruby on Windows: Cygwin, Git, Rxvt, and more&lt;/a&gt;&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>RubyFlow is protecting you from great articles!</title>
    <link href="http://remi.org/2009/04/06/a-better-rubyflow-rss-feed.html" />
    <updated>2009-04-06T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/06/a-better-rubyflow-rss-feed.html</id>
    <content type="html">
      &lt;p&gt;Hey everyone, this is a really short post! Sorry, no screencast today &amp;#8230; hopefully in the next day or 2 :)&lt;/p&gt;
      
      &lt;p&gt;Anyway, do you read &lt;a href='http://rubyflow.com'&gt;RubyFlow&lt;/a&gt;? &lt;a href='http://rubyflow.com'&gt;RubyFlow&lt;/a&gt; rocks and lots of great articles are posted to it daily &amp;#8230; &lt;em&gt;BUT&lt;/em&gt; you&amp;#8217;re not getting all of these updates if you follow its &lt;a href='http://feeds.feedburner.com/Rubyflow'&gt;official RSS Feed&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;Some days, there might be 5 or more posts to &lt;a href='http://rubyflow.com'&gt;RubyFlow&lt;/a&gt; but only 1 or 2 of them show up on the &lt;a href='http://feeds.feedburner.com/Rubyflow'&gt;official RSS Feed&lt;/a&gt; because you need to be &amp;#8220;approved&amp;#8221; for your article to show up in the feed.&lt;/p&gt;
      
      &lt;p&gt;If, like me, you want to see &lt;em&gt;everyone&amp;#8217;s&lt;/em&gt; &lt;a href='http://rubyflow.com'&gt;RubyFlow&lt;/a&gt; posts, here&amp;#8217;s a feed that show&amp;#8217;s &lt;em&gt;ALL&lt;/em&gt; &lt;a href='http://rubyflow.com'&gt;RubyFlow&lt;/a&gt; posts:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://feed43.com/rubyflowraw.xml'&gt;http://feed43.com/rubyflowraw.xml&lt;/a&gt; (&lt;em&gt;caution: may contain spam, altho i haven&amp;#8217;t seen any yet&lt;/em&gt;)&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;( &lt;em&gt;by the way, &lt;a href='http://feed43.com'&gt;Feed43&lt;/a&gt; looks pretty cool &amp;#8230; I didn&amp;#8217;t set this up, though. This is a URL &lt;a href='http://peterc.org'&gt;Peter Cooper&lt;/a&gt; gave me&lt;/em&gt; )&lt;/p&gt;
      
      &lt;p&gt;Enjoy!&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;PS.&lt;/strong&gt; While I&amp;#8217;m on the topic of good feeds for &lt;a href='http://www.ruby-lang.org'&gt;Ruby&lt;/a&gt; news, here are a few of the feeds I follow &amp;#8230; feel free to comment with some of your own recommendations :)&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://rubyflow.com'&gt;RubyFlow&lt;/a&gt; (&lt;a href='http://feed43.com/rubyflowraw.xml'&gt;feed&lt;/a&gt;)&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://www.rubyinside.com'&gt;Ruby Inside&lt;/a&gt; (&lt;a href='http://feedproxy.google.com/RubyInside'&gt;feed&lt;/a&gt;)&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://railstips.org'&gt;Rails Tips&lt;/a&gt; (&lt;a href='http://feeds.feedburner.com/railstips'&gt;feed&lt;/a&gt;)&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://weblog.rubyonrails.org'&gt;Riding Rails&lt;/a&gt; (&lt;a href='http://feeds.feedburner.com/RidingRails'&gt;feed&lt;/a&gt;)&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://www.oreillynet.com/ruby'&gt;O&amp;#8217;Reilly Ruby&lt;/a&gt; (&lt;a href='http://www.oreillynet.com/ruby/blog/index.xml'&gt;feed&lt;/a&gt;)&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;Those are my main Ruby feeds &amp;#8230; any additional recommendations?&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Building your own Sinatra clone: Part IV</title>
    <link href="http://remi.org/2009/04/03/building-your-own-sinatra-clone-part-4.html" />
    <updated>2009-04-03T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/03/building-your-own-sinatra-clone-part-4.html</id>
    <content type="html">
      &lt;p&gt;See &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html'&gt;Part I&lt;/a&gt; for an introduction and a &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html#episode_guide'&gt;full listing of all episodes in the series&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;In this screencast:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;we discover that our &lt;code&gt;helpers&lt;/code&gt; are shared between all applications (bad!), so we make them unique to each application&lt;/li&gt;
      
      &lt;li&gt;we add support to &lt;code&gt;use&lt;/code&gt; &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; middleware&lt;/li&gt;
      
      &lt;li&gt;we review some updates that I made to the code, offline&lt;/li&gt;
      &lt;/ul&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Intro to Sinatra</title>
    <link href="http://remi.org/2009/04/02/intro-to-sinatra.html" />
    <updated>2009-04-02T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/02/intro-to-sinatra.html</id>
    <content type="html">
      &lt;p&gt;I&amp;#8217;ve been recording my screencast mini-series on &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html'&gt;Building your own Sinatra clone&lt;/a&gt; and I realized &amp;#8230; some people out there still haven&amp;#8217;t used &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;!&lt;/p&gt;
      
      &lt;p&gt;Hey you! Ruby developer who hasn&amp;#8217;t used &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;! This is for you :)&lt;/p&gt;
      
      &lt;p&gt;This should get you up and running with &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;, if you haven&amp;#8217;t used it before. If you &lt;em&gt;have&lt;/em&gt; used &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; before, this might not be the screencast for you. Although, I basically do a total braindump of all of the &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; features that I&amp;#8217;m aware of, so &amp;#8230; you &lt;em&gt;might&lt;/em&gt; learn something new.&lt;/p&gt;
      
      &lt;p&gt;If you &lt;em&gt;have&lt;/em&gt; used &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; before and you want to learn more, I recommend checking the &lt;a href='http://www.sinatrarb.com/documentation.html'&gt;Sinatra Documentation&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;If you have &lt;em&gt;not&lt;/em&gt; used &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; before, then check this. Even if you only watch the first 5 minutes, you&amp;#8217;ll have enough to get you up and running in no time!&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Building your own Sinatra clone: Part III</title>
    <link href="http://remi.org/2009/04/01/building-your-own-sinatra-clone-part-3.html" />
    <updated>2009-04-01T00:00:00-07:00</updated>
    <id>http://remi.org//2009/04/01/building-your-own-sinatra-clone-part-3.html</id>
    <content type="html">
      &lt;p&gt;See &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html'&gt;Part I&lt;/a&gt; for an introduction and a &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html#episode_guide'&gt;full listing of all episodes in the series&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;In this screencast, we start adding helper methods like &lt;code&gt;#request&lt;/code&gt;, &lt;code&gt;#response&lt;/code&gt;, and &lt;code&gt;#params&lt;/code&gt;. We also create a &lt;code&gt;Responder&lt;/code&gt; to that the main application and response blocks (eg. &lt;code&gt;get(){ ... }&lt;/code&gt;) are evaluated in different contexts.&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Building your own Sinatra clone: Part II</title>
    <link href="http://remi.org/2009/03/31/building-your-own-sinatra-clone-part-2.html" />
    <updated>2009-03-31T00:00:00-07:00</updated>
    <id>http://remi.org//2009/03/31/building-your-own-sinatra-clone-part-2.html</id>
    <content type="html">
      &lt;p&gt;See &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html'&gt;Part I&lt;/a&gt; for an introduction and a &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html#episode_guide'&gt;full listing of all episodes in the series&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;In this screencast, we test-drive the creation a new &lt;a href='http://github.com/remi/sinatra-clone'&gt;SinatraClone&lt;/a&gt; library.&lt;/p&gt;
      
      &lt;p&gt;We re-implement most of the features prototyped in &lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html'&gt;Part I&lt;/a&gt;, but now using a real, organized library.&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Building your own Sinatra clone: Part I</title>
    <link href="http://remi.org/2009/03/30/building-your-own-sinatra-clone-part-1.html" />
    <updated>2009-03-30T00:00:00-07:00</updated>
    <id>http://remi.org//2009/03/30/building-your-own-sinatra-clone-part-1.html</id>
    <content type="html">
      &lt;p&gt;Have you ever wanted to build your own web framework? Do you want to learn howto create &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; applications?&lt;/p&gt;
      
      &lt;p&gt;The first time I found out about &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;, I had already created my own &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;-based web framework and I wasn&amp;#8217;t particularly interested in &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;. It&amp;#8217;s really just a pretty DSL for &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;. Those days, I used &lt;a href='http://github.com/why/camping'&gt;Camping&lt;/a&gt; for micro web applications. Nowadays, I use &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; &lt;em&gt;all the time&lt;/em&gt; &amp;#8230; it rocks! And, as &lt;a href='http://twitter.com/wycats/status/1395344853'&gt;Yehuda recently pointed out&lt;/a&gt;, &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; is getting lots of hype lately. And so is &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;!&lt;/p&gt;
      
      &lt;p&gt;So, what better time to learn how to use &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; to implement the &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; DSL, yourself!&lt;/p&gt;
      
      &lt;h2 id='episode_guide'&gt;Episode Guide&lt;/h2&gt;
      &lt;br /&gt;
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='/2009/03/30/building-your-own-sinatra-clone-part-1.html'&gt;Part I&lt;/a&gt;: Simple proof of concept script, &lt;code&gt;at_exit&lt;/code&gt;, &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; review, simple routing&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='/2009/03/31/building-your-own-sinatra-clone-part-2.html'&gt;Part II&lt;/a&gt;: Test-drive the creation of our new, organized &lt;a href='http://github.com/remi/sinatra-clone'&gt;SinatraClone&lt;/a&gt; library&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='/2009/04/01/building-your-own-sinatra-clone-part-3.html'&gt;Part III&lt;/a&gt;: Creating &lt;code&gt;#request&lt;/code&gt;, &lt;code&gt;#response&lt;/code&gt;, &lt;code&gt;#params&lt;/code&gt; helpers and the &lt;code&gt;Responder&lt;/code&gt; class&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='/2009/04/03/building-your-own-sinatra-clone-part-4.html'&gt;Part IV&lt;/a&gt;: Make helpers unique to each app, add &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; middleware support, review offline updates&lt;/li&gt;
      
      &lt;li&gt;Part V: TBA - I hope to create more someday, I have lots of implementation ideas :)&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;h2 id='notes'&gt;Notes&lt;/h2&gt;
      
      &lt;p&gt;Once this series is complete, we should end up with a gem that, ideally, can be used as a drop-in replacement for &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;. But does that mean you should use it? This series of screencasts is created for &lt;em&gt;learning&lt;/em&gt; &amp;#8230; specifically to show people how easy it is to write libraries like &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt;. That said &amp;#8230; I don&amp;#8217;t expect &lt;em&gt;anyone&lt;/em&gt; to actually &lt;em&gt;use&lt;/em&gt; this library, once it&amp;#8217;s been created!&lt;/p&gt;
      
      &lt;p&gt;&lt;em&gt;Also&lt;/em&gt;, I &lt;strong&gt;never&lt;/strong&gt; look at the source code for &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; for this series - where would be the fun in that? Everything we implement is fresh (or totally rotten). Reinventing the wheel isn&amp;#8217;t very practical &lt;em&gt;unless&lt;/em&gt; you&amp;#8217;re trying to learn howto invent a wheel, yourself.&lt;/p&gt;
      
      &lt;p&gt;Enjoy!&lt;/p&gt;
      &lt;br /&gt;
    </content>
  </entry>
<entry>
    <title>Rack: Part III =&gt; Middleware</title>
    <link href="http://remi.org/2009/02/28/rack-part-3-middleware.html" />
    <updated>2009-02-28T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/28/rack-part-3-middleware.html</id>
    <content type="html">
      &lt;p&gt;Part 3 in my screencast mini-series on Rack &amp;#8230; checkout parts 1 and 2:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='/2009/02/19/rack-basics.html'&gt;Part I: Rack Basics&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='/2009/02/24/rack-part-2.html'&gt;Part II: Rackup files, Rack::Request, Rack::Response, and more&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;In Part 3, we cover:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;What is Rack middleware?&lt;/li&gt;
      
      &lt;li&gt;How to write your own Rack middleware&lt;/li&gt;
      
      &lt;li&gt;How to use your Rack middleware from any &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; app, from the &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Builder.html'&gt;Rackup&lt;/a&gt; file&lt;/li&gt;
      
      &lt;li&gt;How to use your Rack middleware from &lt;a href='http://www.sinatrarb.com'&gt;Sinatra&lt;/a&gt; and &lt;a href='http://weblog.rubyonrails.org/2009/2/1/rails-2-3-0-rc1-templates-engines-rack-metal-much-more'&gt;Rails 2.3&lt;/a&gt; apps using their built-in middleware support&lt;br /&gt;&amp;#160;&lt;/li&gt;
      &lt;/ul&gt;
    </content>
  </entry>
<entry>
    <title>Rack: Part II</title>
    <link href="http://remi.org/2009/02/24/rack-part-2.html" />
    <updated>2009-02-24T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/24/rack-part-2.html</id>
    <content type="html">
      &lt;p&gt;This is a follow up to my first &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; screencast, &lt;a href='/2009/02/19/rack-basics.html'&gt;Rack Basics&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;In this screencast, we cover a bit more of the basics. Instead of playing around in an &lt;a href='http://en.wikipedia.org/wiki/Interactive_Ruby_Shell'&gt;IRB&lt;/a&gt; shell, we create an executable &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; application using a &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Builder.html'&gt;Rackup&lt;/a&gt; file (the conventional way to run &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; applications).&lt;/p&gt;
      
      &lt;p&gt;We use some &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; middleware and learn howto to read &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Request.html'&gt;Rack Requests&lt;/a&gt; a bit easier and howto generate &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Response.html'&gt;Rack Responses&lt;/a&gt; a bit easier. We also catch &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/ShowExceptions.html'&gt;some exceptions&lt;/a&gt; and get our &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; apps &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Reloader.html'&gt;reloading&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;I hope you enjoy this screencast. Next up in the Rack screencast mini-series: &lt;a href='/2009/02/28/rack-part-3-middleware.html'&gt;Rack middleware&lt;/a&gt;! You&amp;#8217;ll learn how middleware works, how to create your own, and and examples of how to use lots of pre-existing &lt;a href='/2009/02/28/rack-part-3-middleware.html'&gt;Rack middleware&lt;/a&gt;.&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Camping Screencast</title>
    <link href="http://remi.org/2009/02/23/camping-screencast.html" />
    <updated>2009-02-23T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/23/camping-screencast.html</id>
    <content type="html">
      &lt;p&gt;This is a screencast I made that covers nearly everything about creating &lt;span&gt;Camping&lt;/span&gt; applications, way back when. I figured I should actually post this incase it&amp;#8217;s helpful to someone.&lt;/p&gt;
      
      &lt;p&gt;Note: I personally believe that &lt;span&gt;Sinatra&lt;/span&gt; is the &amp;#8220;modern &lt;span&gt;Camping&lt;/span&gt;.&amp;#8221; &lt;span&gt;Camping&lt;/span&gt; was created before the days of &lt;span&gt;Rack&lt;/span&gt;. &lt;span&gt;Sinatra&lt;/span&gt;, on the other hand, is a relatively thin DSL that sits on top of &lt;span&gt;Rack&lt;/span&gt;. There&amp;#8217;s been some interest in creating &amp;#8217;&lt;span&gt;Camping&lt;/span&gt; 2.0&amp;#8217; based on &lt;span&gt;Rack&lt;/span&gt;, but I don&amp;#8217;t know how far along that project is. &lt;span&gt;Sinatra&lt;/span&gt; is the current Ruby micro web framework of choice!&lt;/p&gt;
      
      &lt;p&gt;These days, if you need something easier than &amp;#8220;native &lt;span&gt;Rack&lt;/span&gt;&amp;#8221; but less heavy than &lt;span&gt;Rails&lt;/span&gt; / &lt;span&gt;Merb&lt;/span&gt; / etc &amp;#8230; try out &lt;span&gt;Sinatra&lt;/span&gt;!&lt;/p&gt;
      
      &lt;p&gt;Liquid error: This liquid context does not allow includes.&lt;/p&gt;
      &lt;object height='600' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' width='800' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0'&gt;
        &lt;param name='movie' value='http://remicasts.s3.amazonaws.com/camping.swf' /&gt;
        &lt;param name='play' value='true' /&gt;
        &lt;param name='loop' value='True' /&gt;
        &lt;param name='quality' value='low' /&gt;
        &lt;embed play='true' src='http://remicasts.s3.amazonaws.com/camping.swf' pluginspage='http://www.macromedia.com/go/getflashplayer' type='application/x-shockwave-flash' height='600' loop='True' quality='low' width='800'&gt;
        &lt;/embed&gt;
      &lt;/object&gt;&lt;script src='/javascripts/old-school-swf-player.js' type='text/javascript' /&gt;
    </content>
  </entry>
<entry>
    <title>Rack Basics</title>
    <link href="http://remi.org/2009/02/19/rack-basics.html" />
    <updated>2009-02-19T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/19/rack-basics.html</id>
    <content type="html">
      &lt;p&gt;If you&amp;#8217;re a &lt;a href='http://ruby-lang.org'&gt;Ruby&lt;/a&gt; programmer and you&amp;#8217;ve never directly used &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; before then this screencast is for you. This introduces you to the very basics of &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;If you&amp;#8217;ve used &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; before and / or you&amp;#8217;ve very comfortable with the basics, watch for some additional &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; screencasts coming from me. I hope to make a good mini-series of screencasts about &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; awesomeness.&lt;/p&gt;
      
      &lt;p&gt;I &lt;code&gt;&amp;lt;3&lt;/code&gt; &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;$ sudo gem install rack
      &lt;span class='lnr'&gt;2 &lt;/span&gt;$ irb&lt;/pre&gt;&lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;&amp;gt;&amp;gt; &lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;rubygems&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;2 &lt;/span&gt;&amp;gt;&amp;gt; &lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;rack&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;3 &lt;/span&gt;&amp;gt;&amp;gt; &lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;my_awesome_app&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;4 &lt;/span&gt;&amp;gt;&amp;gt; &lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Handler&lt;/span&gt;::&lt;span class='Type'&gt;SomeAwesomeServer&lt;/span&gt;.run my_awesome_app&lt;/pre&gt;
      &lt;p&gt;See also:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='/2009/02/24/rack-part-2.html'&gt;Part II: Rackup files, Rack::Request, Rack::Response, and more&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='/2009/02/28/rack-part-3-middleware.html'&gt;Part III: Rack middleware&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;&amp;#160;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Test Your ActiveResource API with ActiveRacksource</title>
    <link href="http://remi.org/2009/02/10/test-your-activeresource-api-with-activeracksource.html" />
    <updated>2009-02-10T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/10/test-your-activeresource-api-with-activeracksource.html</id>
    <content type="html">
      &lt;p&gt;Does your web application have an &lt;a href='http://api.rubyonrails.org/classes/ActiveResource/Base.html'&gt;ActiveResource&lt;/a&gt;-based API, or are you thinking of creating one?&lt;/p&gt;
      
      &lt;p&gt;Testing your API&amp;#8217;s client library can be a pain - it has to hit a real, running version of your application. &lt;a href='http://api.rubyonrails.org/classes/ActiveResource/Base.html'&gt;ActiveResource&lt;/a&gt; gives us a way to mock its HTTP calls, via &lt;a href='http://api.rubyonrails.com/classes/ActiveResource/HttpMock.html'&gt;HttpMock&lt;/a&gt; but it&amp;#8217;s a bit of a pain to use &amp;#8230; you have to manually mock out the responses for any and &lt;em&gt;every&lt;/em&gt; call you want to make!&lt;/p&gt;
      
      &lt;p&gt;If you already have a &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; (or &lt;a href='http://www.sinatrarb.com'&gt;Sinatra&lt;/a&gt; or any other &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;-based framework) application that you want to test, why can&amp;#8217;t you just tell &lt;a href='http://api.rubyonrails.org/classes/ActiveResource/Base.html'&gt;ActiveResource&lt;/a&gt; to hit your application when it makes requests? And do it in such a way that doesn&amp;#8217;t require running over a network.&lt;/p&gt;
      
      &lt;h2 id='introducing_activeracksource'&gt;Introducing ActiveRacksource&lt;/h2&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/openrain/active_racksource'&gt;&lt;code&gt;http://github.com/openrain/active_racksource&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/openrain/active_racksource'&gt;Active&lt;strong&gt;Rack&lt;/strong&gt;source&lt;/a&gt; solves this problem. It allows you to give &lt;a href='http://api.rubyonrails.org/classes/ActiveResource/Base.html'&gt;ActiveResource&lt;/a&gt; any &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; application which it&amp;#8217;ll use as a backend.&lt;/p&gt;
      
      &lt;p&gt;Short version:&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;&lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;my_active_resource_based_client_API&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;2 &lt;/span&gt;
      &lt;span class='lnr'&gt;3 &lt;/span&gt;&lt;span class='Type'&gt;MyAPI&lt;/span&gt;::&lt;span class='Type'&gt;Dog&lt;/span&gt;.find &lt;span class='Constant'&gt;:all&lt;/span&gt;  &lt;span class='Comment'&gt;# this will run over HTTP normally&lt;/span&gt;
      &lt;span class='lnr'&gt;4 &lt;/span&gt;
      &lt;span class='lnr'&gt;5 &lt;/span&gt;&lt;span class='PreProc'&gt;require&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;active_racksource&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;6 &lt;/span&gt;&lt;span class='Type'&gt;ActiveResource&lt;/span&gt;::&lt;span class='Type'&gt;Base&lt;/span&gt;.app = &lt;span class='Identifier'&gt;@my_rack_app&lt;/span&gt;
      &lt;span class='lnr'&gt;7 &lt;/span&gt;
      &lt;span class='lnr'&gt;8 &lt;/span&gt;&lt;span class='Type'&gt;MyAPI&lt;/span&gt;::&lt;span class='Type'&gt;Dog&lt;/span&gt;.find &lt;span class='Constant'&gt;:all&lt;/span&gt;  &lt;span class='Comment'&gt;# this will run against the Rack app now!&lt;/span&gt;&lt;/pre&gt;
      &lt;p&gt;Long version: watch the screencast!&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>AuxCodes on Rails</title>
    <link href="http://remi.org/2009/02/08/auxcodes-on-rails.html" />
    <updated>2009-02-08T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/08/auxcodes-on-rails.html</id>
    <content type="html">
      &lt;p&gt;A follow up to &lt;a href='/2009/02/07/introducing-auxcodes.html'&gt;Introducing AuxCodes&lt;/a&gt;, this part shows you howto use &lt;a href='http://github.com/remi/aux_codes'&gt;AuxCodes&lt;/a&gt; in your &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; applications.&lt;/p&gt;
      
      &lt;p&gt;This part introduces some of the basics of &lt;a href='http://github.com/remi/aux_codes'&gt;aux_codes&lt;/a&gt; for anyone who watches this and doesn&amp;#8217;t watch &lt;a href='/2009/02/07/introducing-auxcodes.html'&gt;Part I&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;Check this out if you&amp;#8217;re interested in a way to maintain enum-like data in your &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; database eg. tables that just map IDs to string values like &lt;code&gt;States&lt;/code&gt;, &lt;code&gt;Genders&lt;/code&gt;, &lt;code&gt;Colors&lt;/code&gt;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Introducing AuxCodes</title>
    <link href="http://remi.org/2009/02/07/introducing-auxcodes.html" />
    <updated>2009-02-07T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/07/introducing-auxcodes.html</id>
    <content type="html">
      &lt;p&gt;Does your &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; application have lots of little tables for keeping track of things like genders, states, colors or other enum-like data?&lt;/p&gt;
      
      &lt;p&gt;Way back when, when I was learning database development, a &lt;a href='http://www.corporatewebconsulting.net/menu/about_us/walt.php'&gt;mentor of mine&lt;/a&gt; showed me a technique that he liked to use to consolidate similar enum-esque database tables (tables with just an ID and a string).&lt;/p&gt;
      
      &lt;h2 id='introducing_auxcodes'&gt;Introducing AuxCodes&lt;/h2&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/remi/aux_codes'&gt;AuxCodes&lt;/a&gt; is an &lt;a href='http://api.rubyonrails.org/classes/ActiveRecord/Base.html'&gt;ActiveRecord&lt;/a&gt;-based &lt;a href='http://www.rubygems.org'&gt;gem&lt;/a&gt; that makes it easy to store enum-like data in your applications. It gives you &amp;#8230;&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;a way to maintain all of this data in a &lt;a href='http://www.yaml.org'&gt;YAML&lt;/a&gt; file&lt;/li&gt;
      
      &lt;li&gt;auto-generated &lt;a href='http://api.rubyonrails.org/classes/ActiveRecord/Base.html'&gt;ActiveRecord&lt;/a&gt; classes for these categories, eg. &lt;code&gt;Gender&lt;/code&gt; or &lt;code&gt;Color&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;a simple DSL for accessing your enum data, eg. &lt;code&gt;Gender.female&lt;/code&gt;&lt;/li&gt;
      
      &lt;li&gt;a way to store additional meta data for any of your categories&amp;#8217; codes, eg. &lt;code&gt;Gender.female.abbreviation&lt;/code&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;see &lt;a href='http://github.com/remi/aux_codes'&gt;http://github.com/remi/aux_codes&lt;/a&gt; or watch the screencast!&lt;/p&gt;
      
      &lt;p&gt;checkout &lt;a href='/2009/02/08/auxcodes-on-rails.html'&gt;AuxCodes on Rails&lt;/a&gt; for part II of the screencast &amp;amp; for howto use &lt;a href='http://github.com/remi/aux_codes'&gt;AuxCodes&lt;/a&gt; in your &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; applications.&lt;/p&gt;
      
      &lt;p&gt;&lt;em&gt;aux_codes inspired by &lt;a href='http://www.corporatewebconsulting.net/menu/about_us/walt.php'&gt;Walter Turner&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Scenarios: organizing arbitrary bits of code</title>
    <link href="http://remi.org/2009/02/03/scenarios-a-rubygem-for-organizing-arbitrary-snippets-of-ruby-code.html" />
    <updated>2009-02-03T00:00:00-07:00</updated>
    <id>http://remi.org//2009/02/03/scenarios-a-rubygem-for-organizing-arbitrary-snippets-of-ruby-code.html</id>
    <content type="html">
      &lt;p&gt;&lt;a href='http://github.com/openrain/scenarios'&gt;Scenarios&lt;/a&gt; is a little &lt;a href='http://www.rubygems.org'&gt;RubyGem&lt;/a&gt; for organizing arbitrary snippets of &lt;a href='http://ruby-lang.org'&gt;Ruby&lt;/a&gt; code.&lt;/p&gt;
      
      &lt;p&gt;We specifically use it to load up the development database with data. It&amp;#8217;s especially powerful in combination with a nice factory gem like &lt;a href='http://github.com/thoughtbot/factory_girl'&gt;Factory Girl&lt;/a&gt; / &lt;a href='http://github.com/flogic/object_daddy'&gt;Object Daddy&lt;/a&gt; or, for loading up the database with &lt;em&gt;lots&lt;/em&gt; of data, a data generation gem like &lt;a href='http://faker.rubyforge.org'&gt;Faker&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;To load up the development data with scenario(s) &amp;#8230;&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;$ rake scenarios&lt;span class='Constant'&gt;:load&lt;/span&gt; &lt;span class='Type'&gt;NAME&lt;/span&gt;=dependencies,create_lots_of_data&lt;/pre&gt;
      &lt;p&gt;It can also be useful to use scenarios from tests/specs&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt;1 &lt;/span&gt;describe &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;Home Page&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt; &lt;span class='Statement'&gt;do&lt;/span&gt;
      &lt;span class='lnr'&gt;2 &lt;/span&gt;
      &lt;span class='lnr'&gt;3 &lt;/span&gt;  scenarios &lt;span class='Constant'&gt;:dependencies&lt;/span&gt;, &lt;span class='Constant'&gt;:website_pages&lt;/span&gt;
      &lt;span class='lnr'&gt;4 &lt;/span&gt;
      &lt;span class='lnr'&gt;5 &lt;/span&gt;  it &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;should actually show something on the home page&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;6 &lt;/span&gt;
      &lt;span class='lnr'&gt;7 &lt;/span&gt;&lt;span class='Statement'&gt;end&lt;/span&gt;&lt;/pre&gt;
      &lt;p&gt;See &lt;a href='http://github.com/openrain/scenarios'&gt;http://github.com/openrain/scenarios&lt;/a&gt; or watch the screencast for more info.&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Introducing RackBox</title>
    <link href="http://remi.org/2009/01/29/introducing-rackbox_merb-esque-blackbox-testing-for-rack-and-rails-apps.html" />
    <updated>2009-01-29T00:00:00-07:00</updated>
    <id>http://remi.org//2009/01/29/introducing-rackbox_merb-esque-blackbox-testing-for-rack-and-rails-apps.html</id>
    <content type="html">
      &lt;p&gt;&lt;a href='http://github.com/remi/rackbox'&gt;RackBox&lt;/a&gt; is a new &lt;a href='http://www.rubygems.org'&gt;RubyGem&lt;/a&gt; that adds &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt;-esque &lt;a href='http://en.wikipedia.org/wiki/Black_box_testing'&gt;blackbox testing&lt;/a&gt; to &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; applications. Because it&amp;#8217;s based on &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;, &lt;a href='http://github.com/remi/rackbox'&gt;RackBox&lt;/a&gt; also works with most other Ruby web frameworks, eg. &lt;a href='http://github.com/why/camping'&gt;Camping&lt;/a&gt;, &lt;a href='http://sinatra.github.com'&gt;Sinatra&lt;/a&gt;, etc.&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://github.com/remi/rackbox'&gt;http://github.com/remi/rackbox&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;( &lt;a href='http://s3.amazonaws.com/remicasts/rackbox.avi.zip'&gt;original screencast&lt;/a&gt; )&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Using Firebug to Debug Unobtrusive Javascript</title>
    <link href="http://remi.org/2009/01/06/using-firebug-to-debug-unobtrusive-javascript.html" />
    <updated>2009-01-06T00:00:00-07:00</updated>
    <id>http://remi.org//2009/01/06/using-firebug-to-debug-unobtrusive-javascript.html</id>
    <content type="html">
      &lt;p&gt;I&amp;#8217;ve been using &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;Unobtrusive Javascript&lt;/a&gt; techniques for awhile now and I recently introduced them into some of my client projects for &lt;a href='http://openrain.com'&gt;OpenRain&lt;/a&gt;. Personally, I love &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;UJS&lt;/a&gt; and find it much easier to write than using the &lt;a href='http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html'&gt;Javascript Rails Helpers&lt;/a&gt; or &lt;code&gt;onclick&lt;/code&gt;-style javascript, but some of my teammates have found &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;UJS&lt;/a&gt; difficult to debug. And they&amp;#8217;re right!&lt;/p&gt;
      
      &lt;p&gt;Up until now, I&amp;#8217;ve enjoyed using &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;UJS&lt;/a&gt; so much that I&amp;#8217;ve overlooked its downsides, primarily how difficult it can be to debug. Take CSS for example:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;CSS is great because it separates a page&amp;#8217;s styles from its content&lt;/li&gt;
      
      &lt;li&gt;CSS is awful because it&amp;#8217;s difficult to debug (as it&amp;#8217;s separate from the content)&lt;/li&gt;
      
      &lt;li&gt;CSS was tolerable to begin with but is great now because we have &lt;a href='http://www.getfirebug.com'&gt;awesome tools&lt;/a&gt; to help us debug it!&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;Think about it. Today, we can right-click on any DOM element and see all of it&amp;#8217;s styles and where they&amp;#8217;re coming from. Before &lt;a href='http://www.getfirebug.com'&gt;Firebug&lt;/a&gt;, we tolerated CSS. We knew it was better but it was often difficult to figure out were certain styles were coming from. The &amp;#8220;solution&amp;#8221;: override the cascading styles with new ones. That is, until &lt;a href='http://www.getfirebug.com'&gt;Firebug&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;Compare that to &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;UJS&lt;/a&gt;. Using &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;UJS&lt;/a&gt;, it can be difficult to figure out why, when you click on a link, it&amp;#8217;s not going to the link&amp;#8217;s href. Instead, because of some &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;UJS&lt;/a&gt; events someone has added, the link is doing some crazy things when you click on it and you can&amp;#8217;t figure out why!&lt;/p&gt;
      
      &lt;h2 id='enter_firebugujs'&gt;Enter FirebugUJS&lt;/h2&gt;
      
      &lt;p&gt;As a way to solve this problem, I figured &amp;#8230; why not solve it &lt;em&gt;exactly&lt;/em&gt; the way we do it for CSS? Right now, we can right-click on DOM elements and see all associated styles &amp;#8230; so why not be able to right-click on DOM elements and see all associated UJS events? Now we can &lt;code&gt;:)&lt;/code&gt;&lt;/p&gt;
      
      &lt;p&gt;&lt;img src='http://github.com/remi/firebug-ujs/raw/master/images/screenshot.png' alt='FirebugUJS Screenshot' /&gt;&lt;/p&gt;
      
      &lt;p&gt;I created &lt;a href='http://github.com/remi/firebug-ujs'&gt;a Firefox extension&lt;/a&gt; (a &lt;a href='http://www.getfirebug.com'&gt;Firebug&lt;/a&gt; extension, to be precise), so we can easily see the &lt;a href='http://en.wikipedia.org/wiki/Unobtrusive_Javascript'&gt;UJS&lt;/a&gt; events bound to DOM elements by inspecting them.&lt;/p&gt;
      
      &lt;p&gt;So, it&amp;#8217;s definitely not perfect yet but &amp;#8230; &lt;strong&gt;release early, release often!&lt;/strong&gt;&lt;/p&gt;
      
      &lt;p&gt;Right now, &lt;a href='http://github.com/remi/firebug-ujs'&gt;the extension&lt;/a&gt; should work with &lt;a href='http://jquery.com'&gt;jQuery&lt;/a&gt; and (to some extent) &lt;a href='http://www.danwebb.net/2006/9/3/low-pro-unobtrusive-scripting-for-prototype'&gt;LowPro&lt;/a&gt;. I&amp;#8217;ll try to add &lt;a href='http://www.prototypejs.org'&gt;Prototype&lt;/a&gt; support as well (sans &lt;a href='http://www.danwebb.net/2006/9/3/low-pro-unobtrusive-scripting-for-prototype'&gt;LowPro&lt;/a&gt;) and, if I can figure it out, I&amp;#8217;ll add native JavaScript support (for whenever someone adds an event listener to a DOM element).&lt;/p&gt;
      
      &lt;p&gt;To install, download the &lt;a href='http://github.com/remi/firebug-ujs/raw/master/firebug-ujs.xpi'&gt;xpi&lt;/a&gt; from the &lt;a href='http://github.com/remi/firebug-ujs'&gt;github project&lt;/a&gt; and then File &amp;gt; Open the &lt;a href='http://github.com/remi/firebug-ujs/raw/master/firebug-ujs.xpi'&gt;xpi&lt;/a&gt; in Firefox.&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;NOTE: Requires Firebug!&lt;/strong&gt;&lt;/p&gt;
      
      &lt;p&gt;To use, right-click &amp;gt; Inspect Element and check the Events tab (see screenshot above)&lt;/p&gt;
      
      &lt;p&gt;Let me know what you think!&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Be More Active in the Rails Community</title>
    <link href="http://remi.org/2008/12/23/be-more-active-in-the-rails-community.html" />
    <updated>2008-12-23T00:00:00-07:00</updated>
    <id>http://remi.org//2008/12/23/be-more-active-in-the-rails-community.html</id>
    <content type="html">
      &lt;p&gt;&amp;#8221;&lt;em&gt;I have been trying to be more active in the Rails community&lt;/em&gt;&amp;#8221;, said &lt;a href='http://millarian.com'&gt;Curtis Miller&lt;/a&gt; in the &lt;a href='http://personalityflatline.com/post/64849608/inaugural-session-episode-5-curtis-and-chris'&gt;inaugural episode&lt;/a&gt; of &lt;a href='http://personalityflatline.com'&gt;Personality Flatline&lt;/a&gt;. &amp;#8221;&lt;em&gt;We should all get on some kind of rails forum or ruby forum or whatever it is and try to answer a couple questions.&lt;/em&gt;&amp;#8221;&lt;/p&gt;
      
      &lt;p&gt;I couldn&amp;#8217;t agree more.&lt;/p&gt;
      
      &lt;h2 id='participate_in_forums__groups__channels'&gt;Participate in Forums / Groups / Channels&lt;/h2&gt;
      
      &lt;p&gt;Phoenix has a really good number of professional &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; developers with &lt;em&gt;years&lt;/em&gt; of experience (that&amp;#8217;s a long time for &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt;), and we need to make sure that we&amp;#8217;re giving back to the community. We need to get out of the habit of visiting forums/IRC only when we need them and get into the habit of frequenting these places to help out others.&lt;/p&gt;
      
      &lt;p&gt;I often pop onto the &lt;a href='irc://irc.freenode.org/rubyonrails'&gt;#rubyonrails&lt;/a&gt; IRC channel on &lt;a href='http://freenode.net'&gt;freenode&lt;/a&gt; to ask a quick question and then I pop off. I &lt;em&gt;should&lt;/em&gt; auto-login to &lt;a href='irc://irc.freenode.org/rubyonrails'&gt;#rubyonrails&lt;/a&gt; and other IRC channels to be there to help answer &lt;em&gt;other&lt;/em&gt; peoples&amp;#8217; questions.&lt;/p&gt;
      
      &lt;p&gt;Wanna participate? I recommend &amp;#8230;&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;
      &lt;p&gt;&lt;strong&gt;IRC&lt;/strong&gt;&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;#rubyonrails, #ruby, #merb&lt;/li&gt;
      
      &lt;li&gt;#jquery, #prototype&lt;/li&gt;
      
      &lt;li&gt;#phx.rb (specific to Phoenix)&lt;/li&gt;
      &lt;/ul&gt;
      &lt;/li&gt;
      
      &lt;li&gt;
      &lt;p&gt;&lt;strong&gt;Forums / Groups&lt;/strong&gt;&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://railsforum.com'&gt;Rails Forum&lt;/a&gt;, &lt;a href='http://www.ruby-forum.com'&gt;Ruby Forum&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://groups.google.com/group/rubyonrails-talk?lnk=srg&amp;amp;hl=en&amp;amp;pli=1'&gt;Rails Google Group&lt;/a&gt;, &lt;a href='http://groups.google.com/group/comp.lang.ruby/topics?lnk=srg&amp;amp;hl=en'&gt;Ruby Google Group&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://groups.google.com/group/phoenix-ruby'&gt;Phoenix Ruby Google Group&lt;/a&gt; (specific to Phoenix)&lt;/li&gt;
      &lt;/ul&gt;
      &lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;h2 id='contribute_to_open_source'&gt;Contribute to Open Source&lt;/h2&gt;
      
      &lt;p&gt;We also need to make sure that we&amp;#8217;re making our open source projects available to the public (ie. putting them on &lt;a href='http://github.com'&gt;github&lt;/a&gt; and we&amp;#8217;re contributing &lt;em&gt;back&lt;/em&gt; to the open source projects that we use.&lt;/p&gt;
      
      &lt;p&gt;Fix a bug in a &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; plugin? Send a patch to the author! Or: fork the project on &lt;a href='http://github.com'&gt;github&lt;/a&gt;, apply your patch, and then send the author a &lt;a href='http://github.com/guides/pull-requests'&gt;pull request&lt;/a&gt;. It&amp;#8217;s &lt;em&gt;really&lt;/em&gt; easy. And it feels &lt;strong&gt;awesome&lt;/strong&gt;.&lt;/p&gt;
      
      &lt;p&gt;This morning, when &lt;a href='http://blog.marcchung.com'&gt;Marc&lt;/a&gt; walked into work at &lt;a href='http://openrain.com'&gt;OpenRain&lt;/a&gt;, he had a big smile on his face. Over the weekend, he had contributed to &lt;a href='http://github.com/mojombo/jekyll'&gt;a project&lt;/a&gt; that &lt;a href='http://github.com'&gt;github&lt;/a&gt; uses to generate webpages. He &lt;a href='http://github.com/mojombo/jekyll/commit/9ecbfb2253e11f5cb0364e24d4f13595efdd20b6'&gt;integrated&lt;/a&gt; a &lt;a href='http://www.webrick.org'&gt;WEBrick&lt;/a&gt; server so you can easily develop your &lt;a href='http://github.com/mojombo/jekyll'&gt;jekyll&lt;/a&gt;-based site, without having to set up a webserver. Although he didn&amp;#8217;t get visual credit (someone else committed a similar change), he looked like he was happy to have given back to the community. Coincidentally, I &lt;a href='http://github.com/mojombo/jekyll/commit/6d8c73349e2e05529a3e4f7b27dd808070b7ab0e'&gt;contributed&lt;/a&gt; to the same &lt;span&gt;project&lt;/span&gt; over the weekend! And I can tell you, from my perspective &amp;#8230; &lt;strong&gt;it feels awesome.&lt;/strong&gt;&lt;/p&gt;
      
      &lt;h2 id='blog_tweet_bookmark__comment'&gt;Blog, Tweet, Bookmark, &amp;amp; Comment&lt;/h2&gt;
      
      &lt;p&gt;While contibuting to forums and open source projects is &lt;em&gt;truly&lt;/em&gt; 1337, don&amp;#8217;t underestimate the smaller contributions. Found out about a sweet new &lt;a href='http://www.rubygems.org'&gt;RubyGem&lt;/a&gt;? Tweet about it! And bookmark it on a social bookmarking site like &lt;a href='http://delicious.com'&gt;delicious&lt;/a&gt;, or share it via &lt;a href='http://www.google.com/reader'&gt;Google Reader&lt;/a&gt;. Reading a cool blog post? Write a comment. Thinking of a cool idea? Write a blog post!&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Merb and Rails, Sitting in a Tree ... K-I-S-S-I-N-G</title>
    <link href="http://remi.org/2008/12/23/merb-and-rails-sitting-in-a-tree-k-i-s-s-i-n-g.html" />
    <updated>2008-12-23T00:00:00-07:00</updated>
    <id>http://remi.org//2008/12/23/merb-and-rails-sitting-in-a-tree-k-i-s-s-i-n-g.html</id>
    <content type="html">
      &lt;p&gt;Today is a historic moment for the &lt;a href='http://ruby-lang.org'&gt;Ruby&lt;/a&gt; web development community. &lt;a href='http://rubyonrails.org/merb'&gt;The day Merb joined Rails&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;At first, my heart sank when I heard this news. I&amp;#8217;ve been wanting to learn &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt; for awhile now. &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt; is faster than &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt;, its code is more modular and easier to read. It has a sane mechanism for writing plugins, sans &lt;code&gt;alias_method_chain&lt;/code&gt;. You might say that it feels 1337 in comparison to &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;That said, the past few months have been &lt;em&gt;really&lt;/em&gt; interesting. After the &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt; core team released their first RC for Merb 1.0 at &lt;a href='http://www.merbcamp.com'&gt;MerbCamp&lt;/a&gt; in October, the &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; team definitely seemed to notice and competition between the two frameworks seemed to grow. All of a sudden &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; started releasing new features, faster. After Merb 1.0 was released at &lt;a href='http://rubyconf.org'&gt;RubyConf&lt;/a&gt;, the competition only seemed to grow. &amp;#8221;&lt;em&gt;This is great for the community,&lt;/em&gt;&amp;#8221; we would all say.&lt;/p&gt;
      
      &lt;p&gt;I was happy when &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; &lt;strong&gt;finally&lt;/strong&gt; started accepting &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; (which is what every Ruby web framework should be build on top of), but I&amp;#8217;ll admit &amp;#8230; I was a bit bitter. &amp;#8221;&lt;em&gt;Now that they have real competition, they FINALLY give a shit,&lt;/em&gt;&amp;#8221; is what I was thinking. I was happy thinking that I would start playing with &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt; soon and all of the crappiness of &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; would disappear.&lt;/p&gt;
      
      &lt;p&gt;And then this.&lt;/p&gt;
      
      &lt;p&gt;Initially, I was sad. Then I didn&amp;#8217;t know what to think. Then I started &lt;a href='http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3'&gt;reading&lt;/a&gt; &lt;a href='http://yehudakatz.com/2008/12/23/rails-and-merb-merge/'&gt;a lot&lt;/a&gt; &lt;a href='http://brainspl.at/articles/2008/12/23/merb-is-rails'&gt;of&lt;/a&gt; &lt;a href='http://merbist.com/2008/12/23/rails-and-merb-merge/'&gt;blog&lt;/a&gt; &lt;a href='http://splendificent.com/2008/12/the-merb-rails-merger-announcement-an-inside-opinion/'&gt;posts&lt;/a&gt; and started asking questions and &amp;#8216;listening&amp;#8217; in the #merb IRC channel and &amp;#8230; I know that this is best for everyone.&lt;/p&gt;
      
      &lt;p&gt;The whole reason why &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt; exists and has grown is because people have disagreed with &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; and wanted a framework that:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;is faster&lt;/li&gt;
      
      &lt;li&gt;is more modular&lt;/li&gt;
      
      &lt;li&gt;allows more configuration&lt;/li&gt;
      
      &lt;li&gt;has a public API and is easy to test and refactor&lt;/li&gt;
      
      &lt;li&gt;&amp;#8230; and more&lt;/li&gt;
      &lt;/ul&gt;
      
      &lt;p&gt;Now, &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; (&lt;a href='http://en.wikipedia.org/wiki/David_Heinemeier_Hansson'&gt;DHH&lt;/a&gt;) finally agrees with all of these ideals. &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; is ready to embrace all of &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt;&amp;#8217;s ideals, so &amp;#8230; why not merge?&lt;/p&gt;
      
      &lt;p&gt;Anyway, I fully trust the &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt; core team. They&amp;#8217;re hardcore opinionated, just like &lt;a href='http://en.wikipedia.org/wiki/David_Heinemeier_Hansson'&gt;DHH&lt;/a&gt;, and they wouldn&amp;#8217;t have agreed to this merge if they weren&amp;#8217;t certain that they could create a &lt;strong&gt;better&lt;/strong&gt; web framework by teaming up with the &lt;a href='http://www.rubyonrails.org'&gt;Rails&lt;/a&gt; core team.&lt;/p&gt;
      
      &lt;p&gt;2009 is going to be a &lt;em&gt;sweet&lt;/em&gt; year for Ruby web development :)&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Rack Routing</title>
    <link href="http://remi.org/2008/12/21/rack-routing.html" />
    <updated>2008-12-21T00:00:00-07:00</updated>
    <id>http://remi.org//2008/12/21/rack-routing.html</id>
    <content type="html">
      &lt;p&gt;I &lt;code&gt;&amp;lt;3&lt;/code&gt; &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; is great for thin webservices or simple sites, it even has simple support for dealing with &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Session/Cookie.html'&gt;sessions&lt;/a&gt;, &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Auth/Basic.html'&gt;authentication&lt;/a&gt;, &lt;a href='http://rack.rubyforge.org/doc/classes/Rack/Auth/OpenID.html'&gt;OpenID&lt;/a&gt; and more.&lt;/p&gt;
      
      &lt;p&gt;Where &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; really starts to break down is when you want to do any kindof non-trivial routing.&lt;/p&gt;
      
      &lt;p&gt;So, what are some ways we can add routing to our &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; apps?&lt;/p&gt;
      
      &lt;h2 id='case__when'&gt;case / when&lt;/h2&gt;
      
      &lt;p&gt;The simplest routing, ofcourse, is via simple case statements. Any &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt; app is likely to start out with some kindof simple routing, like this:&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt; 1 &lt;/span&gt;&lt;span class='PreProc'&gt;#! /usr/bin/env ruby&lt;/span&gt;
      &lt;span class='lnr'&gt; 2 &lt;/span&gt;&lt;span class='Comment'&gt;# &lt;/span&gt;
      &lt;span class='lnr'&gt; 3 &lt;/span&gt;&lt;span class='Comment'&gt;# example of case/when style rack routing&lt;/span&gt;
      &lt;span class='lnr'&gt; 4 &lt;/span&gt;&lt;span class='Comment'&gt;#&lt;/span&gt;
      &lt;span class='lnr'&gt; 5 &lt;/span&gt;&lt;span class='Special'&gt;%w(&lt;/span&gt;&lt;span class='Constant'&gt; rubygems thin &lt;/span&gt;&lt;span class='Special'&gt;)&lt;/span&gt;.each {|&lt;span class='Identifier'&gt;lib&lt;/span&gt;| &lt;span class='PreProc'&gt;require&lt;/span&gt; lib }
      &lt;span class='lnr'&gt; 6 &lt;/span&gt;&lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Handler&lt;/span&gt;::&lt;span class='Type'&gt;Thin&lt;/span&gt;.run &lt;span class='Statement'&gt;lambda&lt;/span&gt; { |&lt;span class='Identifier'&gt;env&lt;/span&gt;|
      &lt;span class='lnr'&gt; 7 &lt;/span&gt;  path = env[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;PATH_INFO&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;]
      &lt;span class='lnr'&gt; 8 &lt;/span&gt;  &lt;span class='Statement'&gt;case&lt;/span&gt; path
      &lt;span class='lnr'&gt; 9 &lt;/span&gt;
      &lt;span class='lnr'&gt;10 &lt;/span&gt;  &lt;span class='Statement'&gt;when&lt;/span&gt; &lt;span class='Special'&gt;''&lt;/span&gt;
      &lt;span class='lnr'&gt;11 &lt;/span&gt;  &lt;span class='Statement'&gt;when&lt;/span&gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;/&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;12 &lt;/span&gt;    [&lt;span class='Constant'&gt;200&lt;/span&gt;, {}, &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;routed &lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt;path&lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Constant'&gt; to index&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;]
      &lt;span class='lnr'&gt;13 &lt;/span&gt;
      &lt;span class='lnr'&gt;14 &lt;/span&gt;  &lt;span class='Statement'&gt;when&lt;/span&gt; &lt;span class='Special'&gt;/&lt;/span&gt;&lt;span class='Constant'&gt;chunky&lt;/span&gt;&lt;span class='Special'&gt;/i&lt;/span&gt;
      &lt;span class='lnr'&gt;15 &lt;/span&gt;    [&lt;span class='Constant'&gt;200&lt;/span&gt;, {}, &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;bacon!&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;]
      &lt;span class='lnr'&gt;16 &lt;/span&gt;
      &lt;span class='lnr'&gt;17 &lt;/span&gt;  &lt;span class='Statement'&gt;else&lt;/span&gt;
      &lt;span class='lnr'&gt;18 &lt;/span&gt;    [&lt;span class='Constant'&gt;200&lt;/span&gt;, {}, &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;route not found for &lt;/span&gt;&lt;span class='Special'&gt;#{&lt;/span&gt;path&lt;span class='Special'&gt;}&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;]
      &lt;span class='lnr'&gt;19 &lt;/span&gt;
      &lt;span class='lnr'&gt;20 &lt;/span&gt;  &lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;21 &lt;/span&gt;}&lt;/pre&gt;
      &lt;h2 id='rack__merb_router__diy_dsl'&gt;Rack + Merb Router == DIY DSL&lt;/h2&gt;
      
      &lt;p&gt;Simple case/when routing logic is great. But what if we want to do more complicated routing logic?&lt;br /&gt;The &lt;a href='http://merbivore.com'&gt;Merb&lt;/a&gt; &lt;a href='http://merbivore.com/documentation/current/doc/rdoc/stack/index.html?a=C00000486&amp;amp;name=Router'&gt;Router&lt;/a&gt; comes out of the box with &lt;em&gt;all kinds&lt;/em&gt; of cool functionality. Did you know that you can even perform authentication in the Merb Router? And you can return &lt;em&gt;directly&lt;/em&gt; from it without calling any controllers or anything?&lt;/p&gt;
      
      &lt;p&gt;Watch some of the &lt;a href='http://merbcamp.com/video'&gt;MerbCamp Videos&lt;/a&gt; to see the awesomeness of the Merb Router.&lt;/p&gt;
      
      &lt;p&gt;So, what if you want to delegate routes to classes and methods easily? Or build your own web framework / DSL? The Merb Router can be used outside of Merb to help you do this. Essentially, all the Merb router really does it help you may URIs to hashes and then you can do whatever you want to with the hash.&lt;/p&gt;
      
      &lt;p&gt;While this example is obviously much longer than the simple case/when, you can see how much more powerful this can be. Being able to easily map URIs to hashes and then &amp;#8230; do whatever!&lt;/p&gt;
      &lt;pre class='highlight'&gt;&lt;span class='lnr'&gt; 1 &lt;/span&gt;&lt;span class='PreProc'&gt;#! /usr/bin/env ruby&lt;/span&gt;
      &lt;span class='lnr'&gt; 2 &lt;/span&gt;&lt;span class='Comment'&gt;# &lt;/span&gt;
      &lt;span class='lnr'&gt; 3 &lt;/span&gt;&lt;span class='Comment'&gt;# example of rack routing using the merb router&lt;/span&gt;
      &lt;span class='lnr'&gt; 4 &lt;/span&gt;&lt;span class='Comment'&gt;#&lt;/span&gt;
      &lt;span class='lnr'&gt; 5 &lt;/span&gt;&lt;span class='Special'&gt;%w(&lt;/span&gt;&lt;span class='Constant'&gt; rubygems thin merb-core/dispatch/router extlib &lt;/span&gt;&lt;span class='Special'&gt;)&lt;/span&gt;.each {|&lt;span class='Identifier'&gt;lib&lt;/span&gt;| &lt;span class='PreProc'&gt;require&lt;/span&gt; lib }
      &lt;span class='lnr'&gt; 6 &lt;/span&gt;
      &lt;span class='lnr'&gt; 7 &lt;/span&gt;&lt;span class='Comment'&gt;# we need to call *something* to render our routes, so let's make some little classes&lt;/span&gt;
      &lt;span class='lnr'&gt; 8 &lt;/span&gt;&lt;span class='PreProc'&gt;class&lt;/span&gt; &lt;span class='Type'&gt;Actions&lt;/span&gt;
      &lt;span class='lnr'&gt; 9 &lt;/span&gt;  &lt;span class='PreProc'&gt;def&lt;/span&gt; &lt;span class='Constant'&gt;self&lt;/span&gt;.&lt;span class='Identifier'&gt;index&lt;/span&gt;
      &lt;span class='lnr'&gt;10 &lt;/span&gt;    &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;hello from index!&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='lnr'&gt;11 &lt;/span&gt;  &lt;span class='PreProc'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;12 &lt;/span&gt;&lt;span class='PreProc'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;13 &lt;/span&gt;&lt;span class='PreProc'&gt;class&lt;/span&gt; &lt;span class='Type'&gt;MoreActions&lt;/span&gt;
      &lt;span class='lnr'&gt;14 &lt;/span&gt;  &lt;span class='PreProc'&gt;def&lt;/span&gt; &lt;span class='Constant'&gt;self&lt;/span&gt;.&lt;span class='Identifier'&gt;default&lt;/span&gt;
      &lt;span class='lnr'&gt;15 &lt;/span&gt;    &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;route not found&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='lnr'&gt;16 &lt;/span&gt;  &lt;span class='PreProc'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;17 &lt;/span&gt;  &lt;span class='PreProc'&gt;def&lt;/span&gt; &lt;span class='Constant'&gt;self&lt;/span&gt;.&lt;span class='Identifier'&gt;chunky&lt;/span&gt;
      &lt;span class='lnr'&gt;18 &lt;/span&gt;    &lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;&lt;span class='Constant'&gt;bacon!&lt;/span&gt;&lt;span class='Special'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='lnr'&gt;19 &lt;/span&gt;  &lt;span class='PreProc'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;20 &lt;/span&gt;&lt;span class='PreProc'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;21 &lt;/span&gt;
      &lt;span class='lnr'&gt;22 &lt;/span&gt;&lt;span class='Type'&gt;Rack&lt;/span&gt;::&lt;span class='Type'&gt;Handler&lt;/span&gt;::&lt;span class='Type'&gt;Thin&lt;/span&gt;.run &lt;span class='Statement'&gt;lambda&lt;/span&gt; { |&lt;span class='Identifier'&gt;env&lt;/span&gt;|
      &lt;span class='lnr'&gt;23 &lt;/span&gt;
      &lt;span class='lnr'&gt;24 &lt;/span&gt;  &lt;span class='Comment'&gt;# setup some routes&lt;/span&gt;
      &lt;span class='lnr'&gt;25 &lt;/span&gt;  &lt;span class='Type'&gt;Merb&lt;/span&gt;::&lt;span class='Type'&gt;Router&lt;/span&gt;.prepare &lt;span class='Statement'&gt;do&lt;/span&gt;
      &lt;span class='lnr'&gt;26 &lt;/span&gt;    match(&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;/&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;).to       &lt;span class='Constant'&gt;:class&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;Actions&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;,     &lt;span class='Constant'&gt;:method&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;index&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;27 &lt;/span&gt;    match(&lt;span class='Special'&gt;/&lt;/span&gt;&lt;span class='Special'&gt;\/&lt;/span&gt;&lt;span class='Constant'&gt;chunky&lt;/span&gt;&lt;span class='Special'&gt;/&lt;/span&gt;).to &lt;span class='Constant'&gt;:class&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;MoreActions&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;, &lt;span class='Constant'&gt;:method&lt;/span&gt; =&amp;gt; &lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;chunky&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;
      &lt;span class='lnr'&gt;28 &lt;/span&gt;  &lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;29 &lt;/span&gt;
      &lt;span class='lnr'&gt;30 &lt;/span&gt;  &lt;span class='Comment'&gt;# execute the merb router, getting back a hash for the found route&lt;/span&gt;
      &lt;span class='lnr'&gt;31 &lt;/span&gt;  request = &lt;span class='Type'&gt;Struct&lt;/span&gt;.new(&lt;span class='Constant'&gt;:path&lt;/span&gt;, &lt;span class='Constant'&gt;:method&lt;/span&gt;).new(env[&lt;span class='Special'&gt;'&lt;/span&gt;&lt;span class='Constant'&gt;PATH_INFO&lt;/span&gt;&lt;span class='Special'&gt;'&lt;/span&gt;], &lt;span class='Constant'&gt;:get&lt;/span&gt;)
      &lt;span class='lnr'&gt;32 &lt;/span&gt;  route   = &lt;span class='Type'&gt;Merb&lt;/span&gt;::&lt;span class='Type'&gt;Router&lt;/span&gt;.match(request).last
      &lt;span class='lnr'&gt;33 &lt;/span&gt;
      &lt;span class='lnr'&gt;34 &lt;/span&gt;  &lt;span class='Comment'&gt;# ok, we got a hash back for our path ... do something with it!&lt;/span&gt;
      &lt;span class='lnr'&gt;35 &lt;/span&gt;  &lt;span class='Statement'&gt;if&lt;/span&gt; route.empty?
      &lt;span class='lnr'&gt;36 &lt;/span&gt;    response = &lt;span class='Type'&gt;MoreActions&lt;/span&gt;.default
      &lt;span class='lnr'&gt;37 &lt;/span&gt;  &lt;span class='Statement'&gt;else&lt;/span&gt;
      &lt;span class='lnr'&gt;38 &lt;/span&gt;    response = &lt;span class='Type'&gt;Kernel&lt;/span&gt;.const_get(route[&lt;span class='Constant'&gt;:class&lt;/span&gt;]).send route[&lt;span class='Constant'&gt;:method&lt;/span&gt;]
      &lt;span class='lnr'&gt;39 &lt;/span&gt;  &lt;span class='Statement'&gt;end&lt;/span&gt;
      &lt;span class='lnr'&gt;40 &lt;/span&gt;
      &lt;span class='lnr'&gt;41 &lt;/span&gt;  [&lt;span class='Constant'&gt;200&lt;/span&gt;, {}, response]
      &lt;span class='lnr'&gt;42 &lt;/span&gt;}&lt;/pre&gt;
      &lt;p&gt;If you&amp;#8217;re anything like me, you look at the above code and think &amp;#8220;man, it sure would be easy to make a nice purty DSL like &lt;a href='http://sinatra.rubyforge.org'&gt;Sinatra&lt;/a&gt;&amp;#8217;s this way!&amp;#8221; and you would be right.&lt;/p&gt;
      
      &lt;p&gt;Who needs &lt;a href='http://weblog.rubyonrails.org/2008/12/17/introducing-rails-metal'&gt;Metal&lt;/a&gt; and all that jazz? &lt;a href='http://rack.rubyforge.org'&gt;Rack&lt;/a&gt;&amp;#8217;s awesome all by itself :)&lt;/p&gt;
      
      &lt;p&gt;&lt;em&gt;PS. thanks to &lt;a href='http://blog.marcchung.com'&gt;Marc Chung&lt;/a&gt; for the idea of using the Merb router outside of Merb&lt;/em&gt;&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>Blogging Like a Hacker</title>
    <link href="http://remi.org/2008/12/19/blogging-like-a-hacker.html" />
    <updated>2008-12-19T00:00:00-07:00</updated>
    <id>http://remi.org//2008/12/19/blogging-like-a-hacker.html</id>
    <content type="html">
      &lt;p&gt;I used to have a &lt;a href='http://www.flickr.com/photos/tryingyouth/3137862/'&gt;Blogger Hoodie&lt;/a&gt;.&lt;/p&gt;
      &lt;a href='http://www.flickr.com/photos/tryingyouth/3137862/'&gt;&lt;img src='http://farm1.static.flickr.com/2/3137862_9f18e67024.jpg?v=0' alt='Google Blogger Hoodie, photo by tryingyouth' /&gt;&lt;/a&gt;
      &lt;p&gt;Way back when, I was very into blogging. I loved &lt;a href='http://blogger.com'&gt;Blogger&lt;/a&gt; and then &lt;a href='http://livejournal.com'&gt;Livejournal&lt;/a&gt;. My friends all blogged and it was a great way to stay in-touch and up-to-date with what my friends were up to. Then &lt;a href='http://myspace.com'&gt;MySpace&lt;/a&gt; came along and we had another way to see what our friends were up to. Now, with &lt;a href='http://facebook.com'&gt;Facebook&lt;/a&gt; and &lt;a href='http://twitter.com'&gt;Twitter&lt;/a&gt; (and things like &lt;a href='http://linkedin.com'&gt;LinkedIn&lt;/a&gt;), it&amp;#8217;s much easier to keep up-to-date with not only friends, but business acquaintances or industry leaders / celebrities.&lt;/p&gt;
      
      &lt;p&gt;At some point, I stopped blogging. I moved to &lt;a href='http://twitter.com/remitaylor'&gt;twitter&lt;/a&gt; and facebook. Other services like &lt;a href='http://gmail.com'&gt;gmail&lt;/a&gt;, &lt;a href='http://friendfeed.com'&gt;friendfeed&lt;/a&gt;, and more all help as well, so I don&amp;#8217;t have the same need to follow friends&amp;#8217; blogs (or write my own) that I once had.&lt;/p&gt;
      
      &lt;h2 id='so__what_about_blogging'&gt;So &amp;#8230; What about blogging?&lt;/h2&gt;
      
      &lt;p&gt;Over the past year or 2, as I&amp;#8217;ve gotten more and more into software development. I&amp;#8217;ve met more and more people with technical blogs. I&amp;#8217;ll ask a friend &amp;#8220;how do I get mysql working on OSX?&amp;#8221; and he&amp;#8217;ll direct me to an entry on his blog explaining howto do it. I decided that I needed my own blog to share code, bugfixes, ideas, etc with the world.&lt;/p&gt;
      
      &lt;p&gt;So, I started looking at blogging engines. As a &lt;a href='http://ruby-lang.org'&gt;Ruby&lt;/a&gt; developer, naturally I wanted to find a blogging engine built in &lt;a href='http://ruby-lang.org'&gt;Ruby&lt;/a&gt;, but I didn&amp;#8217;t have a great deal of luck. I played with &lt;a href='http://wordpress.com'&gt;Wordpress&lt;/a&gt; for awhile, but I didn&amp;#8217;t enjoy the syntax whenever I wanted to hack the template or plugins. I started designing my own file-based blogging engine based on simple markdown files and a directory structure. That&amp;#8217;s when fellow &lt;a href='http://openrain.com'&gt;OpenRain&lt;/a&gt; hacker, &lt;a href='http://blog.marcchung.com'&gt;Marc Chung&lt;/a&gt;, showed me &lt;a href='http://github.com/mojombo/jekyll'&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;&lt;a href='http://github.com'&gt;Github&lt;/a&gt; + &lt;a href='http://github.com/mojombo/jekyll'&gt;Jekyll&lt;/a&gt; == the Hacker&amp;#8217;s Blogging Engine&lt;/p&gt;
    </content>
  </entry>
<entry>
    <title>6th Photo</title>
    <link href="http://remi.org/2008/12/19/6th-photo.html" />
    <updated>2008-12-19T00:00:00-07:00</updated>
    <id>http://remi.org//2008/12/19/6th-photo.html</id>
    <content type="html">
      &lt;p&gt;&lt;a href='http://sunnythaper.com/2008/12/14/6th-photo/'&gt;Sunny&lt;/a&gt; and &lt;a href='http://millarian.com/2008/12/15/my-6th-photo'&gt;Curtis&lt;/a&gt; tagged me in the 6th Photo Meme that’s going around. My mission should I chose to accept it: Go to page 6, image 6 on &lt;a href='http://flickr.com/photos/remitaylor/'&gt;my Flickr stream&lt;/a&gt; and post it up. Tag 6 more, call it a post. That image and an explanation follow.&lt;/p&gt;
      &lt;a href='http://flickr.com/photos/remitaylor/243006943/'&gt;
        &lt;img src='http://farm1.static.flickr.com/89/243006943_adf1064500.jpg?v=0' alt='remi&amp;apos;s 6th photo' /&gt;
      &lt;/a&gt;
      &lt;p&gt;&lt;a href='http://flickr.com/photos/remitaylor/sets/72157602219486015/'&gt;Lander&lt;/a&gt; is going through his basket of toys and trying to decide which toy he wants to play with. He&amp;#8217;ll start taking things out until he finds the toy he wants. Sometimes he doens&amp;#8217;t know which one he wants, he just roots through his toys until he finds a good one.&lt;/p&gt;
      
      &lt;p&gt;The 6 people I wish to tag are:&lt;/p&gt;
      
      &lt;ul&gt;
      &lt;li&gt;&lt;a href='http://blog.bustikated.net'&gt;Byron Bowerman&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://sharonbowerman.com'&gt;Sharon Bowerman&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://blog.marcchung.com'&gt;Marc Chung&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://lancewig.com'&gt;Lance Wig&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://prestonlee.com'&gt;Preston Lee&lt;/a&gt;&lt;/li&gt;
      
      &lt;li&gt;&lt;a href='http://disjointthoughts.com'&gt;Ben Smith&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    </content>
  </entry>
</feed>
