<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.mikewest.org/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en">
    <title type="text">Mike West - Posts Only</title>
    <link rel="alternate" type="text/html" href="http://mikewest.org/" />
    
    <id>http://mikewest.org/</id>
    <author>
        <name>Mike West</name>
        <uri>http://mikewest.org/</uri>
        <email>mike@mikewest.org</email>
    </author>

    
    <updated>2010-05-16T00:00:00+02:00</updated>
    
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.mikewest.org/just_posts" /><feedburner:info uri="just_posts" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><subtitle type="html">Just the posts, please. None of that linky goodness for me, thanks.</subtitle><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" /><entry>
        <title type="text">JSLint needs some Bad Parts</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/plagaIdm0UY/jslint-needs-some-bad-parts" />
        <id>http://mikewest.org/2010/05/jslint-needs-some-bad-parts</id>
        <updated>2010-05-16T00:00:00+02:00</updated>
        <published>2010-05-16T00:00:00+02:00</published>
        <content type="html">
&lt;p&gt;One of the few tools that I consider truly indispensable when developing
websites is &lt;a href="http://www.jslint.com/"&gt;JSLint&lt;/a&gt;.  A marvel of applied compiler theory, the program
has saved me from stupid mistakes more times than I care to remember.  I
have it set up to automatically sanity-check my code &lt;a href="http://github.com/mikewest/jslint-utils"&gt;every time I push a
commit to SVN&lt;/a&gt;, and it&amp;rsquo;s generally my best friend in the whole
wide world.&lt;/p&gt;

&lt;p&gt;JSLint isn&amp;rsquo;t always perfect, however, especially when used to check CSS
files.  I think &lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt; is a JavaScript wizard, but I'm
somewhat less blindly acquiescent when it comes to his take on the Good
Parts of style sheets.  For better or worse, browsers are &lt;em&gt;much&lt;/em&gt; less
similar in their interpretation of what I mean when I write a particular
style, and certain hacks and workarounds are par for the course when
putting together a layout of any complexity.  JSLint&amp;rsquo;s CSS checks do a
good job warning about certain types of errors (missing semicolons, for
instance), but a relatively terrible job when it comes to some of the
necessary evils of practical development.  In short, JSLint&amp;rsquo;s CSS mode
needs some &lt;a href="http://github.com/mikewest/jslint/raw/master/CHANGELOG.markdown"&gt;Bad Parts&lt;/a&gt; to be really &lt;em&gt;usable&lt;/em&gt; for me.&lt;/p&gt;

&lt;p&gt;In itself, this wouldn&amp;rsquo;t be an issue.  Crockford has kindly released
JSLint as open source (under a unique (to say the least) &amp;ldquo;Do no evil&amp;rdquo;
license), and I'm generally able to puzzle out how to go about adding
support for the features that I believe are necessary.  Getting those
patches into the mainline JSLint project is, unfortunately, often a
miserable process.  I have two issues with the current process:&lt;/p&gt;

&lt;p&gt;First, there&amp;rsquo;s no public repository (that I've come across).  Crockford
is pretty good about announcing changes on &lt;a href="http://tech.groups.yahoo.com/group/jslint_com/"&gt;the JSLint mailing list&lt;/a&gt;,
and he keeps a timestamp in the current &lt;code&gt;fulljslint.js&lt;/code&gt; file, but that&amp;rsquo;s
hardly a solid basis for contributing patches.  This isn&amp;rsquo;t a show stopper,
it just makes things harder to follow than they could be, and more
difficult to give back to the project than it should be.  I asked about
this &lt;a href="http://tech.groups.yahoo.com/group/jslint_com/message/476"&gt;in May 2009&lt;/a&gt;, and was met with silence.  Ah well.&lt;/p&gt;

&lt;p&gt;Second, the aforementioned list is easily the most (passive-)aggressive
I've been on recently.  The (true) warning that &amp;ldquo;JSLint will hurt your
feelings&amp;rdquo; goes double for posting questions or suggestions, especially
as a newbie.  I almost fell off my chair when I saw &lt;a href="http://tech.groups.yahoo.com/group/jslint_com/message/1168"&gt;this question&lt;/a&gt;
(&amp;ldquo;I have this problem, and I've found this workaround.  Why is it a
problem in the first place?&amp;rdquo;) received &lt;a href="http://tech.groups.yahoo.com/group/jslint_com/message/1170"&gt;this response&lt;/a&gt; (&amp;ldquo;Thanks for
the report.  JSLint now no longer accepts your workaround.&amp;rdquo;)  Crockford
is a &lt;em&gt;smart&lt;/em&gt; guy, and he&amp;rsquo;s opinionated in the best possible way, but he
couples that with a periodic lack of tact that&amp;rsquo;s really influenced the
way the list as a whole works.  It&amp;rsquo;s simply not a fun place to
contribute ideas or code, and that&amp;rsquo;s a shame.  &lt;a href="http://tech.groups.yahoo.com/group/jslint_com/message/1280"&gt;Arguing about the
validity of suggestions&lt;/a&gt; is simply not something I'm willing to do
&lt;em&gt;every single time&lt;/em&gt; I make a suggestion, especially when the suggestions
are quite often met with silence from the one guy who actually has
commit access to the mainline trunk.&lt;/p&gt;

&lt;p&gt;So, to resolve these issues for myself, I'm forking JSLint.  I fully
expect this to be of interest to almost exclusively myself, but I&amp;rsquo;ll
find it useful, and I&amp;rsquo;ll hold out hope that some of the patches will
eventually make it back into JSLint proper.&lt;/p&gt;

&lt;p&gt;To resolve the issue of a base &amp;ldquo;official&amp;rdquo;  repository, I&amp;rsquo;ll pull down
a copy of the current iteration of JSLint on a daily basis, and
mirror it on GitHub (&lt;a href="http://github.com/mikewest/jslint/tree/mirror"&gt;jslint/mirror&lt;/a&gt;).  My patches will be pushed
to &lt;a href="http://github.com/mikewest/jslint/"&gt;jslint/master&lt;/a&gt; (along with QUnit-based regression tests), and
I&amp;rsquo;ll do my best to keep &lt;code&gt;master&lt;/code&gt; merged with the latest from &lt;code&gt;mirror&lt;/code&gt;,
and the changes continually rebased on top of &lt;code&gt;mirror&lt;/code&gt; into
&lt;a href="http://github.com/mikewest/jslint/tree/rebased"&gt;jslint/rebased&lt;/a&gt; for ease of application (in the unlikely event
that Crockford pays attention :) ).&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll keep the &lt;a href="http://github.com/mikewest/jslint/raw/master/CHANGELOG.markdown"&gt;changelog&lt;/a&gt; up to date as I add the functionality
I find that I need to do my job.  If you find the idea useful, I hope
you&amp;rsquo;ll help me out.  Reasonable patches most humbly accepted (although
&lt;em&gt;my&lt;/em&gt; arbitration of &amp;ldquo;reasonable&amp;rdquo; might hurt your feelings too).&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/plagaIdm0UY" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2010/05/jslint-needs-some-bad-parts</feedburner:origLink></entry>

    
    <entry>
        <title type="text">A JavaScript Detection Pattern</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/XrPKdimg6Dk/javascript-detection-pattern" />
        <id>http://mikewest.org/2010/03/javascript-detection-pattern</id>
        <updated>2010-03-06T00:00:00+01:00</updated>
        <published>2010-03-06T00:00:00+01:00</published>
        <content type="html">
&lt;p&gt;Progressive enhancement of our sites and applications has become a relatively well accepted best practice for web development.  It simply makes sense to implement core functionality in a universally accessible way before layering new behaviors and possibilities for interaction on top via JavaScript.&lt;/p&gt;

&lt;p&gt;This implementation model has one drawback that we need to consider.  If we render a basic version of a module before reworking it with JavaScript, it&amp;rsquo;s possible that visitors would briefly be exposed to the unenhanced module, only to see it morph into something new before their eyes.  This distraction is especially likely when we consider the &lt;a href="http://developer.yahoo.com/performance/rules.html#js_bottom"&gt;well-known performance benefits&lt;/a&gt; associated with loading JavaScript at the very bottom of a page.  The page as a whole will load well before JavaScript is completely parsed and executed, leaving a space of time during which the raw versions of your modules are visible.&lt;/p&gt;

&lt;p&gt;To avoid this issue, I'd suggest inserting the following code directly after opening your page&amp;rsquo;s &lt;code&gt;body&lt;/code&gt; element:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script&amp;gt;document.documentElement.className += " js";&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When a visitor comes to the site with JavaScript enabled, this snippet will add a &lt;code&gt;js&lt;/code&gt; class to the document&amp;rsquo;s root node (in most cases, the &lt;code&gt;html&lt;/code&gt; element).  This gives us a styling hook that allows us to generate CSS rules that only take effect when JavaScript is present.  Prefixing rules with a &lt;code&gt;.js&lt;/code&gt; selector ensures that they only apply when this script has executed, meaning that the visitor must have JavaScript enabled in her browser.  We can use this information to pre-style the widgets in preparation for the JavaScript manipulations we&amp;rsquo;ll do later on.&lt;/p&gt;

