<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title>Inventive Labs: Weblog</title>
  
  <id>/weblog</id>
  <updated>
    2010-10-14T00:00:00Z 
  </updated>
  <author>
    <name>inventivelabs.com.au</name>
  </author>
  
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/inventivelabs-weblog" /><feedburner:info uri="inventivelabs-weblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry>
      <title>Booki.sh!</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/booki-sh/" rel="alternate" />
      <id>/weblog/post/booki-sh/</id>
      <updated>
        2010-10-14T21:12:54Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;We&amp;rsquo;ve finally readied a &amp;ldquo;technology preview&amp;rdquo; of our ereading platform! It&amp;rsquo;s consumed quite a large portion of my brain for the last few months. There&amp;rsquo;s plenty more to do, but here at last there&amp;rsquo;s something for you to enjoy reading.&lt;/p&gt;

&lt;p&gt;&lt;img alt="mini-bookish" class="tinybox" src="http://inventivelabs.com.au:80/static/files/assets/91f22f45/mini-bookish.png" title="mini-bookish" /&gt;&lt;/p&gt;

&lt;p&gt;The platform is called &lt;a href="http://booki.sh"&gt;Booki.sh&lt;/a&gt;. On the Booki.sh blog, you&amp;rsquo;ll see &lt;a href="http://blog.booki.sh"&gt;a shelf of books and samples&lt;/a&gt; you can dive into just by clicking. Nothing to install, works on your phone or your iPad or your Kindle3 or your work computer on your lunchbreak. Based, of course, on &lt;a href="http://monocle.inventivelabs.com.au"&gt;Monocle&lt;/a&gt;. Try it out and let us know what you think!&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>A few example Zhooks</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/a-few-example-zhooks/" rel="alternate" />
      <id>/weblog/post/a-few-example-zhooks/</id>
      <updated>
        2010-07-22T13:58:11Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;There is a storied tradition that file formats should be controversially pronounced. I&amp;rsquo;m pleased to say that &lt;a href="http://inventivelabs.com.au/weblog/post/zhook-a-really-simple-ebook-format"&gt;Zhook&lt;/a&gt; is no exception. At the Labs, we&amp;rsquo;ve settled on &amp;ldquo;chook&amp;rdquo; as the standard verbalisation.&lt;/p&gt;

&lt;p&gt;Which should clear up how &lt;a href="http://github.com/joseph/chook"&gt;&lt;em&gt;chook&lt;/em&gt;&lt;/a&gt;, the little web app I just built, came by its dubious appellation. &lt;em&gt;Chook&lt;/em&gt; provides a very simple Zhook Reading System, so you can now test your Zhook files. Upload them at &lt;a href="http://ochook.org/publish"&gt;ochook.org/publish&lt;/a&gt;.*&lt;/p&gt;

&lt;p&gt;While I was doing that, Virginia was tenderly crafting the world&amp;rsquo;s second** Zhook, which you can read in &lt;em&gt;chook&lt;/em&gt;. It&amp;rsquo;s Cory Doctorow&amp;rsquo;s &lt;a href="http://ochook.org/read/001f"&gt;For the Win&lt;/a&gt;, with some nice design touches.&lt;/p&gt;

&lt;p&gt;You can also view it outside the Reading System, &lt;a href="http://ochook.org/books/001f/"&gt;as an Ochook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course we don&amp;rsquo;t actually recommend &lt;em&gt;chook&lt;/em&gt; as an ebook reader — stay tuned for our Monocle-based platform. But if you&amp;rsquo;re interested in ebook experiments, well, Zhook is ongoing.&lt;/p&gt;

&lt;hr /&gt;


&lt;p&gt;&lt;small&gt;
* This service is only for testing your Zhooks, and I may in a few weeks or months or years decide to shut it down or clean it up without much warning.
&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;
** The world&amp;rsquo;s first Zhook was beautifully constructed by John of &lt;a href="http://www.goldengrouse.com/"&gt;The Golden Grouse&lt;/a&gt;. It is Edward Lear&amp;rsquo;s little ode, &lt;a href="http://ochook.org/read/2f8c"&gt;The Quangle-Wangle&amp;rsquo;s Hat&lt;/a&gt;.
&lt;/small&gt;&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>Zhook, a really simple ebook format</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/zhook-a-really-simple-ebook-format/" rel="alternate" />
      <id>/weblog/post/zhook-a-really-simple-ebook-format/</id>
      <updated>
        2010-07-19T12:11:31Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;Perhaps it&amp;rsquo;s just a thought experiment. Perhaps it has a place, like YAML has a place beside XML. It&amp;rsquo;s not intended a slur against EPUB, or a vainglorious attempt to supplant it. But the more I think about books, the more I believe that the content of them is not special, and is wholly within the capabilities of the HTML and CSS specifications. All we really need is a transmissable package (zip is fine), and a bunch of reasonable mark-up conventions.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s what Zhook is.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ochook.org"&gt;&lt;img alt="ochook" src="http://inventivelabs.com.au:80/static/files/assets/0d92a675/ochook_blogwidth.png" title="ochook" /&gt;&lt;/a&gt;
&lt;a href="http://ochook.org"&gt;Read the official specification of Zhook on Ochook.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The book-reading platform that we&amp;rsquo;re building around Monocle will accept Zhook uploads as well as EPUB uploads. We&amp;rsquo;ll be providing the required documentation for our Zhook support closer to launch.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>My long, good-natured article about EPUB 2.1, part 3 of 3</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/my-long-good-natured-article-about-epub-2-1-part-3-of-3/" rel="alternate" />
      <id>/weblog/post/my-long-good-natured-article-about-epub-2-1-part-3-of-3/</id>
      <updated>
        2010-06-21T18:22:13Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;br /&gt;


&lt;p&gt;Lurking solicitously on the periphery of this entire discussion is the Apple iOS App Store, at once dark, dangerous and lascivious. The great surviving print institutions have been loudly prophesying their salvation in it. You can understand how EPUB advocates might find that risible.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t think many people actually have grand delusions that EPUB will be an open standard for portable mobile applications, even just for &amp;lsquo;interactive print&amp;rsquo; applications (which is an unstable distinction in any case). But it does seem that EPUB finds itself curiously in competition with the iOS SDK, and some parts of the Working Group charter suggest that EPUB&amp;rsquo;s spoiling for a fight.&lt;/p&gt;

&lt;p&gt;It would be a spectacularly bad idea if cudgels were taken up. This fight is for HTML5, not EPUB, and HTML5 already has a &lt;a href="http://diveintohtml5.org/offline.html"&gt;fairly sane packaging format&lt;/a&gt;. EPUB should eventually incorporate HTML5, just because it offers greater longevity than XHTML 1.1, but it should return to the idea of packaging actual books, first and foremost. There&amp;rsquo;s a real need for an ebook specification, compact and laser-focussed, and I don&amp;rsquo;t believe we have anything like that yet.&lt;/p&gt;

&lt;h2&gt;A dire warning&lt;/h2&gt;

&lt;p&gt;So my dire warning pertains to the expansive view of EPUB, the view that sees EPUB as the vehicle for the digital future of everything that once rolled off a printing press. To do that drags the whole industry of publishing into an area where they lack expertise, and gives them shoddy tools.&lt;/p&gt;

&lt;p&gt;What must happen is that certain sectors of publishing — including some newspapers, magazines, &lt;a href="http://inventivelabs.com.au/weblog/post/when-books-ain-t-books/"&gt;travel guide publishers&lt;/a&gt;, technical publishers and so on — must realise that they&amp;rsquo;re no longer firmly in the publishing game. Today they are software houses, with vital and precious content wings. If they keep making applications-as-books, they&amp;rsquo;ll just get trampled by real applications (web or closed).&lt;/p&gt;

