<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>0xDECAFBAD - Tag: webdev</title>
    <link href="http://decafbad.com/blog/atom.xml" rel="self"/>
    <link href="http://decafbad.com/blog"/>
    <updated>2011-11-16T16:29:50+00:00</updated>
    <id></id>
    <author>
        <name></name>
        <email>l.m.orchard@pobox.com</email>
    </author>
    

    <entry>
        <title>Putting clouds in boxes for webdevs at Mozilla</title>
        <link href="http://decafbad.com/blog/2011/10/02/putting-clouds-in-boxes"/>
        <updated>2011-10-02T22:45:37+00:00</updated>
        <id>http://decafbad.com/blog/2011/10/02/putting-clouds-in-boxes</id>
        <content type="html">&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: &lt;em&gt;At Mozilla, we're redoubling efforts to attract contributors. And, in the Webdev team, we're &lt;a href=&quot;http://blog.mozilla.com/webdev/2011/10/04/developing-with-vagrant-puppet-and-playdoh/&quot;&gt;using virtual machines&lt;/a&gt; to make it even easier to get started hacking. It makes no sense to demand that a JavaScript ninja or a CSS artisan also be a Python-wielding sysadmin, so we're trying to build &lt;a href=&quot;https://wiki.mozilla.org/Webdev:DevBoxVMImages&quot;&gt;ready-baked VMs for our projects&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/erix/3998080471/&quot; style=&quot;display: block; float: right; text-decoration: none; border: none; margin: 0 0 1em 1em&quot;&gt;&lt;img src=&quot;{{ site.baseurl }}/images/cloud-box.jpg&quot; style=&quot;width: 300px&quot; /&gt;&lt;br /&gt;&lt;small&gt;Lieferung 3 by erix on Flickr&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firefox is more than just a desktop browser, and Mozilla is more than just Firefox. An ever-growing mass of our code is going toward building web sites and services that &lt;a href=&quot;https://wiki.mozilla.org/ReleaseEngineering&quot;&gt;build&lt;/a&gt;, &lt;a href=&quot;http://www.mozilla.org/en-US/firefox/fx/&quot;&gt;ship&lt;/a&gt;, &lt;a href=&quot;https://wiki.mozilla.org/AUS&quot;&gt;update&lt;/a&gt;, &lt;a href=&quot;http://support.mozilla.com/&quot;&gt;support&lt;/a&gt;, &lt;a href=&quot;https://wiki.mozilla.org/Engagement&quot;&gt;promote&lt;/a&gt;, &lt;a href=&quot;https://addons.mozilla.org/&quot;&gt;augment&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/&quot;&gt;document&lt;/a&gt;, &lt;a href=&quot;http://www.mozilla.org/en-US/mobile/sync/&quot;&gt;sync&lt;/a&gt;, &lt;a href=&quot;https://wiki.mozilla.org/Labs/F1&quot;&gt;share&lt;/a&gt;, &lt;a href=&quot;http://identity.mozilla.com/&quot;&gt;identify&lt;/a&gt;, and &lt;a href=&quot;https://wiki.mozilla.org/Socorro&quot;&gt;report&lt;/a&gt;. (And I'm sure I'm missing a further cast of hundreds, here.)&lt;/p&gt;

&lt;h3&gt;Sighting storm clouds on the horizon&lt;/h3&gt;

&lt;p&gt;In other words, more and more of Mozilla is in the &lt;em&gt;cloud&lt;/em&gt;. Unfortunately, many of these projects are really hard to get into as a contributor. It's often hard to find what needs doing in Bugzilla, and it's often hard to get the code up and running in a meaningful way without being both a bit of a sysadmin and a Mozilla insider.&lt;/p&gt;

&lt;p&gt;This is a huge problem. Although Mozilla has a core group of employees, we're not nearly enough to build all of these projects and pursue &lt;a href=&quot;http://www.mozilla.org/about/mission.html&quot;&gt;the mission&lt;/a&gt; on our own. We've gotten to where we are thanks to the volunteer efforts of thousands of contributors—and the only way we'll get where we want to go is through the efforts of thousands (or &lt;em&gt;&lt;a href=&quot;http://commonspace.wordpress.com/2011/02/22/nmm-redux/&quot;&gt;millions&lt;/a&gt;&lt;/em&gt;) more. The good news is that is feels like we're &lt;a href=&quot;https://wiki.mozilla.org/Mozilla.org/Contribute&quot;&gt;waking up to this problem&lt;/a&gt; and starting to get &lt;a href=&quot;https://wiki.mozilla.org/ReMo&quot;&gt;really serious about it&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Sharing recipes for fluffy clouds&lt;/h3&gt;

&lt;p&gt;For my part, I've spent idle time over the past few years trying to work out how to make webdev projects more accessible to new contributors. We've come a long way from the days of just uploading WordPress to an FTP server; these things come with a lot of moving parts nowadays, and the &lt;code&gt;INSTALL.txt&lt;/code&gt; files run long and consume weekends. And so, they filter out all but the most dedicated (or masochistic) volunteers.&lt;/p&gt;

&lt;p&gt;For months, I spun my wheels playing with virtual machines and exporting appliances, doing a lot of things by hand. But then, earlier this year, I discovered both &lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; and &lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt; and had my mind blown. With those tools, I could share recipes for VMs right alongside my code.&lt;/p&gt;

&lt;p&gt;I would never have to set up a webdev environment for myself by hand again—all the fiddly bits of installation and configuration could be codified, checked into github, and flushed from my brain.  But, the real magic is that I could &lt;em&gt;share&lt;/em&gt; this stuff. So, future coworkers and collaborators could benefit from the same reproducible dev enviroments—&lt;em&gt;never having wasted brainpower and weekends on an INSTALL.txt to begin with&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is a really big deal. I &lt;a href=&quot;http://lanyrd.com/2011/osbridge/sdxby/&quot;&gt;presented on it this past June at Open Source Bridge&lt;/a&gt; in Portland (&lt;a href=&quot;http://decafbad.com/2011/06/os-webdev-vm/slides.html&quot;&gt;slides&lt;/a&gt;). I've been talking myself blue about this stuff for months, in opposition to my usual serially enthuastic habits. But, it looks like I've infected my coworkers at Mozilla, because now we're talking about &lt;a href=&quot;http://blog.mozilla.com/webdev/2011/10/04/developing-with-vagrant-puppet-and-playdoh/&quot;&gt;developing with Vagrant, Puppet, and Playdoh&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;No assembly required&lt;/h3&gt;

&lt;p&gt;So, with &lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt;, &lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt;, and &lt;a href=&quot;http://blog.mozilla.com/webdev/2011/10/04/developing-with-vagrant-puppet-and-playdoh/&quot;&gt;Playdoh&lt;/a&gt;, we'll have projects that you can fire up with just a &lt;code&gt;git clone&lt;/code&gt; and a &lt;code&gt;vagrant up&lt;/code&gt; in a command line shell. Forget about &lt;a href=&quot;http://macports.org/&quot;&gt;MacPorts&lt;/a&gt; or &lt;a href=&quot;https://github.com/mxcl/homebrew/&quot;&gt;Homebrew&lt;/a&gt; on Mac OS X, or whatever it is that people using Windows have to install. Take a bike ride or go to lunch, and you'll have a fully configured server running and source code ready for hacking.&lt;/p&gt;

&lt;p&gt;I think we can do better, though. For one, spinning up a fairly complex virtual machine from scratch with &lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; and &lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt; takes a long time and a lot of bandwidth. This can be sped up by &lt;a href=&quot;http://vagrantup.com/docs/boxes.html&quot;&gt;packaging pre-built boxes&lt;/a&gt;. So, one improvement we can pursue is to spin up VMs with Vagrant as a part of our continual integration and deployment processes and package boxes for public download. These are also handy on a thumb drive for sharing at hack events and meetups.&lt;/p&gt;

&lt;p&gt;This still requires &lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; and working with the command-line, though. Not everyone who has something valuable to contribute is a command-line jockey. And, a few of us webdevs have run into issues with &lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt;—it's still early days for that project, after all. Additionally, not everyone who could be a Mozilla contributor owns the kind of hardware necessary to support running a substantial virtual machine.&lt;/p&gt;

&lt;p&gt;So, I've also started playing with &lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt; by itself, to build plain-vanilla VM appliances and to spin up cloud servers on &lt;a href=&quot;http://aws.amazon.com/ec2/&quot;&gt;Amazon EC2&lt;/a&gt; and &lt;a href=&quot;http://www.rackspace.com/cloud/&quot;&gt;Rackspace Cloud Servers&lt;/a&gt;. It's going pretty well, and it's conceivable we could do without &lt;a href=&quot;http://vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; to script the build of &lt;a href=&quot;http://en.wikipedia.org/wiki/Open_Virtualization_Format&quot;&gt;downloadable VM appliances&lt;/a&gt; and to spin up disposable cloud servers.&lt;/p&gt;

&lt;h3&gt;So, now what?&lt;/h3&gt;

&lt;p&gt;There are still some issues to be worked out, so &lt;a href=&quot;https://wiki.mozilla.org/Webdev:DevBoxVMImages&quot;&gt;I've started a wiki page&lt;/a&gt;. And, we need to spread the word that we're doing this to see what people think—and more importantly, see if this helps attract more help. From my years at Mozilla so far and bouncing between projects, VM appliances are things I wish I'd had when faced with a new project. So, having been there—albeit with insider advantages—I'm pretty optimistic that this is a good step forward.&lt;/p&gt;

&lt;p&gt;Of course, it's not the only step: The other thing I mentioned—and have conveniently avoided addressing again throughout the rest of this post—is the issue of finding things to do in Bugzilla. Well, we're working on that too. It's a bit beyond the scope of this blog post, but we have a Mozilla-wide effort to start classifying &lt;a href=&quot;https://bugzil.la/sw:%5Bgood%20first%20bug%5D&quot;&gt;good first bugs&lt;/a&gt; for new contributors and &lt;a href=&quot;http://blog.paulbiggar.com/archive/helping-new-contributors-part-2-mentoring/&quot;&gt;identifying mentors&lt;/a&gt; to contact for help.&lt;/p&gt;

&lt;p&gt;So... what do you think?&lt;/p&gt;

&lt;!-- vim: set wrap wm=5 syntax=mkd textwidth=70: --&gt;

</content>
    </entry>
    
    

    <entry>
        <title>Moved to Jekyll and Disqus</title>
        <link href="http://decafbad.com/blog/2011/06/08/moved-to-jekyll"/>
        <updated>2011-06-08T00:00:00+00:00</updated>
        <id>http://decafbad.com/blog/2011/06/08/moved-to-jekyll</id>
        <content type="html">&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: &lt;em&gt;My blog is now produced by &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt;, with comments hosted by &lt;a href=&quot;http://disqus.com/&quot;&gt;Disqus&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This blog has transitioned between a handful of publishing platforms -
including Movable Type, blosxom, and Wordpress. Well, apparently, it's that
time again.  I've been toying with making a change again for a few years,
and finally just got all the pieces together over the past week. This blog
is now just a pile of static files produced by &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt;, and the comments
are now hosted by &lt;a href=&quot;http://disqus.com/&quot;&gt;Disqus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This has a lot of interesting implications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I can neglect my server for long periods of time without worrying that my
long-outdated copy of Wordpress has been exploited. Really, there's no
reason for me to have a full-featured CMS running here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I could host my entire blog on Amazon S3 or something similar, and be
more neglectful by reducing active code even further. The only crappy
thing is that I don't think I can send &lt;code&gt;decafbad.com&lt;/code&gt; directly to S3, and
would need to redirect to a CNAME on a subdomain on &lt;code&gt;blog.decafbad.com&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I can edit my blog directly on GitHub and, assuming I get the webhooks
set up, have my server rebuild the HTML automatically on a &lt;code&gt;git push&lt;/code&gt;. I
could probably use &lt;a href=&quot;http://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt; and the Jekyll support there,
but I suspect I'll be doing some Weird Things that they won't handle.
(And probably for good reason.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since Disqus has all my comments now, I can stop worrying about running
that code on my server too. I'm a little antsy about putting that in the
cloud, but the escape routes are well lit and I should be able to replace
it easily if I need to. Self-hosted, JS-include-based comments is a
project in my TODO list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;My writing here is now all stored in individual text files, formatted with
Markdown, annotated with YAML metadata, and subject to revision control
under git. This combination feels like it has a lot of longevity and
potential for survival even beyond this current experiment with &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing, editing, and publishing entries here can now more closely match
my daily reality of living in MacVim and git. It sounds lame, but the
notion of swapping over to a Wordpress admin page and working in a
browser textarea has often kept me from even starting a post.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;But, some things are broken, now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/lmorchard/blog.decafbad.com/commit/a79678828ab612c2edb8a8ac3f796199cb922a2e&quot;&gt;Fixed&lt;/a&gt; &lt;strike&gt;No more tag pages. I don't think very many humans visit these pages, but
a lot of search engines do.&lt;/strike&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/lmorchard/blog.decafbad.com/commit/a79678828ab612c2edb8a8ac3f796199cb922a2e&quot;&gt;Fixed&lt;/a&gt; &lt;strike&gt;No more tag feeds. I expect to hear about this soon, since this blog gets
syndicated to Planet Mozilla via my &quot;mozilla&quot; tag feed.&lt;/strike&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No more year / month archive pages or sidebar widget. Not sure how many
people actually stroll down memory lane here on my blog, but I do have a
&lt;a href=&quot;http://decafbad.com/blog/archives&quot;&gt;gigantor huge list of all my posts evar&lt;/a&gt;, now.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A general lack of contextual links to related posts and such. Turns out
that running the LSI option on Jekyll is completely horrible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Regeneration seems less-than-happy in general, and I wish it did
conditional regneration. That is, only produce the HTML for things that
need it because dependencies have changed. No need to rebake the whole
world just because I changed one file.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The bright side is that there are solutions to all the broken things, and
now I have something to tinker with again on my blog.  So, let me know if
anything else looks broken, and hopefully this will get me spewing some
more words out onto this thing soon.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221397880&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221397880&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T17:45:54&quot;&gt;2011-06-08T17:45:54&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Testing a comment here on my new post.&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221404263&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/bkclements.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;bkclements&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221404263&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T17:59:01&quot;&gt;2011-06-08T17:59:01&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Hi, did you happen to look at blogofile for similar functionality?

I'm still trying to decide which way to  go. I prefer ReST markup..&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221408933&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221408933&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T18:08:26&quot;&gt;2011-06-08T18:08:26&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;I've had my eye on Jekyll for awhile now and have a few friends also using it, so I haven't really checked out any other packages. Might be nice to poke around at something based in Python since my Ruby-fu is not strong, but then getting stronger in Ruby is not a bad thing for me.

And, for myself, I'm pretty stubbornly rooted in Markdown for all my writing online&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221530821&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/BillSeitz.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;BillSeitz&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221530821&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T22:01:56&quot;&gt;2011-06-08T22:01:56&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;What kind of metadata are you storing in YAML?&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221547147&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221547147&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T22:30:10&quot;&gt;2011-06-08T22:30:10&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Pretty simple stuff: Title, tags, etc. 

You can see the source for this post here on github, for example:

https://raw.github.com/lmorchard/blog.decafbad.com/master/_posts/2011-06-08-moved-to-jekyll.markdown

I had once-upon-a-time thought about storing posts as RFC 822 messages, with the metadata in headers like email messages. But, this &quot;YAML front matter&quot; approach of Jekyll is a bit more flexible&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221561143&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/facebook-530160304.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;Dave Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221561143&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T23:02:15&quot;&gt;2011-06-08T23:02:15&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Les,

Check out what I did - I actually host my site on github thanks to TofuMatt's suggestion.  It works well and I have archives and whatnot.  In fact, most of my links didn't break.  This also means that I don't have to regenerate and sync, since github knows jekyll:

https://github.com/davedash/davedash.github.com&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221596149&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221596149&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T23:56:45&quot;&gt;2011-06-08T23:56:45&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Hmm... I might have to try that, but on a subdomain like blog.decafbad.com. I have some non-blog stuff here on decafbad.com and don't want to turn the whole thing over to github&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221599902&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/facebook-530160304.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;Dave Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221599902&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-08T23:59:33&quot;&gt;2011-06-08T23:59:33&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;It caused a few things to happen - speed up my deploy time and force me to check things into git.  Also my codez build tags and stuff... &lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-222164526&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/tiernano.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;tiernano&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222164526&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T07:19:54&quot;&gt;2011-06-09T07:19:54&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;So, how did you move directly from Wordpress to Jekyll?  was it simple enough to migrate, or is it a pain?&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222361710&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/facebook-530160304.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;Dave Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222361710&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T13:51:27&quot;&gt;2011-06-09T13:51:27&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;There is a migration script for posts.  I may have had to adjust some
minor things.   Risqué has a migration for comments.  it wasn't too
bad.&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222372008&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/tiernano.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;tiernano&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222372008&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T14:14:31&quot;&gt;2011-06-09T14:14:31&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Already using Disqus for comments on my wordpress install... It's the blog data itself that's the problem... Will have a look and play with the migrators...&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222376509&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222376509&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T14:24:16&quot;&gt;2011-06-09T14:24:16&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;FWIW, the script I tweaked and used for exporting from my Wordpress database is here in github:

https://github.com/lmorchard/blog.decafbad.com/blob/master/_import/wordpress-decafbad.rb

The only real pain was getting the SQL query to pick up tags the way I wanted. Otherwise, it's just getting things into text files.&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222397559&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/tiernano.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;tiernano&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222397559&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T15:07:03&quot;&gt;2011-06-09T15:07:03&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Cool beans man. Will try that out when I get a few min...&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-222453543&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://twitter.com/lroberson&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/twitter-14760653.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://twitter.com/lroberson&quot;&gt;Lee Roberson&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222453543&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T16:45:18&quot;&gt;2011-06-09T16:45:18&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Google Reader keeps getting tricked into thinking several of your posts are new, might be some kind of issue with your pubDate field in RSS, not sure.&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222455188&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222455188&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T16:48:38&quot;&gt;2011-06-09T16:48:38&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Yeah, that's my fault. :/ I had initially exported all my posts missing the actual time part of the pubDate, and then just a little while ago re-exported with the proper datestamps

&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222460871&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/facebook-530160304.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.facebook.com/davedash&quot;&gt;Dave Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222460871&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T16:59:50&quot;&gt;2011-06-09T16:59:50&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;You are worse than Delicious!&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222463870&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222463870&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T17:05:52&quot;&gt;2011-06-09T17:05:52&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;That's probably my fault, too.&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-222453814&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://twitter.com/lroberson&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/twitter-14760653.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://twitter.com/lroberson&quot;&gt;Lee Roberson&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222453814&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T16:45:53&quot;&gt;2011-06-09T16:45:53&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Whups.&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-222489874&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://trickyco.de&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lloydhilaiel.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://trickyco.de&quot;&gt;Lloyd Hilaiel&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222489874&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T17:45:00&quot;&gt;2011-06-09T17:45:00&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Have you had much success in customizing the features and display of the injected DISQUS UI?  

Thile there are several knobs in their UI, but the only form of customization that's worked for me is fiddling with external javscript and CSS...  Specifically things like disabling media upload and changing default sort, and threading seem to be no-ops.&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-222505665&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-222505665&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-09T18:12:39&quot;&gt;2011-06-09T18:12:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Hmm... I haven't even bothered to try customizing yet. I just dropped it in and it vaguely matched the rest of my page style, so I left it alone so far&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-223875231&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/google-ec18b68fb719cdef24375dc3a0ffb29f.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Craig Maloney&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-223875231&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-11T16:00:04&quot;&gt;2011-06-11T16:00:04&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Oh c'mon, there's nothing in the world more fun than updating Wordpress blog every time someone manages to sneeze wrong and cause an exploit. Sheesh, where's your sense of discipline.&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-231386541&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://marlinspikenestor8435.wordpress.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/jolyonwagg1.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://marlinspikenestor8435.wordpress.com/&quot;&gt;jolyonwagg1&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-231386541&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-06-21T23:52:22&quot;&gt;2011-06-21T23:52:22&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Love to use disqus, and would like to integrate it onto my Wordpress blog for comments, as it is so user friendly, but I am not to hot though on all the HTML stuff, any advice would be greatly appreciated, cheers from across the pond.&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-286782681&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/ecmanaut.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Johan Sundström&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-286782681&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-08-15T04:23:30&quot;&gt;2011-08-15T04:23:30&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Your sidebar archive widget was rather cool, layout wise; I bookmarked it as design inspiration, back when it existed.&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-288157091&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/lmorchard.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com/&quot;&gt;Les Orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-288157091&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-08-16T15:58:00&quot;&gt;2011-08-16T15:58:00&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Hmm, I should see if I can find a way to revive that thing as a JS widget or something&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-300334845&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.hopelesscom.de&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/fallenhitokiri.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.hopelesscom.de&quot;&gt;Timo Zimmermann&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-300334845&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-09-01T12:48:10&quot;&gt;2011-09-01T12:48:10&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;how do you feel about using Disqus for your comments?
Any problems or the urge to write your own JS based commenting system? I just feel a bit uncomfortable with a 3rd party provider for something important like comments...&lt;/div&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-300337460&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/tiernano.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;tiernano&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-300337460&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-09-01T12:54:22&quot;&gt;2011-09-01T12:54:22&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Personally speaking, i have been using Disqus comments on my WordPress 
blogs for a while now (couple of years) and its working grand! don't have
 to worry too much about Spam, they manage backups, etc. you can even reply to, or delete comments (if spam does get though) by email, so you can manage them on your phone. &lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Firefox Sync server on Google App Engine</title>
        <link href="http://decafbad.com/blog/2010/07/05/firefox-sync-server-on-google-app-engine"/>
        <updated>2010-07-05T23:00:56+00:00</updated>
        <id>http://decafbad.com/blog/2010/07/05/firefox-sync-server-on-google-app-engine</id>
        <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; &lt;a href=&quot;http://github.com/lmorchard/firefox-sync-appengine&quot;&gt;I built an implementation&lt;/a&gt; of the &lt;a href=&quot;https://wiki.mozilla.org/Labs/Weave/Sync/1.0/API&quot;&gt;Firefox Sync server API&lt;/a&gt; for &lt;a href=&quot;http://appengine.google.com/&quot;&gt;Google App Engine&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.mozilla.com/en-US/firefox/sync/&quot; style=&quot;float: right; padding: 0 0 0em 0em; display: block; text-decoration: none; border: none&quot;&gt;&lt;img src=&quot;http://mozcom-cdn.mozilla.net/img/firefox/sync/sync-background.png&quot; style=&quot;border: none&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To celebrate &lt;a href=&quot;http://en.wikipedia.org/wiki/Independence_Day_%28United_States%29&quot;&gt;Independence Day&lt;/a&gt;, I figured I might take a shot at liberating &lt;a href=&quot;http://www.mozilla.com/en-US/firefox/sync/&quot;&gt;Firefox Sync&lt;/a&gt; from the tyranny of &lt;a href=&quot;https://services.mozilla.com/&quot;&gt;Mozilla's servers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thus, over the past few days, I've &lt;a href=&quot;http://github.com/lmorchard/firefox-sync-appengine&quot;&gt;built a sync server&lt;/a&gt; using the &lt;a href=&quot;https://wiki.mozilla.org/Labs/Weave/Sync/1.0/API&quot;&gt;1.0 Sync API&lt;/a&gt;, hosted on &lt;a href=&quot;http://appengine.google.com/&quot;&gt;Google App Engine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I lied about the &lt;em&gt;tyranny&lt;/em&gt; thing, though—I just wanted to say something clever about the holiday. In reality, with respect to &lt;a href=&quot;http://www.mozilla.com/en-US/firefox/sync/&quot;&gt;Firefox Sync&lt;/a&gt;, Mozilla has done all of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Published &lt;a href=&quot;https://wiki.mozilla.org/Labs/Weave/Sync/1.0/API&quot;&gt;the Sync API spec&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Released &lt;a href=&quot;http://hg.mozilla.org/services/sync-server/&quot;&gt;the source code for the server used in-house&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Explicitly included the option to use a custom server when setting up sync in the browser.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;This means that, although Mozilla offers servers to go along with &lt;a href=&quot;http://www.mozilla.com/en-US/firefox/sync/&quot;&gt;Firefox Sync&lt;/a&gt;, you're totally free to take your data elsewhere. Since your sync data is encrypted and practically opaque to the server, there's no direct profit for Mozilla in offering free sync hosting—not even through any clandestine data mining for devious purposes. It's just that sync makes Firefox a better browser, and &lt;em&gt;somebody&lt;/em&gt; has to run some servers to make it work.&lt;/p&gt;

&lt;p&gt;So, there's every incentive to make it easy for you to switch sync providers and &lt;em&gt;stop freeloading&lt;/em&gt; on Mozilla's servers. Building a server on &lt;a href=&quot;http://appengine.google.com/&quot;&gt;Google App Engine&lt;/a&gt; means I can freeload on &lt;em&gt;Google's&lt;/em&gt; servers!&lt;/p&gt;

&lt;p&gt;I kid, of course. No one's really complaining about freeloaders, and App Engine has quotas in place to head off any serious mooching—which is why I'm not telling you where to find &lt;em&gt;my&lt;/em&gt; sync server deployed on Google App Engine, by the way.&lt;/p&gt;

&lt;p&gt;No, I did this because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firefox Sync and Google App Engine are interesting and important technologies;&lt;/li&gt;
&lt;li&gt;I've already done a bit of work on the PHP-based Firefox Sync server at Mozilla;&lt;/li&gt;
&lt;li&gt;I really wanted to take a break from PHP and spend some time with my old friend Python.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There are, of course, a number of bugs in this server. But, it seems to be working between a number of machines and browser profiles I have at home. Things are really in need of optimization, it suffers from my inexperience with App Engine, and I keep running into those aforementioned App Engine resource limits—especially when updating or deleting large numbers of items (ie. 1000's to 10000's of items).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/lmorchard/firefox-sync-appengine&quot;&gt;&lt;em&gt;Pull requests and issue reports on GitHub are welcome!&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A next step I'd like to take with this thing is to revisit another old friend, the &lt;a href=&quot;http://www.decafbad.com/twiki/bin/view/Main/DesktopWebAppServer&quot;&gt;desktop web app server&lt;/a&gt;. (Also known as the &lt;a href=&quot;http://www.scripting.com/davenet/2001/01/04/desktopWebsites.html#4&quot;&gt;desktop website&lt;/a&gt;.) It seems to me that it would be interesting to scale this server down to a household appliance—say, just for use by my wife and I.&lt;/p&gt;

&lt;p&gt;I'd be especially happy if the work I'm doing for a Google-hosted app could be self-hosted at home. Seeing as the development environment for App Engine runs on my laptop, I'm willing to bet I can hack the whole shebang into a simple, special-purpose app to download and double-click on a home desktop PC for use as your sync hub.&lt;/p&gt;

&lt;p&gt;Anyway, &lt;a href=&quot;http://github.com/lmorchard/firefox-sync-appengine&quot;&gt;check it out&lt;/a&gt; and let me know what you think.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088097&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://coffeeonthekeyboard.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=8371744716a9335eb3dcae228fd9d996&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://coffeeonthekeyboard.com/&quot;&gt;James Socol&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088097&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-06T01:28:02&quot;&gt;2010-07-06T01:28:02&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Assuming you already had a network and a Mac Mini or something at home, it would be pretty interesting to run your own small Sync server just to keep your home computers together. Maybe even use localtunnel for when you're away.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088102&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://morgamic.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=65b020128dafcdb4ef1e5e53c00ed37a&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://morgamic.com/&quot;&gt;Mike&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088102&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-06T01:36:37&quot;&gt;2010-07-06T01:36:37&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;You are a real-life hero!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088105&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088105&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-06T01:52:00&quot;&gt;2010-07-06T01:52:00&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@James: Yup, exactly that. Maybe even roll in some SSL and UPnP port forwarding for easier setup behind a home router. And, if there were a Windows version, it could run on that cruddy desktop back in the spare room.&lt;/p&gt;

&lt;p&gt;@Mike: Naw... this guy is the real hero, &lt;a href=&quot;http://twitter.com/johnolilly/status/17765272082&quot; rel=&quot;nofollow&quot;&gt;even John Lilly agrees&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://blogs.denverpost.com/celebritybull/2008/09/09/greatest-american-hero-coming-to-the-big-screen/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://blogs.denverpost.com/celebritybull/files/2008/09/gah.jpg&quot; alt=&quot;Greatest American Hero&quot; title=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088106&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=1d18681d9fa9b5d50b209a2a926dfe7d&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Crash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088106&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-06T09:20:54&quot;&gt;2010-07-06T09:20:54&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Is there already a App Id for this tool?&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088107&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088107&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-06T10:18:57&quot;&gt;2010-07-06T10:18:57&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Crash: Sure, there's an app ID for &lt;em&gt;my&lt;/em&gt; instance of this sync server. But, as I said in the blog post, I'm not sharing it. At least, not until or unless I get the quota usage down to a point that I wouldn't exhaust the free hosting limits.&lt;/p&gt;

&lt;p&gt;It's pretty easy to deploy your own sync server on AppEngine with the source, though.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088108&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=85283c3d40ca2b1a70a0f877a570107c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Peter Petrov&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088108&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-06T13:18:11&quot;&gt;2010-07-06T13:18:11&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Leslie: The app ID of your instance is visible in app.yaml, so you've shared it anyway :)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088113&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088113&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-06T17:18:47&quot;&gt;2010-07-06T17:18:47&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Peter hah! Right you are! But, at least you had to look at the source of the app first to figure that out :) That is mostly the point of this blog entry after all. Anyone who does that and then uses my installation anyway will probably be sad when I regularly blow away data and eventually make it invite only&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088115&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=4fd1acfa0c7bd0767a90a30fbba73bfb&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Tobias&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088115&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-07T00:24:41&quot;&gt;2010-07-07T00:24:41&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Neat! TyphoonAE http://typhoonae.googlecode.com might help you to build your household appliance.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088117&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3e7e975f0fa432f4ae6604f72c132309&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Kumar McMillan&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088117&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-07T20:59:25&quot;&gt;2010-07-07T20:59:25&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hey Les, this is super cool!  Google App Engine's Datastore API is still very shaky though.  In fact, it's been so bad lately that I've been considering porting one of my heavily used apps over to something else.  Thankfully, this post suggests that fixing the Datastore is their top priority: http://googleappengine.blogspot.com/2010/06/datastore-performance-growing-pains.html&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088119&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://home.kairo.at/blog/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=59d914ad47e5c3fcd4c89668adcd43a2&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://home.kairo.at/blog/&quot;&gt;Robert Kaiser&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088119&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-07-07T21:21:51&quot;&gt;2010-07-07T21:21:51&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Well, I actually feel more comfortable with my data being on Mozilla servers than on Google servers - even with the decreased trust I have in the Mozilla organization, I'd trust it more than Google any day! ;-)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221088120&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://blog.chrisarndt.de&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=02653ae22d36044e6870c17cf3d5a005&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://blog.chrisarndt.de&quot;&gt;Chris Arndt&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221088120&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-09-28T11:06:55&quot;&gt;2010-09-28T11:06:55&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Instead of porting GAE to your desktop, why don't you just port your app to plain Django? Django should run off your desktop with no problems.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Case Study: Building a Bookmark Management UI for Mozilla's BYOB</title>
        <link href="http://decafbad.com/blog/2010/06/22/case-study-building-a-bookmark-management-ui-for-mozillas-byob"/>
        <updated>2010-06-22T22:16:24+00:00</updated>
        <id>http://decafbad.com/blog/2010/06/22/case-study-building-a-bookmark-management-ui-for-mozillas-byob</id>
        <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I just wrote &lt;a href=&quot;http://decafbad.com/2010/06/byob-bookmarks-ui/&quot;&gt;a &lt;strong&gt;long&lt;/strong&gt; case-study about my process in building a bookmark management feature&lt;/a&gt; for Mozilla's &lt;a href=&quot;http://byob.mozilla.com/&quot;&gt;Build Your Own Browser&lt;/a&gt; web application.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://decafbad.com/2010/06/byob-bookmarks-ui/&quot;&gt;&lt;img src=&quot;http://decafbad.com/2010/06/byob-bookmarks-ui/img/bookmarks.png&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, remember that &lt;a href=&quot;http://decafbad.com/blog/2010/06/07/tinderbox-article-tutorial&quot;&gt;tutorial I wrote about writing an article in Tinderbox&lt;/a&gt;? I'd mentioned that it was a digression from another, different article.&lt;/p&gt;