&lt;p&gt;I've put together a &lt;a href="http://mikewest.org/static_content/2010-03-javascript-detection.html"&gt;demonstration of this JavaScript detection technique&lt;/a&gt; in action.  It&amp;rsquo;s worth visiting that demonstration both with and without JavaScript enabled, simply to get a feel for what&amp;rsquo;s possible.  It&amp;rsquo;s not a perfect solution (JavaScript could error out somewhere in the middle of the page, for instance), but I find it to be a reasonable compromise that avoids distracting flashes of incompletely styled content.&lt;/p&gt;

&lt;p&gt;That demonstration, however, is pretty abstract.  Let&amp;rsquo;s look at a more practical example of how this could improve a site&amp;rsquo;s usability.  Take &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt;, for instance: with JavaScript enabled, clicking on the &amp;ldquo;Sign in&amp;rdquo; button in the top right-hand corner of the page exposes the login form, which is otherwise hidden away.  Without JavaScript, the form doesn&amp;rsquo;t show up at all, users are instead directed to a separate page that just displays this form.&lt;/p&gt;

&lt;p&gt;This is a reasonable fallback, all things considered (and certainly better than sites like CNN, whose login link goes nowhere without JavaScript).  Still, I see it as a missed opportunity as the login form&amp;rsquo;s HTML code is delivered to the user on the homepage regardless, it&amp;rsquo;s simply hidden by default.  I think a better decision would have been to design the page such that the login form shows up for all users, and is simply presented differently for users with JavaScript.&lt;/p&gt;

&lt;p&gt;I've implemented a &lt;a href="http://mikewest.org/static_content/2010-03-javascript-detection-twitter.html"&gt;demonstration of how this might work&lt;/a&gt; by copying down the Twitter homepage&amp;rsquo;s code, adding the JavaScript detection snippet from above, moving the login form HTML lower down on the page, and adding a few lines of CSS to make things halfway usable (a caveat: &lt;a href="http://mikewest.org/static_content/2010-03-javascript-detection-twitter.html"&gt;the twitter demo&lt;/a&gt; looks good in Chrome/Webkit, decent in Firefox, and miserable in IE: Twitter&amp;rsquo;s HTML is dependent upon server-side browser detection, which I'm not going to attempt to recreate here.).  I'm no designer, but it seems like a step in the right direction to me, and adds a bit of bulletproofing with next to no effort expended.&lt;/p&gt;

&lt;p&gt;With this in your toolkit, I don&amp;rsquo;t think there&amp;rsquo;s any excuse for mandating a hard requirement for JavaScript for most interactive widgets.  Certainly complex applications would be hard-pressed to come up with ways of presenting the same functionality to all users, but I think we can all agree that &amp;ldquo;simple&amp;rdquo; functionality (like logging in) should be equally available to everyone, and we should absolutely take that into account when building websites.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: &lt;a href="http://timhuegdon.com/"&gt;Tim Huegdon&lt;/a&gt; mentioned, rightly, that &lt;code&gt;class&lt;/code&gt; isn&amp;rsquo;t actually a valid attribute on the &lt;code&gt;html&lt;/code&gt; element, and that it might be better to set the &lt;code&gt;js&lt;/code&gt; class on the document&amp;rsquo;s &lt;code&gt;body&lt;/code&gt; element instead.  It&amp;rsquo;s a valid point, one which ought not be ignored out of hand.  I'm sticking with &lt;code&gt;document.documentElement&lt;/code&gt; for a simple reason: I know it works stably in every browser I've tested (IE6+, FF2+, Safari 2+, Opera 9.5+).  I've heard anecdotal evidence of problems in IE caused by manipulating the document&amp;rsquo;s &lt;code&gt;body&lt;/code&gt; while it&amp;rsquo;s loading (&amp;ldquo;Operation Aborted&amp;rdquo;, and the like), which I've never experienced with this technique, and which I'd like to avoid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update to the Update&lt;/strong&gt;:   &lt;a href="http://vanderven.se/martijn/"&gt;Martijn van der Ven&lt;/a&gt; notes, also rightly, that HTML5 allows &lt;code&gt;class&lt;/code&gt; attributes (as well as all other &lt;a href="http://dev.w3.org/html5/spec/dom.html#global-attributes"&gt;global attributes&lt;/a&gt;) on the &lt;code&gt;html&lt;/code&gt; element.  One more reason to switch over to the &lt;a href="http://diveintohtml5.org/semantics.html#the-doctype"&gt;HTML5 doctype&lt;/a&gt;, if you ask me.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/XrPKdimg6Dk" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2010/03/javascript-detection-pattern</feedburner:origLink></entry>

    
    <entry>
        <title type="text">CSS Rules of Thumb</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/H0JT87Ovepc/CSS-rules-of-thumb" />
        <id>http://mikewest.org/2010/02/CSS-rules-of-thumb</id>
        <updated>2010-02-22T00:00:00+01:00</updated>
        <published>2010-02-22T00:00:00+01:00</published>
        <content type="html">
&lt;p&gt;Apropos of nothing, a few CSS tips that have nothing to do with browser
incompatibilities, and everything to do with your own sanity when dealing
with code you've written:&lt;/p&gt;

&lt;h2&gt;Comment your CSS files&lt;/h2&gt;