&lt;p&gt;The rest of the publishing industry is engaged in a robust tussle over a finite resource: people&amp;rsquo;s sustained attention. Books once presided over the entire supply, but (for some time now) the supply is being eroded from several angles: less leisure time, informational databases, movies and television, mainstream gaming, of course the Internet.&lt;/p&gt;

&lt;p&gt;For these publishers, the ones that are not software houses in chrysalis, it&amp;rsquo;s absurd to compete by trying to &lt;em&gt;become&lt;/em&gt; their competitors. If you show an interactive novel to a nine year old, she will tell you it&amp;rsquo;s a pretty crappy computer game. No-one, really, I promise you, is going to prefer a Vook to Youtube. The only sensible thing for these publishers to do is to carry the strength of their convictions and acknowledge the weight of their expertise: which is in the field of picking, refining and publishing books.&lt;/p&gt;

&lt;p&gt;These publishers need a specification that makes the reading of ebooks — things for which their very best form is a book — as pleasurable as it can be. In order for that spec to be useful to them and their reading audience, it must declare some things out of scope.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>My long, good-natured article about EPUB 2.1, part 2 of 3</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/my-long-good-natured-article-about-epub-2-1-part-2-of-3/" rel="alternate" />
      <id>/weblog/post/my-long-good-natured-article-about-epub-2-1-part-2-of-3/</id>
      <updated>
        2010-06-21T18:31:12Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;br /&gt;


&lt;p&gt;Some of what follows may be less than fully informed, because I&amp;rsquo;m only a casual observer, endeavouring to make a system that is EPUB-friendly if not EPUB-compliant. But it seems to me there are two key problems with the way the EPUB spec is developing.&lt;/p&gt;

&lt;p&gt;The first is that it has no reference implementation, and in places it seems to be drawn on gossamer threads around technical obstacles that have confronted a few major implementations. Unlike HTML, none of these privileged EPUB implementations have really gained market traction yet, but as they wax and wane, they leave their &lt;a href="http://blog.threepress.org/2009/11/28/what-i-would-change-about-epu/"&gt;detritus&lt;/a&gt; in the spec. It appears that EPUB also has a mostly historical habit of gorging on other formats, a habit that might once have prevented it being boxed into a corner of irrelevance, but now creates bloat and dulls the gleam of the spec. There really need not be any provision for an EPUB to &lt;em&gt;contain&lt;/em&gt; a PDF. The XML island stuff looks for all the world like an each-way bet — it could be scaled back significantly.&lt;/p&gt;

&lt;h2&gt;The specification MUST specify&lt;/h2&gt;

&lt;p&gt;Perhaps it is due to this lack of a canonical or dominant implementation that there comes a preference for the woollier words in &lt;a href="http://www.ietf.org/rfc/rfc2119.txt"&gt;RFC 2119&lt;/a&gt;: &lt;em&gt;should&lt;/em&gt;, &lt;em&gt;recommended&lt;/em&gt;, &lt;em&gt;may&lt;/em&gt; and &lt;em&gt;optional&lt;/em&gt;. &lt;em&gt;Must&lt;/em&gt;, &lt;em&gt;required&lt;/em&gt; and &lt;em&gt;shall&lt;/em&gt; are ventured less frequently than a book designer or reading system developer might hope. And this is not abating. For example, although EPUB has a working metadata solution, the Working Group charter proposes &amp;ldquo;native support&amp;rdquo; for a handful of &lt;em&gt;other&lt;/em&gt; metadata standards — as if by providing more options, they make the standard more standard. It&amp;rsquo;s rare to see a spec quite this promiscuous when it comes to other specs, and in my prudish opinion this gets it into trouble.&lt;/p&gt;

&lt;p&gt;As a reading system developer, of course I want to see more clarity about what to support. I shouldn&amp;rsquo;t have to work with the multiple voodoo methods of identifying the (only probable) cover image for a book. I shouldn&amp;rsquo;t have to wonder why on earth that problem, or questions regarding other obviously bookish entities — like tables of contents or font sizes or footnotes — have gone apparently unaddressed.&lt;/p&gt;

&lt;p&gt;But nor should a book designer. I think that&amp;rsquo;s important. Eventually, and not too distantly, production quality will become a differentiating factor for ebooks in the way that it is for print books now. The muck that Adobe InDesign emits will not be considered good enough, just as exporting your website from Microsoft Word is not good enough.&lt;/p&gt;

&lt;p&gt;Then we can hope, if this ebook thing takes off, that an activist group of actual ebook designers emerges and begins pleading for simplicity and consistency. It is the absence of this vital lobby that I think is the second key problem with the manner and rate at which the EPUB spec is evolving.&lt;/p&gt;

&lt;p&gt;Actual ebook designers would beg for level ground. For a single recommended way to mark up footnotes. They would campaign against the fetish for strictness in the spec — which among other things tells them to use the grouchy, disowned child that is XHTML 1.1, therefore to robotically obey its concomitant &lt;a href="http://www.w3.org/TR/2002/NOTE-xhtml-media-types-20020801/"&gt;media type&lt;/a&gt; edicts (and &lt;em&gt;therefore&lt;/em&gt; break so many otherwise workable ebooks, at least in my testing). They would probably push for some level of interactivity, but not as a priority, not as the thing that evolves ebooks into a whole new medium.&lt;/p&gt;

&lt;p&gt;This is because, and perhaps I&amp;rsquo;m being starry-eyed about this mostly-missing bunch of radicals, these actual ebook designers would have some faith in their ability to make reading digital books &lt;em&gt;as books&lt;/em&gt; a sufficiently compelling experience. Which neatly brings me to my dire warning. Tomorrow.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>My long, good-natured article about EPUB 2.1, part 1 of 3</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/my-long-good-natured-article-about-epub-2-1-part-1-of-3/" rel="alternate" />
      <id>/weblog/post/my-long-good-natured-article-about-epub-2-1-part-1-of-3/</id>
      <updated>
        2010-06-21T18:52:49Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;br /&gt;


&lt;p&gt;Last week I wrote a witty essay, incomplete at several thousand words, about why I thought the goals of the &lt;a href="http://www.idpf.org/idpf_groups/epub21wg/IDPF-EPUB-WG-Charter-5-7-2010.html"&gt;EPUB 2.1 Working Group&lt;/a&gt; were &amp;lsquo;broadly antithetical&amp;rsquo; to a &amp;lsquo;sensible and stable ebook specification&amp;rsquo;. Today I threw it away. Even after two rewrites, my attempts at wit came across as disparaging, and that&amp;rsquo;s not what I meant to do.&lt;/p&gt;

&lt;p&gt;The people who have undertaken this work and are involved in these discussions are well-intentioned and capable. It seems to me they are earnest and as much in the dark as the rest of us about the future of books in digital form. So I didn&amp;rsquo;t publish the essay. Good for me. I still have a perspective on this stuff though, and I&amp;rsquo;m going to try again with a narrower purview.&lt;/p&gt;

&lt;p&gt;Today I&amp;rsquo;m just going to list three concerns I have with the idea of interactivity in EPUB books — which is apparently the foremost consideration on the road to 2.1. Tomorrow I&amp;rsquo;ll make a couple of observations about the EPUB specification process, as it appears to an inattentive layperson on the outside. On Thursday I&amp;rsquo;ll close it out, in my bombastic way, with a dire word of warning.&lt;/p&gt;

&lt;h2&gt;Interactions and infractions&lt;/h2&gt;