&lt;p&gt;Well, I just finished a first draft of that article:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://decafbad.com/2010/06/byob-bookmarks-ui/&quot;&gt;It's a case study about building a bookmark management feature for Mozilla's BYOB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Light on code but heavy on narration, it's about what I did and what I was thinking while I did it. There are links to the end product for reference, but it isn't a demonstration of some new trick. Rather, it's a look at my process as a whole.&lt;/p&gt;

&lt;p&gt;I wrote this, in part, for myself: The writing has helped me review things. But, I'm hoping someone else reads it, and then picks up something new or can offer some interesting critique in return.&lt;/p&gt;

&lt;p&gt;And, because I'm curious and like looking behind the scenes, I'd love to see this kind of write-up from more webdevs. There don't seem to be a lot of detailed case studies versus quick one-shot tutorials on isolated techniques. It's probably because the writing is time-consuming, as is the reading. It's not in the genre of bite-sized attractions optimized for promoting blog traffic, but I'd like to see more of them all the same.&lt;/p&gt;
</content>
    </entry>
    
    

    <entry>
        <title>Using Tinderbox to write articles for the web</title>
        <link href="http://decafbad.com/blog/2010/06/07/tinderbox-article-tutorial"/>
        <updated>2010-06-07T04:41:03+00:00</updated>
        <id>http://decafbad.com/blog/2010/06/07/tinderbox-article-tutorial</id>
        <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I just put together &lt;a href=&quot;http://decafbad.com/2010/06/tinderbox-article-tutorial/article.html&quot;&gt;a tutorial about writing an article in HTML&lt;/a&gt; using &lt;a href=&quot;http://www.eastgate.com/Tinderbox/&quot;&gt;Tinderbox&lt;/a&gt; from &lt;a href=&quot;http://www.eastgate.com/&quot;&gt;Eastgate Systems, Inc&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/em&gt; There's a &lt;a href=&quot;http://pc.de/pages/tinderbox-tutorial-be&quot;&gt;Belorussian&lt;/a&gt; translation of this post provided by &lt;a href=&quot;http://pc.de/&quot;&gt;PC&lt;/a&gt; - very cool!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3105/2476581071_7a55c565dd.jpg&quot; alt=&quot;tinderboxicon&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tinderbox Icon by Bryan Bell, via &lt;a href=&quot;http://www.flickr.com/photos/factoryjoe/2476581071/&quot;&gt;flickr.com/photos/factoryjoe&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I've been toying with a set of writing topics to get my blog going again, apropos of &lt;a href=&quot;http://decafbad.com/blog/2010/03/10/pondering-the-cobwebs&quot;&gt;my notion of writing for myself&lt;/a&gt;. But, I like to write at length and have finally decided that life's too short to write in browser &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;'s, no matter how cleverly augmented.&lt;/p&gt;

&lt;p&gt;I did buy &lt;a href=&quot;http://www.red-sweater.com/marsedit/&quot;&gt;MarsEdit 3&lt;/a&gt;, which is a fine app for dashing off short entries. But, for longer things, I found myself doing the actual writing elsewhere and pasting the text into MarsEdit for posting later. I even wrote and posted &lt;a href=&quot;http://decafbad.com/skein/2010/03/11/alpha-vs-delta/&quot;&gt;a whole fanfic novella&lt;/a&gt; this way, and it was a silly way to do things.&lt;/p&gt;

&lt;p&gt;Well, one of the places where writing actually happens for me over the past few years is within &lt;a href=&quot;http://www.eastgate.com/Tinderbox/&quot;&gt;Tinderbox&lt;/a&gt; documents. And, as it turns out, &lt;a href=&quot;http://www.eastgate.com/Tinderbox/&quot;&gt;Tinderbox&lt;/a&gt; has some powerful HTML export facilities that I've left underused until some things finally clicked for me.&lt;/p&gt;

&lt;p&gt;So, I thought I'd try turning that experience back upon itself to produce something worth writing. Without further ado, here's the &lt;a href=&quot;http://github.com/lmorchard/tinderbox-article-tutorial&quot;&gt;source in GitHub&lt;/a&gt;, and the &lt;a href=&quot;http://decafbad.com/2010/06/tinderbox-article-tutorial/article.html&quot;&gt;article exported to HTML for easy reading&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The funny thing is, I started working on this tutorial in the middle of writing another article. So, this post is a particularly advanced form of &lt;a href=&quot;http://catb.org/jargon/html/Y/yak-shaving.html&quot;&gt;Yak Shaving&lt;/a&gt;. I hope it ends up handy for someone, and I hope it leads to the &lt;em&gt;real&lt;/em&gt; articles I'm hoping to produce.&lt;/p&gt;
</content>
    </entry>
    
    

    <entry>
        <title>HTML5 drag and drop in Firefox 3.5</title>
        <link href="http://decafbad.com/blog/2009/07/15/html5-drag-and-drop"/>
        <updated>2009-07-15T15:26:40+00:00</updated>
        <id>http://decafbad.com/blog/2009/07/15/html5-drag-and-drop</id>
        <content type="html">&lt;p&gt;&lt;i&gt;
Oh hey, look! It's another blog post—and this one
&lt;a href=&quot;http://hacks.mozilla.org/2009/07/html5-drag-and-drop/&quot;&gt;is cross-posted on hacks.mozilla.com&lt;/a&gt;.
I won't say this is the start of a renewed blogging habit, but let's see what happens.
&lt;/i&gt;&lt;/p&gt;






&lt;div id=&quot;introduction&quot;&gt;
    &lt;p&gt;
        Drag and drop is one of the most fundamental interactions
        afforded by graphical user interfaces.  In one gesture, it
        allows users to pair the selection of an object with the
        execution of an action, often including a second object in the
        operation.  It's a simple yet powerful UI concept used to
        support copying, list reordering, deletion (ala the Trash / Recycle Bin),
        and even the creation of link relationships.
    &lt;/p&gt;&lt;p&gt;
        Since it's so fundamental, offering drag and drop in web
        applications has been a no-brainer ever since browsers first
        offered mouse events in DHTML.  But, although
        &lt;code&gt;mousedown&lt;/code&gt;, &lt;code&gt;mousemove&lt;/code&gt;, and
        &lt;code&gt;mouseup&lt;/code&gt; made it possible, the implementation has been
        limited to the bounds of the browser window.  Additionally,
        since these events refer only to the object being dragged,
        there's a challenge to find the subject of the drop when
        the interaction is completed.
    &lt;/p&gt;&lt;p&gt;

        Of course, that doesn't prevent most modern JavaScript
        frameworks from abstracting away most of the problems and
        throwing in some flourishes while they're at it.  But, wouldn't
        it be nice if browsers offered first-class support for drag and
        drop, and maybe even extended it beyond the window sandbox?
    &lt;/p&gt;&lt;p&gt;
        As it turns out, this very wish is answered by the HTML 5 specification 
        &lt;a target=&quot;_new&quot; href=&quot;http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dnd&quot;&gt;section on new drag-and-drop events&lt;/a&gt;, and 
        &lt;a target=&quot;_new&quot; href=&quot;https://developer.mozilla.org/En/DragDrop/Drag_and_Drop&quot;&gt;Firefox 3.5 includes an implementation&lt;/a&gt; of those events.
    &lt;/p&gt;&lt;p&gt;
        If you want to jump straight to the code, I've put together 
        &lt;a target=&quot;_new&quot; target=&quot;_new&quot; target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/api-demos.html&quot;&gt;some simple demos&lt;/a&gt; 
        of the new events.  
    &lt;/p&gt;&lt;p&gt;

        I've even scratched an itch of my own and
        built &lt;a target=&quot;_new&quot; target=&quot;_new&quot; target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/outline.html&quot;&gt;the beginnings of an outline editor&lt;/a&gt;,
        where every draggable element is also a drop target—of which
        there could be dozens to hundreds in a complex document, something
        that gave me some minor hair-tearing moments in the past
        while trying to make do with plain old mouse events.
    &lt;/p&gt;&lt;p&gt;
        And, all the above can be downloaded or cloned from 
        &lt;a href=&quot;http://github.com/lmorchard/fx35-drag-and-drop&quot;&gt;a GitHub repository&lt;/a&gt;
        I've created especially for this article—which continues after the jump.
    &lt;/p&gt;
&lt;/div&gt;




&lt;!--more--&gt;




&lt;div id=&quot;events&quot;&gt;

    &lt;h2&gt;The New Drag and Drop Events&lt;/h2&gt;
    &lt;p&gt;
        So, with no further ado, here are the new drag and drop events,
        in roughly the order you might expect to see them fired:
    &lt;/p&gt;
    &lt;dl&gt;
        &lt;dt&gt;&lt;code&gt;dragstart&lt;/code&gt;&lt;/dt&gt;
        &lt;dd&gt;
            A drag has been initiated, with the dragged element as the
            event target.
        &lt;/dd&gt;

        &lt;dt&gt;&lt;code&gt;drag&lt;/code&gt;&lt;/dt&gt;
        &lt;dd&gt;
            The mouse has moved, with the dragged element as the event target.
        &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;dragenter&lt;/code&gt;&lt;/dt&gt;
        &lt;dd&gt;
            The dragged element has been moved into a drop listener,
            with the drop listener element as the event target.
        &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;dragover&lt;/code&gt;&lt;/dt&gt;

        &lt;dd&gt;
            The dragged element has been moved over a drop listener,
            with the drop listener element as the event target.  Since
            the default behavior is to cancel drops, returning
            &lt;code&gt;false&lt;/code&gt; or calling &lt;code&gt;preventDefault()&lt;/code&gt; in
            the event handler indicates that a drop is allowed here.
        &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;dragleave&lt;/code&gt;&lt;/dt&gt;
        &lt;dd&gt;
            The dragged element has been moved out of a drop listener,
            with the drop listener element as the event target.
        &lt;/dd&gt;

        &lt;dt&gt;&lt;code&gt;drop&lt;/code&gt;&lt;/dt&gt;
        &lt;dd&gt;
            The dragged element has been successfully dropped on a drop
            listener, with the drop listener element as the event
            target.
        &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;dragend&lt;/code&gt;&lt;/dt&gt;
        &lt;dd&gt;
            A drag has been ended, successfully or not, with the
            dragged element as the event target.
        &lt;/dd&gt;
    &lt;/dl&gt;

    &lt;p&gt;
        Like the mouse events of yore, listeners can be attached to
        elements using &lt;code&gt;addEventListener()&lt;/code&gt; 
        directly or by way of your favorite JS library.  
    &lt;/p&gt;&lt;p&gt;
        Consider the following example using jQuery, 
        &lt;a target=&quot;_new&quot; target=&quot;_new&quot; target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/api-demos.html#newschool&quot;&gt;also available as a live demo&lt;/a&gt;:
    &lt;/p&gt;
    &lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
