<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Push cx &#187; web</title>
	<atom:link href="http://push.cx/tag/web/feed" rel="self" type="application/rss+xml" />
	<link>http://push.cx</link>
	<description>A tea-drinking web geek's coffee-flavored blog</description>
	<lastBuildDate>Fri, 09 Jul 2010 12:37:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Redirecting Users&#8217; URLs</title>
		<link>http://push.cx/2009/redirecting-users-urls</link>
		<comments>http://push.cx/2009/redirecting-users-urls#comments</comments>
		<pubDate>Tue, 16 Jun 2009 18:46:38 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[human-readable]]></category>
		<category><![CDATA[URLs]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=1196</guid>
		<description><![CDATA[I got an email in response to an old post on how I designed NearbyGamer&#8216;s discussion URLs. It asked how to create readable URLs for a community site where users might edit those URLs. What happens after users have made lots and lots of edits? There are two basic strategies for keeping a changing URL [...]]]></description>
			<content:encoded><![CDATA[<p>
I got an email in response to an old post on how I designed <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL05lYXJieUdhbWVycy5jb20=">NearbyGamer</a>&#8216;s <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNy9kaXNjdXNzaW9uLXVybHMtb3BhcXVlLXVzYWJsZS1hbmQtcmVhZGFibGU=">discussion URLs</a>. It asked how to create readable URLs for a community site where users might edit those URLs. What happens after users have made lots and lots of edits?
</p>

<p>
There are two basic strategies for keeping a changing URL pointing to the same content. Either only part of the URL changes and you look things up by the stable piece (as with the slugs in my previous blog post) or you keep track of old identifiers with pointers to their current identifiers.
</p>

<p>
On NearbyGamers, <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL05lYXJieUdhbWVycy5jb20vdGFncw==">tags</a> are used to identify what games players are open to playing. But there are a huge number of variations: the game Dungeons and Dragons might be listed as D&#038;D, DND, D&#038;D 4, D&#038;D 4th ed., or many more (and that&#8217;s before spelling errors).
</p>

<p>
To deal with this, I borrowed a mechanism from Wikipedia. Users can edit a tag to redirect it to another (which may not have a redirect set to a third, to prevent all sorts of annoying problems). In short, the Tag object might just be used for its column pointing to another Tag.
</p>

<p>
This is functionally equivalent to having a table of redirects. When a request comes in for a particular Tag, I could check a TagRedirect table to see if that tag appears in the <kbd>from</kbd> column and redirect the visitor to the Tag named by the <kbd>to</kbd> column.
</p>

<p>
Redirects are one of the ways your app will have to scale to meet users&#8217; activity. Thinking about redirects as an explicit table makes it clear you have options for how to deal with it: you could add a date column and expire old entries, or limit the number of redirects one user is allowed to make (perhaps over time), or limit the number of redirects one entity allows. You could even replace this database table with a distributed key/value store like memcached (or preferably something more permanent).
</p>

<p>
So allowing users to edit URLs leads to one of three things: either you don&#8217;t allow them to edit the real identifier, you maintain a table of redirects, or you accept broken links.
</p>

<p>
NearbyGamers also uses the third strategy: if a gamer changes their handle, the URL is updated without any kind of redirecting. I considered redirects, but then no one could ever relinquish a handle.
</p>

<p>
URL design is not easy. Allowing users to influence what a URL will be is often really valuable but adds to the difficulty of designing your URLs. This is one of the interesting bits of computer programming where there isn&#8217;t a single answer, you have to pick your tradeoffs to match your needs.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=1196" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2009/redirecting-users-urls/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Small Plans</title>
		<link>http://push.cx/2009/small-plans</link>
		<comments>http://push.cx/2009/small-plans#comments</comments>
		<pubDate>Wed, 11 Feb 2009 19:57:39 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[gems]]></category>
		<category><![CDATA[ListLibrary.net]]></category>
		<category><![CDATA[mailing lists]]></category>
		<category><![CDATA[RailsRumble]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=663</guid>
		<description><![CDATA[My last day at the Post is Feb 20, and I&#8217;m headed to Chicago on the 22nd. I&#8217;ll be helping a family member recover from surgery, so my schedule (both day-to-day and how long I&#8217;ll be in town) is pretty vague, but I&#8217;ll be around at least a few weeks before returning to DC. I [...]]]></description>
			<content:encoded><![CDATA[<p>
My <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=LzIwMDkvZ2l2aW5nLW5vdGljZQ==">last day at the Post is Feb 20</a>, and I&#8217;m headed to Chicago on the 22nd. I&#8217;ll be helping a family member recover from surgery, so my schedule (both day-to-day and how long I&#8217;ll be in town) is pretty vague, but I&#8217;ll be around at least a few weeks before returning to DC.
</p>

<p>
I have three smallish website projects I plan to finish in this time. They&#8217;re in various stages of completion now.
</p>

<p>
The first is a mailing list archive. I&#8217;ve been tinkering with it on and off for about 18 months, and it&#8217;s the closest to a finished state. I really enjoy reading mailing lists, but haven&#8217;t been impressed with any of the sites out there. Often each message is its own page and threads are broken up. So I&#8217;ve done a lot of work on threading above and beyond the basic In-Reply-To and Re: matching, and the site is designed to show a thread per-page with lots of keyboard controls to make it easy to skim. Depending on free time this weekend, I may actually launch this before I leave town.
</p>

<p>
Second is a site cataloging Ruby gems. When I was <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=LzIwMDkvcmFpbHMtZm9ydW0tcm91bmR1cA==">searching out Rails forums</a> I realized there&#8217;s a related problem in finding libraries that I could address. I&#8217;ve done the work to collect basic info on gems, it remains to collect news and blog posts and combine it into a nice presentation.
</p>

<p>
The last small project is my <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwOC9yYWlsc3J1bWJsaW5n">RailsRumble</a> project (which I <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwOC9yYWlsc3J1bWJsZS1wb3N0bW9ydGVt">didn&#8217;t finish</a>): a site for collaboratively producing transcripts of conference presentations. I&#8217;ve let this one simmer in the back of my mind in the four months since that failure and I&#8217;ve given it a better name and planned which features to finish, redesign, or drop. It needs a few days of solid development, a graphic design, and some seed content.
</p>

<p>
I plan to finish and launch these three projects by the end of March, and I&#8217;ll post more as I work on them.
</p>

<p>
The commonality in these three projects is that once I&#8217;ve launched them they require minimal ongoing attention from me and can grow at their own paces. I&#8217;m doing them first because small and well-defined projects fit well with the interrupted and distracted time I&#8217;ll have. I&#8217;d also want to make sure I start out with some successes.
</p>

<p>
Next posts: <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=LzIwMDkvbmVhcmJ5Z2FtZXJzLXRvLWRvLWxpc3Q=">NearbyGamers</a> and <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=LzIwMDkvd2ViLWdhbWU=">The Big Project That I Really Need To Name Already</a>.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=663" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2009/small-plans/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Greasemonkey Scripts: Gamasutra and Arlington Library</title>
		<link>http://push.cx/2008/greasemonkey-scripts-gamasutra-and-arlington-library</link>
		<comments>http://push.cx/2008/greasemonkey-scripts-gamasutra-and-arlington-library#comments</comments>
		<pubDate>Fri, 12 Dec 2008 18:19:47 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Arlington Library]]></category>
		<category><![CDATA[GamaSutra]]></category>
		<category><![CDATA[GreaseMonkey]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=375</guid>
		<description><![CDATA[I signed up to userscripts to share a few of the GreaseMonkey scripts I&#8217;ve written. If you&#8217;re not familiar, GreaseMonkey is a way of reprogramming websites for your own convenience, and userscripts is where folks can share what they&#8217;ve done. The script that&#8217;s useful to the widest audience (and that&#8217;s not saying much) helps out [...]]]></description>
			<content:encoded><![CDATA[<p>
I signed up to <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy91c2Vycy83NDkzOQ==">userscripts</a> to share a few of the GreaseMonkey scripts I&#8217;ve written. If you&#8217;re not familiar, GreaseMonkey is a way of reprogramming websites for your own convenience, and userscripts is where folks can share what they&#8217;ve done.
</p>

<p>
The script that&#8217;s useful to the widest audience (and that&#8217;s not saying much) helps out when I&#8217;m reading <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2dhbWFzdXRyYS5jb20=">Gamasutra.com</a>, which has some of the nicest writing on game design and implementation but breaks all of its articles up into 3-8 pages. I hate all that clicking and waiting, so I wrote <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMzg1MTY=">a script</a> to automatically pull up the one-page printer-friendly version of any article.
</p>

<p>
The <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMzg1MTc=">other</a> <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3VzZXJzY3JpcHRzLm9yZy9zY3JpcHRzL3Nob3cvMzg1MTk=">two</a> are only useful if you use the Arlington county, VA public library system. They have a decent website (though it&#8217;s great when considered against other libraries), but it has a few parts that are annoying for home users because most of their users are on shared PCs inside the libraries. They both require a little hand-editing of your particulars, but they make it easier to manage your account and request holds.
</p>

<p>
I&#8217;m not happy with the <kbd>$x</kbd> boilerplate I had to put at the top of all three. GreaseMonkey scripts can be very powerful, but it doesn&#8217;t seem like they have enough infrastructure around them to really make it easy to use that power. It&#8217;s odd that this hasn&#8217;t improved, given that GM has been around for a few years now, but maybe I&#8217;m just missing some resource. Anyone with more GM experience care to weigh in?
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=375" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2008/greasemonkey-scripts-gamasutra-and-arlington-library/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RailsRumble Postmortem</title>
		<link>http://push.cx/2008/railsrumble-postmortem</link>
		<comments>http://push.cx/2008/railsrumble-postmortem#comments</comments>
		<pubDate>Sun, 19 Oct 2008 23:28:38 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[aasm]]></category>
		<category><![CDATA[Bort]]></category>
		<category><![CDATA[ConfReader]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[haml]]></category>
		<category><![CDATA[open_id_authentication]]></category>
		<category><![CDATA[Paperclip]]></category>
		<category><![CDATA[planning]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[RailsRumble]]></category>
		<category><![CDATA[resource_this]]></category>
		<category><![CDATA[restful_authentication]]></category>
		<category><![CDATA[RSpec]]></category>
		<category><![CDATA[scheduling]]></category>
		<category><![CDATA[teamwork]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=364</guid>
		<description><![CDATA[I failed to launch my Rails Rumble project ConfReader. Why? Poor scheduling Couldn&#8217;t stay up because work is demanding in the election season, so working late would mean I&#8217;d limp through the next week of important coverage. More than that, though, was a bad mistake in scheduling a social outing. I didn&#8217;t figure in some [...]]]></description>
			<content:encoded><![CDATA[<p>
I failed to launch my Rails Rumble project <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=LzIwMDgvcmFpbHNydW1ibGluZw==">ConfReader</a>. Why?
</p>


<h3>Poor scheduling</h3>
<p>
Couldn&#8217;t stay up because work is demanding in the election season, so working late would mean I&#8217;d limp through the next week of important coverage. More than that, though, was a bad mistake in scheduling a social outing. I didn&#8217;t figure in some of travel time and the friend driving wanted to spend a lot more time out, so instead of having a nice morning out I got home at 7 PM tired and in a foul mood. I was able to relax a bit and get some code done, but it cut my available time by more than half.
</p>


<h3>Too many new toys</h3>
<p>
I knew I hadn&#8217;t played with encoding video before, so I asked an expert for some tips and tinkered around breaking test videos down into short, easily-transcribed segments. Not coincidentally, this is basically the only feature that works. I started with <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2dpdGh1Yi5jb20vZnVkZ2VzdHVkaW9zL2JvcnQvdHJlZS9tYXN0ZXI=">bort</a> to get a lot of basic functionality quickly, but I had no experience with most of the plugins it provided (and those I otherwise planned to use).
</p>

<dl>
  <dt>aasm</dt> <dd>Differences between acts_as_state_machine (which I started with) and aasm (the successor that bort ships).</dd>
  <dt>haml</dt> <dd>Translating scaffolding from erb to haml and a (still-unsolved) bug that causes it to render content twice on one page. (And I&#8217;ve even used haml before.)</dd>
  <dt>open_id_authentication/restful_authentication</dt> <dd>I wanted users to be able to contribute anonymously or use OpenID to receive credit for their contributions without having to set up an account, and the plugins came configured for conventional user accounts.</dd>
  <dt>resource_this</dt> <dd>I had to fix a templating bug, and there&#8217;s a fair amount of magic to learn to work with.</dd>
  <dt>rspec</dt> <dd>Scaffolded tests needed slow, tedious tweaks to work with resource_this. I think I like the idea of rspec more than the implementation.</dd>
  <dt>paperclip</dt> <dd>Sorting out finicky path/url issues, and I couldn&#8217;t find a way to mock validates_attachment_presence so several models went unspeced..</dd>
</dl>

<p>
Each of these issues ate 30-60m, and there went the time to build. Some plugins (acts_as_versioned, footnotes, random_finders) just worked great, but none was really related to core functionality. Speaking of which:
</p>


<h3>Core featureset too big</h3>
<p>
The line between nothing and application includes site graphic design, listing conferences, uploading presentation videos, splitting videos into segments, adding transcripts, viewing all of the these, editing transcripts&#8230; I had a lot of features listed as optional, but there was still a long set of base features and each uncovered another one of those frustrations.
</p>


<h3>No teammates</h3>
<p>
It would&#8217;ve helped a lot to have someone to work with. Not just because it would have taken less time to finish the core features, but for the enjoyment of teamwork and to complement my weaknesses.
</p>

<h3>All told</h3>
<p>
I&#8217;m glad I spent time I spent hanging out in #railsrumble or on the RailsRumble present.ly. Even if it didn&#8217;t directly result in items checked off the todo list, it&#8217;s been a fun community to be in, and I was glad to help folks out. I&#8217;m eager to see what other people came up with.
</p>

<p>
I didn&#8217;t enter RailsRumble to win, I entered for the excuse to create what I thought was an interesting small project. I&#8217;ll pick ConfReader back up in a little while, probably after the election. I still think it&#8217;s too good an idea not to build, but I&#8217;m a bit tired right now.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=364" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2008/railsrumble-postmortem/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>RailsRumbling</title>
		<link>http://push.cx/2008/railsrumbling</link>
		<comments>http://push.cx/2008/railsrumbling#comments</comments>
		<pubDate>Thu, 16 Oct 2008 13:01:35 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[crunch]]></category>
		<category><![CDATA[experiment]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[RailsRumble]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=356</guid>
		<description><![CDATA[I&#8217;m participating in RailsRumble this weekend, from 8 PM Friday to 8 PM Sunday. The goal is to build a web application in Ruby on Rails in 48 hours, and I welcome the change of pace of a small project. It&#8217;ll be a fun weekend crunch to build it, and I hope it will be [...]]]></description>
			<content:encoded><![CDATA[ <p>
I&#8217;m participating in <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3JhaWxzcnVtYmxlLmNvbS8=">RailsRumble</a> this weekend, from 8 PM Friday to 8 PM Sunday. The goal is to build a web application in Ruby on Rails in 48 hours, and I welcome the change of pace of a small project. It&#8217;ll be a fun weekend crunch to build it, and I hope it will be a long-term resource for the development community.
</p>

<p>
I&#8217;ve watched a lot of video from conferences in the last month or two, and they really frustrated me. Video is slow and linear &#8212; I could read five presentations instead of watching one and wondering if it&#8217;s going to be worth the time it takes. I really appreciate all the presentations, I just get impatient trying to find out if I&#8217;m going to enjoy one, or waiting for the speaker to make their next interesting point. And it&#8217;s hard to share them &#8212; &#8220;Hey, skim this web page&#8221; is a lot easier than &#8220;Hey, commit to watching this hour&#8221;.
</p>

<p>
My app is going make it easy for folks to collaboratively transcribe presentations so anyone can read them alongside the slides. It&#8217;ll break up video into short pieces so people can help transcribe in a few minutes&#8217; spare time rather than a big hours-long investment. If the presenter has put their slides online, they&#8217;ll be integrated with the text. If you&#8217;re a expert with Flash video and want to join in, I could use a hand &#8212; otherwise, that part of the app will probably just be very plain, a video with a timeline control at the bottom rather than something specialized for transcription.
</p>

<p>
If this sounds like a useful site, I&#8217;d really appreciate a few minutes of your help late Saturday or early Sunday. Teams can only be 4 people, but I got the OK to allow the public to work on content on the site during the contest so it doesn&#8217;t have to launch empty. Just watch this blog (or mail me if you&#8217;d like me to remind you) this weekend for the call to come start using the site. Even a few minutes would be a big help.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=356" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2008/railsrumbling/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Username Showdown</title>
		<link>http://push.cx/2008/username-showdown</link>
		<comments>http://push.cx/2008/username-showdown#comments</comments>
		<pubDate>Wed, 15 Oct 2008 16:41:57 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[handle]]></category>
		<category><![CDATA[username]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=352</guid>
		<description><![CDATA[I was reminded in conversation this morning that I&#8217;ve been meaning for months to pick a username that&#8217;s unique and ties to my legal name. One of the ideas suggested (off-blog) was to play with prefixes/affixes on my last name, so let&#8217;s meet the final contenders: disharkins Chicagoese for &#8216;this Harkins&#8217;, contrariness in that &#8216;dis&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p>
I was reminded in conversation this morning that I&#8217;ve been meaning for months to <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwOC9waWNraW5nLWEtdXNlcm5hbWU=">pick a username</a> that&#8217;s unique and ties to my legal name. One of the ideas suggested (off-blog) was to play with prefixes/affixes on my last name, so let&#8217;s meet the final contenders:
</p>

<dl>

    <dt>disharkins</dt>
    <dd>Chicagoese for &#8216;this Harkins&#8217;, contrariness in that &#8216;dis&#8217; means &#8216;not&#8217;. Amusing anagrams like &#8216;radish sink&#8217; and &#8216;I risk hands&#8217;.</dd>

    <dt>malharkins / harkinsprop</dt>
    <dd>Riffs on my old usage of &#8216;malaprop&#8217; as a handle.</dd>

    <dt>preterharkins</dt>
    <dd>Preter- echos the hyper- prefix that used to be faddishly applied to everything Internet. Only a letter away from my name, which is good and bad.</dd>

    <dt>yharkins</dt> 
    <dd>Aweomsely archaic y-, now really only known in the Scrabble-valuable &#8216;yclept&#8217;, meaning &#8216;to name&#8217; (you could choke on all the meta in this post). Also looks like a question. A little potential for collision, though there aren&#8217;t many first names starting with Y.</dd>

    <dt>harkinsant / harkinsarian</dt>
    <dd>Means &#8216;a person who&#8217;, as in servant or librarian.</dd>

</dl>

<p>
They&#8217;re all <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy53YXNoaW5ndG9ucG9zdC5jb20vd3AtZHluL2NvbnRlbnQvYXJ0aWNsZS8yMDA3LzA1LzIzL0FSMjAwNzA1MjMwMTI5MC5odG1s">Googlenopes</a> except yharkins, which got one use a few years ago on a soon-offline fan forum. 
</p>

<p>
Barring any last-minute wildcards (feel free to suggest), I&#8217;m going to go with one of these handles. Please post a comment to let me know which you like or dislike.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=352" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2008/username-showdown/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SEO Hates Science</title>
		<link>http://push.cx/2008/seo-hates-science</link>
		<comments>http://push.cx/2008/seo-hates-science#comments</comments>
		<pubDate>Fri, 08 Aug 2008 17:10:05 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[science]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[statistics]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=326</guid>
		<description><![CDATA[Over at Hacker News somone posted a (fairly misogynist) fairy tale in which the owners of a small website destroy the traffic bestowed on them through the work of their honest and upright SEO consultant by pushing him too far. Throughout, the noble consultant says things like &#8220;In some weeks, go check your traffic. You’ll [...]]]></description>
			<content:encoded><![CDATA[<p>
Over at Hacker News somone posted a (fairly misogynist) <a
href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL25ld3MueWNvbWJpbmF0b3IuY29tL2l0ZW0/aWQ9MjY5Njg0">fairy
tale</a> in which the owners of a small website destroy the traffic
bestowed on them through the work of their honest and upright SEO
consultant by pushing him too far. Throughout, the noble consultant says
things like &#8220;In some weeks, go check your traffic. You’ll find you’ll
have a couple of thousand people come by each day.&#8221; (and, implausibly,
suceeds), so I <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL25ld3MueWNvbWJpbmF0b3IuY29tL2l0ZW0/aWQ9MjY5ODUz">snarked</a>:
</p>

<div class="blockquote"><blockquote>
This is obviously a fairy tale, no SEO consultant would ever give a
quantified, testable prediction of the effects of their work.
</blockquote></div>

<p>
A self-admitted SEO consultant called bullshit on me, saying that not
all SEOs are snake oil salesmen. Well, no, that wasn&#8217;t the bit of truth
that made my joke funny. It&#8217;s that SEOs make vague, unverifiable claims
rather than specific and measured ones.
</p>

<p>
I realize I&#8217;m painting with a broad brush here, but SEO is so Wild West
that consultants make few or no claims and will take credit for any
improvement rather than demonstrate that it was something they
deliberately accomplished. Yes, some SEO is valid and yes, some do more
than &#8220;uh, give your pages titles&#8221;, and yes, a lucky few have managed to
manipuate Google (for now) into giving them scads of traffic. 
</p>

<p>
SEO is alchemy, not chemistry. It doesn&#8217;t measure what it means for a
keyword to be &#8220;competitive&#8221;, it doesn&#8217;t produce formulas to describe the
value of adding meta tags to a page, it doesn&#8217;t promise &#8220;We&#8217;ll increase
your traffic from organic listings by 112% in six weeks or your money
back&#8221;. Part of this is because it <em>can&#8217;t</em>. Search engines
deliberately keep their algorithms obscure to prevent people gaming
them. But then, it&#8217;s not like reality came with an instruction manual
and physicists have done pretty damn well.
</p>

<p>
SEO is alchemical because it has a broken culture based around
boasting, reputation, and hoarding secrets. Click around a few minutes
on the <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2ZvcnVtcy5kaWdpdGFscG9pbnQuY29t">DigitalPoint forums</a>
for all the chest-thumping you care to stomach. I don&#8217;t claim any
special province over <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy56ZWRzaGF3LmNvbS9yYW50cy9wcm9ncmFtbWVyX3N0YXRzLmh0bWw=">statistics</a>,
but I do know that the scientific method <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3hrY2QuY29tLzU0Lw==">works</a>.
</p>

<p>
Maybe there&#8217;s someone with a couple grad courses in math hiding in a
bunker decomposing Google&#8217;s ranking algorithm. Testing hypotheses, 
running experiments, analyzing results, and all with the statistical
rigor that befits a white lab coat. If you were that guy, would you want
to hang out with SEO consultants?
</p>

<p class="aside">
(Seriously, the consultant waved around
<a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy52b2x0YWdlY3JlYXRpdmUuY29tL2Rvd25sb2FkL1ZvbHRhZ2UlMjAzMCUyMERheSUyMFNFTyUyMENhc2UlMjBTdHVkeS5wZGY=">PDF</a> that
touts an instantaneous and miraculous 462% &#8220;massive improvement&#8221; in
traffic &#8220;pouring in&#8221;&#8230; from 5 daily visitors to 23. I can only guess
that somehow he thinks this &#8220;case study&#8221; helps his argument, as I can&#8217;t
possibly see how.)
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=326" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2008/seo-hates-science/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WWW Will Never Die</title>
		<link>http://push.cx/2008/www-will-never-die</link>
		<comments>http://push.cx/2008/www-will-never-die#comments</comments>
		<pubDate>Fri, 27 Jun 2008 01:18:23 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[domain names]]></category>
		<category><![CDATA[GTLDs]]></category>
		<category><![CDATA[ICANN]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=324</guid>
		<description><![CDATA[ICANN is moving steadily to enact a fast-track process for gTLD creation (where &#8220;fast&#8221; here means &#8220;months instead of years&#8221;), so there could be a few more competitors for .com, .net, .pro, and the rest of the gang in a year or two. Some of the early candidates are .bank, .nyc, and .paris. What this [...]]]></description>
			<content:encoded><![CDATA[<p>
ICANN is <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5ndWFyZGlhbi5jby51ay90ZWNobm9sb2d5LzIwMDgvanVuLzI2L2ludGVybmV0">moving steadily to enact</a> a fast-track process for gTLD creation (where &#8220;fast&#8221; here means &#8220;months instead of years&#8221;), so there could be a few more competitors for .com, .net, <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNy9nb29kLXRpbWluZw==">.pro</a>, and the rest of the gang in a year or two. Some of the early candidates are .bank, .nyc, and .paris.
</p>

<p>
What this means, of course, is that <kbd>www</kbd> will never die. When a website could be advertised at &#8220;strand.nyc&#8221; or even just &#8220;google&#8221;, there needs to be something to indicate to the viewer they should go type this into their computer. It&#8217;s not going to be &#8220;Hey, now that you finally get that .com isn&#8217;t some kind of stutter, type <em>this</em> into your computer:&#8221; and it&#8217;s sure not going to be &#8220;http://&#8221;. It&#8217;s going to be <kbd>www</kbd>, and it&#8217;s going to just barely be the lesser of several evils for a long while.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=324" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2008/www-will-never-die/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Free Shipping From Amazon Merchants</title>
		<link>http://push.cx/2008/free-shipping-from-amazon-merchants</link>
		<comments>http://push.cx/2008/free-shipping-from-amazon-merchants#comments</comments>
		<pubDate>Tue, 06 May 2008 20:41:32 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Amazon merchants]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[game design]]></category>
		<category><![CDATA[online shopping]]></category>
		<category><![CDATA[rating]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/?p=315</guid>
		<description><![CDATA[I read a post today about a guy who bought a camera from an Amazon Merchant and left negative feedback after it was shipped poorly (via BoingBoing). They offered to refund the shipping cost ($75) if he&#8217;d take down his negative feedback. This caught my attention, because it&#8217;s happened to me. A few months ago [...]]]></description>
			<content:encoded><![CDATA[<p>
I read a post today about a guy who bought a camera from an Amazon Merchant and <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2RldGhyb25lci5jb20vMjAwOC8wNS8wNS9ueS1jYW1lcmEtc3RvcmUtb2ZmZXJzLWJyaWJlLXRvLWZpeC1hbWF6b24tcmF0aW5nLw==">left negative feedback</a> after it was shipped poorly (via <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5ib2luZ2JvaW5nLm5ldC8yMDA4LzA1LzA1L2NhbWVyYS1zaG9wLW9mZmVycy1jLmh0bWw=">BoingBoing</a>). They offered to refund the shipping cost ($75) if he&#8217;d take down his negative feedback. This caught my attention, because it&#8217;s happened to me.
</p>

<p>
A few months ago I bought from Amazon Merchants for the first time, getting three things from three different merchants. Everything arrived fine and within the same two days, so I went to leave feedback for all of them. They were all small, easily shipped, reasonably-priced, and they arrived fine, so I just gave them all three stars and got on with my day.
</p>

<p>
Within the next few days, all three vendors contacted me and asked me to remove my &#8220;negative&#8221; feedback. Well, not so much negative as &#8220;average&#8221; when I could have chosen &#8220;superb&#8221;. One looked like a form letter. All of them offered to refund my shipping if I&#8217;d delete my rating to stop pulling down their average rating.
</p>

<p>
It sounds like Amazon Merchants believe that even the smallest amount of feedback that&#8217;s not a 5-star rating hurts them significantly. I don&#8217;t know if that&#8217;s correct, if they&#8217;ll be explicitly punished by Amazon or just don&#8217;t want to risk having a lower total rating than their competitors, but they would all pay to remove my imperfect ratings. (I didn&#8217;t mean to harm them, so I just pulled the reviews without getting refunds.)
</p>

<p>
Perhaps it&#8217;s just chance that all four vendors offered to refund shipping to remove less-than-glowing reviews, but I have to wonder if Amazon&#8217;s feedback system is too strict. Buyers won&#8217;t see real negative feedback because Merchants are paying to have it removed. If Merchants can&#8217;t shrug off a few reviews now and then, unscrupulous buyers could leave negative feedback to bully Merchants into giving discounts after the sale.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=315" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2008/free-shipping-from-amazon-merchants/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Painless Upgrade to Rails 2.0</title>
		<link>http://push.cx/2007/painless-upgrade-to-rails-20</link>
		<comments>http://push.cx/2007/painless-upgrade-to-rails-20#comments</comments>
		<pubDate>Thu, 13 Dec 2007 12:10:20 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[ActiveResource]]></category>
		<category><![CDATA[NearbyGamers]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Rails 2.0]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[upgrade]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2007/painless-upgrade-to-rails-20</guid>
		<description><![CDATA[I spent a dead-easy 2.5 hours last night updating NearbyGamers to Rails 2.0. My svn commit message read (with links added here for convenience): Updated to Rails 2.0.1 rm&#8217;d lib/slash_urls.rb: Rails switched from ; to / to separate actions rm&#8217;d lib/resource_requirements.rb: now included in ActiveResources rm&#8217;d app/helpers/tags_helper.rb and gamers_helper.rb that had old controller names and [...]]]></description>
			<content:encoded><![CDATA[<p>
I spent a dead-easy 2.5 hours last night updating <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL05lYXJieUdhbWVycy5jb20=">NearbyGamers</a> to Rails 2.0. My svn commit message read (with links added here for convenience):
</p>

<blockquote>
Updated to Rails 2.0.1

<ul>
<li>rm&#8217;d <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNy9yYWlscy1zZW1pY29sb25zLW91dC1zbGFzaGVzLWlu">lib/slash_urls.rb</a>: Rails switched from ; to / to separate actions</li>
<li>rm&#8217;d <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2Rldi5ydWJ5b25yYWlscy5vcmcvdGlja2V0Lzc2MzMgd2l0aA0KCmh0dHA6Ly9wdXNoLmN4LzIwMDcvcmFpbHMtc2VtaWNvbG9ucy1vdXQtc2xhc2hlcy1pbgoK">lib/resource_requirements.rb</a>: now included in ActiveResources</li>
<li>rm&#8217;d app/helpers/tags_helper.rb and gamers_helper.rb that had old controller names and were unused anyways</li>
<li>app/controllers/gamers_controller.rb: documented and fixed raw post variable extraction</li><li>updated post_path linkers in many views, controllers, and tests</li>
<li>renamed discussion_anchor_post_path to anchor_discussion_post_path to match the new ordering for nested resource urls</li>
<li>fix tag sorting on <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL05lYXJieUdhbWVycy5jb20vdGFncw==">tag index</a></li>
<li>move tags from /tags/Board+Games to <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL05lYXJieUdhbWVycy5jb20vdGFncy9Cb2FyZF9HYW1lcw==">/tags/Board_Games</a>, as Rails fixed the bug that encoded &#8216; &#8216; as &#8216;+&#8217; in non-get variable parts of the URL</li>
</ul>
</blockquote>

<h2>The Details</h2>

<p>
The first two files I deleted were my patches to URL generation that Rails now includes. The next two helper files I never used, but had had old (singular noun) names.
</p>

<p>
The bit about documentation: the way to get at raw post variables changed, so I tweaked code and left myself a reminder of why I&#8217;m doing it (I had to look at the changelog, which means it wasn&#8217;t self-evident).
</p>

<p>
Nested resources (I have nested <kbd>map.resources :discussions { |d| d.resources :posts }</kbd>) changed from <kbd>discussion_edit_post_url</kbd> to <kbd>edit_discussion_post_url</kbd>, so there was a bunch of places to change that. The next change about anchor is me following this convention with my own convenience method.
</p>

<p>
Tag sorting on the index page was a bug that Snarky pointed out to me. When I made some performance tweaks to that page I forgot to keep sorting tags as they came out of the database. This arguably should&#8217;ve been a revision of its own as it&#8217;s unrelated to the upgrade, but it was an easy one-line bugfix so I let it in.
</p>

<p>
Last, I renamed the tag pages. The tag model&#8217;s <kbd>to_param</kbd> just returns <kbd>self.name</kbd> and Rails would turn &#8220;Board Games&#8221; into &#8220;Board+Games&#8221;. It&#8217;s common but technically incorrect, as + only means space in encoded GET/POST variables. The proper encoding of &#8220;Board%20Games&#8221; was really noisy, so I took a page from Wikipedia&#8217;s pagebook and use underscores instead, like &#8220;Board_Games&#8221;. Was one line in the <kbd>to_param</kbd> and one line in the controller&#8217;s <kbd>load_tag</kbd> before_filter, a dozen lines of tweaking old tests, and seven lines of new tests. Eeeeeasy. 
</p>

<h2>The Verdict</h2>

<p>
Tests, tests, tests. If I didn&#8217;t have a solid test suite, I&#8217;d be noticing bugs two months from now in the least-frequently-exercised bits of code. Not only would I not have remembered to test some of the functionality, I wouldn&#8217;t have remembered the corner cases &#8212; or maybe I&#8217;d just have gotten bored of clicking through pages over and over and ignored the corner cases.
</p>

<p>
None of these were hard fixes and none were frustrating. I&#8217;d probably have finished even sooner if I hadn&#8217;t also been poking <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2ljYW5oYXNjaGVlemJ1cmdlci5jb20vMjAwNy8xMi8xMS9taXRvc2lzLw==">lolcats</a> and chatting with friends. And now I have a big list of shiny new Rails 2.0 features I can put to work in <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL05lYXJieUdhbWVycy5jb20=">NearbyGamers</a>.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=292" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2007/painless-upgrade-to-rails-20/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Because Internet Explorer is a Failure, That&#8217;s Why</title>
		<link>http://push.cx/2007/because-internet-explorer-is-a-failure-thats-why</link>
		<comments>http://push.cx/2007/because-internet-explorer-is-a-failure-thats-why#comments</comments>
		<pubDate>Wed, 07 Nov 2007 12:10:37 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[browser support]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[failure]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[support]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2007/because-internet-explorer-is-a-failure-thats-why</guid>
		<description><![CDATA[About once a month since Firefox came out and was promptly recognized as a six-gallon bucket of awesome I read a blog post about how developers are lazy, shiftless bastards because they don&#8217;t want to support Internet Explorer anymore. Most recently I read Brian Reindel make this claim, so I&#8217;m going to pick on him [...]]]></description>
			<content:encoded><![CDATA[<p>
About once a month since Firefox came out and was promptly recognized as a six-gallon bucket of awesome I read a blog post about how developers are lazy, shiftless bastards because they don&#8217;t want to support Internet Explorer anymore. Most recently I read Brian Reindel <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2Jsb2cucmVpbmRlbC5jb20vMjAwNy8xMS8wNi9tYWtlLXRoZS1hLWdyYWRlLW9yLWZhaWwtdHJ5aW5nLw==">make this claim</a>, so I&#8217;m going to pick on him while I rebut this insult.
</p>

<p>
Yahoo defined the term  &#8220;<a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2RldmVsb3Blci55YWhvby5jb20veXVpL2FydGljbGVzL2dicy8=">graded browser support</a>&#8220;: popular browsers get A-grade support, less common ones get C-grade support, and a tiny number of almost-unused browsers get X-grade support (which is an obfuscated way to say &#8220;no support&#8221;). It makes sense to formally specify where you&#8217;ll spend your time. Reindel manages to turn this whole definition around, though. He writes about A-grade browser support, then drifts into talking about &#8220;A-grade browsers&#8221;. These are not at all the same thing.
</p>

<p>
Developers can choose to give A-grade browser support to Internet Explorer because it enjoys a huge (if declining) market share. Users can&#8217;t tell whether they&#8217;re seeing IE&#8217;s misfeatures, flaws, and bugs or our website&#8217;s, so we work late into the evening to make IE behave enough that we don&#8217;t look bad. Sometimes developers decide that IE isn&#8217;t worth the trouble, and Reindel opines that it&#8217;s because they&#8217;re unprofessional or incompetent. No, it&#8217;s because Internet Explorer is a failure, what&#8217;s why.
</p>

<p>
Internet Explorer is not an &#8220;A-grade browser&#8221;. It has a large number of <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5iYXpvbi5uZXQvbWlzaG9vL2FydGljbGVzLmVwbD9hcnRfaWQ9OTU4">painful</a> and <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5wb3NpdGlvbmlzZXZlcnl0aGluZy5uZXQvZXhwbG9yZXIuaHRtbA==">common bugs</a> that were left to fester for five years between IE 6 and 7 &mdash; and then many still are unfixed. The rise of Firefox (and, to a lesser extent, Opera and Safari) has shown developers how good browsers can be, to say nothing of how well browsers can support developers. It&#8217;s normal and healthy that developers reduce IE support. Aside from the pure professional joy of tools that work, it doesn&#8217;t make business sense to keep spending the majority of your time working around the problems caused by one browser unless that one browser has a strong majority in your userbase.
</p>

<p>
When building the moderately-complex layouts for <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20=">NearbyGamers</a> I realized I was wasting time supporting IE for a tech-savvy audience who likely wouldn&#8217;t be using it. Even though NG is a professional site and the current highlight of my portfolio, with IE&#8217;s 32% share it would be a mistake to spend time tearing my hair out over it instead of improving the site in general. My analytics show that IE users view the same number of pages, visit for the same length of time, and convert in the same numbers as users of A-grade browsers. Yes, in IE the fonts are weird, elements are mispositioned, text spacing is inelegant, and there are probably many other small bugs I haven&#8217;t even bothered looking for. The site isn&#8217;t hemorrhaging IE visitors, so IE is getting more support than it&#8217;s earned. 
</p>

<p>
This behavior isn&#8217;t the straw-man &#8220;laziness&#8221; that Reindel attacks, it&#8217;s the highest professional business sense and commitment to productive quality. Microsoft ignored our half-decade of &#8220;constant complaining&#8221; because they thought they had a lock on the market. Developers who publicly reduce their support for IE are using their voice and their practice to push for better support from the browsers.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=272" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2007/because-internet-explorer-is-a-failure-thats-why/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>These Elves are People</title>
		<link>http://push.cx/2007/these-elves-are-people</link>
		<comments>http://push.cx/2007/these-elves-are-people#comments</comments>
		<pubDate>Thu, 04 Oct 2007 14:00:22 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Club Penguin]]></category>
		<category><![CDATA[gaming]]></category>
		<category><![CDATA[Habbo Hotel]]></category>
		<category><![CDATA[journalism]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[MetaPlace]]></category>
		<category><![CDATA[mmorpgs]]></category>
		<category><![CDATA[online gaming]]></category>
		<category><![CDATA[puzzle pirates]]></category>
		<category><![CDATA[virtual worlds]]></category>
		<category><![CDATA[Washington Post]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web 2.0]]></category>
		<category><![CDATA[World of Warcraft]]></category>

		<guid isPermaLink="false">http://push.cx/2007/these-elves-are-people</guid>
		<description><![CDATA[It&#8217;s important for journalism address virtual worlds because they&#8217;ve become the &#8220;third place&#8221; after Home and Work that Starbucks has been trying to fill for the last decade and change. Adults go online to hang out instead of the bar; teenagers go online to try on new personalities instead of the mall. My barber shocked [...]]]></description>
			<content:encoded><![CDATA[<p>
It&#8217;s important for journalism address virtual worlds because they&#8217;ve become the &#8220;third place&#8221; after Home and Work that Starbucks has been trying to fill for the last decade and change. Adults go online to hang out instead of the bar; teenagers go online to try on new personalities instead of the mall.
</p>

<div class="blockquote"><blockquote>
My barber shocked the hell out of me last week when he told me was playing Horde Priest. Who the hell cares if Joi Ito and his buddies have replaced their non-existent golf game with long sessions in Molten Core? Those guys are nerds. MY FRACKING BARBER IS A HORDE PRIEST PEOPLE.
<cite><a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5yYW5kc2lucmVwb3NlLmNvbS9hcmNoaXZlcy8yMDA2LzAzLzA2L29uZV9sZXNzb25fZnJvbV9hX25pZ2h0X2VsZi5odG1s">Rands</a></cite>
</blockquote></div>

<p>
The real issue is that online gaming has been around 30 years and, thanks to steep drops in the cost of PCs and Internet connectivity, exploded from being a niche subculture to popular entertainment. Imagine if TV hadn&#8217;t blown two decades imitating radio and very slowly growing popular but instead sprang Athena-like into half of American households. Journalism has been catching up, trying to squeeze a <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5hbnRpcG9wZS5vcmcvY2hhcmxpZS9ibG9nLXN0YXRpYy8yMDA3LzA3L3VucGFja2luZ190aGVfemVpdGdlaXN0Lmh0bWw=">huge infodump</a> into a few column inches. Do you confuse the half of your audience who&#8217;ve never changed a channel or do you bore the half who&#8217;ve got surround sound? By exclusively addressing the former, journalism has <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5zY290dGFhcm9uc29uLmNvbS93cml0aW5ncy9hdGhsZXRlcy5odG1s">alienated</a> the latter. 
</p>

<p>
Online communities take the form of chat rooms, blogs, forums, and virtual worlds (which includes games). Journalism more-or-less understands the first three, and the rest is easy from there. Virtual worlds are persistent chat rooms with a sense of place (though the folks involved will probably also talk on blogs and forums). Games are virtual worlds with rules and objectives. When journalists understand this background they can stop writing &#8220;This guy pretends to be an elf&#8221; and start writing &#8220;<a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy56ZW5vZmRlc2lnbi5jb20vP3A9OTU5">These elves are people</a>&#8220;. When journalists understand this background, they&#8217;ll be fighting for column inches instead of wondering what to write, and gamers will be following the news instead of rolling their eyes.
</p>

<p>
The one lesson journalism must learn is to start treating gaming like the mainstream medium it has become. It&#8217;s news when there&#8217;s a major franchise release, or a small studio pushes boundaries, or genres wax and wane &#8212; whether we&#8217;re talking about TV, movies, or games. Journalism fails when it covers games because doesn&#8217;t yet have the expertise to tell <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2ZvcmdlLmlyb25yZWFsbXMuY29tLzIwMDcvMTAvMDMvYnJlYWtpbmctbmV3cy1odWxhLWhvb3BzLW5vLWxvbmdlci1ob3Qv">dead horses</a> from new developments or PR from reality. There are dedicated gaming news outlets, but they&#8217;re nearly all awful because their background is gaming, not journalism; the gaming press hasn&#8217;t been able to build the firewall between news and advertising to do much serious journalism. The few game publishers punish negative and merely critical reviews by withholding access to upcoming titles and gaming press doesn&#8217;t have the diversified income to weather the loss.
</p>

<p>
To briefly talk about specific virtual worlds, Second Life is one world among many, and it&#8217;s <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3ZhbGxleXdhZy5jb20vdGVjaC9zZWNvbmQtbGlmZS9hLXN0b3J5LXRvby1nb29kLXRvLWNoZWNrLTIyMTI1Mi5waHA=">not a good one</a>. Second Life is small, limited, and has no real community. It&#8217;s only been a media darling because it has a modern theme; if you&#8217;re new to virtual worlds Second Life is less intimidating than pointy ears and spaceships. Gaming is maturing into a huge popular medium, especially with the
now-in-progress fusion of casual gaming and online gaming. <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5oYWJiby5jb20=">Habbo Hotel</a> and <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5wdXp6bGVwaXJhdGVzLmNvbQ==">Puzzle Pirates</a> are trailblazers, <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5jbHVicGVuZ3Vpbi5jb20vbmV3cy5odG0=">Club Penguin</a> is the dawning recognition of big
media, and <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5tZXRhcGxhY2UuY29t">Metaplace</a> is the future.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=264" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2007/these-elves-are-people/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails 1.2.1 Impression</title>
		<link>http://push.cx/2007/rails-121-impression</link>
		<comments>http://push.cx/2007/rails-121-impression#comments</comments>
		<pubDate>Thu, 15 Feb 2007 02:52:24 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[assert_select]]></category>
		<category><![CDATA[assert_tag]]></category>
		<category><![CDATA[Barking Stapler]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2007/rails-121-impression</guid>
		<description><![CDATA[I&#8217;m updating NearbyGamers to Rails 1.2.1. Nothing broke except my use of assert_tag in my tests; it&#8217;s been long-regarded as squicky and has been replaced with assert_select. As I&#8217;m tidying up some deprecated code, it occurs to me that this makes for an interesting example of how I feel Rails is changing. Rails is growing [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;m updating <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20=">NearbyGamers</a> to Rails 1.2.1. Nothing broke except my use of <kbd>assert_tag</kbd> in my tests; it&#8217;s been long-regarded as squicky and has been replaced with <kbd>assert_select</kbd>. As I&#8217;m tidying up some deprecated code, it occurs to me that this makes for an interesting example of how I feel Rails is changing.
</p>

<p>
Rails is growing inwards and upwards, not just outwards. They&#8217;re finding better, terser, more Rails-ish ways to express things. They&#8217;re not piling on features, they&#8217;re condensing. <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNy9hbm5vdW5jaW5nLW5lYXJieWdhbWVycw==">I&#8217;ve mentioned</a> that this is what coding in Rails continually feels like: sometimes it just feels off even though it works and is nicer than other languages, and soon I realize a beautiful Right Way to do it.
</p>

<p>
Where Rails gained new features, the developers have redesigned functionality to make me think, &#8220;Wow, of course, that&#8217;s obviously much nicer&#8221; and it does more because it&#8217;s better-designed. Let me give you an example using <kbd>assert_tag</kbd>.
</p>

<p>
I&#8217;ve got tests that render pages and make sure they contain certain bits of HTML. One test used to be:
</p>

<pre>&nbsp;
assert_tag :tag =&gt; <span style="color: #ff0000;">"div"</span>,
           :attributes =&gt; <span style="color: #66cc66;">&#123;</span> :id =&gt; <span style="color: #ff0000;">'notice'</span> <span style="color: #66cc66;">&#125;</span>,
           :child =&gt; <span style="color: #66cc66;">&#123;</span>
             :tag =&gt; <span style="color: #ff0000;">"div"</span>,
             :content =&gt; text
           <span style="color: #66cc66;">&#125;</span></pre>

<p>And now it reads:</p>

<pre>&nbsp;
assert_select <span style="color: #ff0000;">"div#notice &gt; div"</span>, text</pre>

<p>
They rebuilt the assertion to use CSS selectors (with a few <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2Jsb2cubGFibm90ZXMub3JnLzIwMDYvMDkvMDQvYXNzZXJ0X3NlbGVjdC1jaGVhdC1zaGVldC8=">clever additions</a>). Suddently the code is simpler, more idiomatic, and more featureful. And that&#8217;s just what coding Rails feels like.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=216" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2007/rails-121-impression/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Sociable 2.0 Released</title>
		<link>http://push.cx/2007/sociable-20-released</link>
		<comments>http://push.cx/2007/sociable-20-released#comments</comments>
		<pubDate>Sat, 03 Feb 2007 06:50:57 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[Sociable]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2007/sociable-20-released</guid>
		<description><![CDATA[Sociable 2.0 is out! 2.0 contains plenty of new features: 61 sites, subtler icons to avoid clashing with your theme, translation into German, French, Hungarian, and Italian, and more. It lays the groundwork to expand into more languages and more blog engines, so 2007 is going to be bigger than ever. If you&#8217;d like to [...]]]></description>
			<content:encoded><![CDATA[<!-- Sociable:Update date="2007-02-02" -->

<p>
<a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=L3NvY2lhYmxl">Sociable 2.0</a> is out!
</p>

<p>
2.0 contains plenty of new features: 61 sites, subtler icons to avoid clashing with your theme, translation into German, French, Hungarian, and Italian, and more. It lays the groundwork to expand into more languages and more blog engines, so 2007 is going to be bigger than ever.
</p>

<p>
If you&#8217;d like to hear me babble a bit about Sociable, check out <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2RhdmlkZGFsa2EuY29tL2NyZWF0ZXZhbHVlLzIwMDcvMDEvMzEvc29jaWFibGUtMjAtcGx1Z2luLXJlbGVhc2UtaW50ZXJ2aWV3LXBldGVyLWhhcmtpbnMv">this interview</a>. First time I&#8217;ve been interviewed.
</p>

<p>
Sometimes folks ask me if Sociable has a &#8216;tip jar&#8217; so they could donate to support it. The sites that are on by default have generously sponsored Sociable, so keeping them turned on is a great way for you to support Sociable. Thanks!
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=214" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2007/sociable-20-released/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Announcing NearbyGamers</title>
		<link>http://push.cx/2007/announcing-nearbygamers</link>
		<comments>http://push.cx/2007/announcing-nearbygamers#comments</comments>
		<pubDate>Mon, 22 Jan 2007 04:11:06 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[Barking Stapler]]></category>
		<category><![CDATA[NearbyGamers]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2007/announcing-nearbygamers</guid>
		<description><![CDATA[I&#8217;d like to invite you all to check out my newest project, NearbyGamers, a service for tabletop gamers to find other players. (As I mentioned earlier, it&#8217;s a Rails site.) It&#8217;s for people who play RPGs, CCGs, TCGs, wargames, board games &#8212; basically any game where you need to have a live human on the [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;d like to invite you all to check out my newest project, <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL05lYXJieUdhbWVycy5jb20=">NearbyGamers</a>, a service for tabletop gamers to find other players. (As I <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNi9tYWtpbmctdmFsaWQteGh0bWwtZWFzaWVy">mentioned earlier</a>, it&#8217;s a Rails site.) It&#8217;s for people who play RPGs, CCGs, TCGs, wargames, board games &#8212; basically any game where you need to have a live human on the other side of a table if you want to play.
</p>

<img class="content" src="http://push.cx/wp-content/uploads/2007/01/NG-map.png" alt="NearbyGamers map screenshot" />

<p>
Basically it&#8217;s the mashup of a wiki and Google Maps, and I plan to add forums (there are very few things gamers like more than arguing online). I&#8217;ve been hacking at it on and off for a couple months now, and it&#8217;s finally worth talking about. NG is my first large Rails project, and it&#8217;s been a lot of fun. Almost all the time the code is quite dense and beautiful, but several times I&#8217;ve worked up some fairly ugly hackish code I&#8217;m not particularly happy with. And then a few days later an nice, friendly little solution will pop into my head, and it&#8217;s easy to hack in because I have comprehensive tests. (Having tests has really saved my life. I&#8217;ll be posting more about it, but for now I&#8217;ll just say that I couldn&#8217;t have built NG without automated tests.)
</p>

<p>
Some of the early beta testers are computer game fans, so there&#8217;s a fair number of computer games listed on NearbyGamers right now &#8212; heck, <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20vdGFnL1dvcmxkK29mK1dhcmNyYWZ0">World of Warcraft</a> is the most popular tag. I don&#8217;t see what folks will get out of it, but I&#8217;d rather build a pretty open system and let folks find new uses.
</p>

<p>
So check it out, let me know what you think. I&#8217;ve got a <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL25lYXJieWdhbWVycy5jb20vdG9kby55bWw=">todo list</a> online for the curious, and I&#8217;m always taking suggestions.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=197" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2007/announcing-nearbygamers/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Microsoft AdCenter&#8217;s 316-page Terms of Service</title>
		<link>http://push.cx/2006/microsoft-adcenters-316-page-terms-of-service</link>
		<comments>http://push.cx/2006/microsoft-adcenters-316-page-terms-of-service#comments</comments>
		<pubDate>Fri, 29 Dec 2006 20:50:32 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[AdCenter]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2006/microsoft-adcenters-316-page-terms-of-service</guid>
		<description><![CDATA[I signed up for Microsoft AdCenter, and got an interesting presentation of terms and condititions: The terms and conditions are exactly 2,840 words long. At 9 words each, that&#8217;s 316 pages. There&#8217;s no way to resize the TOS div and, yes, the whole form is abnormally wide. Between the above problems and the problems in [...]]]></description>
			<content:encoded><![CDATA[<p>
I signed up for Microsoft AdCenter, and got an interesting presentation of terms and condititions:
</p>

<img class="content" src="http://push.cx/wp-content/uploads/2006/12/adcenter.png" alt="Microsofter AdCenter's TOS" />

<p>
The terms and conditions are exactly 2,840 words long. At 9 words each, that&#8217;s 316 pages. There&#8217;s no way to resize the TOS div and, yes, the whole form is abnormally wide.
</p>

<p>
Between the above problems and the problems in the rest of the signup, I have to guess they failed to test in Firefox. I can see why Microsoft might not want to, but 30% of surfers use Firefox, and it&#8217;s a far higher percentage higher for the web professionals who are going to be using this service.
</p>

<p>
It does get worse: when I go to sign in I type my username and password, click &#8220;Sign In&#8221;, and am presented with the sign in form with my username and no password or errors. It just silently fails to log me in. I&#8217;m not too optimistic about their support, they can&#8217;t even keep the url to it from breaking across two lines in the &#8220;Welcome to AdCenter&#8221; mail.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=192" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2006/microsoft-adcenters-316-page-terms-of-service/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cambrian House Party</title>
		<link>http://push.cx/2006/cambrian-house-party</link>
		<comments>http://push.cx/2006/cambrian-house-party#comments</comments>
		<pubDate>Tue, 27 Jun 2006 18:09:59 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Biz]]></category>
		<category><![CDATA[Cambrian House]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://push.cx/2006/cambrian-house-party</guid>
		<description><![CDATA[Cambrian House, the startup I snuck a peek at and got a hat-tip from has opened for a public beta test. They&#8217;re sort of an open-source business incubator: folks submit ideas, the best of which become projects; folks submit code, art, and copy, the best of which go into the finished project. Cambrian House (or [...]]]></description>
			<content:encoded><![CDATA[<p>
<img class="decoration" src="http://push.cx/wp-content/uploads/2006/06/graphic-avatar.gif" alt="Cambrian House default avatar" height="75" width="75" />
<a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2NhbWJyaWFuaG91c2UuY29t">Cambrian House</a>, the startup I <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNi9wcmUtY2FtYnJpYW4taG91c2U=">snuck a peek at</a> and <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNi9jYW1icmlhbi1kZXZlbG9wbWVudA==">got a hat-tip from</a> has opened for a public beta test. They&#8217;re sort of an open-source business incubator: folks submit ideas, the best of which become projects; folks submit code, art, and copy, the best of which go into the finished project. Cambrian House (or a spinoff company, perhaps) runs the project as an online business, paying royalties back to the folks who contributed.
</p>

<p>
It&#8217;s a darn clever idea and I want to see them succeed. Go easy on the site&#8217;s rough edges, it&#8217;s truly beta, not that faux-beta that Google sticks finished products in for years to avoid doing support.
</p>

<p>
<img class="decoration" src="http://push.cx/wp-content/uploads/2006/06/Peter-Pwned-Us.gif" alt="Cambrian House &quot;9&quot; Award" height="33" width="33" />
True to their CEO&#8217;s mail, I&#8217;m still user number 9. I&#8217;d link to my profile, but I can&#8217;t find a URL for *any* profiles. (Just one of those rough edges that true beta products have.) Contributors can earn cute little awards (think of Boy Scout badges) for sending in ideas and such. I&#8217;ve got a &#8220;9&#8243; award with the text &#8220;Peter will always be #9 to us.&#8221; 
</p>

<p>
I&#8217;ve poked around the site and even <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5jYW1icmlhbmhvdXNlLmNvbS9pZGVhLXdhcnovaWRlYS1zdW1tYXJ5L2lkZWFzX2lkLyVCOHolMDIlRjQlQUElOTIlRDMlQkY=">submitted an idea</a> (I sniffed out the link for my idea, but it&#8217;s an uuugly URL and unfortunately doesn&#8217;t link to my profile). It&#8217;s like a fun project and I&#8217;m already a fan, so I&#8217;ll contribute to a project or two and blog about it.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=144" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2006/cambrian-house-party/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building Clean URLs Into a Site</title>
		<link>http://push.cx/2006/building-clean-urls-into-a-site</link>
		<comments>http://push.cx/2006/building-clean-urls-into-a-site#comments</comments>
		<pubDate>Fri, 23 Jun 2006 17:26:28 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2006/building-clean-urls-into-a-site</guid>
		<description><![CDATA[I wrote about building a site with clean URLs, but that&#8217;s useless to you. No, you&#8217;ve got a creaking hulking monster of a site that coughs up URLs like &#8220;render.php?action=list_mailbox&#038;id=42189&#8243;, was built &#8220;to meet an accelerated schedule&#8221;, and eats summer interns whole. This article tells you how to put clean and human-usable URLs on top [...]]]></description>
			<content:encoded><![CDATA[<p>
I wrote about <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3B1c2guY3gvMjAwNi9idWlsZGluZy1hLXNpdGUtd2l0aC1jbGVhbi11cmxz">building a site with clean URLs</a>, but that&#8217;s useless to you. No, you&#8217;ve got a creaking hulking monster of a site that coughs up URLs like &#8220;render.php?action=list_mailbox&#038;id=42189&#8243;, was built &#8220;to meet an accelerated schedule&#8221;, and eats summer interns whole.
</p>

<p>
This article tells you how to put clean and human-usable URLs on top of the site without even editing your underlying scripts. All these examples mention PHP but it doesn&#8217;t matter what you coded the site in, you just have to be running Apache and have a little familiarity with regular expressions.
</p>

<p>
So we have two goals. First, requests for the new URL are internally rewritten to call the existing scripts without users ever knowing they exist. Second, requests for the old URLs get a 301 redirect to the new URLs so that search engines and good bookmarks immediately switch to the new URLs.
</p>

<p>
Let&#8217;s work through an example <kbd>.htaccess</kbd> file. We take apart the new URLs and map them internally to the old URLs:
</p>

<pre>
RewriteEngine on

RewriteRule ^new/(.*)/(.*)$ /old.php?action=$1&#038;id=$2 [L]
</pre>

<p>
This works great, so we dive into the 301 redirects:
</p>

<pre>
RewriteEngine On

RewriteRule ^new/(.*)/(.*)$ /old.php?action=$1&#038;id=$2 [L]
RewriteCond %{QUERY_STRING} ^action=([a-z]+)&#038;id=([0-9]+)
RewriteRule ^old\.php$ /new/%1/%2? [R=301,L]
</pre>

<p>
<i>Arrrgh!</i> We test this and find a problem: all requests for <kbd>new</kbd> are getting 301 redirected back to <kbd>new</kbd>. Apache is rewriting <kbd>new</kbd> to <kbd>old</kbd> fine, but then it sends the new URL back through mod_rewrite again so we&#8217;re stuck in an infinite loop of redirects (even though the <kbd>[L]</kbd> option is supposed to tell Apache to stop applying rules). We need to turn it up to 11 and tell Apache &#8220;No, really, stop rewriting URLs now&#8221; by setting a flag that it already rewrote the URL.
</p>

<pre>
RewriteEngine on
# This rule just keeps DirectoryIndex working (so requests for / go to /index.php or whatever)
RewriteRule ^$ - [L]
# Set an environment variable REWROTE that we haven't done any rewriting
RewriteRule ^(.*)$ $1 [E=REWROTE:0]

# Flag that the new URL rewrote
RewriteRule ^new/(.*)/(.*)$ /old.php?action=$1&#038;id=$2 [L,E=REWROTE:1]
# Only rewrote the old url if we didn't rewrite
RewriteCond %{ENV:REWROTE} !^1$
RewriteCond %{QUERY_STRING} ^action=([a-z]+)&#038;id=([0-9]+)
RewriteRule ^old\.php$ /new/%1/%2? [R=301,L]
</pre>

<p>
This set of rewrite rules accomplishes both our goals and the new URLs are all we&#8217;ll ever see in the address bar. You can set up any number of rewritten URLs (there&#8217;s no need to repeat the code turning on rewriting and REWROTE flag), editing them for your particular GET variables and layout.
</p>

<p>
Proudly displaying our shiny new URLs, we can send in surgical teams into the site&#8217;s source code file-by-file, slowly and carefully replacing instances of the old URLs with the new ones. Once all the URLs are replaced, you can watch your server logs to see usage of the old URLs fall off. The way is now prepared for you to further beautify your site inside and out.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=142" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2006/building-clean-urls-into-a-site/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Rails Day 2006</title>
		<link>http://push.cx/2006/rails-day-2006</link>
		<comments>http://push.cx/2006/rails-day-2006#comments</comments>
		<pubDate>Sat, 17 Jun 2006 18:02:41 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2006/rails-day-2006</guid>
		<description><![CDATA[I&#8217;m sort of participating in Rails Day 2006. I say &#8220;sorta&#8221; because I&#8217;m trying to build an app in one day but I&#8217;m not actually in the competition. The biggest reason I&#8217;m not officially participating is that contestants are required to use their Subversion server. I&#8217;d still have my code at the end of the [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;m sort of participating in <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3d3dy5yYWlsc2RheTIwMDYuY29tLw==">Rails Day 2006</a>. I say &#8220;sorta&#8221; because I&#8217;m trying to build an app in one day but I&#8217;m not actually in the competition.
</p>

<p>
The biggest reason I&#8217;m not officially participating is that contestants are required to use their Subversion server. I&#8217;d still have my code at the end of the day, but I wouldn&#8217;t have any of my version-control metadata. That&#8217;s totally unacceptable. I&#8217;ll want to be able to rewind to old commits, check out my log messages, all that good stuff. They seem like cool folks and I could probably mail them and ask for a dump, but version control is one of the few places I&#8217;m completely risk averse. A chance at a laptop simply isn&#8217;t worth the hassle, delay, and risk.
</p>

<p>
It&#8217;s plain coincidence that I&#8217;m developing a Rails app today. I saw Rails Day a few weeks ago and forgot about it and wasn&#8217;t reminded until after their registration deadline. (Why is there even a deadline? Who cares whether a participant signs up a week before it starts or six hours into it?)
</p>

<p>
I&#8217;m coding a Rails app today because I finished the tutorial in Agile Web Development With Rails (2nd ed) earlier this week and I need a practice project. I&#8217;m going to completely revamp <a href="http://push.cx/wp-content/plugins/feed-statistics.php?url=aHR0cDovL21hbGFwcm9wLm9yZw==">malaprop.org</a> into a personal portfolio. I&#8217;ve been meaning to do it for months, so it lept out at me when I looked through my TODO file for a well-bounded project.
</p>

<p>
In case anyone is wondering &#8220;Hey, Peter, you crazy Python-lover, what&#8217;s all this about Rails?&#8221; I&#8217;ll explain a little. I&#8217;m going to start up a web-based game and when I evaluated frameworks, Rails was the clear winner for my requirements. Sorry to tease, but that&#8217;s all I&#8217;m going to post about it at the moment. If you&#8217;re curious, just watch this space over the next few weeks.
</p> <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=138" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2006/rails-day-2006/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Developing With Evil</title>
		<link>http://push.cx/2006/developing-with-evil</link>
		<comments>http://push.cx/2006/developing-with-evil#comments</comments>
		<pubDate>Thu, 15 Jun 2006 19:50:06 +0000</pubDate>
		<dc:creator>Peter Harkins</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://push.cx/2006/developing-with-evil</guid>
		<description><![CDATA[allaryin: whee&#8230; allaryin: i&#8217;ve been given a job to put a simple email address subscription form on a site Harkins: sounds pretty easy allaryin: and&#8230; as far as i can tell, the server has neither php nor perl :P allaryin: i&#8217;m running out of options :P Harkins: cgi, baby allaryin: for db access? Harkins: Or [...]]]></description>
			<content:encoded><![CDATA[<p>
<span style="color: red">allaryin</span>: whee&#8230;<br />
<span style="color: red">allaryin</span>: i&#8217;ve been given a job to put a simple email address subscription form on a site<br />
<span style="color: blue">Harkins</span>: sounds pretty easy<br />
<span style="color: red">allaryin</span>: and&#8230; as far as i can tell, the server has neither php nor perl :P<br />
<span style="color: red">allaryin</span>: i&#8217;m running out of options :P<br />
<span style="color: blue">Harkins</span>: cgi, baby<br />
<span style="color: red">allaryin</span>: for db access?<br />                  <span style="color: blue">Harkins</span>: Or change the target of the form to a server you control running PHP/perl that saves the data and redirects back to the other server.<br />
<span style="color: red">allaryin</span>: yeah&#8230;<br />                         <span style="color: red">allaryin</span>: but i really don&#8217;t want to commit any of our server resources to their site :P<br />
<span style="color: green">BSDCat</span>: I think a &#8216;simplicity&#8217; fairy just lost its wings<br />
<span style="color: blue">Harkins</span>: Or make the form GET and write a cron job to scrape access.log.<br />
<span style="color: red">allaryin</span>: &#8230;<br />
<span style="color: red">allaryin</span>: wow.<br />
<span style="color: blue">Harkins</span>: Yes, I&#8217;m evil.<br />
<span style="color: red">allaryin</span>: it&#8217;s beautiful really<br />
<span style="color: blue">Harkins</span>: bwa<br />
<span style="color: red">allaryin</span>: but yes, evil<br />
</p>
 <img src="http://push.cx/wp-content/plugins/feed-statistics.php?view=1&post_id=129" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://push.cx/2006/developing-with-evil/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