&lt;p&gt;The &lt;a href="http://www.idpf.org/idpf_groups/epub21wg/IDPF-EPUB-WG-Charter-5-7-2010.html"&gt;EPUB 2.1 Working Group charter&lt;/a&gt; lists fourteen &amp;ldquo;main problems&amp;rdquo; with ebooks as the existing specification caters to them. Some of the problem descriptions are, in my view, cogent and urgent. Others are not. Most are worth thinking about.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m specifically interested in the first one, which is about interactivity and rich media in ebooks. The charter makes the example of an interactive crossword puzzle, to be achieved by embedding executable scripts in the book&amp;rsquo;s content. Indeed, the term &amp;ldquo;book&amp;rdquo; is too narrow, because as the example implies, this is intended to attract other formerly printed material (such as newspapers) to the EPUB format. The charter continues:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&amp;ldquo;These capabilities are necessary for interactive digital textbooks and digital magazines, and more generally to enable eBooks to evolve into a new medium, rather than simply be digital equivalents of paper books.&amp;rdquo;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;In the previous incarnation of this post, it was after this quote that things got snarky. I&amp;rsquo;m not going to do that now; later I will come back to why I think the ambition expressed above is unhelpful for digital publishing as a distinct and profitable industry.&lt;/p&gt;

&lt;p&gt;But here I will just note the premise: that EPUB-lications should become interactive — and the emphasis: that this is the very fabric of the future of digital publishing.&lt;/p&gt;

&lt;p&gt;My three counterpoints are somewhat bland and technical. Perhaps set against that big thinking they may be unconvincing or obstructionist or pedantic and irrelevant. Those possibilities were why my initial essay was so ardently but unfairly argued. This time, good-naturedly though.&lt;/p&gt;

&lt;br /&gt;


&lt;h3&gt;Security&lt;/h3&gt;

&lt;p&gt;For my own reasons, as the developer of an EPUB-friendly reading system, security is pretty much the start and end of the discussion regarding script-based interactivity within EPUB packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://monocle.inventivelabs.com.au"&gt;Monocle&lt;/a&gt; takes book-like content and embeds it, paginated and with navigation aids, in a webpage. It is, I often say, a way of making books &lt;em&gt;a part of the web&lt;/em&gt;, just as videos and audio are now sharable, linkable, embeddable parts of the web.&lt;/p&gt;

&lt;p&gt;Monocle must be able to manipulate the contents of parts of the book as it displays them. In doing so, due to the nature of &lt;a href="https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript"&gt;JavaScript security measures&lt;/a&gt;, Monocle must expose its execution environment to the components of the book. If these components contain malicious scripts, they could exploit this open access to pinch private data out of cookies or other properties of the page state. Even if one managed to trap EPUBs in that security net, positing some future unidirectional window access or something, that doesn&amp;rsquo;t stop them annoying users with prompts, pop-unders, et cetera.&lt;/p&gt;

&lt;p&gt;Since Monocle is an open solution, we&amp;rsquo;ll leave this choice in the hands of implementers. Scripts will not be stripped from book components, and component iframes will not use &lt;a href="http://blog.whatwg.org/whats-next-in-html-episode-2-sandbox"&gt;the proposed &lt;code&gt;sandbox&lt;/code&gt; attribute&lt;/a&gt;. If you use Monocle and you absolutely trust the EPUBs you&amp;rsquo;re displaying in it (because you created them, for example), you don&amp;rsquo;t have to disable scripting. But the platform we are quietly building around Monocle to make book embedding easy: this will absolutely strip scripts. Trust is simply of greater importance to us.&lt;/p&gt;

&lt;p&gt;Of course, that reason is Monocle-specific. Although for me it is the decisive consideration, we should move on. Next.&lt;/p&gt;

&lt;br /&gt;


&lt;h3&gt;Interaction models&lt;/h3&gt;

&lt;p&gt;When you think about it, there are only two things that a reading system does with EPUB over and above a web browser. One is that it unpacks the somewhat byzantine file into constituent components, serving them up in the correct order. (This feat is perhaps less remarkable than you think.) The other is that it provides an interaction model between the person reading and the HTML being rendered.&lt;/p&gt;

&lt;p&gt;What&amp;rsquo;s an interaction model? It&amp;rsquo;s the thing that might eventually make reading ebooks a joyful experience. It&amp;rsquo;s the flappy, wobbly, paper-like experience of turning a page in iBooks, which has probably done as much as anything to introduce less-than-avid readers to the notion of digital books. It includes the very idea of pagination itself, which is absent (or differently meant) in HTML.&lt;/p&gt;

&lt;p&gt;Contemporary ebook interaction models include turning pages, scrubbing to different parts of the book, selecting and annotating text, creating bookmarks, magnifying text or adjusting the brightness (which in Stanza, for example, may be controlled with a simple vertical swipe), clicking internal links to advance or to view a footnote, et cetera. The experience isn&amp;rsquo;t very rich yet and ebook reading systems still have a lot of work to do making these models intuitive and enjoyable. So far the specification has mostly and properly stayed out of it. But the notion of &amp;ldquo;interactivity&amp;rdquo; scatters these pigeons like a large cat.&lt;/p&gt;

&lt;p&gt;If that crossword puzzle was coded so that a downward swipe displayed the clue for 8-Down, Stanza&amp;rsquo;s brightness control would not work. The Kobo Reader, to which many people here in ebook-device-starved Australia have flocked, would not do anything, because it has no touchscreen or pointer.&lt;/p&gt;

&lt;p&gt;The point is not that there&amp;rsquo;s an engineering problem, at least not for hobbyist reading system developers like me. With Monocle I could pick and choose which interactions go through to scripts and which are reserved for the system. Given Monocle&amp;rsquo;s open design, my hope would be to leave as many of those choices with implementers as possible.&lt;/p&gt;

&lt;p&gt;The point is the uncertain landscape that emerges for book designers. The device capabilities and interactions models of existing reading systems are wildly divergent; far more divergent than the desktop web browsing landscape, for example. And what we&amp;rsquo;ve seen over the last decade on the web is that where features have uneven implementations, web designers have generally avoided them. They have fairly and reasonably stuck to the middle path of wide cross-browser support. In other cases they have favoured the dominant implementation — but for ebooks, there is yet no such thing.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s my second point, and a good part of my third point too: inherent inconsistency in the implementation will make things very difficult for book designers who attempt significant interactivity.&lt;/p&gt;

&lt;br /&gt;


&lt;h3&gt;Implementation minutiae&lt;/h3&gt;

&lt;p&gt;This is the most bland and technical of all my bland and technical points. But I really think it is the rock against which interactivity in EPUB dashes itself, at least until the (not particularly improbable) day when reading systems are developed by software architects and engineers much cleverer than I.&lt;/p&gt;

&lt;p&gt;At this time, more and more reading systems are being built on top of dedicated, drop-in renderers like WebKit. It seems clear that all the momentum for JavaScript-based interactivity comes from WebKit&amp;rsquo;s capabilities. You can see why: its HTML5 parser and feature-set, the typographic and animation possibilities arising from CSS3 standards and de facto standards as well as the &lt;code&gt;canvas&lt;/code&gt; element, and its fast, featureful JavaScript engine. Why wouldn&amp;rsquo;t you unleash that?&lt;/p&gt;

&lt;p&gt;However, even among the handful of reading systems built on top of WebKit of which I have any knowledge, the implementation details of those systems rupture the consistent surface that the renderer appears to provide.&lt;/p&gt;

&lt;p&gt;Here is the problem: between loading a component out of an ebook and displaying it, every reading system modifies the shape of the document data (the DOM). Some do a lot of modification, some do as little as possible. The reasons they do it are generally good and entirely implementation-specific. To take a now-retired example, Liza Daly&amp;rsquo;s trailblazing &lt;a href="http://blog.threepress.org/2009/02/09/introducing-epubjs/"&gt;epubjs&lt;/a&gt; goes looking for places to split paragraphs for the purposes of pagination. It creates new paragraph elements as necessary. The technique is ingenious, but since it modifies the DOM tree of the document substantially, it makes for unstable ground for scripters.&lt;/p&gt;