&lt;div id=&quot;newschool&quot;&gt;
    &lt;div class=&quot;dragme&quot;&gt;Drag me!&lt;/div&gt;
    &lt;div class=&quot;drophere&quot;&gt;Drop here!&lt;/div&gt;
&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    $(document).ready(function() {
        $('#newschool .dragme')
            .attr('draggable', 'true')
            .bind('dragstart', function(ev) {
                var dt = ev.originalEvent.dataTransfer;
                dt.setData(&quot;Text&quot;, &quot;Dropped in zone!&quot;);
                return true;
            })
            .bind('dragend', function(ev) {
                return false;
            });
        $('#newschool .drophere')
            .bind('dragenter', function(ev) {
                $(ev.target).addClass('dragover');
                return false;
            })
            .bind('dragleave', function(ev) {
                $(ev.target).removeClass('dragover');
                return false;
            })
            .bind('dragover', function(ev) {
                return false;
            })
            .bind('drop', function(ev) {
                var dt = ev.originalEvent.dataTransfer;
                alert(dt.getData('Text'));
                return false;
            });
    });
&lt;/script&gt;
    &lt;/pre&gt;
    &lt;p&gt;
        Thanks to the new events and jQuery, this example is both short
        and simple—but it packs in a lot of functionality, as the rest
        of this article will explain.  
    &lt;/p&gt;&lt;p&gt;
        Before moving on, there are at least three things about the above
        code that are worth mentioning:
    &lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;

            &lt;p&gt;
                Drop targets are enabled by virtue of having
                listeners for drop events.  But, 
                &lt;a target=&quot;_new&quot; href=&quot;http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#drag-and-drop-processing-model&quot;&gt;per the HTML 5 spec&lt;/a&gt;,
                draggable elements need an
                attribute of &lt;code&gt;draggable=&quot;true&quot;&lt;/code&gt;, set either in
                markup or in JavaScript.  
            &lt;/p&gt;
            &lt;p&gt;
                Thus, &lt;code&gt;$('#newschool&amp;nbsp;.dragme').attr('draggable', 'true')&lt;/code&gt;.
            &lt;/p&gt;

        &lt;/li&gt;
        &lt;li&gt;
            &lt;p&gt;
                The original DOM event (as opposed to jQuery's event
                wrapper) offers a property called &lt;code&gt;dataTransfer&lt;/code&gt;.
                Beyond just manipulating elements, the new drag and drop
                events accomodate the transmission of user-definable data
                during the course of the interaction.  
            &lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;
            &lt;p&gt;

                Since these are first-class events, you can apply 
                &lt;a target=&quot;_new&quot; href=&quot;http://icant.co.uk/sandbox/eventdelegation/&quot;&gt;the technique of Event Delegation&lt;/a&gt;.
            &lt;/p&gt;&lt;p&gt;
                What's that?  Well, imagine you have a list of 1000
                list items—as part of a deeply-nested outline document,
                for instance.  Rather than needing to attach listeners
                or otherwise fiddle with all 1000 items, simply attach
                a listener to the parent node (eg. the
                &lt;code&gt;&lt;ul&gt;&lt;/code&gt; element) and all events from
                the children will propagate up to the single parent listener.
                As a bonus, all new child elements added after page
                load will enjoy the same benefits.
            &lt;/p&gt;&lt;p&gt;
                &lt;a target=&quot;_new&quot; target=&quot;_new&quot; target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/api-demos.html#delegated&quot;&gt;Check out this demo&lt;/a&gt;, 
                and 
                &lt;a target=&quot;_new&quot; target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/js/drag-delegated.js&quot;&gt;the associated JS code&lt;/a&gt; 
                to see more about these events and Event Delegation.
            &lt;/p&gt;

        &lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;




&lt;div id=&quot;datatransfer&quot;&gt;
    &lt;h2&gt;Using dataTransfer&lt;/h2&gt;
    &lt;p&gt;
        As mentioned in the last section, the new drag and drop events
        let you send data along with a dragged element.  But, it's even
        better than that:  Your drop targets can receive data
        transferred by content objects dragged into the window from 
        other browser windows, and even &lt;i&gt;other applications&lt;/i&gt;.
    &lt;/p&gt;&lt;p&gt;

        Since the example is a bit longer,  
        &lt;a target=&quot;_new&quot; target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/api-demos.html#data_transfer&quot;&gt;check out the live demo&lt;/a&gt;
        and 
        &lt;a target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/js/drag-datatransfer.js&quot;&gt;associated code&lt;/a&gt;
        to get an idea of what's possible with &lt;code&gt;dataTransfer&lt;/code&gt;.
    &lt;/p&gt;&lt;p&gt;
        In a nutshell, the stars of this show are the
        &lt;code&gt;setData()&lt;/code&gt; and &lt;code&gt;getData()&lt;/code&gt; methods of
        the &lt;code&gt;dataTransfer&lt;/code&gt; property exposed by the Event object.
    &lt;/p&gt;

    &lt;p&gt;
        The &lt;code&gt;setData()&lt;/code&gt; method is typically called in the 
        &lt;code&gt;dragstart&lt;/code&gt; listener, loading &lt;code&gt;dataTransfer&lt;/code&gt;
        up with one or more strings of content with associated
        &lt;a href=&quot;https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types#link&quot;&gt;recommended content types&lt;/a&gt;.
    &lt;/p&gt;

    &lt;p&gt;
        For illustration, here's a quick snippet from the example code:
    &lt;/p&gt;
    &lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
var dt = ev.originalEvent.dataTransfer;    
dt.setData('text/plain', $('#logo').parent().text());
dt.setData('text/html', $('#logo').parent().html());
dt.setData('text/uri-list', $('#logo')[0].src);
    &lt;/pre&gt;
    &lt;/p&gt;&lt;p&gt;
        On the other end, &lt;code&gt;getData()&lt;/code&gt; allows you to query
        for content by type (eg. &lt;code&gt;text/html&lt;/code&gt; followed by
        &lt;code&gt;text/plain&lt;/code&gt;).  This, in turn, allows you to decide
        on acceptable content types at the time of the
        &lt;code&gt;drop&lt;/code&gt; event or even during &lt;code&gt;dragover&lt;/code&gt;

        to offer feedback for unacceptable types during the drag.
    &lt;/p&gt;&lt;p&gt;
        Here's another example from the receiving end of the example code:
    &lt;/p&gt;
    &lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
var dt = ev.originalEvent.dataTransfer;    
$('.content_url .content').text(dt.getData('text/uri-list'));
$('.content_text .content').text(dt.getData('text/plain'));
$('.content_html .content').html(dt.getData('text/html'));
    &lt;/pre&gt;
    &lt;p&gt;
        Where &lt;code&gt;dataTransfer&lt;/code&gt; really shines, though, is that
        it allows your drop targets to receive content from 
        sources outside your defined draggable elements and even from
        outside the browser altogether.  Firefox accepts such drags, 
        and attempts to populate &lt;code&gt;dataTransfer&lt;/code&gt; with
        appropriate content types extracted from the external object.
    &lt;/p&gt;&lt;p&gt;

        Thus, you could select some text in a word processor window and
        drop it into one of your elements, and at least expect to find
        it available as &lt;code&gt;text/plain&lt;/code&gt; content.  
    &lt;/p&gt;&lt;p&gt;
        You can also select content in 
        another browser window, and expect to see &lt;code&gt;text/html&lt;/code&gt;
        appear in your events.  Check out the 
        &lt;a target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/outline.html&quot;&gt;outline editing demo&lt;/a&gt;
        and see what happens when you try dragging various elements 
        (eg. images, tables, and lists) and highlighted content from
        other windows onto the items there.
    &lt;/p&gt;

&lt;/div&gt;




&lt;div id=&quot;dragfeedback&quot;&gt;
    &lt;h2&gt;Using Drag Feedback Images&lt;/h2&gt;
    &lt;p&gt;
       An important aspect of the drag and drop interaction is a
       representation of the thing being dragged.  By default in
       Firefox, this is a &quot;ghost&quot; image of the dragged element itself.  But,
       the &lt;code&gt;dataTransfer&lt;/code&gt; property of the original Event
       object exposes the method &lt;code&gt;setDragImage()&lt;/code&gt; for use
       in customizing this representation.
    &lt;/p&gt;&lt;p&gt;

        There's
        &lt;a target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/api-demos.html#feedback_image&quot;&gt;a live demo&lt;/a&gt; of this feature, as well as
        &lt;a target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/js/drag-feedback-images.js&quot;&gt;associated JS code&lt;/a&gt; 
        available.  The gist, however, is sketched out in these code snippets:
    &lt;/p&gt;
    &lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
var dt = ev.originalEvent.dataTransfer;    

dt.setDragImage( $('#feedback_image h2')[0], 0, 0);

dt.setDragImage( $('#logo')[0], 32, 32); 

var canvas = document.createElement(&quot;canvas&quot;);
canvas.width = canvas.height = 50;

var ctx = canvas.getContext(&quot;2d&quot;);
ctx.lineWidth = 8;
ctx.moveTo(25,0);
ctx.lineTo(50, 50);
ctx.lineTo(0, 50);
ctx.lineTo(25, 0);
ctx.stroke();

dt.setDragImage(canvas, 25, 25);
    &lt;/pre&gt;
    &lt;p&gt;
        You can supply a DOM node as the first parameter to 
        &lt;code&gt;setDragImage()&lt;/code&gt;, which includes everything from
        text to images to &lt;code&gt;canvas&lt;/code&gt; elements.  The
        second two parameters indicate at what left and top offset
        the mouse should appear in the image while dragging.
    &lt;/p&gt;&lt;p&gt;

        For example, since the &lt;code&gt;#logo&lt;/code&gt; image is 64x64,
        the parameters in the second &lt;code&gt;setDragImage()&lt;/code&gt;
        method places the mouse right in the center of the image.
        On the other hand, the first call positions the feedback
        image such that the mouse rests in the upper left corner.
    &lt;/p&gt;&lt;p&gt;
    &lt;/p&gt;
&lt;/div&gt;




&lt;div id=&quot;dragfeedback&quot;&gt;

    &lt;h2&gt;Using Drop Effects&lt;/h2&gt;
    &lt;p&gt;
        As mentioned at the start of this article, the drag and drop
        interaction has been used to support actions such as copying,
        moving, and linking.  Accordingly, the HTML 5 specification 
        accomodates these operations in the form of the 
        &lt;code&gt;effectAllowed&lt;/code&gt; and &lt;code&gt;dropEffect&lt;/code&gt;
        properties exposed by the Event object.
    &lt;/p&gt;
    &lt;p&gt;

        For a quick fix, check out the
        &lt;a target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/api-demos.html#drag_effects&quot;&gt;a live demo&lt;/a&gt; 
        of this feature, as well as the
        &lt;a target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/js/drag-effects.js&quot;&gt;associated JS code&lt;/a&gt;.
    &lt;/p&gt;&lt;p&gt;
        The basic idea is that the &lt;code&gt;dragstart&lt;/code&gt; event
        listener can set a value for &lt;code&gt;effectAllowed&lt;/code&gt; like so:
    &lt;/p&gt;

    &lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
var dt = ev.originalEvent.dataTransfer;
switch (ev.target.id) {
    case 'effectdrag0': dt.effectAllowed = 'copy'; break;
    case 'effectdrag1': dt.effectAllowed = 'move'; break;
    case 'effectdrag2': dt.effectAllowed = 'link'; break;
    case 'effectdrag3': dt.effectAllowed = 'all'; break;
    case 'effectdrag4': dt.effectAllowed = 'none'; break;
}
    &lt;/pre&gt;
    &lt;p&gt;The choices available for this property include the following:&lt;/p&gt;
    &lt;dl&gt; 
        &lt;dt&gt;&lt;code&gt;none&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;no operation is permitted &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;copy&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;copy only &lt;/dd&gt;

        &lt;dt&gt;&lt;code&gt;move&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;move only &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;link&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;link only &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;copyMove&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;copy or move only &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;copyLink&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;copy or link only &lt;/dd&gt;
        &lt;dt&gt;&lt;code&gt;linkMove&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;link or move only &lt;/dd&gt;

        &lt;dt&gt;&lt;code&gt;all&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;copy, move, or link &lt;/dd&gt;
    &lt;/dl&gt;
    &lt;p&gt;
        On the other end, the &lt;code&gt;dragover&lt;/code&gt; event listener 
        can set the value of the
        &lt;code&gt;dropEffect&lt;/code&gt; property to indicate the expected effect
        invoked on a successful drop.  If the value does
        not match up with &lt;code&gt;effectAllowed&lt;/code&gt;, the drop will
        be considered cancelled on completion.
    &lt;/p&gt;&lt;p&gt;

        In the 
        &lt;a target=&quot;_new&quot; href=&quot;http://decafbad.com/2009/07/drag-and-drop/api-demos.html#drag_effects&quot;&gt;a live demo&lt;/a&gt;,
        you should be able to see that only elements with matching
        effects can be dropped into the appropriate drop zones.  This
        is accomplished with code like the following:
    &lt;/p&gt;
    &lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
var dt = ev.originalEvent.dataTransfer;
switch (ev.target.id) {
    case 'effectdrop0': dt.dropEffect = 'copy'; break;
    case 'effectdrop1': dt.dropEffect = 'move'; break;
    case 'effectdrop2': dt.dropEffect = 'link'; break;
    case 'effectdrop3': dt.dropEffect = 'all'; break;
    case 'effectdrop4': dt.dropEffect = 'none'; break;
}
    &lt;/pre&gt;
    &lt;p&gt;
        Although the OS itself can provide some feedback, you 
        can also use these properties to update your own visible 
        feedback, both on the dragged element and on the drop zone
        itself.
    &lt;/p&gt;

&lt;/div&gt;




&lt;div id=&quot;conclusion&quot;&gt;
    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;
        The new first-class drag and drop events in HTML5 and Firefox
        make supporting this form of UI interaction simple, concise,
        and powerful in the browser.  But beyond the new simplicity of
        these events, the ability to transfer content between
        applications opens brand new avenues for web-based applications
        and collaboration with desktop software in general.
    &lt;/p&gt;&lt;p&gt;
    &lt;/p&gt;&lt;p&gt;
    &lt;/p&gt;
&lt;/div&gt;




&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090962&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://lmframework.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=03dc722b1852367f02b0b21f02b10675&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://lmframework.com&quot;&gt;David Semeria&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090962&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-16T17:56:52&quot;&gt;2009-07-16T17:56:52&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Wow - thanks for a great introduction to D+D in HTML 5, I'm really looking forward to giving it a thorough road test. &lt;/p&gt;

&lt;p&gt;The key part of the implementation are the target listeners, because, as I'm sure you're aware, onmouseover would historically never fire over the target element because the dragged item would always 'cover it up'. BTW, my proposed solution was to add an 'event transparency' property, which would have made the dragged item invisible from the point of view of selected events, eg onmouseover.&lt;/p&gt;

&lt;p&gt;This implementation is going to take a lot of pain away. You have no idea how many hoops I had to jump through to get a fully generic D+D implementation working without these new calls.&lt;/p&gt;

&lt;p&gt;If you're interested, you can see it working here: http://lmframework.com/page.php?id=vd_twig_short_2&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090964&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=cee7ac3f63d7e8c1367e170bec302c14&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Alex&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090964&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-17T00:13:23&quot;&gt;2009-07-17T00:13:23&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hey,&lt;/p&gt;

&lt;p&gt;Looks great and useful article.  For dragging from external applications (such as the Desktop) is a normal webpage able to get the data from the drop?  I was just playing with it and seem to always get what seems to be a security error with getData or mozGetDataAt.  However, the documentation seems to state that on drop that data should be made available to the page.  Likewise, in the same way an image can be dragged off the page onto the desktop, can an arbitrary element be dragged onto the desktop with whatever file content to be saved?  Thanks for the help.&lt;/p&gt;

&lt;p&gt;Alex&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090966&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://paulisageek.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=b3bb70a4bace7f9bd49f48b149ab95f9&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://paulisageek.com/&quot;&gt;Paul Tarjan&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090966&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-17T04:52:54&quot;&gt;2009-07-17T04:52:54&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Very nice, I didn't know that FF 3.5 actually had this implemented. Time to start playing :)&lt;/p&gt;

&lt;p&gt;Also, how did you do your code posts? Was it just pasting in HTML or do you have a better setup?&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090967&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=066d1e75c9b938053ee6b3d48b1c0f6a&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Animal&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090967&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-17T14:35:21&quot;&gt;2009-07-17T14:35:21&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Seems pretty pointless pressing ahead with this when you just can't write a web app to use it. There's no support. All a bunch of whizzy fun I'm sure, but sod-all use.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090969&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090969&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-17T16:23:10&quot;&gt;2009-07-17T16:23:10&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Animal: Why can't you write a web app to use it?  It's in the HTML5 spec, works in Fx3.5 and Safari 4 / WebKit.  It doesn't have universal support yet, or course, but new standards never do.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090970&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.crearedesign.co.uk&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=87bf21798e390d9043dda7240c1b60f7&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.crearedesign.co.uk&quot;&gt;paul&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090970&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-21T08:08:26&quot;&gt;2009-07-21T08:08:26&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;very nice indeed! i like this, it has definitely opened up new avenues for interaction without using flash. but it will take time before people upgrade to the new browser. a lot of people who browse the web wont realise what the technology will bring and will use their current browser because it does the job!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090971&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=04de859cfd6ef0b75e4ea3cbea143190&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Joel&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090971&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-21T14:36:04&quot;&gt;2009-07-21T14:36:04&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Excellent demos of the new features.&lt;/p&gt;

&lt;p&gt;When using a feedback image on a zoomed in page, should the image not also be scaled up automatically?&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090973&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=41708&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=6d3bf986abdbb431991c3b02eb6e2335&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=41708&quot;&gt;RenegadeX&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090973&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-22T04:13:46&quot;&gt;2009-07-22T04:13:46&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Dragging &amp;amp; dropping &lt;em&gt;is&lt;/em&gt; as you say, a &quot;one of the most fundamental interations&quot; that users of computer graphical interfaces have come to know, and expect.&lt;/p&gt;

&lt;p&gt;It therefore completes dumbfounds me how it is that we &lt;em&gt;still&lt;/em&gt; can not natively drag &amp;amp; scroll (&amp;amp; then drop) in Firefox. We can only drag &amp;amp; drop an item within the currently visible portion of a Firefox webpage or tab, no further up, no further down.&lt;/p&gt;

&lt;p&gt;That is should be limited makes absolutely no sense. Microsoft built the function into their Windows 3.x (file) Explorer, and then when visual browsers came along, naturally carried it through into Internet Explorer. &lt;/p&gt;

&lt;p&gt;Firefox Bug 41708, &quot;Should be able to scroll in the viewport while dragging&quot; was opened in June, 2000 (yes, 9 years ago!) and remains open, and is disregarded by Firefox developers as little more than a trivial little annoyance, and therefore is and should be treated as a low-importance 'enhancement' rather than as the 'standard feature' it should really be.&lt;/p&gt;

&lt;p&gt;If it weren't for the extension 'DragToScroll', which has been around for 3-1/2 years now (not updated in a long time but still works if you override version compatibility), I would have dumped Firefox and switched to a different browser (Maxthon 3, most likely).&lt;/p&gt;

&lt;p&gt;So, I'm wondering (and hoping) -- does the new HTML5 drag and drop specification include anything that if implemented properly would make it possible to scroll &amp;amp; drag?&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090974&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090974&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-22T13:57:42&quot;&gt;2009-07-22T13:57:42&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@RenegadeX: Ugh.  I don't work on the browser itself, but I noticed that unexpected behavior on drag &amp;amp; drop.  The window really should scroll when you get toward the top or bottom while dragging - and, in fact, most pre-HTML5 JS frameworks do that in their own drag &amp;amp; drop abstractions.  &lt;/p&gt;

&lt;p&gt;Until / unless Firefox gets this fixed, the same sort of auto-scrolling could be hacked in to HTML5 drag and drop.  Not perfect, but it's doable.  That is, in the drag event, you can check if the mouse is near the upper or lower edge of the viewport - and if so, start scrolling appropriately. That's pretty much how the JS frameworks do it with old-school D&amp;D&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090975&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.copperbot.net&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=df48b2c2a3a2be51b1e15f10c5fb05da&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.copperbot.net&quot;&gt;CopperBot&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090975&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-23T21:41:07&quot;&gt;2009-07-23T21:41:07&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Very cool article! Thanks for sharing. HTML5 really is going to change everything about how we use and develop for the web. Pretty awesome!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090976&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.AmnesiaGames.cl&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=14ad888c23e28c85c222a73b6c633570&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.AmnesiaGames.cl&quot;&gt;Alexos&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090976&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-26T05:05:44&quot;&gt;2009-07-26T05:05:44&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi, would DD work for uploading files? How can I display a progress bar?
Thanks! 
I've been looking for that several days, and found only applets which I can't use in my proyect :-)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090977&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.sjlwebdesign.co.uk&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=185cd965e0e8ccd15df2f90977cbeaf3&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.sjlwebdesign.co.uk&quot;&gt;Sam&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090977&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-28T13:54:26&quot;&gt;2009-07-28T13:54:26&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Looks fantastic, going to try it out now (once I have upgraded my FF)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090978&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.dankantor.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=60fc8331f617fc905fd682bc4f41ce8d&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.dankantor.com&quot;&gt;Dan Kantor&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090978&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-30T03:10:25&quot;&gt;2009-07-30T03:10:25&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Looks like effectAllowed and dropEffect are not working for FF 3.5 on the Mac. I see effects on Windows and Safari 4 on Mac. I've been playing around with adding borders to the drop target, but the + icon for copy really helps a lot. Hopefully Mozilla will fix this next update.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090979&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.thecssninja.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=8677c9f7c0f6d947bf318c1430d00bfd&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.thecssninja.com/&quot;&gt;Ryan&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090979&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-09-01T02:33:06&quot;&gt;2009-09-01T02:33:06&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Great article it's good to see developments in this area. I wrote an article on the further extensions Firefox 3.6 has done with the dataTransfer method by adding the file attribute so you can access local files and upload them without the need for file inputs. http://www.thecssninja.com/javascript/drag-and-drop-upload&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090982&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=1ed4bbef573bfc014d32356d53103ca2&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;phil swenson&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090982&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-09-03T22:58:36&quot;&gt;2009-09-03T22:58:36&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Why not a first class WYSIWYG rich text editor with copy from clipboard image support?  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;NO ONE&lt;/em&gt; has built a decent text editor in JavaScript - At least not that I've seen.  And browsers don't allow image paste for reasons I don't understand.  &lt;/p&gt;