&lt;p&gt;This is incredibly basic advice that I don&amp;rsquo;t think is taken at all seriously
enough.  I've made an effort over the last few months to begin every CSS file
I write with a comment block that looks something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/**
 *  Title of the CSS file
 *
 *  A Brief description of the CSS file's contents, and, if
 *  relevant, it's dependencies.  This should generally only
 *  be a sentence or three long, anything more, and the file's
 *  almost certainly attempting to do too much.
 *
 *  &amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;
 *      &amp;lt;div class="the markup this css file expects"&amp;gt;
 *          You'll be ever so happy you included this part
 *          in about three months, when you come back to this
 *          project, having completely forgotten it's
 *          structure and purpose.
 *      &amp;lt;/div&amp;gt;
 *  &amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
 *
 *  @author     Mike West &amp;lt;mike@mikewest.org&amp;gt;
 *  @package    some_greppable_name
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the basis upon which you can start writing reasonable CSS rules that
you have a good chance of understanding the next time you read them.
Especially the expected markup.  You may think that&amp;rsquo;s overly verbose, and
simply overkill for most projects, but without it, you&amp;rsquo;ll get lost when trying
to map the file&amp;rsquo;s CSS to anything at all on the actual website you&amp;rsquo;re coding.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s important to put as much context into the CSS file as possible, because
CSS is a complex language when you use it the way you&amp;rsquo;re supposed to. The more
you rely on the cascade to reuse code and concepts, the more you&amp;rsquo;ll come to
rely on good documentation to keep your bearings.&lt;/p&gt;

&lt;h2&gt;Write many, highly specialized CSS files&lt;/h2&gt;

&lt;p&gt;The general rule of thumb about documenting your code has a corollary: &lt;strong&gt;you
should use &lt;em&gt;lots&lt;/em&gt; of CSS files&lt;/strong&gt;.  You should be able to pick up a small,
focused chunk of code, read through it, and understand more or less how it
fits into the site as a whole.  If it depends on some other chunk of code,
that code should be referenced, but not included in the same file.  Here&amp;rsquo;s
why: long CSS files are opaque, confused, and unstructured.  I don&amp;rsquo;t care how
disciplined you are: this is true 100% of the time, without fail.&lt;/p&gt;

&lt;p&gt;If you find yourself sifting through a CSS file, trying to figure out where
best to stick a new bit of code, you&amp;rsquo;re simply doing it wrong. The fewer
CSS files you have, the larger they&amp;rsquo;ll be, and the more tempted you&amp;rsquo;ll be
to simply stick some new rules on the end to save time.  You&amp;rsquo;ll do this
because your teammates are doing it, and they&amp;rsquo;ll do it because you&amp;rsquo;re doing
it. This is the path to poor code quality, poor code reuse, and simple
insanity.&lt;/p&gt;

&lt;p&gt;In short, I see long CSS files as the &lt;a href="http://en.wikipedia.org/wiki/Fixing_Broken_Windows"&gt;broken windows&lt;/a&gt; of web development.
The longer and more convoluted the file, the more likely even the best
developers are to simply make it more confused.&lt;/p&gt;

&lt;h2&gt;Name your files well&lt;/h2&gt;

&lt;p&gt;To whatever extent possible, you should develop a naming convention to make a
file&amp;rsquo;s purpose clear, minimizing the chance that you&amp;rsquo;ll have to go looking for
a good home for new code.&lt;/p&gt;

&lt;p&gt;For example, on my current project, I've written a lot of modules that are all
based upon the same root class.  The markup might look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class="basebox"&amp;gt;
    [Module basics go here]
&amp;lt;/div&amp;gt;

&amp;lt;div class="basebox special"&amp;gt;
    [Module basics, plus "special" markup go here]
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;basebox.css&lt;/code&gt; defines the presentation of the features common to all
&amp;ldquo;Basebox&amp;rdquo; style modules.  In that file&amp;rsquo;s documentation block, I'd define a
&lt;code&gt;@package&lt;/code&gt; of &amp;ldquo;projectname_basebox&amp;rdquo;.  The &amp;ldquo;special&amp;rdquo; presentation is then
defined in &lt;code&gt;basebox_special.css&lt;/code&gt;, with a &lt;code&gt;@package&lt;/code&gt; of
&amp;ldquo;projectname_basebox_special&amp;rdquo;.  The filename makes dependencies clear when
determining import order, and the &lt;code&gt;@package&lt;/code&gt; marker makes dependencies clear
inside the file (and available to &lt;code&gt;grep&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;Style guides are good&lt;/h2&gt;

&lt;p&gt;You should organize a style guide for your team, and stick to it.  As with
any language, it&amp;rsquo;s helpful when your whole team speaks the same dialect.
Insofar as that&amp;rsquo;s true, I think it&amp;rsquo;s more important that you agree on &lt;em&gt;a&lt;/em&gt; set
of rules defining how you write CSS, rather than &lt;em&gt;my&lt;/em&gt; set of rules. The more
your CSS looks like your neighbors, the more likely she is to understand your
rules quickly when she needs to change them (and the more likely &lt;em&gt;you&lt;/em&gt; are to
understand rules you wrote months ago&amp;hellip;).&lt;/p&gt;

&lt;p&gt;That said, you should of course all write CSS like I do.  Because it&amp;rsquo;s the
right way.  Here&amp;rsquo;s how and why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Selectors are to be written in order of specificity, and nested
according to the site&amp;rsquo;s markup.  Given a &lt;code&gt;basebox&lt;/code&gt; module:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class="basebox"&amp;gt;
    &amp;lt;div class="header"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class="body"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class="footer"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I'd expect to see CSS code that looked something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.basebox {
    /* Properties go here */
}
    .basebox .header {
        /* Properties go here */
    }
    .basebox .body {
        /* Properties go here */
    }
    .basebox .footer {
        /* Properties go here */
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I'd argue for this format for the same reasons that indenting a &amp;ldquo;real&amp;rdquo;
programming language makes sense: it&amp;rsquo;s easier to understand a file&amp;rsquo;s
scope when selectors are nested (this, incidentally, is another reason
that multiple CSS files are beneficial: each file&amp;rsquo;s &amp;ldquo;scope&amp;rdquo; begins
anew at the left-hand column).&lt;/p&gt;

&lt;p&gt;This also operates on the principle of least surprise.  I expect to see
the most general rules first, and to work towards more specific rules at
the bottom of the file.  I think most developers would agree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Properties are written &lt;em&gt;one per line&lt;/em&gt;.  Period.  I consider this
self-evident, and I'm always shocked when otherwise intelligent people
argue with me about it.  Writing properties one per line has two
distinct advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Selectors with more than two or three properties don&amp;rsquo;t require
horizontal scrolling.  Nor do they require maintaining a parse
tree in your head while reading code.&lt;/p&gt;

&lt;p&gt;To make this point more clearly, I&amp;rsquo;ll cherry-pick a horrid example
out of &lt;a href="http://github.com/stubbornella/oocss/blob/master/core/grid/grids.css"&gt;Nicole&amp;rsquo;s OOCSS&lt;/a&gt; (Hi, &lt;a href="http://www.stubbornella.org/content/"&gt;Nicole&lt;/a&gt;!  Sorry I'm picking on
you! :) ):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/* This is unreadable */
.lastUnit{display:table-cell;float:none;width:auto;*display:block;*zoom:1;_position:relative;_left:-3px;_margin-right:-3px;} 