&lt;p&gt;Nor do I mean to pick on epubjs: every implementation tweaks the DOM in its own way. Monocle&amp;rsquo;s only interesting advance on epubjs was to get the browser to do the pagination, using CSS columns. So in that regard, Monocle modifies the DOM very little. But Monocle&amp;rsquo;s default &amp;ldquo;page flipper&amp;rdquo; is configured to display two overlapping iframes, so that as the page you&amp;rsquo;re reading turns, you see the next page underneath. Even naively, what this means is that you have two execution environments for scripting, which do not share state. Increment an integer in one frame and it is unchanged in the other. It would be very difficult, even for brilliant book designers, to account for that.&lt;/p&gt;

&lt;p&gt;My guess, and it is only a guess, is that iBooks renders the current component to an off-screen WebView surface, then essentially blits distinct portals of that content onto a &amp;ldquo;paged&amp;rdquo; visual metaphor. If so, this would probably be the purest, least DOM-invasive technique I know of, but even in this case a book designer would need to be aware of many specific implementation details. Similarly for every other reading system, and more so for the very customisable systems like Stanza. Modifications to book CSS, such as Stanza loves to make, will be sufficient to break many scripts.&lt;/p&gt;

&lt;p&gt;The troubling outcome here is not that interactivity will be ignored by book designers. What bothers me is that if book designers adopt these features, they will do so for a particular, presently dominant reading system. They will simply have to choose to support the biggest or the luckiest reading system. Their books won&amp;rsquo;t work, or won&amp;rsquo;t work as well, on anything else. Innovation will in this way be stifled, not stimulated.&lt;/p&gt;

&lt;p&gt;The market and designers will probably do that anyway, but part of the role of the EPUB specification is to avert that.&lt;/p&gt;

&lt;p&gt;Which brings us to some observations on how the spec is being specified. Tomorrow.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>When books ain't books</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/when-books-ain-t-books/" rel="alternate" />
      <id>/weblog/post/when-books-ain-t-books/</id>
      <updated>
        2010-03-20T09:32:37Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;An encyclopedia contains many lessons, but the form of the encyclopedia itself is a useful lesson. Its modern shape was drawn in happy innocence at the dawn of the Enlightenment; after two centuries of the primacy of science and inquiry in the West, it had swelled to consume entire bookshelves. It became ponderous and uncompelling, and actually quite hard to use. So, in the early nineties, encyclopedias were among the vanguard of that great gold-rush: multimedia, and specifically, CD-ROMs. Of all the publishing ventures of the CD-ROM age, multimedia encyclopedias (namely Britannica and Encarta) might be the one example of something that approached critical mass.&lt;/p&gt;

&lt;p&gt;In the process, their vaunted pages lost something of their power: the very heft of human knowledge you felt pulling a volume from the shelf was not easily translated to dropping a disk into a tray, double-clicking an icon, waiting, and pecking out a search term.&lt;/p&gt;

&lt;p&gt;That lost sensation was mourned, but it was not such a bad thing. People came to see an encyclopedia for what it was — not necessarily an intimidating (and quickly dated) academy in printed form, but actually just a database of information about stuff. You could copy and paste a paragraph out of Encarta and into your essay — like a lot of not-so-smart students did in the CD-ROM era and still do now. Of course, smarter kids copied, pasted, then judiciously modified the text in places to cover their tracks. In losing its printed form (and no-one, surely, buys volumes of encyclopedias anymore), it gained a truer form: it left the ivory tower to mingle in the bazaar. In a hop, skip and jump, we had Wikipedia.&lt;/p&gt;

&lt;p&gt;How heavy is Wikipedia? How many metres wide is it? Who wrote and edited it? We don't ask these questions. We do ask how reliable it is — but as a kid in the eighties, my family had Britannicas from 1964. According to that arbiter of truth, the moon was a distant and untrammelled body, a virgin of the night sky. This is why Wikipedia is the most reliable encyclopedia ever written.&lt;/p&gt;

&lt;p&gt;The point is, the encyclopedia is an idea that was necessarily limited by its form. It had to iterate through a number of forms to arrive at its present (and perhaps not final, but still infinitely better) form: a web application.&lt;/p&gt;

&lt;p&gt;Don't think that makes it a special case. Though it's a reference, it is a particular kind of reference — one that suits the model of sitting at a desk and making epistemological leaps of faith. Another kind of reference, the cookbook, has hitherto been poorly suited to a web incarnation, because nobody wants to coat their keyboard and mouse in flour and butter. A book, a book that holds its page when placed on a bench (so a weighty tome and a particular stock), is a much better form. But actually, the clip folder and plastic sheets are a better form again, because the collateral damage of an ordinary kitchen requires some preventative measures. (The internet serves that form very well — with the aid of a printer, of course.)&lt;/p&gt;

&lt;p&gt;But technology promises a still better form, because recipes are what a geek might call well-normalised data. Imagine that I have a few items in the fridge that I want to cook up. With some legwork in the indices of various cookbooks, I can locate a recipe for those ingredients. If a cookbook were a database, I could enter those ingredients and quickly see a list of all possible recipes. Or I could look at the date, discover what fresh food is cheap in mid-autumn, and compose a shopping list for one or two specific recipes. Or I could do many other things besides — such as tap to double the quantities, or whatever. The work to do is to bring the technology into the kitchen, and kitchen-proof it, but that's not hard.&lt;/p&gt;

&lt;p&gt;If you were developing an ereader, and you had digitised a few novels and made the experience good, you might come to a cookbook and wonder how best to display "that kind of book" in your system. You would probably come up with all these possibilities and more. And your answers might be clever, but the question is wrong. The cookbook is moderately well suited to bound paper, but poorly suited to a Kindle. You aren't inventing the future, you're just inventing a stopgap until someone comes along and does it properly — by giving the collection of recipes and folk wisdom a truer form. Your stopgap is like Encarta, if you're lucky.&lt;/p&gt;

&lt;p&gt;I am travelling through San Francisco for a few days, and I have the Lonely Planet application on my phone. The app pays obeisance (too much obeisance) to the bookish origins of the data, but it does at least realise that it isn't a book at all. It's an application. Though I curse the poor implementation of it in the Lonely Planet app, a travel guide is wonderfully well-suited to contextual, database-driven assistance in the form of an app. At any moment I can pull out my phone, and consult the map &lt;em&gt;without looking like a tourist&lt;/em&gt;, finding at a tap my precise location, and the directions to the nearest decent bar. If I had the bound paper version, I would get by, but thirstily.&lt;/p&gt;

&lt;p&gt;Travel guide publishers, in fits and starts, are getting it. Their asset is not their books, but their commissioned knowledge. And their knowledge, freed from the contraints of a linear page order and clunky, painstaking indexing, is much richer and more valuable in another form.&lt;/p&gt;

&lt;p&gt;It's not the same adventure as for encyclopedias, whose patrons are mostly sedentary and browsing on a large screen, but it's the same conclusion. Linearity is a liability. Heft is unhelpful. Books sometimes, not always, but discernably, are not books. For reference publishers, the future shift is much more dramatic than it is for common fiction, opinion and &lt;em&gt;narrative&lt;/em&gt; writing. Don't pander to them, don't try to quell their anxiety by pretending their books are still books, you're doing them no service and wasting your time. Concentrate on the things for which the last page must come after the first — that problem is plenty hard enough.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>Announcing Monocle</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/announcing-monocle/" rel="alternate" />
      <id>/weblog/post/announcing-monocle/</id>
      <updated>
        2010-03-08T16:19:41Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;&lt;a href="http://monocle.inventivelabs.com.au"&gt;Monocle&lt;/a&gt; is an ebook reader. It works in modern web browsers, using standard technologies. It runs in desktop browsers and on mobile devices. It's awesome in Safari and Chrome (the browsers used on iPhone OS and Android devices), increasingly awesome in Firefox, and workable in more standards-fearing browsers like Microsoft's Internet Explorer.&lt;/p&gt;