&lt;p&gt;And by decent I mean just like you'd get in textmate or another editor.  Have the standard text editor features everyone expects:  tab, select indent/select unindent, resize image, home, end, duplicate line, delete line, styling, etc.&lt;/p&gt;

&lt;p&gt;would push the browser to the next level in killing the desktop.  non-techies hate wikis.  They want a real editor.  I do too actually.... would be great for forums, bug tracking system (imagine pasting screen shots in line with your bug desc), email, etc.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090983&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=deed51cddc830e162557b8f01383a057&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Jean-Denis&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090983&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-09-04T00:23:39&quot;&gt;2009-09-04T00:23:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Francisco Tomalski wrote up a nice piece on HTML 5 drag'n drop at http://www.alertdebugging.com/2009/08/16/on-html-5-drag-and-drop/&lt;/p&gt;

&lt;p&gt;where he uncovers that the proposed standard is partially broken. Any comment on his piece?&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090984&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://html5tutorial.net/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3876e030a3fc69a8b59a8c55829fb510&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://html5tutorial.net/&quot;&gt;Lisa&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090984&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-09-09T07:33:08&quot;&gt;2009-09-09T07:33:08&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;This is a great move forward no more relying on 3rd party apps and extensions to play video or audio, i have been reading up on HTML 5 at the &lt;a href=&quot;http://html5tutorial.net/&quot; title=&quot;HTML tutorials&quot; rel=&quot;nofollow&quot;&gt;HTML 5 Tutorials&lt;/a&gt; website, i am now playing around with one of the free templates and was wondering how to embed audio, so thanks a lot, great information, lets hope more people lean towards HTML 5 and SOON!!!&lt;/p&gt;

&lt;p&gt;The drag and drop feature i did not notice was already working in FF 3.5, i was told to get Safari to see HTML 5 in action. Thanks for a great post&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090985&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.useragentman.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=9a579fa051b35266678735c8a3751771&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.useragentman.com&quot;&gt;Zoltan Hawryluk&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090985&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-01-11T15:14:48&quot;&gt;2010-01-11T15:14:48&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;A million thank yous!  This article was great introduction to HTML5 D+D.  With it, I was able to extend it to other browsers.  It was a little painful at first because the browser implementations diverge in significant, but manageable ways.&lt;/p&gt;

&lt;p&gt;If you are interested, check out my article at http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/ if you are interested in my results.&lt;/p&gt;

&lt;p&gt;I noticed you haven't blogged in a while - I hope you haven't stopped totally and continue to share with the webdev community.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221090986&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.lingua-franka.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=e65f416e42c12571ba1c86ae2dadd99f&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.lingua-franka.com&quot;&gt;Raul&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221090986&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-04-26T23:56:02&quot;&gt;2011-04-26T23:56:02&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi, Leslie. I've just come across a problem that's driving me nuts. I'm not fully comfortable with D&amp;amp;D, but managed to move a crosshairs image over a map to very precisely controlled positions. It worked great on FF 3.6 and FF 4. After a couple of days of successful testing, the image suddenly refused to de dropped after being dragged (it rather flew back to its previous position). Do you know if there is a bug in FF that might cause this? &lt;/p&gt;

&lt;p&gt;BTW, during the programming process I updated Firebug, which also is getting a little cranky.&lt;/p&gt;

&lt;p&gt;Thanks for your prompt answer, Raul&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-324410737&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/google-4014af7ac4ea5d00df95bef4503b78dd.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Alexander Plutov&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-324410737&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2011-10-01T11:51:12&quot;&gt;2011-10-01T11:51:12&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;Good post about Drag &amp; Drop http://plutov.by/post/html5_drag_and_drop&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>I (used to) like rev="canonical"</title>
        <link href="http://decafbad.com/blog/2009/04/13/i-like-revcanonical"/>
        <updated>2009-04-13T05:05:50+00:00</updated>
        <id>http://decafbad.com/blog/2009/04/13/i-like-revcanonical</id>
        <content type="html">&lt;p&gt;&lt;em&gt;Update 4/14&lt;/em&gt;: So, I liked &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt;, but I like the notion of pages offering sets of alternative URLs better.  &lt;a href=&quot;http://www.mnot.net/blog/2009/04/14/rev_canonical_bad&quot;&gt;There are enough cracks in the case&lt;/a&gt; for &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; to stop caring about it and instead focus on the notion behind it.  However it's expressed—is it &lt;a href=&quot;http://groups.google.com/group/shortlink&quot;&gt;&lt;code&gt;rel=&quot;shortlink&quot;&lt;/code&gt;&lt;/a&gt; now?—the final remaining things I'd like to see are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An more generalized scope for alternate URL choices asserted by publishers, not just URL shortening.  Other criteria beyond character length include ease of entry on mobile devices (eg. short, but also simple, maybe mostly numeric), ease of verbal mention (eg. billboards, postcards, etc).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HTTP headers are great where available—hooray for HEAD—but it still needs to be in the page for publishers who can't set custom headers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microformats are great, but I'd rather not parse a whole page to the footer to lift out the desired URLs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't panic. Have fun.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;And with that, I'm going to try coming up with other things to write about so this blog doesn't stay dormant.  The rest of this entry remains unedited below...&lt;/p&gt;

&lt;!--more--&gt;


&lt;hr /&gt;


&lt;p&gt;&lt;strike&gt;So, like it says up there: I like &lt;a href=&quot;http://revcanonical.appspot.com/&quot;&gt;rev=&quot;canonical&quot;&lt;/a&gt;.&lt;/strike&gt;&lt;/p&gt;

&lt;p&gt;Basically, it's a way of saying—instead of using that 3rd-party service &lt;em&gt;you&lt;/em&gt; like for munging &lt;em&gt;my&lt;/em&gt; URLs, use one of these pre-munged URLs I've provided.  Ideally, the URLs I provide will be shorter for your needs, but my URLs won't be subject to &lt;a href=&quot;http://joshua.schachter.org/2009/04/on-url-shorteners.html&quot;&gt;potentially distasteful things I object to with respect to a service you might pick&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I like keeping control of URL spaces in the hands of their publishers.  This also opens the field for more individual choice in URL shortening services, allowing more people to try their hand at building a better mouse trap—or allowing publishers to opt out of the mess altogether.&lt;/p&gt;

&lt;p&gt;And, apropos of that, I tend to like &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; as the means of expressing this choice.&lt;/p&gt;

&lt;p&gt;There's a lot more background on this whole shebang, but I'll just stick to my $0.02 on the discussion so far.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://www.25hoursaday.com/weblog/2009/04/11/revcanonicalDiggBarOutrageCausesBadIdeasToComeOutOfTheWoodWork.aspx&quot;&gt;It's too alpha geeky to get adopted—also: NERDS!&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Alpha geeks write plugins for web publishing systems used by less-alpha geeks, who eventually install web publishing systems for those even further down the geek scale.  It's not unheard of for something incredibly nerdy to become relatively common, if it proves useful.&lt;/p&gt;

&lt;p&gt;Feed auto-discovery is in blogging software and browsers now—it was once considered a somewhat arcane usage of the &lt;code&gt;rel&lt;/code&gt; attribute on &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tags in HTML &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://www.25hoursaday.com/weblog/2009/04/11/revcanonicalDiggBarOutrageCausesBadIdeasToComeOutOfTheWoodWork.aspx&quot;&gt;Everyone needs to implement their own URL shortener.&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;No, but everyone gets to pick a shortener for their own URLs—which could coincidentally be self-hosted or third-party.  Isn't the web great?&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://benramsey.com/archives/a-revcanonical-rebuttal/&quot;&gt;The &lt;code&gt;rev&lt;/code&gt; attribute is too hard to understand, people will get it wrong&lt;/a&gt;.&lt;/h3&gt;

&lt;p&gt;I hadn't paid much attention to the &lt;code&gt;rev&lt;/code&gt; attribute until a week or so ago.  I &lt;a href=&quot;http://www.w3.org/TR/html401/struct/links.html#adef-rev&quot;&gt;read the HTML spec on links&lt;/a&gt; again.  Within 10 minutes of reading the spec, my understanding became this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rel=&quot;{X}&quot;&lt;/code&gt; — &quot;this link means {X} in relation to the current page&quot;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rev=&quot;{X}&quot;&lt;/code&gt; — &quot;this current page means {X} in relation to this link&quot;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I may have misunderstood it—if so, explain to me how and I'll admit it's harder to understand than I think.  There are harder concepts in the HTML 4 spec.&lt;/p&gt;

&lt;h3&gt;The &lt;code&gt;rev&lt;/code&gt; attribute is removed in HTML5&lt;/h3&gt;

&lt;p&gt;That's too bad for HTML5.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2006-July/006888.html&quot;&gt;The rationale given for the removal&lt;/a&gt; seems sensible enough.  But, I'd say the rationale for removal is weakened if someone finds a use for the attribute and uses it correctly.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;rel=&quot;shorter&quot;&lt;/code&gt; / &lt;code&gt;rel=&quot;short&quot;&lt;/code&gt; is better and more explicit.&lt;/h3&gt;

&lt;p&gt;I like this idea in general, and I don't &lt;em&gt;really&lt;/em&gt; care strongly enough about &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; vs &lt;code&gt;rel=&quot;short&quot;&lt;/code&gt; to make much noise beyond this blog post.&lt;/p&gt;

&lt;p&gt;But, I prefer the semantics of &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt;, I don't think &lt;code&gt;rel=&quot;short(er)&quot;&lt;/code&gt; is better, and actually I think the less explicit assertion is a feature.  I've not yet been convinced otherwise—but realistically, if either catches on, I'll probably use the most popular.&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; doesn't mean &quot;shorter URL&quot;&lt;/h3&gt;

&lt;p&gt;That's okay—what if I don't &lt;em&gt;want&lt;/em&gt; you to have shortened versions of my URLs?  Doesn't fit in your tweet?  Screw you.  I didn't want you to link to me that badly anyway.  Bah.&lt;/p&gt;

&lt;p&gt;That, of course, is self-defeating.  Conventional use of the attribute will probably yield shorter URLs out of self-interest.  Furthermore, I could even offer a half-dozen URL variations, and you could use the string length function in the language of your choice to pick one on the basis of shortness.  There's a lot of choice to go around here.&lt;/p&gt;

&lt;p&gt;Also, feed auto-discovery links don't always lead to truly alternate versions of the current page—but instead to a useful set of items, many of which may currently appear somewhere on the page.  So, even the &quot;clear&quot; semantics have some play in them as used in the wild.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://shiflett.org/blog/2009/apr/a-rev-canonical-http-header&quot;&gt;A &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; HTTP header is better.&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Hmm, maybe.  It would certainly allow for possibly lighter-weight HEAD requests in determining the alternative URL for a given URL.  But, I would expect it to fall apart in collections of static HTML pages baked by an offline script where web server configuration might not make setting custom headers easy.&lt;/p&gt;

&lt;p&gt;Not everyone has the luxury / inclination to have a dynamic language capable of setting headers running in their web server.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://adactio.com/journal/1568/&quot;&gt;&lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; should appear on hyperlinks in the body of the page&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://decafbad.com/blog/2005/05/08/whats-old-scraping-is-new-again-microformats&quot;&gt;I like microformats&lt;/a&gt;, &lt;a href=&quot;http://decafbad.com/blog/2005/05/17/magic-microformat-forms&quot;&gt;in general&lt;/a&gt;.  But, I don't really want to potentially parse a whole page to find the shorter URL that might be in the footer.  With &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, I only have to parse so far before I find it or give up.&lt;/p&gt;

&lt;p&gt;There's a lot of prior art on this with relation to feed autodiscovery—we used to mainly look for RSS feed URLs inside the page, too.  It sucked.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://benramsey.com/archives/a-revcanonical-rebuttal/#comment-288465&quot;&gt;Claiming to be canonical for another URL is trouble.&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Okay, how about requiring a reciprocal &lt;code&gt;rel=&quot;canonical&quot;&lt;/code&gt; on the same page with &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Trust but verify—and only accept &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; where &lt;code&gt;rel=&quot;canonical&quot;&lt;/code&gt; matches the current URL &lt;em&gt;and&lt;/em&gt; &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; yields a 301 redirect to the &lt;code&gt;rel=&quot;canonical&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I can't see this verification process being necessarily more burdensome than using a 3rd-party shortener API—and that's &lt;em&gt;if&lt;/em&gt; you're paranoid and building an index that needs some measure of resistance to gaming.&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;http://samj.net/2009/04/revcanonical-considered-harmful.html?showComment=1239617160000#c7231589643969293690&quot;&gt;A single character slip from &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; to &lt;code&gt;rel=&quot;canonical&quot;&lt;/code&gt; could wreck your Googlejuice!&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;So, don't do that.&lt;/p&gt;

&lt;p&gt;Maybe Googlejuice should be more resilient.  Maybe it actually is—has anyone actually soured their juice yet with a mistake like this and lived to tell the tale?&lt;/p&gt;

&lt;p&gt;Either way, characters mean things in computer languages, so make sure you use the right ones in the right order.&lt;/p&gt;

&lt;h3&gt;You guys are moving on this stuff too fast!&lt;/h3&gt;

&lt;p&gt;Welcome to 2002, when lots of us had more spare time than employment and we deployed new crap like this on our blogs and sites daily.&lt;/p&gt;

&lt;p&gt;Back in those olden days, we manipulated raw HTML with our bare hands and deployed radioactive code using our teeth—all without benefit of protective change control.  We probably all have cancer of the access logs now, but it was all in the name of Web Science!&lt;/p&gt;

&lt;h3&gt;Too long; didn't read&lt;/h3&gt;

&lt;p&gt;So, yeah.  I like the idea behind &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; and I prefer its expression as &lt;code&gt;rev=&quot;canonical&quot;&lt;/code&gt; best—but the idea is the important thing.  Let's get over the expression part fast and spend more time exploring the nuts and bolts and implications of the concept itself.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091011&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://pigsonthewing.org.uk/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=4e160e713acf1ab8547d1c36233389c3&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://pigsonthewing.org.uk/&quot;&gt;http://pigsonthewing.org.uk/&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091011&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-13T14:00:04&quot;&gt;2009-04-13T14:00:04&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Forget rel=&quot;short&quot; or rel=&quot;shorter&quot;. Try rel=&quot;shortcut&quot;.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091013&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091013&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-13T14:22:53&quot;&gt;2009-04-13T14:22:53&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;...or I could try rev=&quot;canonical&quot; like I said up there.  An actual rationale might be more productive here.  :)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091015&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spindrop.us/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=35b8de09a3685277188d8b8be0e5e3ac&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spindrop.us/&quot;&gt;Dave Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091015&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-13T14:37:21&quot;&gt;2009-04-13T14:37:21&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;So yes, you are understanding &quot;rev&quot; correctly per the spec.  The problem I have is this:&lt;/p&gt;

&lt;p&gt;rel=canonical was introduced so when people went to various urls that a search engine would know that the url specified in rel=canonical was the real one.  Let's do this to make life easier:&lt;/p&gt;

&lt;p&gt;http://foo.com/A
and 
http://foo.com/B&lt;/p&gt;

&lt;p&gt;both go to the exact same page, and the publisher can't for some reason redirect to the canonicalized page (maybe it's amazon and they have stupid large urls with affiliate codes).&lt;/p&gt;

&lt;p&gt;so if the former is canonical then this is present:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;whether you go to /A or /B.&lt;/p&gt;

&lt;p&gt;if they use rev=&quot;canonical&quot;:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Should only be shown if they are visitng /A not /B otherwise that rev statement implies that /A or /B are the canonical forms of &quot;http://f.us/A&quot;.&lt;/p&gt;

&lt;p&gt;I think that's why the rev attribute isn't a very good one.  Honestly I liked the suggestion (you made it maybe) for using rel=&quot;shortcut alternative&quot; or something.&lt;/p&gt;

&lt;p&gt;Am I seeing potential ambiguity when there isn't?&lt;/p&gt;

&lt;p&gt;-d&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091016&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091016&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-13T15:36:42&quot;&gt;2009-04-13T15:36:42&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Dave: I think you may have used some markup in your comment that got filtered out - I'm not exactly sure what you mean. :/&lt;/p&gt;

&lt;p&gt;If we have this URL:&lt;/p&gt;

&lt;p&gt;http://example.com/this/url/is/too/long&lt;/p&gt;

&lt;p&gt;With these links in the head:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;rel=&quot;canonical&quot; href=&quot;http://example.com/this/url/is/too/long&quot;
  rev=&quot;canonical&quot; href=&quot;http://ex.pl/ab&quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then, the URL http://ex.pl/ab will ideally lead to a 301 redirect.  But, if not, it should have the same content as http://example.com/this/url/is/too/long — and therefore list the same reciprocal &quot;canonical&quot; relationship that leads back to the original page.&lt;/p&gt;

&lt;p&gt;That seems disambiguated to me—even more so than &lt;code&gt;rel=&quot;shorter&quot;&lt;/code&gt; or whatnot.  If the URL for a &lt;code&gt;rel=&quot;shorter&quot;&lt;/code&gt; link didn't yield a redirect, we'd never know what was the original page without a corresponding &lt;code&gt;rel=&quot;canonical&quot;&lt;/code&gt; anyway.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091017&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.jm3.net/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/jm3.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.jm3.net/&quot;&gt;John Manoogian III (jm3)&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091017&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-14T01:59:04&quot;&gt;2009-04-14T01:59:04&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;LOL at &quot;soured their juice.&quot; Well written and well reasoned as usual, Les.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091018&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://samj.net/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/samj.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://samj.net/&quot;&gt;samj&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091018&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-14T02:39:30&quot;&gt;2009-04-14T02:39:30&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I've comprehensively rebutted your argument &lt;a href=&quot;http://groups.google.com/group/shortlink/browse_thread/thread/885894c42cbdf8ad/d50be9d1c74bad7a?#d50be9d1c74bad7a&quot; rel=&quot;nofollow&quot;&gt;over there&lt;/a&gt; so I'm not going to do it again here, except to say that given you concede that rel=short* is just as good as rev=canonical, only it's a&amp;gt; not deprecated and b&amp;gt; cannot possibly make sites drop off the face of the Internet, why do you even care enough to write this blog post?&lt;/p&gt;

&lt;p&gt;Sam&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091020&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://samj.net/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/samj.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://samj.net/&quot;&gt;samj&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091020&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-14T02:42:35&quot;&gt;2009-04-14T02:42:35&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Oh, and let's not forget that you can only use this &quot;solution&quot; on the canonical URL itself since it implies that the page it is attached to is itself canonical. That means you're going to have to find another solution for a potentially infinite number of other links to the same content, or risk leaking google juice all over the place.&lt;/p&gt;

&lt;p&gt;Sam&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091023&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091023&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-14T03:51:48&quot;&gt;2009-04-14T03:51:48&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;blockquote&gt;
  &lt;p&gt;why do you even care enough to write this blog post?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because &lt;a href=&quot;http://xkcd.com/386/&quot; rel=&quot;nofollow&quot;&gt;someone is wrong on the Internet&lt;/a&gt;!  And I haven't blogged in awhile, so I needed an excuse.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091024&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spindrop.us/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=35b8de09a3685277188d8b8be0e5e3ac&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spindrop.us/&quot;&gt;Dave Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091024&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-14T04:15:57&quot;&gt;2009-04-14T04:15:57&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Les,&lt;/p&gt;

&lt;p&gt;I not good with words today.  I was trying to say what Sam said:&lt;/p&gt;

&lt;p&gt;&quot;this “solution” on the canonical URL itself since it implies that the page it is attached to is itself canonical&quot;&lt;/p&gt;

&lt;p&gt;Hence, I'd stick with a solution that uses rel - so long as we can just pick an attribute &quot;shorter alternative&quot; or whatever that we can agree on :)&lt;/p&gt;

&lt;p&gt;-d&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091026&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://erikvold.com/index.cfm&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=8fa21a16e24905fba4413501e3afb36e&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://erikvold.com/index.cfm&quot;&gt;Erik Vold&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091026&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-21T03:47:01&quot;&gt;2009-04-21T03:47:01&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Nice rebuttal to all of this rev=canonical opposition, but you gave in man wth?!&lt;/p&gt;

&lt;p&gt;Let me try to back you up a bit, maybe you'll agree with your gut again.&lt;/p&gt;

&lt;p&gt;First I must start with the removal of @rev in html 5. That was an amazingly dumb move, luckily it is a draft still is all I can say. Here is why I believe this:
1) 1 char diff argument: shut up you nub programmers
2) misuse: it's night vs day, black vs white, there is no gray area except that which your confused minds have created. The confusion -I think- usually comes in to play when considering a value, which is easy if you truly understand the diff between @rel and @rev.
3) @rev values can be represented as @rel values: sure I agree but this can not be true without adding more rel values then are necessary with a @rev which is already in the html 4 spec for a reason. If you remove something with use you cause confusion on multiple fronts: first people have to become aware of the change, then they need to understand why the change was made, then they need to make the changes to their code base, and finally when they want to express rev=canonical with a @rel value, debates over what best @rel value represents the equivalent of another @rel value if it were used in @rev occur..&lt;/p&gt;