/* This is less so */
.lastUnit {
    display:        table-cell;
    float:          none;
    width:          auto;
    *display:       block;
    *zoom:          1;
    _position:      relative;
    _left:          -3px;
    _margin-right:  3px;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Properties written on more than one line make version control
(which generally operates with line-based &lt;code&gt;diff&lt;/code&gt; presentation)
much more user friendly.  If I ever had to resolve conflicts in
a file with 100+ character lines, I think I'd simply rewrite the
rule rather than spend the time to figure things out.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;All that said, I do find single-line rulesets acceptable (and, in fact,
preferable) when writing long runs of single-rule groups.  Sprite
definitions are the canonical example.  It simply makes sense to write
code like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.sprited li {
    background: url(/path/to/sprite.png) no-repeat 0 0;
}
    .sprited .s1 { background-position: 0 -20px; }
    .sprited .s2 { background-position: 0 -40px; }
    .sprited .s3 { background-position: 0 -60px; }
    .sprited .s4 { background-position: 0 -80px; }
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Properties are formatted for readability using 4-space tab stops.
Readability improves when the eye has a clean line to jump to.  Again
using Nicole&amp;rsquo;s code as an example, would you rather read this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.lastUnit {
    display: table-cell;
    float: none;
    width: auto;
    *display: block;
    *zoom: 1;
    _position: relative;
    _left: -3px;
    _margin-right: 3px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.lastUnit {
    display:        table-cell;
    float:          none;
    width:          auto;
    *display:       block;
    *zoom:          1;
    _position:      relative;
    _left:          -3px;
    _margin-right:  3px;
}
&lt;/code&gt;&lt;/pre&gt;

I don&amp;rsquo;t think it&amp;rsquo;s much of a contest.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Properties are written in alphabetical order.  This also helps keep
diffs sane, as you no longer get into fights about which rules should
be written together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browser hacks are inline, and documented.  Taking Nicole&amp;rsquo;s example above,
I'd expect to see (at least) two comment blocks, explaining the rationale
behind the various IE hacks:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.lastUnit {
    display:        table-cell;
    float:          none;
    width:          auto;

    /**
     *  @HACK:  Giving `haslayout` to IE 6 and 7 via the
     *          `zoom` and the star hack.
     */
    *display:       block;
    *zoom:          1;

    /**
     *  @HACK:  Something IE6 specific that I don't understand
     *          because it wasn't documented.  Maybe it's in a
     *          wiki somewhere?  Who knows.  Danger!
     */
    _position:      relative;
    _left:          -3px;
    _margin-right:  3px;
}
&lt;/code&gt;&lt;/pre&gt;

This is, of course, more verbose, and will take up some of your valuable
time.  I don&amp;rsquo;t care.  Write the comments anyway.  You&amp;rsquo;ll need them later
on when you've forgotten why you wrote them.  Labeling your hacks makes
you think about and justify them, and makes them simple to remove when
you decide to stop supporting broken browsers.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Write code for human consumption&lt;/h2&gt;

&lt;p&gt;Your code should first and foremost be human-readable.  Of course you want to
deliver a single &lt;a href="http://developer.yahoo.com/performance/rules.html#num_http"&gt;combined&lt;/a&gt; and &lt;a href="http://developer.yahoo.com/performance/rules.html#minify"&gt;minified&lt;/a&gt; CSS file to the browser, and of
course that means that you&amp;rsquo;ll have to do some work to transform the nicely
readable code you've written into something lean and mean for performance and
efficiency (a good place to start would be &lt;a href="http://timhuegdon.com/"&gt;Tim Huegdon&amp;rsquo;s&lt;/a&gt; article
&amp;ldquo;&lt;a href="http://nefariousdesigns.co.uk/archive/2010/02/website-builds-using-make/"&gt;Website Builds Using Make&lt;/a&gt;&amp;rdquo;).&lt;br/&gt;
&lt;/p&gt;

&lt;p&gt;So don&amp;rsquo;t worry about the performance penalties to writing long comments,
detailing every tricky piece of your CSS.  And don&amp;rsquo;t worry about the
performance penalties of splitting your code into many easily understood
chunks.  There aren&amp;rsquo;t any.  Your build process will combine all your files,
and compress them into a single file that&amp;rsquo;s completely incomprehensible to
human eyes.  This is a purely mechanical act, and it&amp;rsquo;s something that should
be scripted.  Your concern when writing code should be &lt;em&gt;your&lt;/em&gt; understanding
of that code, not the browser&amp;rsquo;s.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/H0JT87Ovepc" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2010/02/CSS-rules-of-thumb</feedburner:origLink></entry>

    
    <entry>
        <title type="text">An Accessible Pagination Pattern</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/KHGP-P4aq4o/an-accessible-pagination-pattern" />
        <id>http://mikewest.org/2010/02/an-accessible-pagination-pattern</id>
        <updated>2010-02-09T00:00:00+01:00</updated>
        <published>2010-02-09T00:00:00+01:00</published>
        <content type="html">
&lt;p&gt;Pagination is a basic building block of the web, appearing practically everywhere content is displayed.  From a UI perspective, a pagination widget generally ends up being presented in a very straightforward manner as a horizontal list of links, framed by &amp;ldquo;previous&amp;rdquo; and &amp;ldquo;next&amp;rdquo; links to give the user clear calls to action.  Flickr and CNN provide good examples of this general pattern:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://mikewest.org/static_content/2010-02-pagination-pattern.png" alt="Pagination widgets on Flickr and CNN" /&gt;&lt;/p&gt;

&lt;p&gt;Flickr marks this up as a flat series of &lt;code&gt;a&lt;/code&gt; tags inside a &lt;code&gt;div&lt;/code&gt;, CNN as a &lt;code&gt;ul&lt;/code&gt;, containing one &lt;code&gt;li&lt;/code&gt; for each page.  And those certainly aren&amp;rsquo;t the only options: while doing a bit of research for a project at work, I came across a much wider than expected variety of markup, and no clear &amp;ldquo;best practice.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;After thinking about it a bit, and grilling my more intelligent friends, I've settled on a pattern that I think works pretty well.  It&amp;rsquo;s nothing at all groundbreaking, but is certainly worth documenting as a markup pattern I'd advocate.  The HTML is straightforward (and an &lt;a href="http://mikewest.org/static_content/2010-02-pagination-pattern.html"&gt;example&lt;/a&gt; is available):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;p id="paginglabel" class="audible"&amp;gt;Pagination&amp;lt;/p&amp;gt;
&amp;lt;ul role="navigation" aria-labelledby="paginglabel"&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href="#"&amp;gt;&amp;lt;span class="audible"&amp;gt;%TYPE% Page&amp;lt;/span&amp;gt;1&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href="#" rel="prev"&amp;gt;&amp;lt;span class="prev"&amp;gt;Previous&amp;lt;span class="audible"&amp;gt;: %TYPE% Page&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;2&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;p&amp;gt;&amp;lt;span class="audible"&amp;gt;You're currently reading %TYPE% page &amp;lt;/span&amp;gt;3&amp;lt;/p&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href="#" rel="next"&amp;gt;&amp;lt;span class="next"&amp;gt;Next&amp;lt;span class="audible"&amp;gt;: %TYPE% Page&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;4&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href="#"&amp;gt;&amp;lt;span class="audible"&amp;gt;%TYPE% Page &amp;lt;/span&amp;gt;5&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I see a few advantages to this markup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clear signposting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The widget uses the &lt;a href="http://www.w3.org/TR/2009/WD-wai-aria-20091215/states_and_properties#aria-labelledby"&gt;&lt;code&gt;aria-labelledby&lt;/code&gt; attribute&lt;/a&gt; to instruct
capable browsers to use the contents of the preceding paragraph as a
label, and the &lt;a href="http://www.paciellogroup.com/blog/?p=106"&gt;&lt;code&gt;role&lt;/code&gt; attribute&lt;/a&gt; to demarcate the &lt;code&gt;ul&lt;/code&gt; as a
navigation landmark on the page.&lt;/p&gt;

&lt;p&gt;These are especially important for visitors making use of screenreaders or
other assistive technologies, as they typically have the option of
navigating through a page&amp;rsquo;s content by jumping directly from one list to
the next, or from one landmark to the next.  In such a scenario, the label
and role will be announced before reading the contents of the list,
providing essential information about its context and purpose which would
otherwise be lacking.&lt;/p&gt;

&lt;p&gt;Likewise, the previous and next pages are given &lt;a href="http://www.w3.org/TR/REC-html40/struct/links.html#h-12.1.2"&gt;&lt;code&gt;rel&lt;/code&gt; attributes&lt;/a&gt;,
making their relationship to the current page crystal clear, and available
to any capable parser.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clear link text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A link containing only the text &amp;ldquo;1&amp;rdquo; is more or less useless to a visitor
who can&amp;rsquo;t visually link the text to it&amp;rsquo;s context.  Adding that context is
simply done, however, by placing some additional text inside the link.  An
addition as trivial as &amp;ldquo;Page 1&amp;rdquo; makes a huge difference in comprehension.
This text can be hidden for sighted users by wrapping it in a &lt;code&gt;span&lt;/code&gt;, and
&lt;a href="http://accessibilitytips.com/2008/03/05/avoiding-visibility-hidden/"&gt;positioning it offscreen&lt;/a&gt; via CSS.  The current page is called
out in the same way, providing the visitor with additional context.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deduplication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CNN and Flickr made the same choice when marking up the widget&amp;rsquo;s &amp;ldquo;Previous&amp;rdquo;
and &amp;ldquo;Next&amp;rdquo; links.  Even though these both link off to items which are also
available in the list, the link has been duplicated, breaking the
relationship between the visible page number, and the textual label.  I'd
argue that it&amp;rsquo;s better to group the two into the same &lt;code&gt;a&lt;/code&gt; element, using one
link for both elements.&lt;/p&gt;

&lt;p&gt;The markup above does just that, placing the textual labels inside the link
element itself, making it clear that the previous page is page 2.  The
presentation of the &amp;ldquo;previous&amp;rdquo; and &amp;ldquo;next&amp;rdquo; links to the left and right of
the list, respectively, can be handled by positioning their containing
&lt;code&gt;span&lt;/code&gt;s absolutely.  This requires approximate knowledge of the text&amp;rsquo;s
size, and can usually be accommodated even in multi-language environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sound over Semantics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For pagination, it seems like it would make perfect sense to use an ordered
list rather than the unordered list I've chosen here.  It&amp;rsquo;s almost
certainly semantically correct, as the list of pages is indeed ordered, and
that order is indeed meaningful.&lt;/p&gt;

&lt;p&gt;In this case, however, I think it&amp;rsquo;s the wrong choice.  &lt;a href="http://www.nvda-project.org/"&gt;NVDA&lt;/a&gt; (which is
the only screen reader I have access to at the moment) reads ordered lists
as &amp;ldquo;One.  [List item content]  Two.  [List item content] &amp;hellip;&amp;rdquo;  An unordered
list, on the other hand, doesn&amp;rsquo;t number the items as they&amp;rsquo;re read. Since I'm
explicitly including the page number in the link, an &lt;code&gt;ol&lt;/code&gt; simply sounds
strange and repetitive: &amp;ldquo;One.  Example Page one. Link.  Two. Example page
two. Link. &amp;hellip;&amp;rdquo;  Assuming other readers like &lt;a href="http://www.freedomscientific.com/products/fs/jaws-product-page.asp"&gt;Jaws&lt;/a&gt; and &lt;a href="http://www.gwmicro.com/Window-Eyes/"&gt;WindowEyes&lt;/a&gt;
behave similarly, an unordered list simply &lt;em&gt;sounds&lt;/em&gt; better.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Thanks to &lt;a href="http://morethanseven.net/"&gt;Gareth&lt;/a&gt; for the good &lt;a href="http://twitter.com/garethr/status/9292593418"&gt;question&lt;/a&gt; that I'd neglected to
address.)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I've put together a &lt;a href="http://mikewest.org/static_content/2010-02-pagination-pattern.html"&gt;quick example of this markup at work&lt;/a&gt;.  I hope you
reach for it next time you need a pagination widget.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/KHGP-P4aq4o" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2010/02/an-accessible-pagination-pattern</feedburner:origLink></entry>

    
    <entry>
        <title type="text">MacSpeech Dictate: First Impressions</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/r-axoiJVW94/macspeech-dictate-first-impressions" />
        <id>http://mikewest.org/2009/11/macspeech-dictate-first-impressions</id>
        <updated>2009-11-19T00:00:00+01:00</updated>
        <published>2009-11-19T00:00:00+01:00</published>
        <content type="html">
&lt;p&gt;I suspect that the first thing any developer does when they get their hands on &lt;a href="http://www.macspeech.com/dictate/"&gt;MacSpeech Dictate&lt;/a&gt; is to begin writing a review of MacSpeech Dictate &lt;em&gt;in&lt;/em&gt; MacSpeech Dictate. I am no exception.&lt;/p&gt;

&lt;p&gt;Over the last three months I've develop more pain than usual in my wrists and elbows.  It&amp;rsquo;s not been painful enough to stop me from typing altogether, but certainly enough to make me stop and think about the amount of time I spend typing at the computer.&lt;/p&gt;

&lt;p&gt;My dad has been playing with Dragon Naturally Speaking on and off for quite some time now, so speech recognition software has been on my radar for years.  In fact, I suspect he personally financed the software&amp;rsquo;s research and development over the first few years of its life&amp;hellip; Of course the software was initially more or less worthless, its output was simply miserable through the first few versions.  But my dad continued to upgrade.  Year after year he picked up a new version of Dragon, installed it, spent hours training at, and eventually began to actually get things done using the software.  Now it&amp;rsquo;s my turn.&lt;/p&gt;

&lt;p&gt;So, first impressions (beyond the fact that it&amp;rsquo;s simply strange to talk instead of type):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I'm a little surprised at the delay between my speech and its recognition. It shouldn&amp;rsquo;t be surprising when considering how much work is involved in this sort of thing, but it is. I speak, and about a second and a half later text appears on the screen. As long as I'm not actually paying attention to the screen, this doesn&amp;rsquo;t bother me at all. At the moment, however, I'm paying quite a bit of attention to the screen, so it&amp;rsquo;s a little distracting.&lt;/p&gt;

&lt;p&gt;The text is generally correct, so that delay is easy enough to ignore. There is a slider in the preferences that offers a balance between speed and accuracy. I&amp;rsquo;ll play with that later, as I'm interested in the effect it has on the text produced.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I'm very surprised at the out-of-the-box accuracy. Dictate is doing a much better job than I expected it to, especially given my lack of experience with speech recognition software, and the seemingly insubstantial amount of text used to train the program. I read to it for about 10 minutes total and based on that small amount of training, I'm getting something like 90% accuracy. Reading back over the text that Dictate has produced, I certainly see some issues: it&amp;rsquo;s not perfect by any means.  I&amp;rsquo;ll need to go back and edit a few portions, but overall I'm impressed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I need to get used to the command structure. Specifically, I need to train myself to pause before and after commands. Dictate will delete the last phrase when I say &amp;ldquo;scratch that,&amp;rdquo; and delete the last word when I say &amp;ldquo;scratch word.&amp;rdquo; If I speak too fluidly, Dictate doesn&amp;rsquo;t recognize &amp;ldquo;scratch that&amp;rdquo; as a command. When I make a mistake I have to remember to pause a moment before correcting myself. That&amp;rsquo;ll take some time to get used to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dictate forces me to pay much more attention to the words I choose then I usually do. I normally write very fluidly, editing myself as I go. I&amp;rsquo;ll write half a sentence, jump back to the paragraph before to make a change, delete the sentence I'd started, rewrite the sentence, and start again. That process simply doesn&amp;rsquo;t work with speech recognition software. It&amp;rsquo;s much more difficult to jump around in the document, so it&amp;rsquo;s much more important for me to address a topic more linearly. I have to think before I speak, which is new to me.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Overall, I like this. I think it&amp;rsquo;s something I can get used to. It&amp;rsquo;s certainly better on my hands and wrists, and that&amp;rsquo;s something I very much appreciate at the moment. So far, it&amp;rsquo;s looking like a worthwhile purchase. Let&amp;rsquo;s see how I feel about a week or two.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A note on process:&lt;/strong&gt; I dictated this document via Dictate in a bit more than half an hour, stopping relatively often to figure out exactly what I was doing. I then copied the text out of Dictate&amp;rsquo;s notepad, pasted into a real editor, and cleaned up the text. I'm not thrilled with workflow, but it&amp;rsquo;s not bad.  Much less typing, which I'm certainly happy about.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/r-axoiJVW94" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2009/11/macspeech-dictate-first-impressions</feedburner:origLink></entry>

    
    <entry>
        <title type="text">My Jekyll Fork</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/ac4QnQuHRGQ/my-jekyll-fork" />
        <id>http://mikewest.org/2009/11/my-jekyll-fork</id>
        <updated>2009-11-12T00:00:00+01:00</updated>
        <published>2009-11-12T00:00:00+01:00</published>
        <content type="html">
&lt;p&gt;&lt;a href="http://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; is an interesting project, a well-architected throwback to a time before unnecessary dynamism reigned supreme.  In contrast to blog engines like Wordpress or Textile, Jekyll doesn&amp;rsquo;t attempt to do anything other than push raw content through a few simple filters out into the world in the form of static HTML files.  Jekyll&amp;rsquo;s &lt;a href="http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html"&gt;publication philosophy&lt;/a&gt; is very much in line with my own, and I appreciate the work that&amp;rsquo;s gone into it.  It&amp;rsquo;s relatively widely used, and therefore much more stable and well-tested than anything I'd write on my own.  Given my &lt;a href="http://twitter.com/mikewest/status/4605321990"&gt;recent experience&lt;/a&gt;, I want something that will Just Work™, and this looks like it.  I finished moving this site to Jekyll yesterday, and I'm quite happy with how it&amp;rsquo;s working&amp;hellip;&lt;/p&gt;

&lt;p&gt;It doesn&amp;rsquo;t fit me perfectly, though.  Here, I&amp;rsquo;ll point to a few features that I think are missing, and a few design decisions that I think are worth reconsideration.  Happily, it&amp;rsquo;s an open source project, so I&amp;rsquo;ll also be able to point to my fork of the project where I'm busy addressing these shortcomings.&lt;/p&gt;

&lt;h2&gt;&amp;ldquo;Generated&amp;rdquo; Pages: Tags and Archives&lt;/h2&gt;

&lt;p&gt;The biggest gap I see in Jekyll&amp;rsquo;s feature set is support for &amp;ldquo;generated&amp;rdquo; pages (covered in &lt;a href="http://github.com/mojombo/jekyll/issues#issue/16"&gt;Issue #16&lt;/a&gt;).  HTML that Jekyll produces is tied one-to-one with files you create on the filesystem.  This has the appeal of simplicity, fails in a number of ways to support two quasi-dynamic things that I consider essential to the kind of sites Jekyll aims to produce: tags, and archives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags&lt;/strong&gt; are a nice way of grouping content on a site, and surfacing that content to readers in an unobtrusive way.  Jekyll, out of the box, does a miserable job of making them available in templates.  &lt;code&gt;site.tags&lt;/code&gt; gives you a list of &lt;em&gt;all&lt;/em&gt; the site&amp;rsquo;s tags, &lt;code&gt;page.tags&lt;/code&gt; gives you the tags for the current page, and that&amp;rsquo;s it.  That&amp;rsquo;s simply not enough structured data to do anything useful with; I want more.  &amp;ldquo;More&amp;rdquo;, in my case, meaning two things: a separate page for each tag at &lt;code&gt;/tags/[TAG]&lt;/code&gt;, listing each article that fits; and a page listing out all the tags on the site (in cloud form, if only because I'm &lt;em&gt;so&lt;/em&gt; Web 2.0).  The latter is (painfully) possible out of the box, the former is not.&lt;/p&gt;

&lt;p&gt;My solution (based heavily on &lt;a href="http://matflores.com/"&gt;Matt Flores&lt;/a&gt;&amp;lsquo; &lt;a href="http://github.com/matflores/jekyll/commit/abd0491c451b77bd119a0071457a362c35e6c2f6"&gt;fork&lt;/a&gt;) is available in the &lt;a href="http://github.com/mikewest/jekyll/tree/tag_index"&gt;tag_index branch&lt;/a&gt; of my Jekyll fork.  The implementation is very low-impact: simply add a &lt;code&gt;tag_detail.html&lt;/code&gt; layout to your site&amp;rsquo;s &lt;code&gt;_layouts&lt;/code&gt; directory.  Jekyll will auto-generate pages using that layout for each tag on your site, providing &lt;code&gt;page.tag&lt;/code&gt; as a variable inside each as they&amp;rsquo;re rendered.  This allows you to dive into &lt;code&gt;site.tags&lt;/code&gt; to pull out lists of articles in a very straightforward way.  Once rendered into HTML, the result is placed into a directory you specify via a configuration variable (&lt;code&gt;tag_root&lt;/code&gt;).  This has worked brilliantly for me here on this site.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Archive pages&lt;/strong&gt; listing out content written during a certain period are another nice way of dividing up posts on a site.  Especially useful for sites with more than a few posts, it&amp;rsquo;s a mechanism for showing users posts that fit together temporally.  It&amp;rsquo;s nice to be able to see &lt;a href="/2007"&gt;all of 2007&amp;rsquo;s posts&lt;/a&gt;, for instance.  Or &lt;a href="/2008/11"&gt;all posts from November of 2008&lt;/a&gt;.&lt;br/&gt;
&lt;/p&gt;

&lt;p&gt;Again, I borrowed a bit of code from Matt Flores, brought it up to date with the latest Jekyll tag (0.5.4 at the time I'm writing this), and check it into the &lt;a href="http://github.com/mikewest/jekyll/tree/archive"&gt;archive branch&lt;/a&gt; of my fork.  Similarly to the tagging system above, archives depend on adding a few extra layouts.  &lt;code&gt;archive_yearly.html&lt;/code&gt;, &lt;code&gt;archive_monthly.html&lt;/code&gt;, and &lt;code&gt;archive_daily.html&lt;/code&gt; are supported, and offer &lt;code&gt;page.year&lt;/code&gt;, &lt;code&gt;page.month&lt;/code&gt;, and &lt;code&gt;page.day&lt;/code&gt;, which can be used to reference posts in &lt;code&gt;site.collated_posts&lt;/code&gt;.  My &lt;a href="http://github.com/mikewest/mikewest.org/blob/master/_layouts/archive_monthly.html"&gt;&lt;code&gt;archive_monthly.html&lt;/code&gt;&lt;/a&gt; is indicative of how this can work.&lt;/p&gt;

&lt;p&gt;Generated pages are written to &lt;code&gt;/[YEAR]/index.html&lt;/code&gt;, &lt;code&gt;/[YEAR]/[MONTH]/index.html&lt;/code&gt;, and &lt;code&gt;/[YEAR]/[MONTH]/[DAY]/index.html&lt;/code&gt; if posts exist over the specified time period.&lt;/p&gt;

&lt;h2&gt;Filters&lt;/h2&gt;

&lt;p&gt;Jekyll uses the &lt;a href="http://www.liquidmarkup.org/"&gt;Liquid&lt;/a&gt; templating engine, which isn&amp;rsquo;t exactly my first choice.  It&amp;rsquo;s a solid engine, as far as it goes, but it&amp;rsquo;s no &lt;a href="http://jinja.pocoo.org/2/"&gt;Jinja2&lt;/a&gt;.  Regardless, Jekyll has built in a number of useful filters that can be used to perform operations on text before it&amp;rsquo;s rendered.  &lt;code&gt;textilize()&lt;/code&gt; is a good example of this, running text through a Textile parser, then writing the output instead of the original text.  It&amp;rsquo;s great!&lt;/p&gt;

&lt;p&gt;Except, of course, for the fact that Textile is hideous.  :)  I much prefer to write Markdown formatted text (it&amp;rsquo;s just easier for me to read, really), so I was a bit miffed when I discovered that a Markdown counterpart to &lt;code&gt;textilize()&lt;/code&gt; was simply missing.&lt;/p&gt;

&lt;p&gt;A more robust system is being discussed (slowly) in &lt;a href="http://github.com/mojombo/jekyll/issues#issue/19"&gt;Issue #19&lt;/a&gt;.  I decided not to wait for a perfect solution, and simply added &lt;code&gt;markdownize()&lt;/code&gt; in the &lt;a href="http://github.com/mikewest/jekyll/tree/filters"&gt;filters branch&lt;/a&gt; of my fork.  A trivial, but &lt;em&gt;very&lt;/em&gt; necessary change.&lt;/p&gt;

&lt;h2&gt;Default Configuration Values&lt;/h2&gt;

&lt;p&gt;I really like the way that Jekyll expects posts to be formatted.  Each post lives in it&amp;rsquo;s own file, and each file begins with a YAML block specifying metadata such as titles, teasers, and layout style.  This allows you to configure each post separately, and lends quite a bit of flexibility to the end product.&lt;/p&gt;

&lt;p&gt;As &lt;a href="http://github.com/mojombo/jekyll/issues#issue/19"&gt;Issue #25&lt;/a&gt; points out, it'd be nice if layout in particular could be specified at the site level as a default value.  Posts that need different layouts are (generally) few and far between, and a global configuration would make the most common case a bit simpler.&lt;/p&gt;

&lt;p&gt;Henrik &lt;a href="http://github.com/henrik/jekyll/commit/77bf31c42c25c2f87c215348a816b730104fe820"&gt;took a stab at a solution&lt;/a&gt; to the problem, which I ran off with and improved upon in the &lt;a href="http://github.com/mikewest/jekyll/tree/post_defaults"&gt;post_defaults branch&lt;/a&gt; of my fork.  I'm waiting on someone to take a look at this work now, but I'm not holding my breath for it to be merged into the official release.&lt;/p&gt;

&lt;h2&gt;Problematic Design&lt;/h2&gt;

&lt;p&gt;Beyond gaps in the feature set, Jekyll does one or two things that I simply disagree with.&lt;/p&gt;

&lt;p&gt;Jekyll tightly couples content and layout by assuming that both will exist together in a defined directory structure.  Leaving a bit of complexity to the side, a typical Jekyll site contains a &lt;code&gt;_posts&lt;/code&gt; subdirectory filled to the brim with lovely raw content, and a &lt;code&gt;_layouts&lt;/code&gt; directory filled with &lt;a href="http://www.liquidmarkup.org/"&gt;Liquid&lt;/a&gt;-based HTML templates.  The former is exclusively concerned with content, the latter exclusively with layout.&lt;/p&gt;

&lt;p&gt;For the same reasons that we eventually started building websites without inline style information, separating the concerns of the site&amp;rsquo;s semantics from it&amp;rsquo;s layout and behavior, I don&amp;rsquo;t believe that these bits belong in the same repository.  At a minimum, I'd like to be able to deploy a version of my website&amp;rsquo;s look and feel without worrying about whether or not I tagged the release before or after adding a post.  The one activity has nothing to do with the other, and both ought be able to proceed in parallel.  Jekyll&amp;rsquo;s current implementation encourages mixing the two, which I don&amp;rsquo;t appreciate.  Instead, I prefer to run two distinct repositories: one containing &lt;a href="http://github.com/mikewest/mgc/"&gt;pure content&lt;/a&gt;, the other containing &lt;a href="http://github.com/mikewest/mikewest.org/"&gt;site-specific layout and configuration&lt;/a&gt;.  This feels cleaner to me.&lt;/p&gt;

&lt;p&gt;The solution I've hacked together is available in the &lt;a href="http://github.com/mikewest/jekyll/tree/contentpath"&gt;contentpath branch&lt;/a&gt; of my Jekyll fork.  I've added a single configuration variable (&lt;code&gt;content_root&lt;/code&gt;) that contains an absolute path to the directory containing the site&amp;rsquo;s content.  That directory will be parsed in it&amp;rsquo;s entirety (e.g. no &lt;code&gt;_posts&lt;/code&gt; subdirectory is required).  If a &lt;code&gt;_posts&lt;/code&gt; directory exists in the usual location (&lt;code&gt;[SITE_ROOT]/_posts/&lt;/code&gt;) it will be parsed as well to ensure backwards compatibility.&lt;br/&gt;
&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t expect this change to make it into the main tree, as it&amp;rsquo;s probably not interesting for Jekyll&amp;rsquo;s main audience of GitHub Pages users who &lt;em&gt;do&lt;/em&gt; in fact very much want to deal with a single repository.  Moreover, when dealing with potentially malicious users, it&amp;rsquo;s not a brilliant idea to give them the ability to generate publicly accessible pages from &lt;em&gt;any&lt;/em&gt; readable directory on a system.  For my use, however, it&amp;rsquo;s more or less perfect, and I&amp;rsquo;ll do my best to keep it rebased on top of the latest Jekyll tags for anyone else who&amp;rsquo;s of the same mind.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/ac4QnQuHRGQ" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2009/11/my-jekyll-fork</feedburner:origLink></entry>

    
    <entry>
        <title type="text">Fallow fields, revisited</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/116QoaYj9io/fallow-fields-revisited" />
        <id>http://mikewest.org/2009/10/fallow-fields-revisited</id>
        <updated>2009-10-04T00:00:00+02:00</updated>
        <published>2009-10-04T00:00:00+02:00</published>
        <content type="html">
&lt;p&gt;I'm currently in the process of gutting my website, and rebuilding it piece by piece.  I suspect I'm doing this to distract myself from the fact that I don&amp;rsquo;t seem to have anything interesting floating around in my head to write about.  &amp;ldquo;Surely it&amp;rsquo;s the &lt;em&gt;site&amp;rsquo;s&lt;/em&gt; fault; raze it to the ground!&amp;rdquo;, the large, simple, and shouty part of my brain tells me.  So I build anew (this is possibly &lt;a href="http://mikewest.org/2009/09/productivity-or-my-lack-thereof"&gt;ironic&lt;/a&gt;, but I'm ignoring that).&lt;/p&gt;

&lt;p&gt;Happily, the small, quiet, and generally reasonable portion of my brain agrees with the plan, at least insofar as it&amp;rsquo;s clear that the current system (&lt;a href="http://github.com/mikewest/fallow/"&gt;fallow&lt;/a&gt;) was a solid idea but poorly implemented.  The system works, and I'm happy I wrote it.  It was a good introduction to Ruby and Git, and a good reason to migrate off the almost-as-inefficient-as-wordpress Textpattern.  But it&amp;rsquo;s failing me in a number of ways, the most important being that I literally forgot how to get content onto the site, and it took me 45 minutes of reading through painfully structured Ruby code to figure it out again.  That&amp;rsquo;s the sort of thing that happens when you don&amp;rsquo;t touch a website for 6 months.&lt;/p&gt;

&lt;p&gt;Rather that catalog the failings of the system I'm replacing (for they are legion), I'd like to touch on the carefully considered bits I'm keeping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;URL structure: Posts live at &lt;code&gt;/[year]/[month]/[URLified Title]&lt;/code&gt; which
seems more or less perfect to me.  It&amp;rsquo;s meaningful, while containing just
enough temporal context to make completely outdated information easy to
spot.  Moreover, it provides a natural &lt;code&gt;/[year]/&lt;/code&gt; and &lt;code&gt;/[year]/[month]/&lt;/code&gt;
for yearly and monthly archive pages.  Tag pages live under &lt;code&gt;/tags/[tag]&lt;/code&gt;,
which makes sense, and ad hoc pages have ad hoc URLs (&lt;code&gt;/is/&lt;/code&gt;, for instance).
This strikes me as a clean setup, one which I can&amp;rsquo;t see any way to improve
upon.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Content storage: The site&amp;rsquo;s content consists entirely of UTF-8 encoded text
files on disk.  Text files are simple to work with, and have a more or less
infinite shelf life.  A site like this one simply doesn&amp;rsquo;t need a database,
a single flat text file per piece of content is &lt;a href="http://mnmlist.com/a-case-for-storing-all-your-info-in-text-files/"&gt;good enough&lt;/a&gt;.  Metadata
(title, tags, etc.) is contained in a YAML block at the top of each file.
It&amp;rsquo;s a format that is clear, human readable, and easily parsed, and I'm
especially pleased to see that the format I'd decided upon for Fallow
matches up quite well against more widely used systems like &lt;a href="http://jekyllrb.com/"&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Static HTML: Dynamic content doesn&amp;rsquo;t really exist on this site.  I write an
article, then post it online.  That&amp;rsquo;s the extent of the processing that
particular page needs.  The server shouldn&amp;rsquo;t be working to rebuild an
article from last week (or last year!) every time it&amp;rsquo;s requested, that&amp;rsquo;s
simply wasteful.  This site, therefore, generates a page once when it&amp;rsquo;s
created, or when a template changes, and then simply serves that cached copy
over and over again.  Similarly, overview pages (like tag pages, or current
archives) are regenerated when a new article is published, then served
straight from disk.  On a small VPS, I can serve upwards of 300 static
requests per second through Nginx with extremely low load.  Textpattern
would fall over and die at those absurd traffic levels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Historical redirects: The (miserable) &lt;code&gt;/blog/id/[ID]&lt;/code&gt; URL structure I
decided upon in 2005 still works for the content I've kept from that period.
The (also bad) &lt;code&gt;/archives/[Title]/&lt;/code&gt; structure from 2007-8 works too.  The
(not so lovely) Tumblr-generated links for content that used to be at
&lt;code&gt;blog.mikewest.org&lt;/code&gt; will redirect nicely.  All these old URLs will continue
to generate nice, clean permanent redirects
&lt;a href="http://www.w3.org/Provider/Style/URI"&gt;for the foreseeable future&lt;/a&gt;: why make the reader jump through hoops
created by my lack of foresight?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So, those are the good bits I'd like to keep going as I rebuild.  With the understanding that I'm about to make one of those dangerous &amp;ldquo;forward looking statements&amp;rdquo; that I never seem to follow through on as cleanly as I'd like, I expect &lt;code&gt;mikewest.org&lt;/code&gt; to be running a new Jekyll-based backend sometime in October.  With luck, no one will notice a thing but me.  With even more luck, I&amp;rsquo;ll squeeze out a post or two about the bits of Jekyll I'm adjusting, and the places where it&amp;rsquo;s falling down completely.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/116QoaYj9io" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2009/10/fallow-fields-revisited</feedburner:origLink></entry>

    
    <entry>
        <title type="text">Productivity Or My Lack Thereof</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/0IS5ewDHGIg/productivity-or-my-lack-thereof" />
        <id>http://mikewest.org/2009/09/productivity-or-my-lack-thereof</id>
        <updated>2009-09-23T00:00:00+02:00</updated>
        <published>2009-09-23T00:00:00+02:00</published>
        <content type="html">
&lt;p&gt;I just spent the last half-hour screwing around with my Vim configuration to set up a &amp;ldquo;more perfect&amp;rdquo; writing environment.  Fullscreen!  Eighty columns!  Proper line-wrapping!  Large, readable font!  Markdown syntax highlighting!  Spellcheck!  Etcetera, etcetera!  Hilariously wrongheaded, of course, since I created this environment &lt;em&gt;instead of&lt;/em&gt; writing anything.  Likewise, I've played around with &lt;a href="http://todotxt.com/"&gt;todo.sh&lt;/a&gt; quite a bit in the last week or two (it&amp;rsquo;s nice), trying to put together a good system for recording my ever-growing list of things I need to take care of.  Perhaps there&amp;rsquo;s a reason that the list is ever-growing.&lt;/p&gt;

&lt;p&gt;Building new bash scripts that make recording tasks easier might &lt;em&gt;feel&lt;/em&gt; like Doing Important Work, but it isn&amp;rsquo;t.  Not really.  This is unfortunately true even when &amp;ldquo;write new bash scripts to make recording tasks easier&amp;rdquo; is on my newly created todo list.&lt;/p&gt;

&lt;p&gt;This is a long way of saying that &lt;a href="http://www.marco.org/about"&gt;Marco Arment&lt;/a&gt; is &lt;a href="http://www.marco.org/182893582"&gt;dead on&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;  The best way to increase your productivity, hack your life, and be
  minimalist is to stop reading those sites.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Also, hello Internet.  It&amp;rsquo;s been a while.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/0IS5ewDHGIg" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2009/09/productivity-or-my-lack-thereof</feedburner:origLink></entry>

    
    <entry>
        <title type="text">Mnot's Redbot</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/NXacJNm5RaA/mnots-redbot" />
        <id>http://mikewest.org/2009/05/mnots-redbot</id>
        <updated>2009-05-23T00:00:00+02:00</updated>
        <published>2009-05-23T00:00:00+02:00</published>
        <content type="html">
&lt;p&gt;&lt;a href="http://www.mnot.net/"&gt;Mark Nottingham&lt;/a&gt; has put together a really useful tool that aids in the analysis of the behavior of HTTP resources.  Visit &lt;a href="http://redbot.org/"&gt;http://redbot.org/&lt;/a&gt;, type in a web address, and Redbot will report the resource&amp;rsquo;s cachability based on the returned headers, and provide a helpful list of recommendations for improvement.&lt;/p&gt;

&lt;p&gt;Running it on &lt;a href="http://mikewest.org/"&gt;http://mikewest.org/&lt;/a&gt;, for instance, &lt;a href="http://redbot.org/?uri=http%3A%2F%2Fwww.mikewest.org%2F"&gt;flags the fact&lt;/a&gt; that I compress the response if the browser tells me that it can accept compressed content, but that I've neglected to send the proper &lt;code&gt;Vary&lt;/code&gt; header to let caches know that the response needs to be negotiated, and cached based on the &lt;code&gt;Accept-Encoding&lt;/code&gt; request header.  This is &lt;em&gt;useful&lt;/em&gt;, especially for &lt;em&gt;actual&lt;/em&gt; applications for which it might matter.&lt;/p&gt;

&lt;p&gt;So useful, in fact, that I'm forking it to submit some patches.  Mark&amp;rsquo;s put the Redbot code up on GitHub (&lt;a href="http://github.com/mnot/redbot/tree/master"&gt;mnot/redbot&lt;/a&gt;), and I've started putting together a &lt;a href="http://github.com/mikewest/redbot/blob/master/src/redbotcli.py"&gt;command line version&lt;/a&gt; based on the web version he&amp;rsquo;s built.&lt;/p&gt;

&lt;p&gt;I've mentioned that &lt;a href="http://mikewest.org/2008/11/i-love-github"&gt;I love GitHub&lt;/a&gt;, right?  This is exactly why.  :)&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/NXacJNm5RaA" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2009/05/mnots-redbot</feedburner:origLink></entry>

    
    <entry>
        <title type="text">Playing with Placemaker</title>
        <link rel="alternate" href="http://feeds.mikewest.org/~r/just_posts/~3/rzeMzpFeZm8/playing-with-placemaker" />
        <id>http://mikewest.org/2009/05/playing-with-placemaker</id>
        <updated>2009-05-21T00:00:00+02:00</updated>
        <published>2009-05-21T00:00:00+02:00</published>
        <content type="html">
&lt;p&gt;Yahoo&amp;rsquo;s latest API is really quite cool: &lt;a href="http://developer.yahoo.com/geo/placemaker/guide/"&gt;Placemaker&lt;/a&gt; takes your unstructured data (e.g. any HTML page, RSS feed, etc), and extracts a nice list of &lt;em&gt;locations&lt;/em&gt; that your data refers to.  It&amp;rsquo;s a brilliant tool, and I can think of quite a few ways I'd like to use it in the future.  Along with their release of a &lt;em&gt;ton&lt;/em&gt; of &lt;a href="http://developer.yahoo.com/geo/geoplanet/data/"&gt;WhereOnEarth ID codes&lt;/a&gt; that allows you to make use of Yahoo&amp;rsquo;s various geo-services, this is a really good day to play with geocoding unstructured data.&lt;/p&gt;

&lt;p&gt;So, let&amp;rsquo;s play:&lt;/p&gt;

&lt;p&gt;Accessing Placemaker is simple: assuming that you've somehow managed to &lt;a href="http://developer.yahoo.com/wsregapp/"&gt;obtain an application id&lt;/a&gt;, you simply make an HTTP &lt;code&gt;POST&lt;/code&gt; request to Yahoo!&amp;rsquo;s Placemaker endpoint with a tiny bit of data specifying the nature of the data you&amp;rsquo;re dealing with, and it&amp;rsquo;s URL.  If you like &lt;code&gt;curl&lt;/code&gt; on the command line, this might look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;curl -d 'inputLanguage=en-US&amp;amp;documentType=text/html&amp;amp;documentURL=http://mikewest.org/&amp;amp;appid=[APPID]' http://wherein.yahooapis.com/v1/document
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;rsquo;ll get back an XML document (RSS is also available as a response format).  Digging into the contents yields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Boilerplate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;contentlocation xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xmlns="http://wherein.yahooapis.com/v1/schema" xml:lang="de-DE"&amp;gt;
  &amp;lt;processingTime&amp;gt;0.380778&amp;lt;/processingTime&amp;gt;
  &amp;lt;version&amp;gt; build 090508&amp;lt;/version&amp;gt;
  &amp;lt;documentLength&amp;gt;15906&amp;lt;/documentLength&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A (list of) document element(s) containing the extracted locations:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;document&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A best guess at the document&amp;rsquo;s &amp;ldquo;scope&amp;rdquo; (the smallest region that &amp;ldquo;best
describes&amp;rdquo; the document):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &amp;lt;administrativeScope&amp;gt;
      &amp;lt;woeId&amp;gt;20071093&amp;lt;/woeId&amp;gt;
      &amp;lt;type&amp;gt;County&amp;lt;/type&amp;gt;
      &amp;lt;name&amp;gt;&amp;lt;![CDATA[Munich, Bavaria, DE]]&amp;gt;&amp;lt;/name&amp;gt;
      &amp;lt;centroid&amp;gt;
        &amp;lt;latitude&amp;gt;48.1549&amp;lt;/latitude&amp;gt;
        &amp;lt;longitude&amp;gt;11.5417&amp;lt;/longitude&amp;gt;
      &amp;lt;/centroid&amp;gt;
    &amp;lt;/administrativeScope&amp;gt;
    &amp;lt;geographicScope&amp;gt;
      &amp;lt;woeId&amp;gt;29388625&amp;lt;/woeId&amp;gt;
      &amp;lt;type&amp;gt;MMA&amp;lt;/type&amp;gt;
      &amp;lt;name&amp;gt;&amp;lt;![CDATA[MMA München, Bavaria, DE]]&amp;gt;&amp;lt;/name&amp;gt;
      &amp;lt;centroid&amp;gt;
        &amp;lt;latitude&amp;gt;48.1549&amp;lt;/latitude&amp;gt;
        &amp;lt;longitude&amp;gt;11.5417&amp;lt;/longitude&amp;gt;
      &amp;lt;/centroid&amp;gt;
    &amp;lt;/geographicScope&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Latitude/longitude for a bounding box that contains the places mentioned
in the document (which makes it trivial to draw an &amp;ldquo;area of discussion&amp;rdquo; on
a map):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &amp;lt;extents&amp;gt;
      &amp;lt;center&amp;gt;
        &amp;lt;latitude&amp;gt;48.1364&amp;lt;/latitude&amp;gt;
        &amp;lt;longitude&amp;gt;11.5775&amp;lt;/longitude&amp;gt;
      &amp;lt;/center&amp;gt;
      &amp;lt;southWest&amp;gt;
        &amp;lt;latitude&amp;gt;48.0417&amp;lt;/latitude&amp;gt;
        &amp;lt;longitude&amp;gt;11.3771&amp;lt;/longitude&amp;gt;
      &amp;lt;/southWest&amp;gt;
      &amp;lt;northEast&amp;gt;
        &amp;lt;latitude&amp;gt;48.2292&amp;lt;/latitude&amp;gt;
        &amp;lt;longitude&amp;gt;11.749&amp;lt;/longitude&amp;gt;
      &amp;lt;/northEast&amp;gt;
    &amp;lt;/extents&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detailed breakdown of the places mentioned in your document, giving you
lat/long coordinates identifying the place&amp;rsquo;s center point.  Moreover, it
tells you &lt;em&gt;where&lt;/em&gt; in your document the place was found (string offsets
&lt;em&gt;and&lt;/em&gt; XPath expressions, to each their own).  This is helpful for those
occasions when the text you've entered doesn&amp;rsquo;t exactly match the place&amp;rsquo;s
name that Yahoo returns (&amp;ldquo;Munich&amp;rdquo; vs. &amp;ldquo;Munich, Bavaria, DE&amp;rdquo;, in this
example)  Annotating your documents with this data should be a piece of
cake.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    &amp;lt;placeDetails&amp;gt;
      &amp;lt;place&amp;gt;
        &amp;lt;woeId&amp;gt;676757&amp;lt;/woeId&amp;gt;
        &amp;lt;type&amp;gt;Town&amp;lt;/type&amp;gt;
        &amp;lt;name&amp;gt;&amp;lt;![CDATA[Munich, Bavaria, DE]]&amp;gt;&amp;lt;/name&amp;gt;
        &amp;lt;centroid&amp;gt;
          &amp;lt;latitude&amp;gt;48.1364&amp;lt;/latitude&amp;gt;
          &amp;lt;longitude&amp;gt;11.5775&amp;lt;/longitude&amp;gt;
        &amp;lt;/centroid&amp;gt;
      &amp;lt;/place&amp;gt;
      &amp;lt;matchType&amp;gt;0&amp;lt;/matchType&amp;gt;
      &amp;lt;weight&amp;gt;1&amp;lt;/weight&amp;gt;
      &amp;lt;confidence&amp;gt;7&amp;lt;/confidence&amp;gt;
    &amp;lt;/placeDetails&amp;gt;
    &amp;lt;referenceList&amp;gt;
      &amp;lt;reference&amp;gt;
        &amp;lt;woeIds&amp;gt;676757&amp;lt;/woeIds&amp;gt;
        &amp;lt;start&amp;gt;50&amp;lt;/start&amp;gt;
        &amp;lt;end&amp;gt;56&amp;lt;/end&amp;gt;
        &amp;lt;isPlaintextMarker&amp;gt;0&amp;lt;/isPlaintextMarker&amp;gt;
        &amp;lt;text&amp;gt;&amp;lt;![CDATA[Munich]]&amp;gt;&amp;lt;/text&amp;gt;
        &amp;lt;type&amp;gt;xpathwithcounts&amp;lt;/type&amp;gt;
        &amp;lt;xpath&amp;gt;&amp;lt;![CDATA[/html[1]/body[1]/div[2]/div[1]/p[1]]]&amp;gt;&amp;lt;/xpath&amp;gt;
      &amp;lt;/reference&amp;gt;
    &amp;lt;/referenceList&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And some more boilerplate.  :)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;/document&amp;gt;
&amp;lt;/contentlocation&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Full documentation of the Placemaker &lt;a href="http://developer.yahoo.com/geo/placemaker/guide/api_docs.html#query_parameters"&gt;query parameters&lt;/a&gt; and &lt;a href="http://developer.yahoo.com/geo/placemaker/guide/api-reference.html"&gt;response format&lt;/a&gt; are available on YDN.  Christian has put together a demo of a &lt;a href="http://isithackday.com/hacks/placemaker/"&gt;basic PHP implementation&lt;/a&gt; (though it&amp;rsquo;s XSSable, and shouldn&amp;rsquo;t ever be used in production).&lt;/p&gt;

&lt;p&gt;In general, this is &lt;em&gt;brilliant&lt;/em&gt; stuff.  I'm looking forward to playing with it!&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/just_posts/~4/rzeMzpFeZm8" height="1" width="1"/&gt;</content>
    <feedburner:origLink>http://mikewest.org/2009/05/playing-with-placemaker</feedburner:origLink></entry>

</feed>