&lt;p&gt;Try it out: &lt;a href="http://monocle.inventivelabs.com.au"&gt;http://monocle.inventivelabs.com.au&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've open-sourced it under the MIT licence, which is the most liberal of the mainstream software licences. It can be used by anyone, for private or commercial use, for free (as in speech and as in beer) — as long as they retain the licence information in any copy of the software.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://monocle.inventivelabs.com.au" title="Mon-iphone" &gt;&lt;img alt="Mon-iphone" class="neg_column" src="http://inventivelabs.com.au:80/static/files/assets/3fd3e109/mon-iphone.png" title="Mon-iphone" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is, we're giving it away.&lt;/p&gt;

&lt;p&gt;Why are we doing this?&lt;/p&gt;

&lt;p&gt;We're concerned that the current ebook landscape is dominated by large companies trying to lock publishers, authors and readers into their devices and distribution models. We suspect this might be good for those companies, but no good for everyone else. There's a need to open up these fields to smaller players, and to give the consumer — the person who loves to read books and to 'have' books — better choices.&lt;/p&gt;

&lt;p&gt;We expect ebook reading devices to steadily converge with other communication devices. In the past e-readers have been fairly isolated from the network, but as they gain connectivity, consumers will demand better access to the web. Even Amazon's Kindle has stripped-down HTML rendering. Apple's iPad has one of the most advanced browsers around.&lt;/p&gt;

&lt;p&gt;The one single platform we expect future e-reading devices to have in common is the web browser. If you want to give your readership the freedom to own (forever) the books they buy from you, the web is where it will happen.&lt;/p&gt;

&lt;p&gt;Monocle is unique in providing this functionality. Monocle is also unique in giving publishers and retailers a way to design not only the book's content, but the way it looks and feels too. It's simple at heart, but has enormous flexibility in the way tables of contents, page numbers, running heads, and bookmarks work — even how it feels to 'turn' a page.&lt;/p&gt;

&lt;p&gt;Because it's delivered by a web browser, the file format question really doesn't arise. Any text-based format your books' data is in — Monocle can be made to display it. Integrating it with the EPUB standard is straightforward (we've already done it).&lt;/p&gt;

&lt;p&gt;Monocle also sidesteps the DRM question, because no files are passed around. If you want to put Monocle behind a paid membership wall, or restrict it to particular devices or IP addresses, that's easy to do. But it's not required by the technology.&lt;/p&gt;

&lt;p&gt;If you think Monocle could be an important part of the way you publish digital content, feel free to get some techies exploring &lt;a href="http://github.com/joseph/monocle"&gt;Monocle's source code&lt;/a&gt;. Or for expert consultation on an e-publishing strategy and workflow with Monocle, drop us a line. You'll find our contact form on the &lt;a href="http://inventivelabs.com.au:80/about-the-labs"&gt;About the Labs&lt;/a&gt; page.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>The magic behind Castanaut is open source</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/the-magic-behind-castanaut-is-open-source/" rel="alternate" />
      <id>/weblog/post/the-magic-behind-castanaut-is-open-source/</id>
      <updated>
        2010-02-24T12:41:48Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;Two years after we released &lt;a href="http://gadgets.inventivelabs.com.au/castanaut"&gt;Castanaut&lt;/a&gt;, I've decided to open source the little command-line utility that powers keyboard and mouse input within Castanaut.&lt;/p&gt;

&lt;p&gt;It might have want of a better name, but it's called &lt;em&gt;osxautomation&lt;/em&gt; because that's what I called it. Here's the &lt;a href="http://github.com/joseph/osxautomation"&gt;github repository for osxautomation&lt;/a&gt;, with full compilation and usage instructions in the README file.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>Get your Notepods!</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/get-your-notepods/" rel="alternate" />
      <id>/weblog/post/get-your-notepods/</id>
      <updated>
        2009-09-11T15:55:10Z
      </updated>
      <author>
        <name>Virginia Murdoch</name>
      </author>
      <content type="html">&lt;p&gt;Inventive Labs has teamed up with &lt;a href="http://jackywinter.com"&gt;the Jacky Winter Group&lt;/a&gt; to produce &lt;a href="http://notepod.net"&gt;Notepods&lt;/a&gt; - sketchbooks for your app ideas, in a package reminiscent of your favourite smartphone.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Notepod3" src="http://inventivelabs.com.au:80/static/files/assets/f06ade00/notepod3_blogwidth.jpg" title="Notepod3" /&gt;&lt;/p&gt;

&lt;p&gt;It's incredibly fun to come up with an idea in the pub over a few beers and have it produced in the space of ten short days, website and all. &lt;a href="http://notepod.net"&gt;Get yours now!&lt;/a&gt;.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>Peeking at previews in Blueprint</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/peeking-at-previews-in-blueprint/" rel="alternate" />
      <id>/weblog/post/peeking-at-previews-in-blueprint/</id>
      <updated>
        2008-12-26T17:25:49Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;I just uploaded a little Quicktime movie of a recent change to Blueprint: &lt;a href="http://pockets.josephpearson.org/abc7/bp_sprung_preview.mov"&gt;spring-loaded previews&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's only a small change, but one that has been on my list since, oh, the 4th of December 2006 — when our version control system tells me I started working on the 'drafting' functionality that is at the core of Blueprint.&lt;/p&gt;

&lt;p&gt;Formerly, you just clicked the &lt;em&gt;Preview&lt;/em&gt; tab to check your changes before saving them. The preview would pop up in the same grey frame you see in the movie. The recent change was to animate the transition — and to allow you to "pull" on the tab to "peek" at the preview.&lt;/p&gt;

&lt;p&gt;Like I said, it's a small change, and you could argue it's mere eye candy. But it has stayed on my list of things to do because exactly these sorts of user interactions give an interface its &lt;em&gt;handling&lt;/em&gt; — the sense that you're steering it, rather than poking at it. From this, the people using the system develop a confidence and an instinct.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>Migrating from Lighthouse to Redmine</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/migrating-from-lighthouse-to-redmine/" rel="alternate" />
      <id>/weblog/post/migrating-from-lighthouse-to-redmine/</id>
      <updated>
        2008-12-15T17:46:27Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;We love &lt;a href="http://lighthouseapp.com"&gt;Lighthouse&lt;/a&gt;, but here at the Labs our needs have begun to change and Lighthouse no longer feels like a best fit for us. So we've upped stumps and moved to &lt;a href="http://redmine.org"&gt;Redmine&lt;/a&gt;, which is less flashy but better complements our workflow (such as it is).&lt;/p&gt;

&lt;p&gt;I took a couple of hours to write a rake task that politely exploits the Lighthouse API and imports almost all available data from that system into a Redmine instance.&lt;/p&gt;

&lt;p&gt;Here it is:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://inventivelabs.com.au:80/static/files/assets/32bfd614/lighthouse_import.rake" class="download blank"&gt;&lt;img alt="Lighthouse import.rake" src="http://inventivelabs.com.au:80/images/mimetypes/blank.gif?1229052343" title="Lighthouse import.rake" /&gt;&lt;label&gt;&lt;span&gt;Download file (5Kb)&lt;/span&gt;&lt;br /&gt;&lt;em&gt;lighthouse_import.rake&lt;/em&gt;&lt;/label&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;Steps:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install the task file into &lt;code&gt;lib/tasks&lt;/code&gt; in your Redmine directory.&lt;/li&gt;
&lt;li&gt;Add the &lt;a href="http://github.com/Caged/lighthouse-api/tree/master"&gt;lighthouse-api ruby library&lt;/a&gt; as a plugin. This essentially involves running the following command from Redmine's &lt;em&gt;&lt;code&gt;vendor/plugins&lt;/code&gt;&lt;/em&gt; directory:
&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/Caged/lighthouse-api.git .&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;If you haven't already:

&lt;ul&gt;
&lt;li&gt;create your database and configure your &lt;code&gt;database.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rake db:migrate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rake redmine:load_default_data&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Log into Redmine and create the projects that will contain the data you're importing from Lighthouse. Configure them however you like — in order for the import to happen, they must be named &lt;em&gt;exactly&lt;/em&gt; as they are in Lighthouse.&lt;/li&gt;
&lt;li&gt;You can similarly create users and assign them to these projects. Any users with matching names to Lighthouse users will be recognised by the importer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In Lighthouse, set up an API token if you haven't already. This can (and should) be a read-only token.&lt;/li&gt;
&lt;li&gt;Now run the script:
&lt;pre&gt;&lt;code&gt;$ rake import:lighthouse LH_ACCOUNT=abc LH_TOKEN=xyz...321&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Obviously the &lt;code&gt;LH_ACCOUNT&lt;/code&gt; and &lt;code&gt;LH_TOKEN&lt;/code&gt; environment variables should be entered as per your Lighthouse account. You can also pass in &lt;code&gt;CREATE_USERS=1&lt;/code&gt; to actually create user accounts where they are referenced in the Lighthouse data — they will have dummy names and email addresses, and their passwords will match their login names. If you don't pass in this flag, any unrecognised user references will be assigned to the first admin user.&lt;/p&gt;

&lt;p&gt;The script could use a little refactoring, but it worked very well for our needs. Let me know how you go.&lt;/p&gt;
</content>
    </entry>
  
    <entry>
      <title>A Bloggie for Ms Fits</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/a-bloggie-for-ms-fits/" rel="alternate" />
      <id>/weblog/post/a-bloggie-for-ms-fits/</id>
      <updated>
        2008-03-18T15:43:13Z
      </updated>
      <author>
        <name>Virginia Murdoch</name>
      </author>
      <content type="html">&lt;p&gt;The fabulous &lt;a href="http://reasonsyouwillhateme.com"&gt;Reasons You Will Hate Me&lt;/a&gt; has just been &lt;a href="http://2008.bloggies.com"&gt;honoured with a Bloggie&lt;/a&gt; for Best Australian Weblog. Inventive Labs designed Ms Fits an appropriately sexy new site in the middle of 2007, and built a custom content management system to suit some of her specific requirements - in particular, the now world-famous 'Friday Q&amp;amp;A'.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Rywhm" src="http://inventivelabs.com.au:80/static/files/assets/103861/rywhm.png" title="Rywhm" /&gt; &lt;/p&gt;

&lt;p&gt;Congratulations, Ms Fits!&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>The other things</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/the-other-things/" rel="alternate" />
      <id>/weblog/post/the-other-things/</id>
      <updated>
        2008-02-25T10:48:33Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;We do have a habit of saying how busy we are at the Labs, to the extent that it's almost a little obnoxious. We do, in fact, occasionally find time to craft software that is not for particular paying clients, but has a wider audience.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://inventivelabs.com.au/weblog/post/the-writing-s-on-the-magnetic-wall"&gt;Fridge&lt;/a&gt;, our Facebook app, is an example of this. That was a fun project, and the reception has been really rewarding. I worry about the commercial trajectory and privacy implications of Facebook, but in developing Fridge I gained a high regard for their technical platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gadgets.inventivelabs.com.au/tabulate" title="Demo graphic" &gt;&lt;img alt="Demo graphic" class="inline" src="http://inventivelabs.com.au:80/static/files/assets/102594/demo_graphic_blogwidth.png" title="Demo graphic" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;By far our most popular project is &lt;a href="http://gadgets.inventivelabs.com.au/tabulate"&gt;Tabulate&lt;/a&gt;, released in October last year, for iPhones and iPod Touches. It gives you a slick interface for, well, power-browsing in multiple windows with MobileSafari. Tens of thousands of Apple device owners are using it.&lt;/p&gt;

&lt;p&gt;Also for iPhones, released by stealth and only shortly after Tabulate, is &lt;a href="http://code.google.com/p/kapow"&gt;Kapow!&lt;/a&gt; -- a digital comic book viewer. I think only about three people in the world use it, but they seem to love it.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gadgets.inventivelabs.com.au/castanaut" title="Gadget" &gt;&lt;img alt="Gadget" class="neg_column" src="http://inventivelabs.com.au:80/static/files/assets/102597/gadget_admin_icon.png" title="Gadget" /&gt;&lt;/a&gt; On the weekend we released another project that's been in (mostly weekend) development for a month or so: &lt;a href="http://gadgets.inventivelabs.com.au/castanaut"&gt;Castanaut&lt;/a&gt;. In technical terms this is a Ruby DSL for writing executable scripts that control input and application interaction during screencast recording. &lt;/p&gt;

&lt;p&gt;In layman's terms it's a way you can take the screencast notes that you're already writing down on paper before recording, &lt;strong&gt;double-click&lt;/strong&gt; them, and have a screencast saved and ready for publishing. It's kinda freaky.&lt;/p&gt;

&lt;h3&gt;The many tentacles of Inventive Labs&lt;/h3&gt;

&lt;p&gt;So, we've had a recent proliferation of subdomains here at the Labs. Two of them may interest you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://gadgets.inventivelabs.com.au"&gt;Gadgets&lt;/a&gt;: this is where we put the publicly available goodies we develop.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wisdom.inventivelabs.com.au"&gt;Wisdom&lt;/a&gt;: a more frequently updated stream of mostly technical but occasionally humourous objects that preoccupy us.&lt;/li&gt;
&lt;/ul&gt;</content>
    </entry>
  
    <entry>
      <title>Eight days at the Labs</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/eight-days-at-the-labs/" rel="alternate" />
      <id>/weblog/post/eight-days-at-the-labs/</id>
      <updated>
        2007-11-27T12:31:21Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;One of the items on our extremely well-populated todo list is to update our &lt;a href="http://inventivelabs.com.au:80/portfolio"&gt;Portfolio&lt;/a&gt; page. It'll happen  shortly, but meantime I thought I'd give you a quick look at three sites we've launched in the last eight days.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.readings.com.au"&gt;&lt;img alt="readings" src="http://inventivelabs.com.au:80/static/files/assets/101230/readings_blogwidth.jpg" title="readings" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Several months in the making, the new &lt;a href="http://www.readings.com.au"&gt;Readings&lt;/a&gt; website gives this iconic Melbourne business the online stature it deserves. Integrating with their inventory and ordering systems, the site makes fascinating use of "product collections" to recreate the serendipity of browsing in-store. Added to that is a powerful and greatly simplified search, regular postings of events, news, product reviews and downloads, and a shopping basket that is secure, intuitive and remarkably fun.&lt;/p&gt;

&lt;p&gt;We're rather proud of the Readings website, which we built from scratch in &lt;a href="http://www.rubyonrails.org"&gt;Rails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://bestqualitycrab.com"&gt;BestQualityCrab&lt;/a&gt; is an unusual experiment in the convergence of blogging and geography. &lt;a href="http://bestqualitycrab.com"&gt;&lt;img alt="bqc" class="neg_column" src="http://inventivelabs.com.au:80/static/files/assets/101234/bqc.jpg" title="bqc" /&gt;&lt;/a&gt; We constructed the site in Blueprint for a small cohort of Melbourne academics, who explain it like this: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;It starts from the belief that blogs are usually created around time-centred ways of organising thoughts and narratives. BestQualityCrab starts from the idea that blog thinking and narratives can be organised in terms of space and place as well as time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Blogs are rarely quite this interesting to explore. In fact, we think BQC might herald an entirely new category of weblogs.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.wired-consulting.com.au"&gt;
&lt;img alt="wired" class="neg_column" src="http://inventivelabs.com.au:80/static/files/assets/101238/wired.jpg" title="wired" /&gt;&lt;/a&gt; &lt;a href="http://www.wired-consulting.com.au"&gt;Wired Consulting&lt;/a&gt; is a new Australian telecommunications consultancy with a remarkable pool of talent. This is our second collaboration with David Koopmans of &lt;a href="http://www.mokummarketing.com"&gt;Mokum Marketing&lt;/a&gt;, and once again shows the flexibility of Blueprint.&lt;/p&gt;