&lt;p&gt;I submit the debate which the opposition to rev=canonical are having over rel=short* as evidence that @rev is required. A link with rev=canonical that is short is a short url of the canonical url by definition, thus rel=short* is redundant for the use case of discovering a short url for the canonical url of some document. Albeit, I think rel=shorturl (or whatever is finally decided on) could be used by the publisher to indicate a preferred short url(s), if say there were &amp;gt;1 rev=canonical.&lt;/p&gt;

&lt;p&gt;In an algorithm to discover a short url for a document one method could be to scan all links and find the shortest rev=canonical, or if a rel=shorturl is provided then use that and stop scanning immediately. My point is that rev=canonical should be used. Also rel=shorturl adds a marginal benefit to rev=canonical.&lt;/p&gt;

&lt;p&gt;Another point, a rel=shorturl is rev=canonical by definition, thus if you were to use rel=shorturl and @rev were alive and well as it should be, you should automatically add rev=canonical (even though it is implied).&lt;/p&gt;

&lt;p&gt;Another argument the opposition make to using rev=canonical is that the number of rev=canonical's are possibly infinite, so I say only list the rev=canonical's which a user may find of interest for the use cases you can imagine.&lt;/p&gt;

&lt;p&gt;Another case for using rev=canonical is using rev=canonical with rel=mobile perhaps? so that a user can scan rev=canonical's for a rel=mobile url which is short enough to fit in the newest microblog gadget. Where a rel=mobile without rev=canonical could be the mobile site's homepage, even better for this link would be rel=&quot;mobile home&quot; without rev=canonical.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091029&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://erikvold.com/index.cfm&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=8fa21a16e24905fba4413501e3afb36e&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://erikvold.com/index.cfm&quot;&gt;Erik Vold&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091029&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-21T05:17:14&quot;&gt;2009-04-21T05:17:14&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;The reasons why I like rev=canonical: http://erikvold.com/blog/index.cfm/2009/4/21/rev_canonical_good&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221091030&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221091030&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-28T05:31:35&quot;&gt;2009-04-28T05:31:35&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Erik: Well, I &quot;gave in&quot; mainly because I wasn't really looking for a fight and had a vacation to attend to.&lt;/p&gt;

&lt;p&gt;After that, the amount of hyperbolic stop energy being slung around rel=short{foo} has exhausted my care for the subject.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Enter the LizardFeeder</title>
        <link href="http://decafbad.com/blog/2009/01/06/enter-the-lizardfeeder"/>
        <updated>2009-01-06T00:01:54+00:00</updated>
        <id>http://decafbad.com/blog/2009/01/06/enter-the-lizardfeeder</id>
        <content type="html">&lt;p&gt;[caption id=&quot;attachment_1582&quot; align=&quot;alignright&quot; width=&quot;247&quot; caption=&quot;The Mozilla Tree&quot;]&lt;a href=&quot;http://blog.lizardwrangler.com/2008/07/29/the-mozilla-tree/&quot;&gt;&lt;img src=&quot;http://decafbad.com/blog/wp-content/uploads/2009/01/moz-tree.jpg&quot; alt=&quot;The Mozilla Tree&quot; title=&quot;moz-tree&quot; width=&quot;247&quot; height=&quot;191&quot; class=&quot;size-full wp-image-1582&quot; /&gt;&lt;/a&gt;[/caption]&lt;/p&gt;

&lt;p&gt;Behind Firefox is Mozilla, and behind Mozilla is a community.  And the Mozilla community acts a lot like an ecosystem, which can be visualized &lt;a href=&quot;http://blog.lizardwrangler.com/2008/07/29/the-mozilla-tree/&quot;&gt;as a kind of living tree&lt;/a&gt;—not to confused with the &lt;a href=&quot;https://developer.mozilla.org/en/mozilla-central&quot;&gt;mozilla-central tree&lt;/a&gt;.  Oh yeah, and Mozilla is the name of &lt;a href=&quot;http://www.mozilla.org/reorganization/&quot;&gt;both a Foundation and a Corporation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Confused yet?  If not, then we should talk so you can explain it to me, because it all looks pretty tangly and &lt;a href=&quot;http://en.wikipedia.org/wiki/Intertwingularity&quot;&gt;intertwingled&lt;/a&gt; to me.  Nonetheless, it seems to work, and produces a good chunk of my favorite software and technologies.&lt;/p&gt;

&lt;p&gt;There are many efforts to track what's going on—including &lt;a href=&quot;http://planet.mozilla.org/&quot;&gt;planets&lt;/a&gt; and &lt;a href=&quot;http://blog.mozilla.com/about_mozilla/&quot;&gt;newsletters&lt;/a&gt; and &lt;a href=&quot;https://bugzilla.mozilla.org/&quot;&gt;bugzillas&lt;/a&gt; and &lt;a href=&quot;https://wiki.mozilla.org/WeeklyUpdates/2009-01-05&quot;&gt;wikis&lt;/a&gt; and &lt;a href=&quot;http://hg.mozilla.org/&quot;&gt;repositories&lt;/a&gt; and &lt;a href=&quot;http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox&quot;&gt;tinderboxen&lt;/a&gt;.  Some of these resources report on, or are driven by, the activity occurring in the others.  Some are automated, and others are carefully stitched together by hand.  None offer a full picture of what's going on in the &lt;a href=&quot;http://ascher.ca/blog/2008/06/19/whats-mozillas-scope-what-should-it-be/&quot;&gt;Mozilla galaxy&lt;/a&gt; in a way that's casually comprehensible by a sane human being.&lt;/p&gt;

&lt;p&gt;Of course, that's not a slight against any of these sites or the people maintaining them—extracting an overview from such an organic phenomenon is neither easy nor straightforward.  But, it might be fun to try.&lt;/p&gt;

&lt;p&gt;As an infovore and avid practitioner of &lt;a href=&quot;http://decafbad.com/blog/2005/09/23/the-zen-of-firehose-drinking&quot;&gt;continuous partial attention&lt;/a&gt;, my first impulse is to reach for a firehose and stick my head into the stream.  Relax, defocus, and try to let my pattern recognizers do their thing—sometimes those pattern recognizers are in my head, and &lt;a href=&quot;http://decafbad.com/hgwebdir.cgi/hacking_rss_and_atom/file/f7a85b9fd48a/ch15_popular_links.py&quot;&gt;sometimes they're written in Python&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;[caption id=&quot;attachment_1585&quot; align=&quot;alignright&quot; width=&quot;225&quot; caption=&quot;Firefox Victory!&quot;]&lt;a href=&quot;http://www.flickr.com/photos/intothefuzz/2571283860/in/set-72157605179678562/&quot;&gt;&lt;img src=&quot;http://decafbad.com/blog/wp-content/uploads/2009/01/robo-225x300.jpg&quot; alt=&quot;Firefox Victory Robot&quot; title=&quot;firefox-victory&quot; width=&quot;225&quot; height=&quot;300&quot; class=&quot;size-medium wp-image-1585&quot; /&gt;&lt;/a&gt;[/caption]&lt;/p&gt;

&lt;p&gt;But, for Mozilla, I couldn't find a stream of sufficient volume or completeness to satisfy me or &lt;a href=&quot;http://www.digitpress.com/dpsoundz/destroyhimrobots.wav&quot;&gt;my robots&lt;/a&gt;.  Happily, though, my feeding urge found itself aligned with a project to discover the patterns of contribution in the Mozilla community and to find a way to thank the contributors responsible.&lt;/p&gt;

&lt;p&gt;So, while we're still working on the thank-you angle, allow me to introduce you to &lt;a href=&quot;http://feeds.mozilla.com/&quot;&gt;the Lizardfeeder&lt;/a&gt;.  The &lt;a href=&quot;http://feeds.mozilla.com/&quot;&gt;LizardFeeder&lt;/a&gt; is a feed aggregator, &lt;a href=&quot;https://svn.mozilla.org/projects/lizardfeeder/trunk/&quot;&gt;whose source code&lt;/a&gt; is built atop &lt;a href=&quot;http://www.intertwingly.net/code/venus/&quot;&gt;Sam Ruby's Planet Venus&lt;/a&gt;. The &lt;a href=&quot;http://feeds.mozilla.com/&quot;&gt;LizardFeeder&lt;/a&gt; pulls together and archives activity streams from a wide variety of Mozilla community sources.  Beyond the usual human-readable pages produced by a &lt;a href=&quot;http://planet.mozilla.org/&quot;&gt;blog-gathering Planet&lt;/a&gt;, the &lt;a href=&quot;http://feeds.mozilla.com/&quot;&gt;LizardFeeder&lt;/a&gt; accumulates &lt;a href=&quot;http://feeds.mozilla.com/archives/index.json&quot;&gt;statistical and historical data&lt;/a&gt; meant for consumption and analysis by robots.&lt;/p&gt;

&lt;p&gt;At present, the only robot navigating the &lt;a href=&quot;http://feeds.mozilla.com/&quot;&gt;LizardFeeder&lt;/a&gt; archives is an AJAX-ified user interface that animates the firehose as a near real-time or time-lapsed stream of events scrolling by.&lt;/p&gt;

&lt;p&gt;This is just meant as a conversation starter, though.  I'm hoping to &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=469838&quot;&gt;gather feedback and find more sources&lt;/a&gt;, as well as to entice creative community members to come up with more sophisticated visualizations of this data.&lt;/p&gt;

&lt;p&gt;So, take a look, &lt;a href=&quot;http://feeds.mozilla.com/&quot;&gt;check it out&lt;/a&gt;, and let me know what you think!&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083355&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=eb4ef8f72f933b04a27b118070ac538e&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;dria&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083355&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-01-06T01:26:18&quot;&gt;2009-01-06T01:26:18&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Is there a list of what sources are already being read by the LizardFeeder anywhere?  I scanned through the various links here but didn't see anything obvious :)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083356&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083356&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-01-06T01:37:15&quot;&gt;2009-01-06T01:37:15&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Yeah, that part could use some improvement.  There's a monster list here:&lt;/p&gt;

&lt;p&gt;http://feeds.mozilla.com/sources.opml&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083358&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://briks.si&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=315c86c9c01a5ced617aa58ef641902d&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://briks.si&quot;&gt;Brian King&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083358&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-01-06T10:11:46&quot;&gt;2009-01-06T10:11:46&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Excellent stuff. I was going to ask about access to the list of sources for each category, but Dria beat me to it.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083359&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083359&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-01-06T15:26:50&quot;&gt;2009-01-06T15:26:50&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Actually, it occurs to me that this config file might work as a more readable version of the list of sources:&lt;/p&gt;

&lt;p&gt;https://svn.mozilla.org/projects/lizardfeeder/trunk/conf/config.ini-dist&lt;/p&gt;

&lt;p&gt;There's also this, which is where most of the previous list came from: &lt;/p&gt;

&lt;p&gt;https://svn.mozilla.org/projects/lizardfeeder/trunk/conf/hg-feeds.opml-dist&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083360&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://ozten.myopenid.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=4021c2acfc5b98b6dfe2d0ec26432ce1&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://ozten.myopenid.com/&quot;&gt;Austin King&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083360&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-01-06T20:55:52&quot;&gt;2009-01-06T20:55:52&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Thanks for the background surrounding lizard feeder. Great post!&lt;/p&gt;

&lt;p&gt;+1 Dria and Brian&lt;/p&gt;

&lt;p&gt;Maybe make the title of the link to the OPML more descriptive than just &quot;Feeds&quot; and/or link to it in the body of the UI too and write something around it to encourage other's visualizations.&lt;/p&gt;

&lt;p&gt;Awesome work Les.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083361&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=a1c5374b594738e98be48f7f193443b3&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Sanjay Parekh&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083361&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-02-04T20:38:04&quot;&gt;2009-02-04T20:38:04&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Is the AJAX UI available anywhere for download?  I'd like to hack it for another use altogether.  Great visualization and great application.  Good job.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083362&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=7881dcee98d7df7e89939afd191c92ce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Deen Seth.&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083362&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-09-16T18:21:02&quot;&gt;2009-09-16T18:21:02&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;This is a very good idea.  Can we accomplish the same result using Yahoo Pipe?  Do you plan to add events from Bugzilla, and mailing list to the feed?&lt;/p&gt;

&lt;p&gt;I am more interested in development activities.  There aren't much in code category.&lt;/p&gt;

&lt;p&gt;I am interested in analyzing development related events.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>An unnecessary Template Attribute Language</title>
        <link href="http://decafbad.com/blog/2008/11/01/an-unnecessary-template-attribute-language"/>
        <updated>2008-11-01T19:23:23+00:00</updated>
        <id>http://decafbad.com/blog/2008/11/01/an-unnecessary-template-attribute-language</id>
        <content type="html">&lt;p&gt;A funny thing happened on the way to building &lt;a href=&quot;http://svn.mozilla.org/projects/lizardfeeder/trunk/&quot;&gt;a delayed real-time feed display&lt;/a&gt;:  I got temporarily obsessed with implementing &lt;a href=&quot;http://github.com/lmorchard/jquery-tal-template/tree/master&quot;&gt;a template language in JavaScript&lt;/a&gt; that, as it turned out later, I didn't need.  About &lt;a href=&quot;http://svn.mozilla.org/projects/lizardfeeder/trunk/&quot;&gt;the feed project itself&lt;/a&gt;, I hope to write more soon—but for now I want to get this extra template language thing out of my system and see if anyone else might have a use for it.&lt;/p&gt;

&lt;p&gt;See, I had a notion it would be keen if I had access to the same template language on the client as on the server.  I needed to render a number of list items statically on the server with feed entries, then update that list with new entries on the client as they became available through JSON feed polling.  It'd be a pain in the butt to maintain two separate list item templates for client and server, so I reached for a shared template language.&lt;/p&gt;

&lt;p&gt;Never mind that I'd just gotten done writing &lt;a href=&quot;http://www.amazon.com/gp/product/0470452021?ie=UTF8&amp;amp;tag=0xdecafbad01-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;c%0D%0Areative=9325&amp;amp;creativeASIN=0470452021&quot;&gt;a small book on Dojo&lt;/a&gt;, and was already aware of the existence of the &lt;a href=&quot;http://svn.dojotoolkit.org/src/dojox/trunk/dtl/README&quot;&gt;DojoX Django Template Language&lt;/a&gt;.  This might've worked, since the server end of things was written in Python (though not with Django).  That the JavaScript side already used &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt; wasn't &lt;em&gt;too&lt;/em&gt; tall a hurdle.  Also, I'm sure there are a handful of other JavaScript/Python template language match-ups to be found.&lt;/p&gt;

&lt;p&gt;But, let's be honest here:  I've always been a fan of Zope's &lt;a href=&quot;http://wiki.zope.org/ZPT/TALSpecification14&quot;&gt;Template Attribute Language&lt;/a&gt; for their &lt;a href=&quot;http://wiki.zope.org/ZPT/FrontPage&quot;&gt;Page Templates&lt;/a&gt;, and have long wondered how hard it would be to implement.  The concept seems so much cleaner to me than most string-formatting template languages, and the workflow from mockup-to-template and back again has always been appealing to me when it works.  So, when my first few experimental steps in trying my hand at it actually started working, I couldn't stop coding.&lt;/p&gt;

&lt;p&gt;And now, &lt;a href=&quot;http://github.com/lmorchard/jquery-tal-template/tree/master/jquery.taltemplate.js&quot;&gt;the thing&lt;/a&gt; is mostly done.  It has no tests, has features left undone, and probably yields plenty of bugs—but I finished it enough to use it practically, and that was long enough to convince me it wasn't the right tool for the job.&lt;/p&gt;

&lt;p&gt;Still, though, I can't help thinking it might be the right tool for &lt;em&gt;some&lt;/em&gt; job.  That could be because I spent a lot of time on it, or that I'm unreasonably fond of &lt;a href=&quot;http://wiki.zope.org/ZPT/TALSpecification14&quot;&gt;TAL&lt;/a&gt;, but it still feels like a decent little plugin to have on hand.  Maybe someone reading this will have a similar conclusion.&lt;/p&gt;

&lt;p&gt;Oh and by the way, plain &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt; turned out to be a better tool for &lt;a href=&quot;http://svn.mozilla.org/projects/lizardfeeder/trunk/&quot;&gt;the job in question&lt;/a&gt;.  This seems to nicely balance the duplicate effort between server and client, demanding only that I stick with semantically significant CSS class names in the server template—something I should be doing anyway:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;        // Clone and populate a new entry.
        var new_item = $('#feed-items .entry:last')
            .clone()
            .attr('class', entry_classes.join(' ')) 
            .find('.group span')
                .text(tags['group'])
            .end()
            .find('.title')
                .find('.favicon')
                    .attr('src', favicon)
                .end()
                .find('.link')
                    .attr('href', entry.link)
                    .text(entry.title)
                .end()
            .end()
            .find('.updated')
                .find('.timeago')
                    .attr('title', entry.updated)
                    .text(entry_updated.strftime('%+'))
                    .timeago()
                .end()
                .find('.time')
                    .text(entry_updated.strftime('%I:%M %p'))
                .end()
            .end()
            .find('.author')
                .text(entry.author || 'n/a')
            .end()
            .prependTo('#feed-items')
            .hide();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, &lt;em&gt;plain&lt;/em&gt; is a relative term here.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083366&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3f398029eea744ce9ba9147aab627557&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;brad clements&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083366&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-11-03T21:26:42&quot;&gt;2008-11-03T21:26:42&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Groan,&lt;/p&gt;

&lt;p&gt;Too bad I haven't had a chance to finish documenting (and tweaking) the ATALi project.&lt;/p&gt;

&lt;p&gt;It's a collection of Alternative TAL Implementations.&lt;/p&gt;

&lt;p&gt;It currently has TAL for xslt (server side using libxslt directly or via lxml with metal support)&lt;/p&gt;

&lt;p&gt;and TAL for javascript (no libraries needed, though it does recognize mochikit iterators, no metal)&lt;/p&gt;

&lt;p&gt;https://launchpad.net/atali&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083367&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.jm3.net/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/jm3.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.jm3.net/&quot;&gt;John Manoogian III (jm3)&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083367&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-11-24T18:51:17&quot;&gt;2008-11-24T18:51:17&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Have you seen &quot;trimpath&quot;?&lt;/p&gt;

&lt;p&gt;http://code.google.com/p/trimpath/wiki/JavaScriptTemplates&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Jelly Stains and Web Masons</title>
        <link href="http://decafbad.com/blog/2008/10/29/jelly-stains-and-web-masons"/>
        <updated>2008-10-29T14:42:23+00:00</updated>
        <id>http://decafbad.com/blog/2008/10/29/jelly-stains-and-web-masons</id>
        <content type="html">&lt;p&gt;From Mark Bernstein's entry on &lt;a href=&quot;http://www.markbernstein.org/Oct0801/PracticalPrototypeandscrip.html&quot;&gt;Practical Prototype and script.aculo.us&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;When chemists consult a volume about professional chemical technique, or when surgeons reach for the latest update on neuroanatomy, they can usually find a book that isn't couched in terms of silly examples and jokes. So can poets, mathematicians, and geologists. For some reason, though, it has become the accepted practice that language manuals should spend lots of time with silly, self-deprecating jokes, and that their example applications should be breakfast loggers and fantasy football leagues (or, conversely, payroll programs).&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;As an tech author with just a few books under my belt, Mark's take on &lt;a href=&quot;http://www.amazon.com/gp/product/1590599195?ie=UTF8&amp;amp;tag=0xdecafbad-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1590599195&quot;&gt;Practical Prototype and script.aculo.us&lt;/a&gt; struck a bit of a sour note for me, because I'd like to work on making my tech writing more entertaining than not.  I think that's a good thing, but I'm willing to be convinced otherwise.&lt;/p&gt;

&lt;p&gt;I think the issue is that there are different meanings for &quot;professional&quot; when it comes to the web.  There are web scientists and there are web masons.  Web scientists pursue fundamentals and disambiguations, while web masons are busy building the next micro-site for the new product release from the almighty client.  Many web scientists are also computer scientists and many web masons are also web scientists—but most web masons I've known come from creative liberal or fine arts backgrounds.&lt;/p&gt;

&lt;p&gt;Though, for what it's worth, even amongst computer scientists there's still a tradition of &lt;a href=&quot;http://www.amazon.com/Little-Schemer-Daniel-P-Friedman/dp/0262560992/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1225292376&amp;amp;sr=8-1&quot;&gt;leaving room for jelly stains&lt;/a&gt; and other oddities.  This seems to be the sort of thing Mark acknowledges with dismay.  (&quot;It’s not fair to blame Mr. DuPont for the general vice.&quot;)&lt;/p&gt;

&lt;p&gt;Is playfulness in literature just a computer science thing?  I'm not a chemist; maybe chemists just  don't like being funny in writing, or maybe their jokes are more subtle.&lt;/p&gt;

