<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.hypsometry.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.hypsometry.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Hypsometry</title>
    <link>http://blog.hypsometry.com</link>
    <language>en</language>
    <webMaster>info@hypsometry.com (Chris Boone)</webMaster>
    <copyright>Copyright 2005-2008</copyright>
    <ttl>60</ttl>
    <pubDate>Wed, 23 Apr 2008 03:00:28 GMT</pubDate>
    <description>Modal Synthesis</description>
    <geo:lat>37.74873</geo:lat><geo:long>-122.415457</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.hypsometry.com/hypsometry/blog/articles" type="application/rss+xml" /><feedburner:emailServiceId>1041929</feedburner:emailServiceId><feedburner:feedburnerHostname>http://www.feedburner.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.hypsometry.com%2Fhypsometry%2Fblog%2Farticles" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.hypsometry.com%2Fhypsometry%2Fblog%2Farticles" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.hypsometry.com/hypsometry/blog/articles" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.hypsometry.com%2Fhypsometry%2Fblog%2Farticles" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.hypsometry.com%2Fhypsometry%2Fblog%2Farticles" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><item>
      <title>On music, and simplicity, and success.</title>
      <link>http://blog.hypsometry.com/archives/2008/4/23/on_music_and_simplicity_and/</link>
      <pubDate>Wed, 23 Apr 2008 02:59:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/4/23/on_music_and_simplicity_and/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2317274147/"&gt;&lt;img src="http://farm4.static.flickr.com/3258/2317274147_7060d023dc_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://muxtape.com/"&gt;Muxtape&lt;/a&gt; is incredibly simple: Upload some songs and you&amp;#8217;ve got a mix.&lt;/p&gt;&lt;p&gt;As a friend of mine wrote:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;It feels like there&amp;#8217;s nothing to it. But really, I like that. There seems to be little space for people&amp;#8217;s overblown internet identities. Only jams.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;So true. No friends, no profiles, no activity updates, no notification emails&amp;#8212;just the music. All you need, and nothing more.&lt;/p&gt;&lt;p&gt;You can listen to my current mix at &lt;a href="http://cboone.muxtape.com/"&gt;cboone.muxtape.com&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/276372812" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/design">design</category>
      <category domain="http://blog.hypsometry.com/archives/tags/music">music</category>
    </item>
    <item>
      <title>On tea, hand printing, layers, type, and the door to my kitchen.</title>
      <link>http://blog.hypsometry.com/archives/2008/3/12/on_tea_hand_printing_layers/</link>
      <pubDate>Wed, 12 Mar 2008 09:12:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/3/12/on_tea_hand_printing_layers/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2303601394/"&gt;&lt;img src="http://farm3.static.flickr.com/2013/2303601394_bef66fc384_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Last week I spent a few days brainstorming the design of our new site. That included &lt;a href="http://twitter.com/cboone/statuses/766735439"&gt;a lovely afternoon&lt;/a&gt; at &lt;a href="http://www.samovartea.com/"&gt;Samovar&lt;/a&gt;, sketching, rereading &lt;a href="http://blog.hypsometry.com/archives/2008/3/5/on_tradition_harmony_pitch_the/"&gt;Bringhurst&lt;/a&gt;, and looking through &lt;a href="http://www.tdc.org/publications/annual28.html"&gt;Typography 28&lt;/a&gt;, last year&amp;#8217;s edition of &lt;a href="http://www.tdc.org/"&gt;the Type Directors Club&lt;/a&gt; annual.&lt;/p&gt;&lt;p&gt;The work in it &amp;#8211; both the winners and the other selections &amp;#8211; is superb, as it should be. &lt;a href="http://hammerpress.net/posters/poster_pop_ups/hp030_popup.html"&gt;The winning poster&lt;/a&gt;, for a &lt;a href="http://www.wilcoworld.net/"&gt;Wilco&lt;/a&gt; show, was created by &lt;a href="http://hammerpress.net/"&gt;Hammerpress&lt;/a&gt;, a design and letterpress studio in Kansas City, Missouri. It&amp;#8217;s a beautiful, subtle, and elegant piece of work.&lt;/p&gt;&lt;p&gt;Hammerpress and Brady Vest, the studio&amp;#8217;s founder, have six other posters featured in Typography 28. All of them letter pressed in a style that&amp;#8217;s old fashioned in its components &amp;#8211; the typefaces, the decorations, the centered text &amp;#8211; but contemporary in its execution. You can see more of their poster work &lt;a href="http://hammerpress.net/posters/posters.html"&gt;in their site&amp;#8217;s gallery&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;One thing all the pieces have in common are colors that overlap in a dense, bright, but coherent jumble. Each print is built up from layers of ink, whether type or image or decoration, one atop the next.&lt;/p&gt;&lt;p&gt;Coincidentally, I bought &lt;a href="http://hammerpress.net/art_prints/art_print_pop_ups/art_print_popup_1.html"&gt;a Hammerpress print&lt;/a&gt; the other day. Four layers of white ink on a brown stock.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2330259510/"&gt;&lt;img src="http://farm4.static.flickr.com/3146/2330259510_d13f9230c2_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I didn&amp;#8217;t buy it directly from the studio, but &lt;a href="http://www.curiosityshoppeonline.com/leartpr.html"&gt;from the Curiosity Shoppe&lt;/a&gt;, which just recently opened up a storefront &lt;a href="http://tinyurl.com/2rl2y2"&gt;down the street&lt;/a&gt; from me. They sell a variety of beautiful but odd things. Right now they&amp;#8217;re showing a series of &lt;a href="http://www.curiosityshoppeonline.com/wobysaap.html"&gt;giant felt handguns&lt;/a&gt; by &lt;a href="http://www.sarahapplebaum.com/"&gt;Sarah Moli Newton Applebaum&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;But no, sadly, the new site will be neither felted nor letterpressed.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/250494309" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/design">design</category>
    </item>
    <item>
      <title>On tradition, harmony, pitch, the atonal, typography, Fibonacci, and coincidence.</title>
      <link>http://blog.hypsometry.com/archives/2008/3/5/on_tradition_harmony_pitch_the/</link>
      <pubDate>Wed, 05 Mar 2008 09:30:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/3/5/on_tradition_harmony_pitch_the/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2302807799/"&gt;&lt;img src="http://farm4.static.flickr.com/3213/2302807799_f475c71b0a_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Harmony and pitch.&lt;/h2&gt;&lt;p&gt;In &amp;sect;3.1.1 of &lt;a href="http://en.wikipedia.org/wiki/The_Elements_Of_Typographic_Style"&gt;The Elements of Typographic Style&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Robert_Bringhurst"&gt;Robert Bringhurst&lt;/a&gt; draws an analogy between the sequence of type sizes traditionally used by typographers and &lt;a href="http://en.wikipedia.org/wiki/Diatonic_scale"&gt;the diatonic scale&lt;/a&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;In the sixteenth century, a series of common sizes developed among European typographers, and the series survived with little change and few additions for 400 years. [...] This is the typographic equivalent of the diatonic scale. But modern equipment makes it possible to set, in addition to these sizes, all the sharps and flats and microtonal intervals between.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In other words, modern typesetting &amp;#8211; done via software and printer, instead of type and press &amp;#8211; allows &lt;a href="http://en.wikipedia.org/wiki/Atonality"&gt;the atonal&lt;/a&gt;. Unlike in music, however, alternate systems have not arisen.&lt;/p&gt;&lt;p&gt;Further, typesetting on the web makes it not just possible to avoid the traditional sizes, but actually difficult to set them. There are so many issues involved: Which browser is being used, what its defaults are, what units you use to specify sizes, the flow of inheritance of sizes through the page, etc. If you&amp;#8217;ve done more than a dab of web design, you&amp;#8217;re well familiar with how complex type sizing can be.&lt;/p&gt;&lt;p&gt;But what&amp;#8217;s important here is not the precise size of each piece of text on your site, as rendered on the client by a browser. What matters is the size of each piece of text relative to the others.&lt;/p&gt;&lt;p&gt;To put it again in musical terms, the specific frequency of the note is less important than the overall structure of the scale containing that note. Harmony, not pitch. As if typesetting had returned to the days when one orchestra&amp;#8217;s A was quite different from another&amp;#8217;s.&lt;/p&gt;&lt;h2&gt;The tradition.&lt;/h2&gt;&lt;p&gt;Here&amp;#8217;s a section of that traditional sequence, set for the web:&lt;/p&gt;&lt;div style="font-size: 10px;"&gt;&lt;div style="font-size: 1em; line-height: 1.81;"&gt; Long primer (10 point). &lt;/div&gt;&lt;div style="font-size: 1.1em; line-height: 1.64"&gt; Small pica (11 point). &lt;/div&gt;&lt;div style="font-size: 1.2em; line-height: 1.5"&gt; Pica (12 point). &lt;/div&gt;&lt;div style="font-size: 1.4em; line-height: 1.29"&gt; English (14 point). &lt;/div&gt;&lt;div style="font-size: 1.6em; line-height: 1.13"&gt; Columbian (16 point). &lt;/div&gt;&lt;div style="font-size: 1.8em; line-height: 2"&gt; Great primer (18 point). &lt;/div&gt;&lt;div style="font-size: 2.1em; line-height: 1.72"&gt; Double small pica (21 point). &lt;/div&gt;&lt;div style="font-size: 2.4em; line-height: 1.5"&gt; Double pica (24 point). &lt;/div&gt;&lt;div style="font-size: 3.6em; line-height: 1.5"&gt; Double great primer (36 point). &lt;/div&gt;&lt;/div&gt;&lt;p&gt;The traditional scale continues both above and below the sizes shown here. But this seems pretty much enough for the web. Much smaller, and the type is hard to read. Much bigger, and you&amp;#8217;re dealing with a strange case.&lt;/p&gt;&lt;p&gt;Implementing this system is simple. Sticking to it rigorously, in the absence of any external constraints, is the hard part.&lt;/p&gt;&lt;h2&gt;Implementation, in theory.&lt;/h2&gt;&lt;p&gt;Following &lt;a href="http://alistapart.com/articles/howtosizetextincss"&gt;Richard Rutter&amp;#8217;s text sizing method&lt;/a&gt;, I start by declaring the &lt;code&gt;font-size&lt;/code&gt; of the document&amp;#8217;s &lt;code&gt;body&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;body {&lt;br/&gt;  font-size: 100%;&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This minimizes text size variation across browsers, especially in the extreme (large and small) sizes. &lt;code&gt;100%&lt;/code&gt; is, in theory, equal to &lt;code&gt;16px&lt;/code&gt;. User defaults and zooming can easily change that, even if nothing else does. But that&amp;#8217;s okay: All I&amp;#8217;m concerned with is the relative sizing of the type.&lt;/p&gt;&lt;p&gt;All the sites I&amp;#8217;ve designed recently have had a wrapper &lt;code&gt;div&lt;/code&gt; containing the entire contents of the page. Like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;body&amp;gt;&lt;br/&gt;  &amp;lt;div class="everything"&amp;gt;&lt;br/&gt;    The whole damn page.&lt;br/&gt;  &amp;lt;/div&amp;gt;&lt;br/&gt;&amp;lt;/body&amp;gt;&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I can take advantage of that wrapper &lt;code&gt;div&lt;/code&gt; to bring down the whole page&amp;#8217;s &lt;code&gt;font-size&lt;/code&gt; to &lt;code&gt;10px&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#everything {&lt;br/&gt;  font-size: 0.625em; /* 16px * 0.625 â‰ˆ 10px, or long primer size. */&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;10px&lt;/code&gt; is great, both because it&amp;#8217;s about the smallest size I care to use normally and because it simplifies the following math tremendously. All the visible contents of the page are contained within &lt;code&gt;div#everything&lt;/code&gt;, so all the elements will inherit a computed &lt;code&gt;font-size&lt;/code&gt; of &lt;code&gt;10px&lt;/code&gt;. So I can resize them in in terms of &lt;code&gt;em&lt;/code&gt;, which is effectively a simple multiplier. To get &lt;code&gt;14px&lt;/code&gt; type all I have to do is multiply the inherited value by 1.4: &lt;code&gt;font-size: 1.4em&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;You might note that I&amp;#8217;ve blurred the distinction between &lt;a href="http://en.wikipedia.org/wiki/Point_%28typography%29"&gt;points&lt;/a&gt; and &lt;a href="http://www.w3.org/TR/REC-CSS1#length-units"&gt;pixels&lt;/a&gt;. (Oh lord. Let&amp;#8217;s not get into the whole pixel unit discussion.) And I&amp;#8217;m talking about things in terms of pixels as if their sizes could be possibly be fixed. But again, neither matters here. What matters are the relationships between the numbers, not the actual numbers themselves. It&amp;#8217;s a matter of harmony, not frequency.&lt;/p&gt;&lt;p&gt;You might further note that I&amp;#8217;m not declaring the &lt;code&gt;line-height&lt;/code&gt; of anything, nor discussing it at all. &lt;code&gt;line-height&lt;/code&gt; is another story entirely, and one I&amp;#8217;ll deal with separately.&lt;/p&gt;&lt;p&gt;At any rate, I can go on and declare the type sizes of some common elements based on the page-wide default of &lt;code&gt;10px&lt;/code&gt; I&amp;#8217;ve set:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;h1 {&lt;br/&gt;  font-size: 2.4em; /* 10px * 2.4 = 24px, or double pica size. */&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;code&gt;&lt;br/&gt;h2 {&lt;br/&gt;  font-size: 2.1em; /* 10px * 2.1 = 21px, or double small pica size. */&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;code&gt;&lt;br/&gt;p {&lt;br/&gt;  font-size: 1.2em; /* 10px * 1.2 = 12px, or pica size. */&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Simple enough. Though, as I said above, the theory of the implementation is easy.&lt;/p&gt;&lt;h2&gt;Systems.&lt;/h2&gt;&lt;p&gt;This is not about blind adherence to tradition. A coherent, harmonious system is more likely to produce elegant and satisfying results than a haphazard jumble.&lt;/p&gt;&lt;p&gt;Other systems are, of course, possible. Bringhurst, in &amp;sect;8.2, suggests alternatives based on &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_sequence"&gt;the Fibonacci sequence&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Golden_section"&gt;the golden section&lt;/a&gt;, including two different double-stranded Fibonacci series, one used by &lt;a href="http://en.wikipedia.org/wiki/Le_Corbusier"&gt;Le Corbusier&lt;/a&gt; in &lt;a href="http://en.wikipedia.org/wiki/Modulor"&gt;his Modulor scale&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Those are intellectually satisfying, but their actual make-up seems less useful for typesetting on the web. The Modulor system uses fractional sizes, and &lt;a href="http://ejohn.org/blog/sub-pixel-problems-in-css/"&gt;browser sub-pixel rendering problems&lt;/a&gt; are ample enough in normal usage &amp;#8211; no need to encourage them. And both sequences are lighter on sizes in the low end of the range, which seems the most useful part of it for web work.&lt;/p&gt;&lt;p&gt;The traditional sequence seems good enough for my purposes.&lt;/p&gt;&lt;h2&gt;Coincidence.&lt;/h2&gt;&lt;p&gt;Also note that today&amp;#8217;s date, &lt;a href="http://en.wikipedia.org/wiki/Date_format#mm.2Fdd.2Fyy_or_mm.2Fdd.2Fyyyy_.28month.2C_day.2C_year.29"&gt;as written in the States&lt;/a&gt;, is 3-5-8, which makes today a sort of &lt;a href="http://fritzhorstman.com/news/2008/03/05/fibonacci-day-/"&gt;Fibonacci day&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/246569212" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/CSS">CSS</category>
      <category domain="http://blog.hypsometry.com/archives/tags/typography">typography</category>
    </item>
    <item>
      <title>On passwords, forgetfulness, and ease of use.</title>
      <link>http://blog.hypsometry.com/archives/2008/2/25/on_passwords_forgetfulness_and_ease/</link>
      <pubDate>Mon, 25 Feb 2008 07:25:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/2/25/on_passwords_forgetfulness_and_ease/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2270433536/"&gt;&lt;img src="http://farm3.static.flickr.com/2095/2270433536_302121a4a6_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;A problem.&lt;/h2&gt;&lt;p&gt;Every site that allows password sign in has a little link on its sign in page. Sometimes it reads as a question: &lt;em&gt;Forgot your password?&lt;/em&gt; Sometimes a first person statement: &lt;em&gt;I forgot my password&lt;/em&gt;. Sometimes it&amp;#8217;s just a terse fragment: &lt;em&gt;Forgot password&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;You click it and are taken to another page, where you can ask for a new password to be emailed to you. On the forgot-my-password page you have to enter your email address. Typically the form on that page is extremely simple: Some explanatory text, a text input field, and a submit button.&lt;/p&gt;&lt;p&gt;When the web application receives the submitted form, it checks its database to find the submitted email address. Assuming it finds the address, the application updates the user&amp;#8217;s password and emails them a notice about it. If it doesn&amp;#8217;t find the address, it returns the user to the same page and complains about the failure.&lt;/p&gt;&lt;p&gt;All of which is simple, straightforward, well established custom. Almost every web application has this feature, and this feature works in almost exactly the same manner across the board.&lt;/p&gt;&lt;p&gt;But there&amp;#8217;s one problem here. It&amp;#8217;s not uncommon for a user, hoping to sign in to a site, to enter his email address and then realize that he&amp;#8217;s forgotten his password. In other words, it&amp;#8217;s not uncommon for a user to realize that he&amp;#8217;s only got half of the needed data after having already entered the first half.&lt;/p&gt;&lt;p&gt;What happens then? He finds the expected &lt;em&gt;Forgot password&lt;/em&gt; link, clicks it, and is whisked off to the forgot-my-password page. And then has to enter his email address again.&lt;/p&gt;&lt;p&gt;This certainly isn&amp;#8217;t a large problem. People type their email addresses into forms all day, every day. Lots of people use form managers to do it for them. (Though the form managers probably remember their passwords too, so they&amp;#8217;re not in this bind in the first place.) How long does it take? A few seconds, at most. How much trouble is it? Not much.&lt;/p&gt;&lt;p&gt;But why cause your users any trouble at all? Even a little trouble is more than necessary.&lt;/p&gt;&lt;h2&gt;A solution.&lt;/h2&gt;&lt;p&gt;The solution I&amp;#8217;m using on our new site is simple. The short explanation: The forgot-my-password link uses Javascript to grab the value of the email address already entered, then appends it, as a query parameter, to the forgot-my-password &lt;span class="caps"&gt;URL&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;The forgot-my-password link looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;a href="/account/forgot_password" class="forgot_password"&amp;gt;Forgot password&amp;lt;/a&amp;gt;&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We&amp;#8217;ve rolled our own &lt;a href="http://en.wikipedia.org/wiki/Unobtrusive_Javascript"&gt;unobtrusive Javascript&lt;/a&gt; library, but it functions in many ways like &lt;a href="http://www.danwebb.net/"&gt;Dan Webb&amp;#8217;s&lt;/a&gt; &amp;#32; &lt;a href="http://lowpro.stikipad.com/"&gt;Low Pro&lt;/a&gt;. Using that, I registered a behavior handler for the forgot-my-password link:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Event.addBehavior({&lt;br/&gt;  "a.forgot_password" : Account.Behavior.forgotPasswordBehavior&lt;br/&gt;});&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In other words, all links with a class of &lt;code&gt;forgot_password&lt;/code&gt; get extended with the behaviors defined in &lt;code&gt;Account.Behavior.forgotPasswordBehavior&lt;/code&gt;. That behavior is simple:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Account.Behavior = {&lt;br/&gt;  forgotPasswordBehavior : {&lt;br/&gt;    onclick: function() {&lt;br/&gt;      if ($F("email") != "") {&lt;br/&gt;        this.href = this.href + "?" + $("email").serialize();&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In other words, &lt;code&gt;forgotPasswordBehavior&lt;/code&gt; defines an &lt;code&gt;onclick&lt;/code&gt; handler that rewrites the relevant element&amp;#8217;s &lt;code&gt;href&lt;/code&gt; to append whatever the user has entered in the &lt;code&gt;email&lt;/code&gt; field. It uses &lt;a href="http://prototypejs.org/"&gt;Prototype&lt;/a&gt; to &lt;a href="http://prototypejs.org/api/utility/dollar-f"&gt;get the value of the field&lt;/a&gt; and &lt;a href="http://prototypejs.org/api/form/element/serialize"&gt;rewrite it in &lt;code&gt;name=value&lt;/code&gt; format&lt;/a&gt;, so that it can be passed as a &lt;span class="caps"&gt;URL&lt;/span&gt; query parameter. And it only does its work if the user has actually entered something in the &lt;code&gt;email&lt;/code&gt; field. No point in adding the useless &lt;code&gt;?email=&lt;/code&gt; to the &lt;span class="caps"&gt;URL&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Then, in the &lt;code&gt;forgot_password.rhtml&lt;/code&gt; view, the email field is generated like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;%= form.text_field(:email, :value =&amp;gt; h(params[:email])) %&amp;gt;&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which creates the appropriate field using the email passed as a &lt;span class="caps"&gt;URL&lt;/span&gt; parameter as its value, if one exists.&lt;/p&gt;&lt;p&gt;Any user who has forgotten his password and wants to request a new one has implicitly declared his desire to use your site, and to use it now. Seems like anything you can do to help him with that is a good thing.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/241168350" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/Rails">Rails</category>
      <category domain="http://blog.hypsometry.com/archives/tags/design">design</category>
      <category domain="http://blog.hypsometry.com/archives/tags/interface">interface</category>
    </item>
    <item>
      <title>On nothingness, degrees of okay, bodies, success, and freaking out.</title>
      <link>http://blog.hypsometry.com/archives/2008/2/23/on_nothingness_degrees_of_okay/</link>
      <pubDate>Fri, 22 Feb 2008 17:41:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/2/23/on_nothingness_degrees_of_okay/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2270418046/"&gt;&lt;img src="http://farm3.static.flickr.com/2305/2270418046_c135700193_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sometimes, on &lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt;, you don&amp;#8217;t want a controller method to render anything. For instance, &lt;a href="http://prototypejs.org/api/ajax/request"&gt;an &lt;span class="caps"&gt;AJAX&lt;/span&gt; request&lt;/a&gt; might only need to know that the action succeeded. The status of the response is enough to communicate that, with no rendering required.&lt;/p&gt;&lt;p&gt;So you write &lt;code&gt;render(:nothing =&amp;gt; true)&lt;/code&gt;. Rails renders nothing for you, and, by default, returns a successful status code (&lt;code&gt;200 OK&lt;/code&gt;). Simple enough.&lt;/p&gt;&lt;p&gt;But how do you test for that? It&amp;#8217;s easy to test for redirections (&lt;a href="http://api.rubyonrails.com/classes/ActionController/Assertions/ResponseAssertions.html#M000355"&gt;&lt;code&gt;assert_redirected_to&lt;/code&gt;&lt;/a&gt;), successful template renderings (&lt;a href="http://api.rubyonrails.com/classes/ActionController/Assertions/ResponseAssertions.html#M000356"&gt;&lt;code&gt;assert_template&lt;/code&gt;&lt;/a&gt;), and specific responses (&lt;a href="http://api.rubyonrails.com/classes/ActionController/Assertions/ResponseAssertions.html#M000354"&gt;&lt;code&gt;assert_response&lt;/code&gt;&lt;/a&gt;). But testing for nothingness?&lt;/p&gt;&lt;p&gt;Rails &lt;a href="http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_controller/base.rb?rev=8441#L909"&gt;renders nothingness&lt;/a&gt; as &amp;ldquo; &amp;rdquo;. Not an empty string, that is, but one space.&lt;/p&gt;&lt;p&gt;From a certain theoretical perspective, this is not exactly right. Nothingness in response to a &lt;a href="http://en.wikipedia.org/wiki/HTTP_GET#Request_Methods"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt;&lt;/a&gt; should probably return a &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5"&gt;&lt;code&gt;204 No Content&lt;/code&gt;&lt;/a&gt; status code. After all, that is precisely the &lt;span class="caps"&gt;HTTP&lt;/span&gt; definition of &amp;#8220;nothing to render&amp;#8221;. And, in that case, the protocol dictates that no body be included in the response. Which seems perfect, right? Declare that you&amp;#8217;ve got nothing to render and render nothing, communicating success implicitly. Simple and sweet.&lt;/p&gt;&lt;p&gt;(Things get &lt;a href="http://dev.rubyonrails.org/ticket/9524"&gt;more&lt;/a&gt; &amp;#32; &lt;a href="http://dev.rubyonrails.org/ticket/10974"&gt;complicated&lt;/a&gt; when dealing with &lt;span class="caps"&gt;HEAD&lt;/span&gt; requests. In that case the client has explicitly asked for the headers and nothing but the headers, with no response body needed.)&lt;/p&gt;&lt;p&gt;However, theory tends to fall apart a bit when in the face of actual browsers. &lt;a href="http://developer.yahoo.com/"&gt;The good folks at Yahoo&lt;/a&gt; have looked into this while building &lt;a href="http://developer.yahoo.com/yui/"&gt;the Yahoo User Interface Library&lt;/a&gt;, and &lt;a href="http://developer.yahoo.com/yui/build/connection/README"&gt;have figured out&lt;/a&gt; that &lt;a href="http://en.wikipedia.org/wiki/IE6"&gt;&lt;span class="caps"&gt;IE6&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/IE7"&gt;&lt;span class="caps"&gt;IE7&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://www.opera.com/"&gt;Opera&lt;/a&gt;, and Safari can&amp;#8217;t handle the &lt;code&gt;204&lt;/code&gt; when it comes via &lt;a href="http://en.wikipedia.org/wiki/XHR"&gt;XMLHttpRequest&lt;/a&gt;. Errors result, headers are lost, responses are left undefined, and communication failure is wrongly declaimed.&lt;/p&gt;&lt;p&gt;(Just to complicate things further, Safari might actually have fixed this as of 3.0. I&amp;#8217;m not clear on that, though. Either way, it&amp;#8217;s still a cross-browser issue.)&lt;/p&gt;&lt;p&gt;In other words, &lt;code&gt;204 No Content&lt;/code&gt; will break on some of the most common browsers when used with &lt;span class="caps"&gt;AJAX&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;What to do? Well, pass along the only appropriate status code that the browsers can handle, for starters: &lt;code&gt;200 OK&lt;/code&gt;. Having done that, though, you&amp;#8217;ve now set the browsers up to expect some sort of response with their &lt;code&gt;OK&lt;/code&gt;. And &lt;a href="http://dev.rubyonrails.org/changeset/1818"&gt;it seems&lt;/a&gt; that if you give Safari a completely empty response body, it freaks out a bit and doesn&amp;#8217;t handle the response properly.&lt;/p&gt;&lt;p&gt;Thus the Rails hack of redefining nothingness, in this context, as a little bit of whitespace.&lt;/p&gt;&lt;p&gt;Knowing that, testing for the successful rendering of nothing is easy:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def assert_rendered_nothing&lt;br/&gt;  assert_equal(@response.body, " ", "The response was not empty.")&lt;br/&gt;  assert_response(:success, "The response was not successful.")&lt;br/&gt;end&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Check the body of the response for being &amp;ldquo; &amp;rdquo; and check the status code to be sure that it indicates success. Okay, and pretty good too.&lt;/p&gt;&lt;p&gt;An aside, though not too far: This makes my third post on nothingness this calendar year. (&lt;em&gt;Cf.&lt;/em&gt; &amp;#32; &lt;a href="http://blog.hypsometry.com/archives/2008/1/30/on_hunches_ruby_rails_why/"&gt;nihilism&lt;/a&gt; and &lt;a href="http://blog.hypsometry.com/archives/2008/2/15/on_the_hinterlands_openid_cookies/"&gt;the hinterlands&lt;/a&gt;.) I&amp;#8217;m not sure what to say about that.&lt;/p&gt;&lt;p&gt;NB: &lt;a href="http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_controller/base.rb?rev=8441#L255"&gt;The Rails definition of success&lt;/a&gt; is a simple one. &lt;a href="http://prototypejs.org/api/ajax/request"&gt;Really&lt;/a&gt;, a successful status code is one that&amp;#8217;s not in the redirection range (from 300 to 399), the client error range (from 400 to 499), or the server error range (from 500 to 599).&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/239866229" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/Rails">Rails</category>
    </item>
    <item>
      <title>On the hinterlands, OpenID, cookies, jars, slippery beasts, indifference, patches of monkeys, and the difference between a general sort of nothing and nothingness in particular.</title>
      <link>http://blog.hypsometry.com/archives/2008/2/15/on_the_hinterlands_openid_cookies/</link>
      <pubDate>Fri, 15 Feb 2008 12:35:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/2/15/on_the_hinterlands_openid_cookies/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2265900920/"&gt;&lt;img src="http://farm3.static.flickr.com/2331/2265900920_002724ceaa_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;More news from the poorly mapped hinterlands of Railsia.&lt;/p&gt;&lt;p&gt;In our new app, we&amp;#8217;re allowing people to sign in using &lt;a href="http://openidexplained.com/"&gt;OpenID&lt;/a&gt;. Which is cool, and progressive, and generally a Good Thing. Except for the bit that implementing it&amp;#8217;s a nuisance.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.dannyburkes.com/"&gt;Danny&amp;#8217;s&lt;/a&gt; fully on top of the technical side, which eludes me to a surprising degree. But that&amp;#8217;s okay, because the interface side is plenty complex enough to keep me up late. Today I&amp;#8217;ve been working on finessing the details of the actual sign in flow, focusing on what happens when things go wrong.&lt;/p&gt;&lt;p&gt;We&amp;#8217;ve got this combination sign in page with a tabbed interface, where you can sign in using either a password or an OpenID &lt;span class="caps"&gt;URL&lt;/span&gt;. Two forms, one per sign in option, although you only see one at a time.&lt;/p&gt;&lt;p&gt;If you try to sign in using an OpenID &lt;span class="caps"&gt;URL&lt;/span&gt;, we save that &lt;span class="caps"&gt;URL&lt;/span&gt; in a cookie called &lt;code&gt;signin_openid_url&lt;/code&gt;. When the page is rendered, a helper method checks to see if the &lt;code&gt;signin_openid_url&lt;/code&gt; cookie exists, and, assuming it does, renders the page such that the OpenID sign in form is visible.&lt;/p&gt;&lt;p&gt;Which form is displayed is determined by which form has &lt;code&gt;.active&lt;/code&gt; applied to it. Using &lt;span class="caps"&gt;CSS&lt;/span&gt; rules like these:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#content form.content_tab&lt;br/&gt;{&lt;br/&gt;  display: none;&lt;br/&gt;}&lt;br/&gt;&lt;/code&gt;&lt;code&gt;&lt;br/&gt;#content form.content_tab.active&lt;br/&gt;{&lt;br/&gt;  display: block;&lt;br/&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which form has &lt;code&gt;.active&lt;/code&gt; applied to it is determined by the helper that checks the value of the &lt;code&gt;signin_openid_url&lt;/code&gt; cookie. Here&amp;#8217;s where we get to the hinterlands of Rails.&lt;/p&gt;&lt;p&gt;The helper we wrote initially was this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def prefer_openid_signin?&lt;br/&gt;  !cookies[:signin_openid_url].nil?&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pretty simple: Ask for the cookie identified by &lt;code&gt;:signin_openid_url&lt;/code&gt;, check to see if it&amp;#8217;s &lt;code&gt;nil?&lt;/code&gt;, and return the inverse of that answer.&lt;/p&gt;&lt;p&gt;And it worked most of the time. Unfortunately, it only worked most of the time.&lt;/p&gt;&lt;p&gt;When you enter an invalid &lt;span class="caps"&gt;URL&lt;/span&gt; and submit the form, that &lt;span class="caps"&gt;URL&lt;/span&gt; gets stuck into the cookie and all is well. When you enter &lt;em&gt;no&lt;/em&gt; URL, however, and submit the form, things go wrong. &lt;code&gt;prefer_openid_signin?&lt;/code&gt; was returning &lt;code&gt;false&lt;/code&gt;, even though the &lt;code&gt;signin_openid_url&lt;/code&gt; cookie should have been set.&lt;/p&gt;&lt;p&gt;Examining the parameters that were being passed, and the cookies that were being created, I could see that &lt;code&gt;params[:openid_url] =&amp;gt; ""&lt;/code&gt; when the empty &lt;span class="caps"&gt;URL&lt;/span&gt; form was submitted. This is as it should be. According to &lt;a href="http://dev.rubyonrails.org/ticket/5694#comment:12"&gt;Rails dogma&lt;/a&gt;, empty text fields should yield empty strings, not &lt;code&gt;nil&lt;/code&gt; values.&lt;/p&gt;&lt;p&gt;Then the &lt;code&gt;signin_openid_url&lt;/code&gt; cookie was being created, with the correct value of &lt;code&gt;""&lt;/code&gt;. But when I asked for the value back again, using &lt;code&gt;cookies[:signin_openid_url]&lt;/code&gt;, I got &lt;code&gt;nil&lt;/code&gt; instead of &lt;code&gt;""&lt;/code&gt;. Clearly, the distinction between an empty string and &lt;code&gt;nil&lt;/code&gt; was being lost somewhere along the way.&lt;/p&gt;&lt;p&gt;The loss starts with &lt;a href="http://ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI/Cookie.html"&gt;&lt;code&gt;CGI::Cookie&lt;/code&gt;&lt;/a&gt;, which is &lt;a href="http://ruby-doc.org/stdlib/"&gt;the Ruby Standard Library&amp;#8217;s&lt;/a&gt; HTTP cookie class. &lt;code&gt;CGI::Cookie&lt;/code&gt; always returns an &lt;code&gt;Array&lt;/code&gt; when asked for the value of a cookie. Always. No matter that most cookies have one and only one value.&lt;/p&gt;&lt;p&gt;Then, in its parsing of the values sent by a client to the server, &lt;code&gt;CGI::Cookie&lt;/code&gt; manipulates things such that any empty strings become &lt;code&gt;nil&lt;/code&gt;. To be more precise, when a client sends a cookie with an empty string as its value to the server, &lt;code&gt;CGI::Cookie&lt;/code&gt; turns that value into an empty &lt;code&gt;Array&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;code&gt;ActionController.cookies&lt;/code&gt; uses a container to hold the cookies created by &lt;code&gt;CGI::Cookie&lt;/code&gt;. The container&amp;#8217;s class is &lt;a href="http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_controller/cookies.rb"&gt;&lt;code&gt;CookieJar&lt;/code&gt;&lt;/a&gt;, and &lt;code&gt;CookieJar&lt;/code&gt; behaves mostly like a &lt;code&gt;Hash&lt;/code&gt;. But not quite. More on that in a second.&lt;/p&gt;&lt;p&gt;Anyway, when you ask &lt;code&gt;CookieJar&lt;/code&gt; for the value of a cookie: &lt;code&gt;CookieJar&lt;/code&gt; checks the size of the &lt;code&gt;Array&lt;/code&gt; that &lt;code&gt;CGI::Cookie&lt;/code&gt; has given it, and if it contains more than one value you get the first value. But if it contains one value, or none, you get the value of what it contains. So if it contains no values, then the &lt;code&gt;Array&lt;/code&gt; is empty, and &lt;code&gt;CookieJar&lt;/code&gt; returns &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This is contrary to &lt;a href="http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_controller/cookies.rb"&gt;what the documentation in the source says&lt;/a&gt;, which is that &lt;code&gt;nil&lt;/code&gt; is returned &amp;#8220;if no such cookie exists&amp;#8221;. Rather, &lt;code&gt;nil&lt;/code&gt; is returned if no such cookie exists or if such a cookie exists but contains no value.&lt;/p&gt;&lt;p&gt;So it seems that cookies on Rails &lt;a href="http://www.40withegg.com/2007/1/5/rails-cookies-mangles-the-hash-interface"&gt;are slippery beasts&lt;/a&gt;. As I said above, a &lt;code&gt;CookieJar&lt;/code&gt; behaves mostly like a &lt;code&gt;Hash&lt;/code&gt;. The way in which it doesn&amp;#8217;t is that it redefines the setter and the getter methods. Which borders on perverse, in my opinion. The reason for the perversity is that it needs to handle both the setting of outgoing cookies and the getting of incoming cookies. So the interfaces for the two actions are necessarily different. However, that still doesn&amp;#8217;t explain why they chose to combine the two different actions into one pseudo-&lt;code&gt;Hash&lt;/code&gt; is beyond me. Why not create a new, appropriate, non-confusing interface?&lt;/p&gt;&lt;p&gt;Double anyway. Even though getting and setting cookies in a &lt;code&gt;CookieJar&lt;/code&gt; doesn&amp;#8217;t work like a &lt;code&gt;Hash&lt;/code&gt;, you&amp;#8217;d think it would work like a &lt;code&gt;Hash&lt;/code&gt; in other regards. You can&amp;#8217;t rely on it to return the values you give it, but you&amp;#8217;d think it would be able to tell you if it has a key in it or not.&lt;/p&gt;&lt;p&gt;I&amp;#8217;d think. Or I thought, so I rewrote the &lt;code&gt;prefer_openid_signin?&lt;/code&gt; helper to just check the &lt;code&gt;CookieJar&lt;/code&gt; for the presence of the relevant key. (Which corresponds to the existence of the relevant cookie.) As follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def prefer_openid_signin?&lt;br/&gt;  cookies.has_key?(:signin_openid_url)&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No. No luck. Bah. Back to the source.&lt;/p&gt;&lt;p&gt;&lt;code&gt;CookieJar&lt;/code&gt;, unlike every other use of &lt;code&gt;Hash&lt;/code&gt; in Rails, is not a &lt;a href="http://api.rubyonrails.com/classes/HashWithIndifferentAccess.html"&gt;&lt;code&gt;HashWithIndifferentAccess&lt;/code&gt;&lt;/a&gt;. Which means that if you give it a &lt;code&gt;Symbol&lt;/code&gt; as a key when setting a value, you must use the same &lt;code&gt;Symbol&lt;/code&gt; to get the value back. And if you use a &lt;code&gt;String&lt;/code&gt; to set, you must use a &lt;code&gt;String&lt;/code&gt; to get.&lt;/p&gt;&lt;p&gt;But that&amp;#8217;s okay, right? Since my OpenID &lt;span class="caps"&gt;URL&lt;/span&gt; cookie creating helper looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def remember_signin_openid_url(url)&lt;br/&gt;  cookies[:signin_openid_url] = { :value =&amp;gt; url, :expires =&amp;gt; 10.years.from_now }&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The helper sets the cookie using the &lt;code&gt;Symbol&lt;/code&gt;&lt;code&gt;:signin_openid_url&lt;/code&gt;, so the other helper should be able to get it using the same &lt;code&gt;Symbol&lt;/code&gt;. Right?&lt;/p&gt;&lt;p&gt;Wrong. &lt;code&gt;CookieJar&lt;/code&gt; &amp;#32; &lt;em&gt;only&lt;/em&gt; uses &lt;code&gt;Strings&lt;/code&gt; as keys. If you pass it a &lt;code&gt;Symbol&lt;/code&gt;, it converts it to the corresponding &lt;code&gt;String&lt;/code&gt;, and never looks back. &lt;code&gt;Symbols&lt;/code&gt; not welcome here.&lt;/p&gt;&lt;p&gt;Okay, got it. So I rewrote the helper as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def prefer_openid_signin?&lt;br/&gt;  cookies.has_key?("signin_openid_url")&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ah. Which totally works.&lt;/p&gt;&lt;p&gt;But that&amp;#8217;s annoying. I don&amp;#8217;t want to have to remember that dealing with cookies is the one time on Rails when I need to care about whether I&amp;#8217;m using a &lt;code&gt;Symbol&lt;/code&gt; or a &lt;code&gt;String&lt;/code&gt;. (And I&amp;#8217;ve been bitten by this same, um, quirk when testing cookies.)&lt;/p&gt;&lt;p&gt;Thank goodness for &lt;a href="http://en.wikipedia.org/wiki/Monkey_patch"&gt;monkey patching&lt;/a&gt;. I wrote the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;module ActionController&lt;br/&gt;  class CookieJar &amp;lt; Hash&lt;br/&gt;    def has_key?(key)&lt;br/&gt;      super(key.to_s)&lt;br/&gt;    end&lt;br/&gt;    alias :contains? :has_key?&lt;br/&gt;  end&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And put it in &lt;code&gt;lib/cookie_jar.rb&lt;/code&gt;, and required it in &lt;a href="http://ryandaigle.com/articles/2007/2/23/what-s-new-in-edge-rails-stop-littering-your-evnrionment-rb-with-custom-initializations"&gt;the appropriate initializer&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now I can check for the existence of a cookie by checking for the existence of the corresponding key, or in more elegant fashion by asking &lt;code&gt;cookies.contains?(:signin_openid_url)&lt;/code&gt;. That&amp;#8217;s still one more hoop than I really should have to jump through, but at least it&amp;#8217;s only one.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/235909545" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/OpenID">OpenID</category>
      <category domain="http://blog.hypsometry.com/archives/tags/Rails">Rails</category>
    </item>
    <item>
      <title>On consumerism, compost, camping, framing, high-density polyethylene, recycling, and doing the right thing.</title>
      <link>http://blog.hypsometry.com/archives/2008/2/11/on_consumerism_compost_camping_framing/</link>
      <pubDate>Mon, 11 Feb 2008 10:50:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/2/11/on_consumerism_compost_camping_framing/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2251083935/"&gt;&lt;img src="http://farm3.static.flickr.com/2246/2251083935_f39f712276_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Like most people these days, I order a lot of stuff. I&amp;#8217;m big on &lt;a href="http://blog.hypsometry.com/archives/2008/1/26/on_the_sense_of_humor/"&gt;buying locally&lt;/a&gt;, of course, but there are a lot of things that I simply can&amp;#8217;t get locally, at least not without significant expenditures of time and energy.&lt;/p&gt;&lt;p&gt;Pretty often that stuff comes shipped in &lt;a href="http://en.wikipedia.org/wiki/Tyvek"&gt;Tyvek&lt;/a&gt; envelopes. Tyvek&amp;#8217;s great stuff, in a lot of ways: I&amp;#8217;ve worn &lt;a href="http://www2.dupont.com/NOWApp/DPPRequestGateway/0/5/?command=VCProductFamilyIntro&amp;#38;prod=1032"&gt;protective suits made of it&lt;/a&gt; while mucking out &lt;a href="http://en.wikipedia.org/wiki/Composting_toilets"&gt;composting toilets&lt;/a&gt; at &lt;a href="http://www.farmandwilderness.org/"&gt;Farm and Wilderness&lt;/a&gt;, I&amp;#8217;ve used it as &lt;a href="http://www.ultralightbackpacker.com/tyvek.html"&gt;an ultralight groundcloth while camping&lt;/a&gt;, and I&amp;#8217;ve &lt;a href="http://www2.dupont.com/Tyvek_Construction/en_US/"&gt;wrapped houses in it during construction&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Even though it&amp;#8217;s just a fancy &lt;a href="http://en.wikipedia.org/wiki/Hdpe"&gt;&lt;span class="caps"&gt;HDPE&lt;/span&gt; plastic&lt;/a&gt;, envelopes made of Tyvek are not generally recyclable. The same plastic (#2) in bottle form is easy to recycle; some places, &lt;a href="http://www.sunsetscavenger.com/recycleqa.htm#1"&gt;like San Francisco&lt;/a&gt;, even allow recycling of &lt;span class="caps"&gt;HDPE&lt;/span&gt; tubs; but almost no one will recycle &lt;span class="caps"&gt;HDPE&lt;/span&gt; envelopes.&lt;/p&gt;&lt;p&gt;Turns out, however, that &lt;a href="http://envelopes.tyvek.com/en/science/versitile/vers_recycle.shtml"&gt;DuPont themselves will recycle your Tyvek envelopes&lt;/a&gt;, free of charge. Take one Tyvek envelope, turn it inside out, fill it with other Tyvek envelopes, and address it to:&lt;/p&gt;&lt;blockquote&gt;Tyvek Recycle&lt;br/&gt;  Attn. Shirley Cimburke&lt;br/&gt;  2400 Elliham Avenue #A&lt;br/&gt;  Richmond, &lt;span class="caps"&gt;VA 23237&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;I guess that&amp;#8217;s not totally free of charge: You have to pay a bit of postage.&lt;/p&gt;&lt;p&gt;And it&amp;#8217;s a bit strange shipping stuff back across the country to be recycled. Is it worth the energy use? In other words, is the energy used by the shipping back, and then the recycling itself, less than the energy wasted by simply throwing the envelopes out? Maybe I should write Shirley a note.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/233486890" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/recycling">recycling</category>
    </item>
    <item>
      <title>On Aquarius, Camino, proper server behavior, searching, and laziness.</title>
      <link>http://blog.hypsometry.com/archives/2008/2/8/on_aquarius_camino_proper_server/</link>
      <pubDate>Fri, 08 Feb 2008 05:17:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/2/8/on_aquarius_camino_proper_server/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://flickr.com/photos/cboone/2246162670/"&gt;&lt;img src="http://farm3.static.flickr.com/2267/2246162670_3593138384_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.hypsometry.com/archives/2008/1/26/on_the_sense_of_humor/"&gt;As I mentioned&lt;/a&gt;, I spend a fair amount of time on &lt;a href="http://aquariusrecords.org/"&gt;the Aquarius Records website&lt;/a&gt;. They carry &lt;a href="http://aquariusrecords.org/bin/search.cgi?search_string=tristan%20perich"&gt;stuff that no one else has&lt;/a&gt;, and their reviews are fabulous.&lt;/p&gt;&lt;p&gt;(An aside: A few weeks ago, I found myself in &lt;a href="http://www.othermusic.com/index.cgi"&gt;Other Music&lt;/a&gt;, trying to decide whether to buy a CD. I didn&amp;#8217;t quite trust their opinion on the matter, so I busted out &lt;a href="http://flickr.com/photos/hypsography/"&gt;my phone&lt;/a&gt;, went into &lt;a href="http://www.apple.com/iphone/features/index.html#internet"&gt;Safari&lt;/a&gt;, and found a review of the CD on the Aquarius site. That should give you a sense of the situation.)&lt;/p&gt;&lt;p&gt;Their site is plenty functional, though if your eyes are as sensitive as mine, I wouldn&amp;#8217;t recommend viewing the source. The main way to interact with it is through the keyword search. However, the muscle behind the search is &lt;a href="http://en.wikipedia.org/wiki/Cgi_script"&gt;a &lt;span class="caps"&gt;CGI&lt;/span&gt; script&lt;/a&gt; (stored in &lt;code&gt;/bin&lt;/code&gt;, of course), to which the search form &lt;a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_Methods"&gt;POSTs&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This is annoying. Because the form POSTs your search, the &lt;span class="caps"&gt;URL&lt;/span&gt; of your search results is always the same, no matter what you searched for: &lt;a href="http://aquariusrecords.org/bin/search.cgi"&gt;http://aquariusrecords.org/bin/search.cgi&lt;/a&gt;. If you reload that page, you&amp;#8217;ll get an annoying dialog box from your browser, checking to make sure that really want to do that. If you bookmark that page and return to it later, you&amp;#8217;ll get an &lt;em&gt;Internal Server Error&lt;/em&gt; message. Ditto for copying and pasting the &lt;span class="caps"&gt;URL&lt;/span&gt; (to email to a friend, for instance).&lt;/p&gt;&lt;p&gt;What the site should be doing, of course, is redirecting your search to a &lt;span class="caps"&gt;URL&lt;/span&gt; that responds to &lt;a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_Methods"&gt;&lt;span class="caps"&gt;GET&lt;/span&gt; requests&lt;/a&gt; and that contains the searched for string in the &lt;span class="caps"&gt;URL&lt;/span&gt; itself. (&lt;a href="http://en.wikipedia.org/wiki/Post/Redirect/Get"&gt;Post, redirect, get&lt;/a&gt;, that is.) Then all those little annoyances would go away.&lt;/p&gt;&lt;p&gt;It turns out, however, that Aquarius&amp;#8217;s search script doesn&amp;#8217;t actually care whether you &lt;span class="caps"&gt;POST&lt;/span&gt; or &lt;span class="caps"&gt;GET&lt;/span&gt; to it. The string to be searched for needs to be passed as the &lt;code&gt;search_string&lt;/code&gt; parameter, and that&amp;#8217;s enough: &lt;a href="http://aquariusrecords.org/bin/search.cgi?search_string=daniel%20higgs"&gt;http://aquariusrecords.org/bin/search.cgi?search_string=daniel higgs&lt;/a&gt;, for example. Which is fully bookmarkable, copy-and-pasteable, reloadable, and error free.&lt;/p&gt;&lt;p&gt;&lt;a href="http://caminobrowser.org/"&gt;Camino&lt;/a&gt; is my main browser these days. One of its many cool features is the ability to create search shortcuts. I&amp;#8217;ve got a whole pile of them set up, for all the different searches I perform often: &lt;a href="http://wikipedia.org/"&gt;Wikipedia&lt;/a&gt;, &lt;a href="http://weather.com"&gt;the weather&lt;/a&gt;, &lt;a href="http://amazon.com"&gt;Amazon&lt;/a&gt;, &lt;a href="http://movies.yahoo.com"&gt;movies&lt;/a&gt;, &lt;a href="http://yelp.com"&gt;Yelp&lt;/a&gt;, &lt;a href="http://sfpl.org/"&gt;the library&lt;/a&gt;, etc.&lt;/p&gt;&lt;p&gt;To create one for Aquarius:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;I went to a search &lt;span class="caps"&gt;URL&lt;/span&gt; that I had created, &lt;a href="http://aquariusrecords.org/bin/search.cgi?search_string=daniel%20higgs"&gt;http://aquariusrecords.org/bin/search.cgi?search_string=daniel higgs&lt;/a&gt;, and bookmarked it, changing the name to the more general &amp;#8220;Aquarius Records Search&amp;#8221;.&lt;/li&gt;&lt;li&gt;Then I went to Camino&amp;#8217;s bookmarks page and edited the bookmark&amp;#8217;s &lt;span class="caps"&gt;URL&lt;/span&gt; to be &lt;code&gt;http://aquariusrecords.org/bin/search.cgi?search_string=%s&lt;/code&gt;. That&amp;#8217;s the key: Change the search string to &lt;code&gt;%s&lt;/code&gt;. Camino will automatically replace &lt;code&gt;%s&lt;/code&gt; with your search string.&lt;/li&gt;&lt;li&gt;Last, I assigned the shortcut &lt;code&gt;aq&lt;/code&gt; to the bookmark.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Now I can type &lt;code&gt;aq paul metzger&lt;/code&gt; into Camino and go directly to the Aquarius search page for &lt;a href="http://www.paulmetzger.net/"&gt;Paul Metzger&lt;/a&gt;. Simple and easy, and good for your ears.&lt;/p&gt;&lt;p&gt;You can read &lt;a href="http://caminobrowser.org/documentation/bookmarks/#shortcuts"&gt;more complete information on Camino&amp;#8217;s search shortcuts&lt;/a&gt; on their documentation page. &lt;a href="http://www.mozilla.com/en-US/firefox/"&gt;Firefox&lt;/a&gt; has &lt;a href="http://www.mozilla.org/docs/end-user/keywords.html"&gt;the same feature&lt;/a&gt;, and I think &lt;a href="http://haoli.dnsalias.com/Saft/index.html"&gt;Saft&lt;/a&gt; adds a similar feature to &lt;a href="http://www.apple.com/safari/"&gt;Safari&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/231825481" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/Aquarius">Aquarius</category>
      <category domain="http://blog.hypsometry.com/archives/tags/Camino">Camino</category>
    </item>
    <item>
      <title>On habits, simplicity, obsolescence, and Zachary Schneirov's sense of humor.</title>
      <link>http://blog.hypsometry.com/archives/2008/2/7/on_habits_simplicity_obsolescence_and/</link>
      <pubDate>Thu, 07 Feb 2008 08:33:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/2/7/on_habits_simplicity_obsolescence_and/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2240841446/"&gt;&lt;img src="http://farm3.static.flickr.com/2344/2240841446_70e8652e37_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;For a few years now I&amp;#8217;ve been using &lt;a href="http://notational.net/"&gt;Notational Velocity&lt;/a&gt; for, well, for just about everything. As its author, Zachary Schneirov, puts it:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;While there are many, many note-taking programs for Mac &lt;span class="caps"&gt;OS X&lt;/span&gt;, Notational Velocity is the only one that actually operates in a useful manner.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It&amp;#8217;s as simple as it possibly could be, and all the more powerful for that. All you do is write notes and search for text, and there&amp;#8217;s one interface to perform both those functions.&lt;/p&gt;&lt;p&gt;The components are simple: There are notes, and each note consists of a title and some body text. (Completely plain text.) And you can see a list of your notes, in which each entry shows both the title and the beginning of the body text. And there&amp;#8217;s a search bar, which is the most powerful part.&lt;/p&gt;&lt;p&gt;For instance, I keep my todo list in a note called &amp;#8220;today&amp;#8221;. To get to that note, I start typing &amp;#8220;today&amp;#8221; into the search bar. The search bar autocompletes (in a soft, unobtrusive manner, unlike iTunes, for instance) what I&amp;#8217;m typing. At the same time, a list of all notes containing (in either their titles or their bodies) whatever I&amp;#8217;ve typed so far. By the time I&amp;#8217;ve typed &amp;#8220;to&amp;#8221;, the note titled &amp;#8220;today&amp;#8221; has been selected for me. In addition, I can see all the other notes I&amp;#8217;ve created that contain &amp;#8220;to&amp;#8221;, such as a note that contains the address of a friend in Washing&lt;strong&gt;to&lt;/strong&gt;n, a note that contains my serial number for &lt;a href="http://www.roxio.com/enu/products/toast/titanium/overview.html"&gt;&lt;strong&gt;To&lt;/strong&gt;ast&lt;/a&gt;, a bunch of notes with my full name Chris&lt;strong&gt;to&lt;/strong&gt;pher, and so on.&lt;/p&gt;&lt;p&gt;So that&amp;#8217;s simple enough. I just select the note I want from the list, tab into the main text editing area, and do whatever I need to do.&lt;/p&gt;&lt;p&gt;One entry in my current todo list is &amp;#8220;call &lt;a href="http://fernwoodbigsur.com/"&gt;Fernwood&lt;/a&gt;&amp;#8221;. If I type &amp;#8220;fernwood&amp;#8221; into the search bar, the list of notes narrows down to just one: &amp;#8220;today&amp;#8221;, where I&amp;#8217;ve reminded myself to make a camping reservation for a &lt;a href="http://folkyeah.com/"&gt;folkYEAH&lt;/a&gt;&lt;a href="http://www.fernwoodbigsur.com/music.html"&gt;show&lt;/a&gt;. But because there&amp;#8217;s no note with the title &amp;#8220;fernwood&amp;#8221;, Notational Velocity only shows me that note in the list; it doesn&amp;#8217;t select it. If I tab into the text entry field, then the application will automatically create a new note for me, with the title &amp;#8220;fernwood&amp;#8221;, where I can enter my reservation information.&lt;/p&gt;&lt;p&gt;In other words, the search bar tries to find what you&amp;#8217;re looking for, but if it can&amp;#8217;t, it assumes that you&amp;#8217;re creating something new. Simple as could be.&lt;/p&gt;&lt;p&gt;Notational Velocity has a bit of &lt;a href="http://www.google.com/search?q=%22notational+velocity%22"&gt;a cult following&lt;/a&gt;. I think I first read about it &lt;a href="http://www.43folders.com/2004/09/28/you-shall-know-us-by-our-notational-velocity"&gt;on 43 Folders&lt;/a&gt;, back in 2004. Unfortunately, Schneirov stopped updating the application as of &lt;a href="http://notational.net/downloadnv.html"&gt;version 1.1.1&lt;/a&gt;, which was sometime back in 2005. Which means that there&amp;#8217;s no Intel version available, which means that it&amp;#8217;s dying a slow death.&lt;/p&gt;&lt;p&gt;Last summer &lt;a href="http://www.pjhyett.com/"&gt;PJ Hyett&lt;/a&gt; created a Rails version of the application for the web, called &lt;a href="http://vjot.com/"&gt;vJot&lt;/a&gt;. (And &lt;a href="http://errtheblog.com/posts/58-jottin-to-the-fullest"&gt;released it&lt;/a&gt; as &lt;a href="http://en.wikipedia.org/wiki/Mit_license"&gt;open source&lt;/a&gt;.) vJot&amp;#8217;s slick, but a web application doesn&amp;#8217;t really fit into the same slot in my workflow as Notational Velocity. So it looks like I&amp;#8217;m stuck with it, slowness and proprietary database format and all.&lt;/p&gt;&lt;p&gt;Today I just figured out how to speed it up, in one crucial regard. Notational Velocity allows you to set a hot key that will bring the application to the front. For some reason, this has revealed itself to be one of the application&amp;#8217;s worst performance bottlenecks. After a year and a half of being annoyed by the delay of bringing to the front, it finally occurred to me to trigger it using &lt;a href="http://docs.blacktree.com/quicksilver/what_is_quicksilver"&gt;Quicksilver&lt;/a&gt;. (Yes, my other favorite application which is essential to my workflow and &lt;a href="http://lifehacker.com/software/exclusive-lifehacker-interview/quicksilvers-creator-on-the-future-of-qs-330548.php"&gt;whose development has also stopped&lt;/a&gt;.) Quicksilver, it seems, is &lt;em&gt;much&lt;/em&gt; faster at revealing Notational Velocity than Notational Velocity itself.&lt;/p&gt;&lt;p&gt;Simple enough to do: Go into Notational Velocity and set the hot key to some combination that I&amp;#8217;ll never press, then go into Quicksilver and &lt;a href="http://docs.blacktree.com/quicksilver/preferences/triggers_preferences"&gt;create a new trigger&lt;/a&gt; that opens Notational Velocity when I press command-option-space.&lt;/p&gt;&lt;p&gt;Oh, and even if you don&amp;#8217;t care about anything I&amp;#8217;ve said here, go over to &lt;a href="http://notational.net/"&gt;the Notational Velocity site&lt;/a&gt; anyway, just to check out the brilliant photographs. Please.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/231264250" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/design">design</category>
      <category domain="http://blog.hypsometry.com/archives/tags/interface">interface</category>
    </item>
    <item>
      <title>On the quiet archivist that lurks inside us all.</title>
      <link>http://blog.hypsometry.com/archives/2008/2/5/on_the_quiet_archivist_that/</link>
      <pubDate>Tue, 05 Feb 2008 15:02:00 GMT</pubDate>
      <guid>http://blog.hypsometry.com/archives/2008/2/5/on_the_quiet_archivist_that/</guid>
      <author>hypsometry.blog@cboone.fea.st (Chris Boone)</author>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hypsography/2245692214/"&gt;&lt;img src="http://farm3.static.flickr.com/2092/2245692214_b3b4f862bf_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://nytimes.com/"&gt;The New York Times&lt;/a&gt;, &lt;a href="http://designobserver.com/"&gt;Design Observer&lt;/a&gt;, and the &lt;a href="http://aiga.org/"&gt;&lt;span class="caps"&gt;AIGA&lt;/span&gt;&lt;/a&gt; are collecting and archiving amateur photographs of the American voting process. &lt;a href="http://pollingplaces.nytimes.com/"&gt;The Polling Place Photo Project&lt;/a&gt; aims to have photographs of every polling place in the country, all of them available under &lt;a href="http://creativecommons.org/"&gt;the Creative Commons&lt;/a&gt; &amp;#32; &lt;a href="http://creativecommons.org/licenses/by-nd/3.0/"&gt;Attribution No Derivatives license&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm/post_photographs"&gt;Posting photographs&lt;/a&gt; is easy: Just choose a file and enter some information about where you voted. You can &lt;a href="http://pollingplaces.nytimes.com/content.cfm/browse_photographs"&gt;browse the submitted photographs&lt;/a&gt;, and search by various characteristics. The photographs all show roughly the same things, but none of them show exactly the same things.&lt;/p&gt;&lt;p&gt;Little old ladies checking people&amp;#8217;s names.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=1076629&amp;#38;photoID=3185813&amp;#38;fromSearch=1"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/8/0/4/images/img_0019.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;So many signs.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=1970294&amp;#38;photoID=6238313&amp;#38;fromSearch=1"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/1/2/4/1/images/img_8840.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In New York they use levers, in San Francisco they use paper ballots.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=1127438&amp;#38;photoID=3354313&amp;#38;StartRow=2&amp;#38;SearchNum=1"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/8/3/5/images/redlever.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=2048197&amp;#38;photoID=6575654"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/1/2/7/2/images/img_1627.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Finished voters get stickers.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=1282142&amp;#38;photoID=3801109"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/9/2/3/images/6a00c2251c0db9f21900e398d9acf80003-320pi-1.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The American flag is everywhere.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=1357582&amp;#38;photoID=4013662&amp;#38;StartRow=0&amp;#38;SearchNum=1"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/9/6/3/images/flag_pollinglocation.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Snowmen like Obama.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=928649&amp;#38;photoID=2710313&amp;#38;StartRow=0&amp;#38;SearchNum=1"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/7/0/6/images/obama%20snowman1.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;And then there&amp;#8217;s Flat Stanley.&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=1340329&amp;#38;photoID=3938342"&gt;&lt;img src="http://pollingplaces.nytimes.com/resources/pollproject/9/5/4/images/img_0271.jpg" alt="" style="max-width: 100%" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://pollingplaces.nytimes.com/content.cfm?page=photo_detail&amp;#38;voterID=2362313&amp;#38;photoID=7768894"&gt;My contribution&lt;/a&gt; is a little out of focus, but it&amp;#8217;s been that kind of day.&lt;/p&gt;&lt;img src="http://feeds.hypsometry.com/~r/hypsometry/blog/articles/~4/230101848" height="1" width="1"/&gt;</description>
      <category domain="http://blog.hypsometry.com/archives/tags/elections">elections</category>
      <category domain="http://blog.hypsometry.com/archives/tags/photography">photography</category>
    </item>
  </channel>
</rss>