&lt;p&gt;&lt;br style="clear: both"&gt;&lt;/p&gt;

&lt;p&gt;Three big sites in a little over a week is not bad for a team of two inventors. Obviously our pace isn't always so quick, but since August we've launched 14 Blueprint sites of varying complexity. And you wonder why we love our little CMS so much.&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Scheduling periodic tasks in a Rails application</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/scheduling-periodic-tasks-in-a-rails-application/" rel="alternate" />
      <id>/weblog/post/scheduling-periodic-tasks-in-a-rails-application/</id>
      <updated>
        2007-11-08T17:49:28Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;There's a number of solutions around for forking out of the Rails http request cycle and performing intermittent or long-running operations within your Rails application environment. Some of the most well-documented options are summarised on the &lt;a href="http://wiki.rubyonrails.org/rails/pages/HowToRunBackgroundJobsInRails"&gt;Rails wiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Looking for a way to schedule actions like 'fetch this feed every 15 minutes', 'clear out old sessions from the db', and 'take a snapshot of each site' for Blueprint, I investigated most of these options.&lt;/p&gt;

&lt;p&gt;In the past I've used the reliable cron/runner combination, but this requires additional setup -- outside of your app -- on each server where the app is deployed. There are recipes out there for updating the cron table via Capistrano, but this is difficult to do in a way that preserves existing cron configuration. BackgrounDrb and AP4R both look accomplished, but are really intended to solve other (and bigger) problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://openwferu.rubyforge.org/"&gt;OpenWFEru&lt;/a&gt; is a Workflow Engine, which sounds impressively enterprisey. I don't know much about that, but it comes with a pretty good scheduler &amp;#8212; check out the API for it &lt;a href="http://openwferu.rubyforge.org/rdoc/classes/OpenWFE/Scheduler.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This can be used to create a cron-like scheduler within Rails. I wanted the scheduler to run as a separate process alongside the pack of Mongrels that handle web requests, started and stopped by Capistrano. Ruby has a great 'daemons' gem that takes care of daemonising processes for you.&lt;/p&gt;

&lt;p&gt;If you need something like this, install these two gems:&lt;/p&gt;

&lt;pre&gt;
$ sudo gem install -y openwferu daemons
&lt;/pre&gt;

&lt;p&gt;Then create script/schedule:&lt;/p&gt;

&lt;pre&gt;
#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
APP_DIR = File.join(File.dirname(File.expand_path(__FILE__)), '..')

Daemons.run_proc(
  'schedule',
  :dir_mode =&gt; :normal, 
  :dir =&gt; File.join(APP_DIR, 'log'),
  :multiple =&gt; false,
  :backtrace =&gt; true,
  :monitor =&gt; true,
  :log_output =&gt; true
) do

  # Daemonising changes the pwd to /, so we need to switch 
  # back to RAILS_ROOT.
  Dir.chdir(APP_DIR)

  # Load our Rails environment.
  require File.join('config', 'environment')

  begin
    # Initialise the OpenWFE scheduler object.
    require 'openwfe/util/scheduler'
    scheduler = OpenWFE::Scheduler.new
    scheduler.start

    # Now assign jobs to the scheduler (see API). For example:
    scheduler.schedule_every('15m') { Feed.fetch_and_consume! }

    # Tell the scheduler to perform these jobs until the 
    # process is stopped.
    scheduler.join
  rescue =&gt; e
    RAILS_DEFAULT_LOGGER.warn "Exception in schedule: #{e.inspect}"
    exit
  end
end
&lt;/pre&gt;

&lt;p&gt;Chmod this file to be executable, then test it:&lt;/p&gt;

&lt;pre&gt;
$ chmod a+x script/schedule
$ script/schedule start
&lt;/pre&gt;

&lt;p&gt;Monitor the file at log/schedule.output -- most errors will be reported here. It will log to log/&amp;lt;environment&amp;gt;.log. Run 'script/schedule' with no arguments to see how to stop and restart it, and do other daemonoid things if you like.&lt;/p&gt;

&lt;p&gt;You can then create a task within your Capistrano deployment recipies along the lines of:&lt;/p&gt;

&lt;pre&gt;
task :after_restart do
  run "RAILS_ENV=#{rails_env} #{current_path}/script/schedule stop"
  run "RAILS_ENV=#{rails_env} #{current_path}/script/schedule start"
end
&lt;/pre&gt;</content>
    </entry>
  
    <entry>
      <title>Using Blueprint as a Drafting Tool</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/using-blueprint-as-a-drafting-tool/" rel="alternate" />
      <id>/weblog/post/using-blueprint-as-a-drafting-tool/</id>
      <updated>
        2007-09-11T10:50:03Z
      </updated>
      <author>
        <name>Virginia Murdoch</name>
      </author>
      <content type="html">&lt;p&gt;A couple of weeks ago I spent a day designing and building simple default templates for each of &lt;a href="http://inventivelabs.com.au:80/blueprint"&gt;Blueprint&lt;/a&gt;'s core page types ('blueprints'), ostensibly to help us demonstrate the system more easily to clients and friends. There are currently ten generic blueprints – Page, News, Links, Search, Events, Contact, Projects, Blog, Gallery and People – and each of them has one or more templates, all mixing a bit of logic with some HTML. There are companion javascript and CSS files, too.&lt;/p&gt;

&lt;p&gt;&lt;img alt="blueprint_default" class="inline" src="http://inventivelabs.com.au:80/static/files/assets/6650/blueprint_default.png" /&gt; &lt;/p&gt;

&lt;p&gt;A by-product of completing this task is that Blueprint has gone from being something I started working with after the architecture of a new site was established (most often with pen and paper, followed by laborious and under-appreciated site maps put together in &lt;s&gt;Illustrator&lt;/s&gt; &lt;a href="http://www.freeverse.com/apps/app/?id=6020"&gt;Lineform&lt;/a&gt;), to being an indispensible tool in the drafting process: I can create a working site prototype in mere seconds, and manipulate it quickly within the drag-n-drop interface, testing hypotheses and seeing roadblocks much sooner than if I were starting from sketches.&lt;/p&gt;

&lt;p&gt;&lt;img alt="structure" class="inline" src="http://inventivelabs.com.au:80/static/files/assets/6654/structure.png" /&gt; &lt;/p&gt;

&lt;p&gt;Obviously this isn't a substitute for thinking through the more complex IA requirements of larger sites, but for a typical small Blueprint site it's both appropriate and efficient, since whatever is achieved at this stage is carried over seamlessly into the development. &lt;/p&gt;

&lt;p&gt;It's also considerably easier for people we're working with to understand, since the results have the dimension and interactivity of a finished site.&lt;/p&gt;

&lt;p&gt;&lt;img alt="preview" class="inline" src="http://inventivelabs.com.au:80/static/files/assets/6659/preview.png" /&gt; &lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Like that but with this: view inheritance in Rails</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/like-that-but-with-this-view-inheritance-in-rails/" rel="alternate" />
      <id>/weblog/post/like-that-but-with-this-view-inheritance-in-rails/</id>
      <updated>
        2007-09-05T16:47:16Z
      </updated>
      <author>
        <name>God</name>
      </author>
      <content type="html">&lt;p&gt;Yesterday I wrote about &lt;a href="http://www.inventivelabs.com.au/weblog/post/providing-default-content-in-rails-layouts"&gt;a simple method&lt;/a&gt; that lets you to place default content in your Rails layouts. This default content can be optionally overridden by your views using the standard-issue &lt;code&gt;content_for&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's handy enough on its own, but it's also a piece of a somewhat larger puzzle — something I've called view inheritance. The principle is that, just as Ruby classes can extend from parent classes, so ERB templates should be able to extend from parent templates.&lt;/p&gt;