&lt;p&gt;In any case, I think the &quot;practical&quot; genre of tech books is aimed at people who want to get something done, aren't interested in or have little time for context or background, yet wouldn't mind being entertained during the course of weekend tinkering and self-education.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;So, a good book. But take out the jokes, trim back the sample code (or dispatch it to the Web site where it makes more sense), and give us to professional perspective, and everyone is going to be much happier.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The guidelines with which I'm familiar for tech books in the &quot;practical&quot; or similar genres include advice such as &quot;show, don't tell&quot;.  They also suggest that, although sample code should be made available online, the author should compose the book assuming that it's a standalone product.  Web sites and CDROMs with code often vanish, but a bound book remains stable—which is especially useful on a cross-country flight without net access.  Professional perspective is of course a desirable thing to work into the prose, but job #1 is to illustrate the right way to do things through running code.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;How does Prototype+Javascript relate to other languages — C++/STL, say, or SELF? What, precisely, are the semantics of the key methods? I don't need the inevitable chapter 1 pitch for the wonderfulness of Javascript and the badness of MSIE, but it might be a good place for a quick summary for the pros. Call by reference • no pointers • primitives are objects • everything has a prototype slot • parens() do this, braces {} do that, brackets [] do something else • single and double quotes are different. Kernighan &amp;amp; Ritchie did this so well in C, and it’s not like we’re not familiar with their example.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I'd posit that most in the audience for &quot;practical&quot; tech books are entirely unfamiliar with Kernigan &amp;amp; Ritchie and haven't touched a line of C source code.  Most of these readers have probably tumbled down the slope from HTML to CSS and finally to JavaScript in order to get something interesting to happen in a browser—and usually while under an unreasonable deadline.&lt;/p&gt;

&lt;p&gt;I'd really be surprised if many readers have heard of &lt;a href=&quot;http://en.wikipedia.org/wiki/Self_programming_language&quot;&gt;Self&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/Standard_Template_Library&quot;&gt;C++/STL&lt;/a&gt; or have much of a grounding at all in computer science or programming language fundamentals.  Having these fundamentals would of course help web masons get a deeper understanding of the technologies that make the job possible, but the pragmatic rewards tend not to make up for the effort involved.&lt;/p&gt;

&lt;p&gt;So, to sum up, the purpose for this entry isn't to beat up on Mark Bernstein.  He's written a great deal of prose and code that I respect, so his opinion is interesting to me.  Rather, I've tried to express my own understanding of this writing market, and hoping I've aimed at the right goals.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086683&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.markbernstein.org/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=cdb20bf8e09680028612532944833686&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.markbernstein.org/&quot;&gt;Mark Bernstein&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086683&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-29T16:51:59&quot;&gt;2008-10-29T16:51:59&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I'd settle for a better class of joke!&lt;/p&gt;

&lt;p&gt;On tech content, doesn't it annoy &lt;em&gt;you&lt;/em&gt; that it's hard (or impossible) to find a book about a Web framework or language or facility that takes advantage of what you already know?  One that doesn't assume you've never seen a language before?  &lt;/p&gt;

&lt;p&gt;I understand that publishers want the book to appeal to everyone.  But it's not that the reader needs to know Kernighan: &lt;em&gt;you&lt;/em&gt; know, right?  So you know that it's entirely practical to tell a colleague pretty much everything she needs to know about a (famously tricky) new language in one chapter, starting from Kernighan's example 1 -- the original &quot;Hello, world&quot;.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086685&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://plasmasturm.org/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=e17949267bbfe21a0fadf1bbf00592b4&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://plasmasturm.org/&quot;&gt;Aristotle Pagaltzis&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086685&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-29T20:28:27&quot;&gt;2008-10-29T20:28:27&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I think part of the difference is in the subjects themselves. Programming deals with pure thought stuff, yet at the same time attempts to model concepts from the physical reality. In contrast, science textbooks deal with intrinsically tangible stuff, while mathematics textbooks deal with the abstract for abstraction’s sake. The temptation to offset the potential dullness of pure thought stuff by using it to model goofy examples is obviously high.&lt;/p&gt;

&lt;p&gt;Corroborating my theory would be the fact that elementary, low-abstraction maths books tend to bring up oddball examples too – eg. consider the sorts of things used to illustrate the rule of proportion.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086686&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spindrop.us/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=efe33dc2c55f641837501293866f7dc5&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spindrop.us/&quot;&gt;Dave Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086686&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-30T00:53:54&quot;&gt;2008-10-30T00:53:54&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Most books about web technology are meant to have a shelf life of a few years.  They aren't reference guides, and they aren't meant to stand the test of time.&lt;/p&gt;

&lt;p&gt;PHP, Python, Prototype, etc will all change.&lt;/p&gt;

&lt;p&gt;Because of this, they can employ jokes and real-world examples.  Jokes make reading the content enjoyable.  Examples are step by step instructions to creating something useful.&lt;/p&gt;

&lt;p&gt;If those aren't needed there's always reference guides.&lt;/p&gt;

&lt;p&gt;I don't publish books, but I do write tutorials on my blog on occasion.  One pattern I employ in my blog the &quot;executive summary&quot; pattern.  I start with the take-away, the code snippet, the answer if you will.  Then I spend the rest of the post (behind the fold, if you will) explaining the answer and interjecting my style.&lt;/p&gt;

&lt;p&gt;I like doing this, because it's what I would want.  I want to know the answer, and then I can read on for some backstory... rather than having to separate the wheat from the chaff.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086688&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://andrewdupont.net/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=fede7405a0e4cd5722e0b85920a0728c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://andrewdupont.net/&quot;&gt;Andrew Dupont&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086688&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-31T03:30:21&quot;&gt;2008-10-31T03:30:21&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I'm quite familiar with the trend Mark's talking about. And I agree that it shouldn't count against me or my book, but perhaps I'm a bit biased there.&lt;/p&gt;

&lt;p&gt;Three things.&lt;/p&gt;

&lt;p&gt;First: my book reads the way it reads because that's how I write. The process of writing the thing was torturous enough that I doubt I'd have finished it if I subjected every word to the scrutiny of a hypothetical skeptical reader. I'm not good enough at the craft for that. I think that each author has to find his best angle on the material and write that way. Because there are many books and many publishers, it &lt;em&gt;tends&lt;/em&gt; to balance out.&lt;/p&gt;

&lt;p&gt;Second: my book covers two JavaScript frameworks built to simplify common tasks. Basic familiarity with JavaScript is assumed. Right away that's a step away from the theoretical and toward the practical. I think tech books are best when they stick to one or the other, rather than try to drift between them.&lt;/p&gt;

&lt;p&gt;Third: the book Mark wants has already been written: &lt;cite&gt;JavaScript: The Good Parts&lt;/cite&gt;, by Doug Crockford. Doug's style is dry and academic, but also direct and substantive. If I tried to write in that style it'd be only a pale imitation.&lt;/p&gt;

&lt;p&gt;Anyway... the &quot;quirky&quot; trend, I agree, can be tiring. As it applies to my book, the sticking point seems to be whether I'm &lt;em&gt;actually funny&lt;/em&gt;. Readers of this weblog will simply have to buy the book to find out. It's several hundred pages long and has a fresh, earthy &quot;new book&quot; smell.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086691&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086691&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-31T03:47:37&quot;&gt;2008-10-31T03:47:37&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Mark: Yeah, these days my first impulse is not to reach for the latest book on a new technology like a web framework or new language.  I usually head straight for the source code or start soaking in whatever documentation may be lying around on the web.&lt;/p&gt;

&lt;p&gt;I suppose I could be a macho geek and say that's why I'm writing the books now—but to be honest I don't tend to get much out of practical programming books.  They seem to sell, though, so I keep wondering if mine shouldn't be lighter or more fun, should I get the opportunity to produce more of them.&lt;/p&gt;

&lt;p&gt;My first book was about half-and-half prose and code, with barely any screen shots to be found.  I got to about equal parts code, prose, and screen grabs in my second—I thought that might make it easier reading.  &lt;/p&gt;

&lt;p&gt;The latest one doesn't have any jokes, but I tried to get straight to the core framework features and spotlight a few obscure magical bits.  I worry if it might be a bit too dry.&lt;/p&gt;

&lt;p&gt;But yeah, I do wish there were more (though maybe shorter) books that started from the assumption that I've got a CS degree and have tangled with a few languages and libraries so far.  On the other hand, I do like having a sense for the author in a book—but that might be thanks to the fact that I read more blogs than books these days and enjoy the personal touches.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086692&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086692&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-31T04:05:01&quot;&gt;2008-10-31T04:05:01&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Andrew: Hey, thanks for dropping in for a comment!  I can completely sympathize with needing to find a groove to handle how grueling producing one of these books can be—especially if you're more programmer than writer.  (That's me, right now, anyway.)  You need to get the best thing out there in the shortest amount of time, and find a way to get yourself to finish it.&lt;/p&gt;

&lt;p&gt;At any rate, congrats on the new book, and I hope the cross-blog chatter sells a few more copies for you!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Writing a Delicious command for Ubiquity</title>
        <link href="http://decafbad.com/blog/2008/09/01/writing-a-delicious-command-for-ubiquity"/>
        <updated>2008-09-01T04:37:03+00:00</updated>
        <id>http://decafbad.com/blog/2008/09/01/writing-a-delicious-command-for-ubiquity</id>
        <content type="html">&lt;p&gt;In my &lt;a href=&quot;http://decafbad.com/blog/2008/08/31/ubiquity-cracks-open-personal-mashup-tinkering&quot; title=&quot;Ubiquity cracks open personal mashup tinkering&quot;&gt;last post&lt;/a&gt;, I got all fluffy about how cool &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; is but didn't share any code to prove the point.  As it happens, I have come up with at least one useful command that I'm starting to use habitually in posting bookmarks to Delicious.  You can &lt;a href=&quot;http://decafbad.com/UbiquityCommands/&quot;&gt;subscribe to my command&lt;/a&gt; or &lt;a href=&quot;http://decafbad.com/hg/UbiquityCommands/file/tip/delicious.ubiq.js&quot;&gt;check out the full source&lt;/a&gt;—this post will serve as a dissection of the thing.  Since this will be fairly lengthy, follow along after the jump.&lt;/p&gt;

&lt;p&gt;Oh, and it's been awhile since I posted something this in-depth around here, so feel free to let me know how this first draft works.  And, bug reports and patches are of course welcome.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;To begin, consider the following code starting off the command source code:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;1&quot;&gt;
/**
 * share-on-delicious - an Ubiquity command for sharing bookmarks on
 * delicious.com
 *
 * l.m.orchard@pobox.com
 * http://decafbad.com/
 * Share and Enjoy!
 */
var uext = Application.extensions.get('ubiquity@labs.mozilla.com');

var cookie_mgr = Components.classes[&quot;@mozilla.org/cookiemanager;1&quot;]
    .getService(Components.interfaces.nsICookieManager);
&lt;/pre&gt;


&lt;p&gt;The first thing to note here is that a short header comment introduces the command.  This isn't required, but it's a good idea.  It's also something you can't really do with bookmarklets.  On the other hand, Greasemonkey user scripts expect metadata about the script to be provided here, but Ubiquity doesn't use this convention.&lt;/p&gt;

&lt;p&gt;Second, notice that the code accesses some chrome-level resources.  Again, this is something unavailable to bookmarklets and Greasemonkey user scripts.  Just take a look at the &lt;a href=&quot;http://developer.mozilla.org/en/FUEL&quot;&gt;FUEL library documentation&lt;/a&gt; to get a quick sense of what's available using that simplified API, not to mention what's available using the lower-level browser APIs.&lt;/p&gt;

&lt;p&gt;Now, check out this next chunk of code, which begins the construction of an Ubiquity command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;13&quot;&gt;
CmdUtils.CreateCommand({
    
    name:        
        'share-on-delicious',
    icon:
        'http://delicious.com/favicon.ico',
    description: 
        'Share the current page as a bookmark on delicious.com',
    help:        
        'Select text on the page to use as notes, or enter your own ' + 
        'text after the command word.  You can also assign tags to the '+ 
        'bookmark with the &quot;tagged&quot; modifier, and alter the bookmark ' + 
        'default page title with the &quot;entitled&quot; modifier.  Note that ' + 
        'you must also already be logged in at delicious.com to use ' +
        'this command.',

    homepage:   
        'http://decafbad.com',
    author: { 
        name: 'Leslie Michael Orchard', 
        email: 'l.m.orchard@pobox.com' 
    },
    license:
        'MPL/GPL/LGPL',
&lt;/pre&gt;


&lt;p&gt;Whereas Greasemonkey scripts support metadata in the header comment, the Ubiquity command script API works a little differently.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/chrome/content/cmdutils.js&quot;&gt;&lt;code&gt;CmdUtils&lt;/code&gt; module&lt;/a&gt; provided by Ubiquity offers a &lt;code&gt;CreateCommand&lt;/code&gt; function, which expects an object as a parameter.  The object literal whose construction is begun in the code above serves as a self-contained package for the command, bearing metadata describing the command as well as containing all the code necessary to implement it.&lt;/p&gt;

&lt;p&gt;So, in the above code block, you can see the machine-readable description of the command—including a command name, display icon, home page URL, author information, and license.  The command name (&lt;code&gt;share-on-delicious&lt;/code&gt;) will be used by the Ubiquity command parser, but the rest of the description will also be used in the list of commands available to the user, invoked by the &lt;code&gt;command-list&lt;/code&gt; command, like so:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/2008/ubiq-share-on-delicious-list.jpg&quot; style=&quot;border: 1px solid #333; margin: 0.25em; padding: 0.25em&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Moving along, this next chunk of code introduces the first functional bits of the command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;37&quot;&gt;
    takes: { notes: noun_arb_text },
    modifiers: { 
        tagged:  noun_arb_text,
        entitled: noun_arb_text
    },
&lt;/pre&gt;


&lt;p&gt;Like smart keyword shortcut bookmarks, Ubiquity commands accept user-supplied input.  But, what's unique to Ubiquity is that it employs a parser whose goal is to support something approximating natural language.  At present, this results in commands that support a single primary argument—declared above with the &lt;code&gt;takes&lt;/code&gt; property—and any number of additional keyword modifiers—declared above by the &lt;code&gt;modifiers&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;For the command under construction here, this establishes a pattern something like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;share-on-delicious {notes} [tagged {tags} entitled {title}]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Content for the &lt;code&gt;{notes}&lt;/code&gt; argument can either be typed directly by hand, or it can be supplied by text highlighted on the page.  To use highlighted text, you can either issue the command alone, or use the word &lt;code&gt;this&lt;/code&gt; for the &lt;code&gt;{notes}&lt;/code&gt; argument before including further modifiers.&lt;/p&gt;

&lt;p&gt;The modifiers &lt;code&gt;tagged&lt;/code&gt; and &lt;code&gt;entitled&lt;/code&gt; are optional, and can be used in any order.  Each of these keywords signifies the start of a different argument—which unfortunately can collide with the literal data supplied for notes, which will hopefully be a rare occurrence.&lt;/p&gt;

&lt;p&gt;All of this adds up command invocations including the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;share-on-delicious
share-on-delicious I really like this page tagged nifty amusing
share-on-delicious this entitled This bookmark has no tags
sh this tagged osx software apple entitled This is good OS X software
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That last example is important—since I have no other commands starting with &quot;&lt;code&gt;sh&lt;/code&gt;&quot;, I can abbreviate the full command.  Ubiquity only requires enough of a command name to disambiguate it within your collection of commands.&lt;/p&gt;

&lt;p&gt;Another thing to note is the use of the constant value &lt;code&gt;noun_arb_text&lt;/code&gt;, which declares that these arguments should expect any arbitrary text as input.&lt;/p&gt;

&lt;p&gt;This facility is not exploited for the present command, but Ubiquity defines &lt;a href=&quot;http://hg.toolness.com/ubiquity-firefox/file/tip/ubiquity/chrome/content/nlparser/en/nountypes.js&quot;&gt;noun types&lt;/a&gt;.  These include concepts such as plain text, dates, address book contacts, browser tabs, bookmark tags, and more.  You can define your own noun types, as well as implement suggestion schemes that help guide the user toward constructing useful input values in the command interface.  You can &lt;a href=&quot;https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial#Introduction_to_Noun_Types&quot;&gt;read more about this&lt;/a&gt; in the official author tutorial.&lt;/p&gt;

&lt;p&gt;Next up is a quick bit of command-specific configuration:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;42&quot;&gt;
    /**
     * Command configuration settings.
     */
    _config: {
        // Base URL for the delicious v1 API
        api_base:      'https://api.del.icio.us',

        // Domain and name of the delicious login session cookie.
        cookie_domain: '.delicious.com',
        cookie_name:   '_user'
    },
&lt;/pre&gt;


&lt;p&gt;Since this command will be posting to Delicious via the V1 API, it's handy to declare the base URL for the API in an easily changed spot.  That way, you could change this value later on to point the command at another implementation of the API.&lt;/p&gt;

&lt;p&gt;Additionally, this command will employ a little-known authentication trick supported by the Delicious API that accepts the user's login cookie set by the Delicious website—this &quot;cookie god&quot; auth is used by the official Delicious addon for Firefox.  It's handy for piggybacking on the website login and removing the need to ask the user for their username and password again and possibly storing it in an insecure manner.&lt;/p&gt;

&lt;p&gt;In fact, this next chunk of code defines a utility method to rummage through the cookie jar:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;53&quot;&gt;
    /**
     * Dig up the Delicious login session cookie.
     */
    _getUserCookie: function() {
        var iter = cookie_mgr.enumerator;
        while (iter.hasMoreElements()) {
            var cookie = iter.getNext();
            if( cookie instanceof Components.interfaces.nsICookie &amp;&amp; 
                cookie.host.indexOf(this._config.cookie_domain) != -1 &amp;&amp; 
                cookie.name == this._config.cookie_name) {
                return decodeURIComponent(cookie.value);
            }
        }
    },
&lt;/pre&gt;


&lt;p&gt;The method defined above, &lt;code&gt;._getUserCookie()&lt;/code&gt;, uses the browser's cookie manager and the values defined in the previous configuration section to find the login session cookie set for Delicious.  Take note that this is far beyond the allowed capabilities of bookmarklets and Greasemoney user scripts—this is digging straight into the browser itself, skipping past the usual content-space security restrictions.&lt;/p&gt;

&lt;p&gt;In other words: In Ubiquity, &lt;em&gt;the gun is loaded&lt;/em&gt; and you should be careful.&lt;/p&gt;

&lt;p&gt;Moving along, consider this next utility method:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;67&quot;&gt;
    /**
     * Given input data and modifiers, attempt to assemble data necessary to
     * post a bookmark.
     */
    _extractBookmarkData: function(input_obj, mods) {
        return {
            _user:
                this._getUserCookie(),
            url:
                context.focusedWindow.location,
            description:
                mods.entitled.text || context.focusedWindow.document.title,
            extended: 
                input_obj.text,
            tags:
                mods.tagged.text
        };
    },
&lt;/pre&gt;


&lt;p&gt;Named &lt;code&gt;._extractBookmarkData()&lt;/code&gt;, this utility method accepts the results of Ubiquity's parser interpreting the primary argument and modifier arguments supplied by the user.  Using these data structures, it attempts to build a structure representing the fields of a Delicious bookmark.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;_user&lt;/code&gt; field is used for authentication via the site login cookie.  The &lt;code&gt;url&lt;/code&gt; is set from the location bar of the current page.  The &lt;code&gt;description&lt;/code&gt;, or title, field of the bookmark is taken from either the &lt;code&gt;entitled&lt;/code&gt; modifier or the title of the current page.  The &lt;code&gt;tags&lt;/code&gt;, if any, come from the &lt;code&gt;tagged&lt;/code&gt; modifier.  And, finally, the &lt;code&gt;extended&lt;/code&gt; notes for the bookmark are taken from the primary input argument of the command.&lt;/p&gt;

&lt;p&gt;As you'll see shortly, this utility method will be used in both the preview and the execution of the command.&lt;/p&gt;

&lt;p&gt;Next, there's one more utility method to cover:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;85&quot;&gt;
    /**
     * Given an object, build a URL query string
     */
    _buildQueryString: function(data) {
        var qs = [];
        for (k in data) if (data[k]) 
            qs.push( encodeURIComponent(k) + '=' + 
                encodeURIComponent(data[k]) );
        return qs.join('&amp;');
    },
&lt;/pre&gt;


&lt;p&gt;In anticipation of using the Delicious V1 API, the &lt;code&gt;._buildQueryString()&lt;/code&gt; method accepts an object and constructs a URL query string from the encoded properties of the object.  This will be paired with the &lt;code&gt;._extractBookmarkData()&lt;/code&gt; method to supply data for API calls.&lt;/p&gt;

&lt;p&gt;Moving along, it's time to start digging into the meat of this Ubiquity command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;95&quot;&gt;
    /**
     * Present a preview of the bookmark under construction during the course
     * of composing the command.
     */
    preview: function(pblock, input_obj, mods) {

        var bm          = this._extractBookmarkData(input_obj, mods);
        var user_cookie = this._getUserCookie();
        var user_name   = (user_cookie) ? user_cookie.split(' ')[0] : '';

        var ns = { user_name: user_name, bm: bm };
        var tmpl;
&lt;/pre&gt;


&lt;p&gt;With this code, the implementation of command method &lt;code&gt;.preview()&lt;/code&gt; has begun.  This method is used by Ubiquity to generate a live preview of the command.  Called with a DOM node (&lt;code&gt;pblock&lt;/code&gt;) and partially completed command input (&lt;code&gt;input_obj&lt;/code&gt; and &lt;code&gt;mods&lt;/code&gt;), this method is expected to build a representation of the command's results in the DOM node.  As the user types, this method will be called over and over again, ideally offering feedback as the user composes a command.&lt;/p&gt;

&lt;p&gt;Continuing on, consider this next chunk of code checking the validity of command input:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;107&quot;&gt;
        if (!user_name) {

            // If there's no user name, there's no login, so this command won't work. 
            tmpl = [ 
                '&lt;p style=&quot;color: #d44&quot;&gt;No active user found - log in at ', 
                '&lt;img src=&quot;http://delicious.com/favicon.ico&quot;&gt; ',
                '&lt;b&gt;&lt;a style=&quot;color: #3774D0&quot; href=&quot;http://delicious.com&quot;&gt;delicious.com&lt;/a&gt;&lt;/b&gt; ', 
                'to use this command.&lt;/p&gt;'
            ].join('');

        } else if (!bm.description) {

            // If there's no title, then this is an error too.
            tmpl = [ 
                '&lt;p style=&quot;color: #d44&quot;&gt;A title is required for bookmarks on ', 
                '&lt;img src=&quot;http://delicious.com/favicon.ico&quot;&gt; ',
                '&lt;b&gt;&lt;a style=&quot;color: #3774D0&quot; href=&quot;http://delicious.com&quot;&gt;delicious.com&lt;/a&gt;&lt;/b&gt; ', 
                '&lt;/p&gt;'
            ].join('');
&lt;/pre&gt;


&lt;p&gt;This chunk of code first checks for a user name, which can be extracted from a valid Delicious login cookie, if one was found.  If not found, the command will fail—so the preview built here will instruct the user to login at Delicious before going further.&lt;/p&gt;

&lt;p&gt;The second precondition for using the command is that the bookmark has been given a title.  By default, this is the title of the current page—but, some pages don't offer titles.  So, an error needs to be flagged if the user hasn't manually supplied a title in this case.&lt;/p&gt;

&lt;p&gt;Finally, notice in both of these error cases, a string of HTML is composed in the variable &lt;code&gt;tmpl&lt;/code&gt;.  This will be used at the end of the method to populate the DOM node passed in as &lt;code&gt;pblock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, assuming that all the command's prerequisites have been met, it's time to try constructing a proper preview for the results of this command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;126&quot;&gt;
        } else {

            // Attempt to construct a vaguely delicious-esque preview of a bookmark.
            tmpl = [ 
                '&lt;style type=&quot;text/css&quot;&gt;',
                    '.preview a { color: #3774D0 }',
                    '.del-bookmark { font: 12px arial; color: #ddd; background: #eee; line-height: 1.25em }',
                    '.del-bookmark a.title { color: #1259C7 }',
                    '.del-bookmark .full-url { color: #396C9B; font-size: 12px; display: block; padding: 0.25em 0 }',
                    '.del-bookmark .notes { color: #4D4D4D }',
                    '.del-bookmark .tags { color: #787878; padding-top: 0.25em; text-align: right }',
                '&lt;/style&gt;',
                '&lt;div class=&quot;preview&quot;&gt;',
                    '&lt;p&gt;Share a bookmark at &lt;img src=&quot;http://delicious.com/favicon.ico&quot;&gt; ',
                        '&lt;b&gt;&lt;a href=&quot;http://delicious.com/${user_name}&quot;&gt;delicious.com/${user_name}&lt;/a&gt;&lt;/b&gt;:&lt;/p&gt;',
                    '&lt;div class=&quot;del-bookmark&quot;&gt;',
                        '&lt;div style=&quot;padding: 1em;&quot;&gt;',
                        '&lt;a class=&quot;title&quot; href=&quot;${bm.url}&quot;&gt;${bm.description}&lt;/a&gt;',
                        '&lt;a class=&quot;full-url&quot; href=&quot;${bm.url}&quot;&gt;${bm.url}&lt;/a&gt;',
                        bm.extended ? 
                            '&lt;div class=&quot;notes&quot;&gt;${bm.extended}&lt;/div&gt;' : '',
                        bm.tags ?
                            '&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;tags:&lt;/span&gt; ${bm.tags}&lt;/div&gt;' : '',
                    '&lt;/div&gt;',
                '&lt;/div&gt;'
            ].join(&quot;\n&quot;);

        }

        pblock.innerHTML = CmdUtils.renderTemplate(tmpl, ns);
    },
&lt;/pre&gt;


&lt;p&gt;Building on the notion that previews are built in a DOM node, the code above uses both CSS and HTML to assemble a quick-and-dirty facsimile of a Delicious bookmark—which will be rendered like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/2008/ubiq-share-on-delicious-preview.jpg&quot; style=&quot;border: 1px solid #333; margin: 0.25em; padding: 0.25em&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Also note that Ubiquity provides a template engine for use in generating content—namely the &lt;a href=&quot;http://code.google.com/p/trimpath/wiki/JavaScriptTemplates&quot;&gt;JavaScript Templates&lt;/a&gt; engine from the &lt;a href=&quot;http://code.google.com/p/trimpath/wiki/TrimPath&quot;&gt;TrimPath&lt;/a&gt; project.  This engine may eventually be replaced with another, but the notion is that Ubiquity will provide tools to more easily generate previews and more.&lt;/p&gt;

&lt;p&gt;The conclusion of the &lt;code&gt;.preview()&lt;/code&gt; method uses the template engine with a call to &lt;code&gt;CmdUtils.renderTemplate()&lt;/code&gt; to inject content into the preview element by way of the &lt;code&gt;.innerHTML&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Now that the preview is out of the way, it's time to get down to implementing the execution of the command:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;157&quot;&gt;    
    /**
     * Attempt to use the delicious v1 API to post a bookmark using the 
     * command input
     */
    execute: function(input_obj, mods) {
        var bm          = this._extractBookmarkData(input_obj, mods);
        var user_cookie = this._getUserCookie();
        var user_name   = (user_cookie) ? user_cookie.split(' ')[0] : '';

        if (!user_name) {
            // If there's no user name, there's no login, so this command won't work. 
            displayMessage('No active user found - log in at delicious.com ' +
                'to use this command.');
            return false;
        }

        if (!bm.description) {
            // If there's no title, somehow, then this is an error too.
            displayMessage(&quot;A title is required for bookmarks at delicious.com&quot;);
            return false;
        }
&lt;/pre&gt;


&lt;p&gt;Mirroring the &lt;code&gt;.preview()&lt;/code&gt; method, the &lt;code&gt;.execute()&lt;/code&gt; method first checks for validity of the arguments given by the user.  A missing user name or title result in a notification that the command has failed.&lt;/p&gt;

&lt;p&gt;But, if the arguments are all valid, it's time to actually issue a request to the Delicious V1 API:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;178&quot;&gt;
        var path = '/v1/posts/add';
        var url  = this._config.api_base + path;

        var req = Components.classes[&quot;@mozilla.org/xmlextras/xmlhttprequest;1&quot;].
            createInstance();

        req.open('POST', url, true);

        req.onload = function(ev) { 
            displayMessage('Bookmark &quot;' + bm.description + '&quot; ' + 
                'shared at delicious.com/' + user_name);
        }

        req.onerror = function(ev) { 
            displayMessage('ERROR: Bookmark &quot;' + bm.description + '&quot; ' + 
                ' NOT shared on delicious.com/' + user_name);
        }
&lt;/pre&gt;


&lt;p&gt;Using the base URL for the Delicious API declared earlier in the configuration section, the &lt;code&gt;.execute()&lt;/code&gt; method constructs an API URL for the &lt;code&gt;/v1/posts/add&lt;/code&gt; method.  Then, it creates an instance of &lt;code&gt;XMLHttpRequest&lt;/code&gt; from the browser to be used in sending the API request.  Event handlers are registered with the object to present notifications to the user indicating whether or not the API request was successful.&lt;/p&gt;

&lt;p&gt;At long last, it's time to wrap up this method and make the API request:&lt;/p&gt;

&lt;pre lang=&quot;javascript&quot; line=&quot;195&quot;&gt;
        req.setRequestHeader('Authorization', 'Basic Y29va2llOmNvb2tpZQ=='); // btoa('cookie:cookie')

        var mediator = Components.classes[&quot;@mozilla.org/appshell/window-mediator;1&quot;].
            getService(Components.interfaces.nsIWindowMediator);
        var win = mediator.getMostRecentWindow(null);
        var user_agent = win.navigator.userAgent + &quot;;Ubiquity-share-on-delicious&quot;;

        req.setRequestHeader(&quot;User-Agent&quot;, user_agent);      

        req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.send(this._buildQueryString(bm));
    },

    EOF:null // I hate trailing commas
});
&lt;/pre&gt;


&lt;p&gt;The login cookie authentication supported by the Delicious V1 API is triggered by supplying a user name / password pair of &lt;code&gt;cookie&lt;/code&gt;, which is done by setting the &lt;code&gt;Authorization&lt;/code&gt; request header.  The login cookie is then expected to be passed in as the POST variable &lt;code&gt;_user&lt;/code&gt;, which is done in the &lt;code&gt;._extractBookmarkData()&lt;/code&gt; utility method.&lt;/p&gt;

&lt;p&gt;Another bit here that shows more access of browser resources is the construction of a unique User-Agent header for this API call based on the browser's own User-Agent string, something that's suggested in the guidelines for using the Delicious API.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;.execute()&lt;/code&gt; method—and the command itself—is wrapped up with by sending off the bookmark data encoded as POST form variables with the &lt;code&gt;._buildQueryString()&lt;/code&gt; utility method.&lt;/p&gt;

&lt;p&gt;And, that's it—a command-driven Delicious browser extension in a little over 200 lines of code.  There's still more to be done to really make this thing full-featured, but I think this shows off the basic features of Ubiquity.  I'm hoping to dig in deeper and explore further, taking a look at running Greasemonkey-style code at &lt;a href=&quot;https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial#Running_on_page_load_and_startup&quot;&gt;browser startup and page load&lt;/a&gt;, as well as playing with some more browser chrome features.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085986&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jclark.org/weblog/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=d0a9ab4b71ce193e98b7284ca257e327&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://jclark.org/weblog/&quot;&gt;Jason Clark&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085986&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T14:47:35&quot;&gt;2008-09-01T14:47:35&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;First off-  fantastic post.  Great to see a lengthy post here again, although I'm one to talk.  This is an excellent introduction to Ubiquity command development, and tres useful to boot.&lt;/p&gt;

&lt;p&gt;I'm wondering why you chose to construct and post the XMLHttpRequest manually instead of using jQuery, which is included with Ubiquity.  I don't know that there's any benefit other than some simplicity, but I took a crack at converting your code to use jQuery, which works nicely.  In the 'execute' function, replace everything after &quot;var url  = this._config.api_base + path;&quot; with this (hope code blocks work in comments):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
        var win = context.focusedWindow;
        var user_agent = win.navigator.userAgent + &quot;;Ubiquity-share-on-delicious&quot;;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    jQuery.ajax({
      type: &quot;POST&quot;,
      url: url,
      data: this._buildQueryString(bm),
      username: &quot;cookie&quot;,
      password: &quot;cookie&quot;,
      beforeSend: function( req ) {
        req.setRequestHeader(&quot;User-Agent&quot;, user_agent); 
      },
      error: function() {
        displayMessage('ERROR: Bookmark &quot;' + bm.description + '&quot; ' + 
            ' NOT shared on delicious.com/' + user_name);
      },
      success: function() {
        displayMessage('Bookmark &quot;' + bm.description + '&quot; ' + 
            'shared at delicious.com/' + user_name);
      },
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Also, with both versions of the code, I'm seeing some unexpected behavior around authentication.  Assume I'm logged in to delicious, with &quot;stay logged in&quot; checked, and I restart my browser.  Trying to post with the command fails with a 401 unauthorized, even though I can see the cookie was sent (via Live HTTP Headers extension).  Going to delicious.com shows me logged in, and once I've viewed the site, the command works.  Except that now I can't reproduce; but I know it happened because I've got the headers.  At any rate, it is working nicely, but the previous failure is bugging me... feel like I'm overlooking something.  &lt;/p&gt;

&lt;p&gt;Thanks again for an awesome post.  Hope to see more of the same.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085988&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=e799a79441c7543be48562403411cd13&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Ryan Scott Scheel&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085988&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T15:07:01&quot;&gt;2008-09-01T15:07:01&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;You should be helping with the documentation, if you aren't already.  Very nice job with this article;&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085991&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://azarask.in&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=e4307f205d017ba76647806951e14bb0&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://azarask.in&quot;&gt;Aza Raskin&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085991&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-02T01:44:13&quot;&gt;2008-09-02T01:44:13&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi Leslie,&lt;/p&gt;

&lt;p&gt;This is a beautiful tutorial on writing a Ubiquity command. We'd love your help in making Ubiquity's documentation better (especially dev facing). You should totally link to this from the Ubiquity Wiki -- or even add the content in someway.&lt;/p&gt;

&lt;p&gt;Anyway, just wanted to say thanks.&lt;/p&gt;

&lt;p&gt;-- Aza&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085993&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.slackorama.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=15b474c86cd73c2d12c1d77af11c1d8a&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.slackorama.com&quot;&gt;seth&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085993&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-08T17:30:16&quot;&gt;2008-09-08T17:30:16&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Am I doing something wrong?  &lt;/p&gt;

&lt;p&gt;When I enter in &quot;sh this tagged tag1 tag2 entitled This is a title&quot; everything after the tagged is added as a tag. It's not seeing the entitled part.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085994&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spyced.blogspot.com/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=849810634810c960e5e7c27fa54a0f5b&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://spyced.blogspot.com/&quot;&gt;http://spyced.blogspot.com/&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085994&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-15T19:12:58&quot;&gt;2008-09-15T19:12:58&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Did something break?  I'm getting a 404 accessing http://decafbad.com/hg/UbiquityCommands/file/tip/delicious.ubiq.js&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085995&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085995&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-15T23:07:42&quot;&gt;2008-09-15T23:07:42&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Yeah, looks like I had a small snafu with switching back from Lighttpd to Apache.  Left out a rewrite rule - doh!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085996&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=357a20e8c56e69d6f9734d23ef9517e8&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Tony&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085996&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-10-22T04:56:03&quot;&gt;2008-10-22T04:56:03&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Great article. This is replacing my delicious bookmarklet. Thanks!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085997&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=31461076fcbce091ff822fc9ac31315d&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;dgtlchlk&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085997&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-14T01:06:57&quot;&gt;2009-04-14T01:06:57&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Great article and command.
Wish it worked correctly with the latest 0.1.8 release though. No matter what text you put in it adds everything as the notes. The tagged and entitled modifiers don't work.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085999&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.nolanhergert.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=957e24509baf770ba57ad306e20f201c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.nolanhergert.com&quot;&gt;Nolan&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085999&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-04-16T03:10:07&quot;&gt;2009-04-16T03:10:07&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I second that comment. Delicious is actually saying the link given was &quot;chrome://browser/content/browser.xul&quot; and marking it as harmful inside delicious!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086002&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=3d056a5b07c384647fe0806b0dfc429e&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Justin&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086002&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-06T12:39:39&quot;&gt;2009-07-06T12:39:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi Leslie,&lt;/p&gt;

&lt;p&gt;Thanks for the delicious ubiquity command. Unfortunately, as one of the commenters above mentions, the tagged modifier doesn't seem to work. I'm using Ubiquity 0.5 pre and typing the phrase:&lt;/p&gt;

&lt;p&gt;share tagged foo&lt;/p&gt;

&lt;p&gt;Adds the bookmark to Delicious with the note text &quot;tagged foo&quot;&lt;/p&gt;

&lt;p&gt;Cheers, Justin&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221086004&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://ericscalf.com/stream&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=0775f9beff626496b86d7cb602e5f46f&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://ericscalf.com/stream&quot;&gt;Eric&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221086004&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-07-20T22:43:17&quot;&gt;2009-07-20T22:43:17&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Echoing others.. I'm using the latest ubiquity (err, next to latest.. 0.1.8?), and doing &quot;share-on-delicious this is a note tagged testing&quot; saves the link with notes &quot;this is a note tagged testing&quot; and no tags. :(  Then again, the other delicious command I've found (by someone else) is having the same issue.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Ubiquity cracks open personal mashup tinkering</title>
        <link href="http://decafbad.com/blog/2008/08/31/ubiquity-cracks-open-personal-mashup-tinkering"/>
        <updated>2008-08-31T04:07:22+00:00</updated>
        <id>http://decafbad.com/blog/2008/08/31/ubiquity-cracks-open-personal-mashup-tinkering</id>
        <content type="html">&lt;p&gt;When I was a wee hacker, I lived my digital life though a &lt;a href=&quot;http://www.virtualsky.net/iadoremyc64/&quot;&gt;Commodore 64&lt;/a&gt;.  I played games on it, did homework, talked to people far away—you know, all the stuff they showed in the pictures on the box.  I also took things apart—both the machine itself and software running on it.  I grew up learning that my digital environment was ultimately understandable, &lt;a href=&quot;http://cbm.csbruce.com/~csbruce/cbm/transactor/&quot;&gt;susceptible to tinkering&lt;/a&gt;, and open to being bent to my own purposes.&lt;/p&gt;

&lt;p&gt;From the Commodore 64, I graduated eventually to terminals and text editors, opening portals mostly onto computers elsewhere via powerful UNIX command shells.  And, of course, over the past decade, this has largely given way to life in a browser.&lt;/p&gt;

&lt;p&gt;Yet, for a little while, particularly in the first few years of browsers, freedom to tinker seemed cramped.  JavaScript had yet to arrive, and was a little messy when it did.  There was no relatively easy addon development.  And, though the portals opened by a browser were richer than those provided by terminals, the paths of navigation defined by links controlled by site owners offered less freedom of movement than UNIX commands.  I could create my own pages, but I couldn't do much to others' pages.&lt;/p&gt;

&lt;p&gt;But then, javascript: URLs came around, dots were connected, and &lt;a href=&quot;http://en.wikipedia.org/wiki/Bookmarklet&quot;&gt;bookmarklets&lt;/a&gt; were born.  Suddenly, it was possible to customize &lt;em&gt;my&lt;/em&gt; browsing environment with arbitrary JavaScript code having access to the current page—no matter &lt;em&gt;whose&lt;/em&gt; page it was.  And, through the various tricks of the AJAX trade, bookmarklets have only gotten more capable throughout the years.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.mozilla.org/docs/end-user/keywords.html&quot;&gt;Smart keyword shortcuts&lt;/a&gt; came around a little later, allowing quick access to bookmarks via simple keywords typed into the location bar.  The smart part, though, came in the form of bookmarked URLs with placeholders and keywords given arguments to fill the placeholders—allowing not only quick access to bookmarked pages but also search engine forms bookmarked with late-bound fields.&lt;/p&gt;

&lt;p&gt;Bookmarklets inherited the benefits of smart keyword shortcuts.  The same placeholder in http: URLs can be inserted into the code of a javascript: URL, thus parameterizing the JavaScript code and incidentally turning the location bar into a kind of primitive command line.  For example, one of my most heavily used &quot;&lt;a href=&quot;http://naeblis.cx/weblog/2004/08/09/DeliciousAddresslets&quot;&gt;addresslets&lt;/a&gt;&quot; is based on &lt;a href=&quot;http://ejohn.org/blog/super-fast-delicious-bookmarklet/&quot;&gt;John Resig's original &quot;Super-Fast Delicious Bookmarklet&quot;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another leap in prying open the browser tinkering space came in the form of &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt;—an addon-powered environment created explicitly for the purpose of end-user scripting applied to others' pages.  &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt; user scripts can do more than bookmarklets, and with a much better development environment to boot.  And, though a user script can't do quite as much as a proper browser addon, they're much easier to hack on and distribute.&lt;/p&gt;

&lt;p&gt;Now, consider one of &lt;a href=&quot;http://labs.mozilla.com/&quot;&gt;Mozilla Labs&lt;/a&gt;' &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;newest projects&lt;/a&gt;, named &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt;.  This rough and experimental addon for Firefox combines and improves upon everything I've described so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; is a hackable command line environment, better than &lt;a href=&quot;http://en.wikipedia.org/wiki/Bookmarklet&quot;&gt;bookmarklets&lt;/a&gt; and smart &lt;a href=&quot;http://www.mozilla.org/docs/end-user/keywords.html&quot;&gt;keyword shortcuts&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; enables persistent customization of others' pages, not unlike &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; facilitates live in-browser creation and web-based subscription to user commands and scripts;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; gives access to browser chrome resources without a need for frequent restarts;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So far, most of the &lt;a href=&quot;https://labs.toolness.com/ubiquity-herd/&quot;&gt;commands&lt;/a&gt; I see popping up since the 0.1 release have not accomplished much more than &lt;a href=&quot;http://www.mozilla.org/docs/end-user/keywords.html&quot;&gt;smart keyword shortcuts&lt;/a&gt; in the location bar could.  But, it's early yet, and &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; is far from limited to these commands.&lt;/p&gt;

&lt;p&gt;Once the basics have been well-explored, I expect to see more people taking a crack at the broader capabilities offered by &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt;.  &lt;a href=&quot;http://en.wikipedia.org/wiki/Bookmarklet&quot;&gt;Bookmarklets&lt;/a&gt; and &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;Greasemonkey&lt;/a&gt; can't access browser chrome—but &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; can.  &lt;a href=&quot;http://labs.mozilla.com/2008/08/introducing-ubiquity/&quot;&gt;Ubiquity&lt;/a&gt; also offers a user interface that's so much more promising than keyword shortcuts, including command previews and typed parameters with suggestions.&lt;/p&gt;

&lt;p&gt;Ubiquity promises web-wide mashups directed by a conversational command interface.  All in all, the potential of this makes me feel like my digital environment—browser and web as a whole—is getting even more intimately, personally hackable.&lt;/p&gt;

&lt;p&gt;It'll be very interesting to see where this project goes.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089574&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=22b4e824255828f5aedd0e6e2558dc52&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;Raul&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089574&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T10:20:58&quot;&gt;2008-08-31T10:20:58&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Hi, was using the original delicious command linked from the Ubiquity wiki, just tried yours and its definitely more polished and functional. Great job with the preview and the extra functionality. Only thing is 'share-to-delicious' is too much to type so I unsubscribed the previous command and changed the namespace in yours. This is clearly going to become a problems as the commands proliferate.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089575&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089575&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T14:43:39&quot;&gt;2008-08-31T14:43:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Raul: &quot;share-to-delicious&quot; is long, but keep in mind is that you only need to type enough of the command to disambiguate it.  That is, all I type is &quot;sh this tagged osx software apple&quot; because I have no other commands starting with &quot;sh&quot;.  Watch the list of commands in the preview as you type.  Those tell you what the parser thinks of what you're typing as you type.  It's like automatic tab-completion.&lt;/p&gt;

&lt;p&gt;Also, I think there's work planned to put some usage based sorting into the command parser, preferring the commands you use most in order of disambiguation.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089576&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089576&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T15:33:24&quot;&gt;2008-08-31T15:33:24&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Nice post. I share your sentiment with regards to Ubiquity commands. A lot of commands that I see are just plain simple searches. I hope developers will work on more interesting things. For example, even things like auto-form filling for this comment (possibly even on page load without having to type a command) could be done by Ubiquity. There's still a lot more room for experimentation.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089578&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089578&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T15:45:59&quot;&gt;2008-08-31T15:45:59&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;But otherwise, I &lt;em&gt;really&lt;/em&gt; like your command especially the preivew. We should include it as a builtin command, if you don't mind. :)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089580&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089580&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-08-31T15:51:20&quot;&gt;2008-08-31T15:51:20&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I noticed a bug in your command. If I select some text in the awesomebar, the bookmark url is chrome. You should use something the command utils to get the url, instead.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089582&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089582&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T06:17:37&quot;&gt;2008-09-01T06:17:37&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;@Abi: Making this a built-in command is totally fine by me!  It can use more work, though, for sure.&lt;/p&gt;

&lt;p&gt;Also, I can reproduce that bug.  Ugh.  I can't find any methods in the CmdUtils to get the current page URL, though.  I'll keep poking a bit though.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089584&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=af8b180d6d4092fb42fe6b5e0b21536c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://abcdefu.wordpress.com&quot;&gt;Abi&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089584&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-01T06:50:23&quot;&gt;2008-09-01T06:50:23&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Your blog seems to be rejecting code (that's why I had so many posts in the first place). You can get the current page url using (with dots):&lt;/p&gt;

&lt;p&gt;CmdUtils  getDocumentInsecure() location href&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221089586&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://theunfocused.net/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=738af918f39d544f8b0d765850c986f8&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://theunfocused.net/&quot;&gt;Blair McBride&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221089586&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-09-02T02:50:12&quot;&gt;2008-09-02T02:50:12&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I recommend against using getDocumentInsecure() - its got &quot;Insecure&quot; in its name for a reason! Instead, you should use:&lt;/p&gt;

&lt;p&gt;Application.activeWindow.activeTab.uri.spec&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>date-based pagination</title>
        <link href="http://decafbad.com/blog/2008/07/17/date-based-pagination"/>
        <updated>2008-07-17T18:16:01+00:00</updated>
        <id>http://decafbad.com/blog/2008/07/17/date-based-pagination</id>
        <content type="html">&lt;p&gt;Here's a small idea I've not yet had the chance to try out on a large scale:  Time-based pagination in lieu of page-number-based pagination for personal content - ie. blogs, bookmarks, status updates, etc.  (You know, User Generated Content except I dislike the term.)&lt;/p&gt;

&lt;p&gt;Page numbers change over time, while time-based URLs are stable.  Most people don't generate an unreasonable amount of stuff in a day, so a page-per-day might not be so bad.  But, if there's too much stuff, degenerate to a page-per-12-hours or whatnot.&lt;/p&gt;

&lt;p&gt;Delicious used to have something like this in the web UI, back in the mists of 2003 or so, but Joshua got rid of it after a few design iterations.  The Delicious API is still somewhat based on it, which causes some confusion—but I tend to like it, thus this post.&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085362&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://beesbuzz.biz/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/plaidfluff.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://beesbuzz.biz/&quot;&gt;fluffy&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085362&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-17T20:22:38&quot;&gt;2008-07-17T20:22:38&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;You mean, like the date-based archives that Movable Type has had for ages?&lt;/p&gt;

&lt;p&gt;Yeah, I like those.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085363&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://brevity.org/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=55d0166df4149bbea204bb997f8447cb&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://brevity.org/&quot;&gt;Neil Kandalgaonkar&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085363&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-18T19:44:42&quot;&gt;2008-07-18T19:44:42&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I've had the same idea for Upcoming, for obvious reasons... our SRP pagination would then be permalinks.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221085364&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.anildash.com/&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/anildash.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.anildash.com/&quot;&gt;Anil Dash&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221085364&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-25T17:11:40&quot;&gt;2008-07-25T17:11:40&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Actually, yeah, we built the default pagination for archives in MT4 to be category-by-month, for exactly this reason. I regularly see &quot;?page=2&quot; in URLs and it just seems like such an obvious, avoidable mistake for so many to have embraced. SEO aside, permalinks that are destined to expire over time seem pretty reader-hostile, too.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>Queue everything and delight everyone</title>
        <link href="http://decafbad.com/blog/2008/07/04/queue-everything-and-delight-everyone"/>
        <updated>2008-07-04T19:17:18+00:00</updated>
        <id>http://decafbad.com/blog/2008/07/04/queue-everything-and-delight-everyone</id>
        <content type="html">&lt;p&gt;This is a blog post I've had simmering in my brainmeats for well over a year or two.  I'm suddenly inspired to break blog-radio-silence and get it out of my head.&lt;/p&gt;

&lt;p&gt;From &lt;a href=&quot;http://www.russellbeattie.com/blog/let-the-microblogs-bloom&quot;&gt;Let the microblogs bloom - RussellBeattie.com&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;Once this is widely accepted (and I'm sure there are many that would argue with me), the thing that will separate these types of services won't be whether they stay up (ala Twitter), but how fast your subscription messages are updated. Some services might be smaller or offer more features but not update as quickly whereas others will pride themselves on being as close to real-time as possible. The key is that it's all about messaging, not publishing. (Oh, and this also facilitates federation as well, but that's another topic).&lt;/blockquote&gt;


&lt;p&gt;See also: &lt;a href=&quot;http://randomfoo.net/blog/id/4182&quot;&gt;Rearchitecting Twitter: Brought to You By the 17th Letter of the Alphabet - random($foo)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the problems it seems most modern web apps face is the tendency to want to do everything all at once, and all in the same code that responds directly to a user.  Because, while you're in there building a user interface, it's &lt;em&gt;easy&lt;/em&gt; to implement everything else that needs to happen in that same UI module or library.&lt;/p&gt;

&lt;p&gt;Someone wants to post a bookmark?  Someone wants to post a message?  Well, of course you want the system to cross-reference and deliver that new piece of User Generated Content through every permutation of tag, recipient, keyword, and notification channel supported by your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But&lt;/strong&gt;, do you &lt;em&gt;really&lt;/em&gt; have to do everything all at once—while the person who generated that content is tapping his or her foot, waiting for the web interface to respond with feedback?  Are all of these things immediately vital to the person watching the browser spin, &lt;em&gt;right now&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;No.  Your user wants to get on with things.  He or she wants to see the submitted content get accepted and, as feedback and confirmation, see it reflected in a personal view immediately.  Does it matter—to &lt;em&gt;this person&lt;/em&gt;, at &lt;em&gt;this moment&lt;/em&gt;—whether it shows up &lt;em&gt;simultaneously&lt;/em&gt; in a friend's inbox, the public timeline, a global tag page, or even an RSS or Atom feed?&lt;/p&gt;

&lt;p&gt;Again, no, simultaneity doesn't really matter—because no human beings actually appreciate it.  Instead, imagine a ripple effect of concentric social and attention contexts with associated people spreading out from the original submission.  (This probably rates the creation of a diagram someday.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To make the person who's submitting something happy, offer feedback visible in their own personal context in under 50-200 milliseconds.  (That is, less than half-a-second at worst, in people terms.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The next person to delight is someone following the first person's published content—and humanly speaking, delays of &lt;em&gt;tens of thousands of milliseconds&lt;/em&gt; can be acceptable here.  (That is, 1-10 seconds at worst, in people terms.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, you can start worrying about strangers, allowing the content to propagate to tag pages, keyword tracking pages, and other public views—and I'd assert that delays of &lt;em&gt;hundreds of thousands of milliseconds&lt;/em&gt; are acceptable here.  (That is, 1-2 minutes at worst, in people terms.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The idea here is that the social structure can help you scale, while still delighting people.  Even with these delays, the system is still better at getting the word out than the original content creator would be at notifying all the others involved with an out-of-band system like IM or email.  And that's at worst—on most good days, all the delays should tend to be on the order of seconds or less.&lt;/p&gt;

&lt;p&gt;And how do you do all of this?  Use queues.  Sure, the original submission of content can and should be done all at once—just enough to get the content into the user's collection.  Then, queue a job for further processing and get out of the way.  In fact, just queue one job from the user interface—the processor of &lt;em&gt;that&lt;/em&gt; queue can then queue further jobs for all the other individual processing tasks that are likely susceptible to plenty of parallel processing and horizontal scaling.&lt;/p&gt;

&lt;p&gt;Meanwhile, the original user creating content has been thanked for their submission and life goes on.  In fact, their life may include going on to submit many more pieces of content in rapid succession, thanks to your delightfully responsive web user interface.&lt;/p&gt;

&lt;p&gt;And, in the end, that's really the purpose of a web-based content creation interface—accepting something as quickly as possible to make the user happy enough to continue submitting more.  The other part of the user interface, retrieval, serves simply to get the original content distributed as fast as can be reasonably expected.&lt;/p&gt;

&lt;p&gt;Now, preparing for fast retrieval is another story.  The flip side to processing queues are message inboxes—expect content duplicated everywhere and fetched simply, rather than using cleverly expressed SQL joins that bring a system to its knees.  But, that's another post altogether. :)&lt;/p&gt;

&lt;div id=&quot;comments&quot; class=&quot;comments archived-comments&quot;&gt;
            &lt;h3&gt;Archived Comments&lt;/h3&gt;
            
        &lt;ul class=&quot;comments&quot;&gt;
            
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083313&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://fatalerror.in&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=15516fd23722eeca86b8ea91738eea4b&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://fatalerror.in&quot;&gt;shyam&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083313&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-04T21:12:46&quot;&gt;2008-07-04T21:12:46&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Interesting bits of conversation happening all over the place regarding queues and the irony of it all - the much maligned Java has had workqueues since the early days.&lt;/p&gt;

&lt;p&gt;What everyone will learn, rather painfully in in cases like Twitter, is that all data is not created, consumed or processed equally. If you write your system which treats data equally you'll wind up with many Twitters all over the place.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083314&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=2377f34a68801b861c3e54e1301f0dce&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.decafbad.com&quot;&gt;l.m.orchard&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083314&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-04T21:37:30&quot;&gt;2008-07-04T21:37:30&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Oh, definitely.  Work queues are not a new thing at all.  It's just that I think there're a lot of modern web app builders who skipped Java &quot;enterprise&quot; software—skipped, or hoped to run away—and are rediscovering the whole set of problems.  Maybe the solutions will be less over-engineered this time.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083315&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://mikewarot.blogspot.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=04f21a4b6a007063d191b66c34f71710&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://mikewarot.blogspot.com&quot;&gt;Mike Warot&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083315&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-04T21:40:15&quot;&gt;2008-07-04T21:40:15&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;The thing that drives me nuts about twitter is that the core data rate is only about 30k/second... yet it kept going down. It's easy to spit out a broadcast to a subnet and never even miss a packet if there are only 100 of them per second or so. There's no reason on god's green earth that twitter should be anywhere near overloaded.&lt;/p&gt;

&lt;p&gt;Bad architecture, on the other hand, is the work of Satan. ;-)&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083317&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://simonwillison.net/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=ac7005eff7720218df4cf0c72ddf6a3d&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://simonwillison.net/&quot;&gt;Simon Willison&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083317&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-04T21:40:39&quot;&gt;2008-07-04T21:40:39&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Thank you! I've been trying to put my thumb on why queues are so interesting for months; this expresses it perfectly.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083319&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://blog.wachob.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=5c8ad784d2b5d12d57cf707dded1d58c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://blog.wachob.com&quot;&gt;Gabe Wachob&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083319&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-04T22:54:10&quot;&gt;2008-07-04T22:54:10&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Usually I would have something serious to say in agreement with you, because I do so much agree with you.&lt;/p&gt;

&lt;p&gt;But I have just one comment: &lt;/p&gt;

&lt;p&gt;DUH!!!&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083320&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.docuverse.com/blog/donpark/&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=88f2ee32d146425a422f58f8eab5424b&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.docuverse.com/blog/donpark/&quot;&gt;Don Park&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083320&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-06T05:16:32&quot;&gt;2008-07-06T05:16:32&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Good suggestions. For social services like Twitter, I would also add one more item:&lt;/p&gt;

&lt;p&gt;Prioritize by Relationship&lt;/p&gt;

&lt;p&gt;For example, two-way Twitter relationships (mutual-follow or recent @ or direct message exchange) should be refreshed before one-way. One can go further by placing higher priority on users whom poster sent messages to or received from within past X-hours.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083323&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.rabbitmq.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=6f355ae1f33640b777cae294092116ff&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.rabbitmq.com&quot;&gt;alexis&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083323&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-10T12:35:25&quot;&gt;2008-07-10T12:35:25&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;er... eventually consistent social graphs anyone?&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083324&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://cosmicrealms.com&quot;&gt;&lt;img src=&quot;http://disqus.com/api/users/avatars/Sembiance.jpg&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://cosmicrealms.com&quot;&gt;Robert Schultz&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083324&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-10T13:36:22&quot;&gt;2008-07-10T13:36:22&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I agree with everything you've said. Especially the last part, duplicating data in the format it will be retrieved in rather than using complicated and CPU intensive SQL queries. This is especially true for any sort of statistics or reporting. I learned this by seeing my website's statistics growing slower and slower to retrieve as more and more traffic caused the database to become larger and larger and all of a sudden those queries that ran nearly instantly, even with good indexing were taking several seconds to return.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083326&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=8acae029d9833597f8eb1623f94ef7e6&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;citric&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083326&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-10T21:49:19&quot;&gt;2008-07-10T21:49:19&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Web apps doing things while the user waits unnecessarily is an old phenomenon. I think it's often a matter of developers not wanting to (and/or being politically unable to) venture into what they consider the sysadmin's domain. Take the way-too-common case of apps that make the client wait while it does housekeeping. Why isn't this in a cron job? One reason is maybe this is KewlOSSBlogWikiPackage and it's simpler to say &quot;just untar the package under htdocs and you're done&quot; instead of saying &quot;also, unpack these scripts in a non-servable area and set them up to run hourly, but not all at the same time; stagger them a little. And run them with the same UID your web server is running as&quot;. But we end up with a lot of apps that (badly) reimplement basic tools their OS ships with in the first place.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083327&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://webseitz.fluxent.com/wiki&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=1d7a7610cb0f02de44be3c4186f82ac3&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://webseitz.fluxent.com/wiki&quot;&gt;Bill Seitz&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083327&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-07-28T21:23:06&quot;&gt;2008-07-28T21:23:06&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I wonder if you're still setting the bar too high for low-priority connections. I mean, microblogging &lt;em&gt;isn't&lt;/em&gt; really messaging, and maybe isn't (shouldn't-be?) conversation. &lt;/p&gt;

&lt;p&gt;So why wouldn't 10-15min be good enough?&lt;/p&gt;

&lt;p&gt;What % of &quot;messages&quot; are &lt;em&gt;read&lt;/em&gt; instantly after they hit an inbox?&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083328&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.yukes.com/2008/11/jimdo-dropr-php-messa&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=151a00c8656ea5c733dff2ac3adb27a3&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://www.yukes.com/2008/11/jimdo-dropr-php-messa&quot;&gt;Jay Yukes&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083328&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2008-11-23T10:35:55&quot;&gt;2008-11-23T10:35:55&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I had to solve a similar problem.  Needed the fastest possible response, so had to rule out interacting with the Database directly from the web app.  Used PHP message queue Dropr to defer all DB work.  It is very fast, easily over 1000 messages/second&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083329&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=70c1729db01a21a2a9d236f336e3beff&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;&quot;&gt;jmxz&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083329&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-02-13T20:00:13&quot;&gt;2009-02-13T20:00:13&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Wow those comments make me feel old.  I remember when these java queues everyone's referring to reminded me of how I had a VAX dedicated to queuing and scheduling batch jobs for a Cray.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083331&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://chr.ishenry.com&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=4ab185c23be3076c02c2b7b7f48062d1&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://chr.ishenry.com&quot;&gt;Chris Henry&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083331&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2009-06-11T20:09:47&quot;&gt;2009-06-11T20:09:47&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;Handling load is probably one of the biggest problems facing websites today.  Queueing is definitely the way to go, but like you said, sites need the type of architecture where it's easy to deploy services to different machines.  Usually by the time the site is under load, it's too late...&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;li class=&quot;comment&quot; id=&quot;comment-221083333&quot;&gt;
            &lt;div class=&quot;meta&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;
                    &lt;a class=&quot;avatar image&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://9fans.net&quot;&gt;&lt;img src=&quot;http://www.gravatar.com/avatar.php?gravatar_id=5b5f08225c299dd0955eb13d6b5c043c&amp;amp;size=32&amp;amp;default=http://mediacdn.disqus.com/1320279820/images/noavatar32.png&quot;/&gt;&lt;/a&gt;
                    &lt;a class=&quot;avatar name&quot; rel=&quot;nofollow&quot; 
                       href=&quot;http://9fans.net&quot;&gt;maht&lt;/a&gt;
                &lt;/div&gt;
                &lt;a href=&quot;#comment-221083333&quot; class=&quot;permalink&quot;&gt;&lt;time datetime=&quot;2010-05-04T14:50:05&quot;&gt;2010-05-04T14:50:05&lt;/time&gt;&lt;/a&gt;
            &lt;/div&gt;
            &lt;div class=&quot;content&quot;&gt;&lt;p&gt;I use Inotify as my queue messaging system&lt;/p&gt;

&lt;p&gt;http://maht0x0r.blogspot.com/2009/06/serialising-multiple-writers-in-shell_20.html&lt;/p&gt;

&lt;p&gt;Inotify can wait on MOVED_TO or CLOSE_WRITE events so that you can add them to the queue when the upload has finished.&lt;/p&gt;

&lt;p&gt;It should also be noted that this is a mnethod of load balacing too. Instead of 1000 parallel thumbnails being produced all context switching away, you can determine how many processes get spawned, use the OS' resource managing features etc.&lt;/p&gt;&lt;/div&gt;
            
        &lt;/li&gt;
    
        &lt;/ul&gt;
    
        &lt;/div&gt;



</content>
    </entry>
    
    

    <entry>
        <title>OPML reading lists in FeedMagick2</title>
        <link href="http://decafbad.com/blog/2007/10/17/opml-reading-lists-in-feedmagick2"/>
        <updated>2007-10-17T07:22:47+00:00</updated>
        <id>http://decafbad.com/blog/2007/10/17/opml-reading-lists-in-feedmagick2</id>
        <content type="html">&lt;p&gt;For anyone who's interested:  I've been hacking a little bit on &lt;a href=&quot;http://decafbad.com/trac/wiki/FeedMagick&quot;&gt;FeedMagick2&lt;/a&gt; again, with the latest addition being an OPML reading list feed blender.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://nick.typepad.com/blog/2005/10/reading_lists_f.html&quot;&gt;What's an OPML reading list?&lt;/a&gt;  Basically, it's the same as as OPML export of a feed reader's subscription list - only rather than doing a one-time import into another program, the OPML is itself treated as a live feed.  A feed reader that supports OPML reading lists will continually check the list for updates and sync RSS/Atom feed subscriptions with its contents, maybe in a special sub-folder.&lt;/p&gt;

&lt;p&gt;Here's a quick demo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://decafbad.com/2007/04/FeedMagick2/?pipeline=readinglist&amp;amp;url=http%3A%2F%2Fdecafbad.com%2F2007%2F04%2FFeedMagick2%2Fdocs%2Fmaster.opml&amp;amp;format=rss&amp;amp;run=Run+Pipeline&quot;&gt;An RSS feed blended from many of the sites I use daily&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://decafbad.com/2007/04/FeedMagick2/docs/master.opml&quot;&gt;The OPML reading list used as input for the above blend&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The itch I mean to eventually scratch is to replace the front page of decafbad.com with a live updating aggregation of the stuff I create and capture daily on the web.  It'll be basically a self-assembling &lt;a href=&quot;http://en.wikipedia.org/wiki/Tumblelog&quot;&gt;tumblelog&lt;/a&gt; pulled from many different services across the web.  It'll also replace the footer of accumulated crud I've got on this very blog - which I thought was a good idea at one point, but now consider &lt;a href=&quot;http://decafbad.com/twiki/bin/view/Main/NeatLikeDigitalWatches&quot;&gt;NeatLikeDigitalWatches&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With that in mind, the next thing I plan to develop is an &lt;a href=&quot;http://microformats.org/wiki/hatom&quot;&gt;hAtom&lt;/a&gt; module or XSL transform.  This will turn the blended feed into an XHTML page.  Maybe someday, &lt;a href=&quot;http://hatomic.org&quot;&gt;hAtomic&lt;/a&gt; will launch, and I'll have a nice pretty style for the page too.  Some time after that, I might work up a module that stows away dated historical archives of the feed and pages.  I have &lt;a href=&quot;http://decafbad.com/svn/trunk/FeedMagick2/TODO&quot;&gt;further plans and ideas&lt;/a&gt;, but I'm trying to focus on the itchy spots first so that I might actually get something done in this round of serial enthusiasm.&lt;/p&gt;
</content>
    </entry>
    
    
</feed>