&lt;p&gt;Consider this template, a.html.erb:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;% default_content_for :title do %&amp;gt;
  &amp;lt;h1&amp;gt;Bonjour&amp;lt;/h1&amp;gt;
&amp;lt;% end %&amp;gt;
&amp;lt;/html&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Now b.html.erb, which &lt;em&gt;inherits&lt;/em&gt; a.html.erb:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;% inheriting_view 'a' do %&amp;gt;
  &amp;lt;% content_for :title do %&amp;gt;
    &amp;lt;h1&amp;gt;Aloha&amp;lt;/h1&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

&lt;p&gt;That says "do everything that the first template does, but make the title say 'Aloha'".&lt;/p&gt;

&lt;p&gt;Of course we're not doing much different from what a layout does yet — we've just shifted responsibility for specifying the layout file from the controller (or outer view) to the view itself. Sometimes that's not very useful, and although view inheritance can be wielded as a general replacement for layouts, I'm not really recommending it.&lt;/p&gt;

&lt;p&gt;But what about this scenario? You have a model X, and an XController that serves up a form for X. Then you need a model Y, which is like X but with a few extra fields. So you create the Y model:&lt;/p&gt;

&lt;pre&gt;
class Y &amp;lt; X
&lt;/pre&gt;

&lt;p&gt;And perhaps a YController:&lt;/p&gt;

&lt;pre&gt;
class YController &amp;lt; XController
&lt;/pre&gt;

&lt;p&gt;But how do you add the extra fields to the form? Like this:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;% inheriting_view 'x/form' do %&amp;gt;
  &amp;lt;% content_for :additional_fields do %&amp;gt;
    &amp;lt;fieldset&amp;gt;
      &amp;lt;legend&amp;gt;Geography&amp;lt;/legend&amp;gt;
      &amp;lt;label&amp;gt;Latitude
        &amp;lt;%= @f.text_field('latitude') %&amp;gt;
      &amp;lt;/label&amp;gt;
      &amp;lt;label&amp;gt;Longitude
        &amp;lt;%= @f.text_field('longitude') %&amp;gt;
      &amp;lt;/label&amp;gt;
    &amp;lt;/fieldset&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

&lt;p&gt;So &lt;acronym title="Don't Repeat Yourself"&gt;DRY&lt;/acronym&gt; you'll need a beer when you're done.&lt;/p&gt;

&lt;p&gt;Here's the code:&lt;/p&gt;

&lt;pre&gt;
  def inheriting_view(options = {}, &amp;block)
    # We accept a shorthand syntax -- if options is a string, render as a file.
    return inheriting_view({:file =&gt; options}, &amp;block) if options.is_a?(String)

    bind = options[:binding]

    # Get our differences and additions to the view we're inheriting.
    if block_given?
      bind ||= block.binding
      instance_variable_set(:@content_for_layout, capture(&amp;block)) 
    end

    raise "Important: inheriting_view() requires a block. " +
      "An empty block (eg, using {}) is suitable." unless bind 

    # If we're inheriting a partial, lend our local context to that partial.
    options[:locals] = eval("local_assigns", bind) if options[:partial]

    # Render our parent view.
    concat(render(options), bind)
  end
&lt;/pre&gt;

&lt;p&gt;(Yes, this works for partials inheriting other partials too.)&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>Providing default content in Rails layouts</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/providing-default-content-in-rails-layouts/" rel="alternate" />
      <id>/weblog/post/providing-default-content-in-rails-layouts/</id>
      <updated>
        2007-09-04T11:11:10Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;Another quick tip for Rails view developers. We commonly employ the following snippet in our layouts:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;%= (out=yield :sidebar) ? out : render(:partial =&gt; 'sidebar') %&amp;gt;
&lt;/pre&gt;

&lt;p&gt;This thorny little one-liner says, if the view we're rendering for this layout has &lt;code&gt;&lt;a href="http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#M000638"&gt;content_for&lt;/a&gt; :sidebar&lt;/code&gt;, show that content. Otherwise show the default content (which we've tucked away in the 'sidebar' partial).&lt;/p&gt;

&lt;p&gt;It's a handy pattern because it lets your views &lt;em&gt;opt&lt;/em&gt; to modify some aspect of the layout, without having to — they can go with the default sidebar content if they don't care.&lt;/p&gt;

&lt;p&gt;However. Firstly, it's a bit unsightly. Secondly, you must put the default content in a partial (unless it's short enough to just be a string — an approach that is arguably uglier). In most cases, the default content for a block in a layout is best described in that layout, so that you don't have to go hunting down other files to get a picture of what the layout displays. Here's a better way:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;% default_content_for :sidebar do %&amp;gt;
  &amp;lt;p&amp;gt;This is the default sidebar content! (et cetera)&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

&lt;p&gt;So now, if the view specifies some &lt;code&gt;content_for :sidebar&lt;/code&gt;, the contents of the block above (ie, the &amp;lt;p&amp;gt; tag) will &lt;em&gt;not&lt;/em&gt; be rendered. If the view doesn't do that, then the layout will render the contents of the block.&lt;/p&gt;

&lt;p&gt;If you'd prefer this idiom in your views, drop the following method into application_helper.rb:&lt;/p&gt;

&lt;pre&gt;
def default_content_for(name, &amp;block)
  name = name.kind_of?(Symbol) ? ":#{name}" : name
  out = eval("yield #{name}", block.binding)
  concat(out || capture(&amp;block), block.binding)
end
&lt;/pre&gt;

&lt;p&gt;This method is full of &lt;a href="http://corelib.rubyonrails.org/classes/Binding.html"&gt;binding&lt;/a&gt;s and &lt;a href="http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#M000637"&gt;capture&lt;/a&gt;s, which you can read up on at your leisure, or feel free to ask questions in the comments.&lt;/p&gt;</content>
    </entry>
  
    <entry>
      <title>The writing's on the magnetic wall</title>
      <link href="http://inventivelabs.com.au:80/weblog/post/the-writing-s-on-the-magnetic-wall/" rel="alternate" />
      <id>/weblog/post/the-writing-s-on-the-magnetic-wall/</id>
      <updated>
        2007-09-03T14:47:58Z
      </updated>
      <author>
        <name>Joseph</name>
      </author>
      <content type="html">&lt;p&gt;Many, many moons ago (thirty-seven, to be exact), I made a little DHTML application called &lt;em&gt;The Fridge&lt;/em&gt;. You had a bunch of word tiles that you pushed and shoved into the shape of a poem, much like &lt;a href="http://www.magneticpoetry.com/"&gt;Magnetic Poetry&lt;/a&gt; on fridges all over the world. It was good fun and much loved by many people, but with the passage of time the flocking crowds  dwindled down to a core of devotees. And then, as is the way of things, they too found other pastimes.&lt;/p&gt;

&lt;p&gt;Last week we took a couple of days out at the Labs to turn The Fridge into a &lt;a href="http://www.facebook.com/apps/application.php?id=10761020563"&gt;Facebook application&lt;/a&gt;. This manifestation is even more fun than the last, because you can now create your own sets of words  and share them with others. Also, crafting miniature epics on your friends' walls for posterity is a rather satisfying pursuit.&lt;/p&gt;

&lt;p&gt;Here's what it looks like:&lt;/p&gt;

&lt;p&gt;&lt;img alt="fridge-wide" src="http://inventivelabs.com.au:80/static/files/assets/6538/fridge_wide_teaser_blogwidth.gif" /&gt; &lt;/p&gt;

&lt;p&gt;If you have a Facebook account, &lt;a href="http://www.facebook.com/apps/application.php?id=10761020563"&gt;take it for a spin&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
  
</feed>

