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

<channel>
	<title>James Pearce &#187; Programming</title>
	<atom:link href="http://tripleodeon.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://tripleodeon.com</link>
	<description>Living the mobile dream</description>
	<lastBuildDate>Fri, 02 Dec 2011 14:11:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<cloud domain='tripleodeon.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Bacon Off</title>
		<link>http://tripleodeon.com/2011/11/bacon-off/</link>
		<comments>http://tripleodeon.com/2011/11/bacon-off/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 22:30:38 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=644</guid>
		<description><![CDATA[Dave Kaneda and I wandered along to the Facebook Mobile Hack last week. We spend a lot of time attending, speaking at, and sponsoring hackathons, but wanted to have a go at getting involved for ourselves. Consider it SenchaCon decompression or something. The event as a whole was excellent &#8211; some great sessions and a [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://9-bits.com/'>Dave Kaneda</a> and I wandered along to the Facebook Mobile Hack last week. We spend a lot of time attending, speaking at, and sponsoring hackathons, but wanted to have a go at getting involved for ourselves. Consider it <a href="http://secure.lenos.com/lenos/sencha/SenchaCon2011/">SenchaCon</a> decompression or something.<br />
<span id="more-644"></span></p>
<p>The event as a whole was excellent &#8211; some great sessions and a strong focus on using HTML5 for mobile apps. Facebook&#8217;s new graph API, for example, encourages developers to think about how to semantically describe users&#8217; contextualized activities (how many sedentary web users do you see in this <a href='http://www.youtube.com/watch?v=q3b94kFBah8'>video</a>?). All part of an exciting mobile future for the web&#8217;s next decade.</p>
<p>Team Sencha was probably rather too ambitious. But after several frantic hours, we managed something that more or less worked.</p>
<p><img src="http://tripleodeon.com/wp-content/uploads/2011/11/bacon1-500x266.png" alt="" title="bacon1" width="500" height="266" class="alignnone size-large wp-image-645" /></p>
<p>Our app was to be <strong><a href='https://github.com/jamesgpearce/BaconOff'>BaconOff</a></strong>, a two player game to match actors from your Facebook-liked movies against each other based on their <a href="http://en.wikipedia.org/wiki/Six_Degrees_of_Kevin_Bacon#Bacon_numbers">Bacon Number</a>, Top-Trumps-style. The server-side, node.js, hosted and deployed easily to Heroku, and which handles the Facebook authentication, delivers a Sencha Touch app, containing an access token, to the browser. (No doubts at all this can be more elegant and secure).</p>
<p>The first thing the app does is <a href="https://github.com/jamesgpearce/BaconOff/blob/master/client/app/stores/movies.js#L30">pull</a> a list of your favorite movies from Facebook. Once loaded, each movie record <a href="https://github.com/jamesgpearce/BaconOff/blob/master/client/app/stores/movies.js#L11">calls imdbapi.com</a>, a wrapper around IMDB&#8217;s database, and fetches four actors from each of your favorite movies.</p>
<p>Those actors are then created as a further type of model, each of which has a <a href="https://github.com/jamesgpearce/BaconOff/blob/master/client/app/stores/actors.js#L7">bacon-number-fetching method</a>. We hoped to use YQL to get the values from <a href="http://oracleofbacon.org/">Oracle of Bacon</a>, but it was barred by a robots.txt condition. Slightly cheekily, we used our node backend to <a href="https://github.com/jamesgpearce/BaconOff/blob/master/web.js#L54">proxy a request</a> to that server anyway, and then handle the common condition of there being more than one entry for each actor&#8217;s name.</p>
<p><img src="http://tripleodeon.com/wp-content/uploads/2011/11/bacon2-266x500.png" alt="" title="bacon2" width="250" height="469" class="alignnone size-large wp-image-647" /><img src="http://tripleodeon.com/wp-content/uploads/2011/11/bacon3-266x500.png" alt="" title="bacon3" width="250" height="469" class="alignnone size-large wp-image-647" /></p>
<p>In the meantime, and no thanks to me, we had a sweet UI and CSS3-animated loading screen &#8211; all Sass goodness from Mr Kaneda of course.</p>
<p><iframe src="http://baconoff.herokuapp.com/loading.html" width='200' height='200' style='border:0;margin:auto;display:block'>//</iframe></p>
<p>We&#8217;d hoped to avoid having state stored anywhere on the server or in the client, using the social graph alone. Eventually we figured it was unavoidable, and quickly had to write a game state storage layer on the server side. It uses a contemporary storage platform known as&#8230; the <a href="https://github.com/jamesgpearce/BaconOff/blob/master/web.js#L93">file system</a>. Ahem.</p>
<p>From here on, with time running out, and with a flying visit required to my son&#8217;s (excellent!) school play on the other side of El Camino, code started sprawling as we dashed for something demonstrable.</p>
<p>APIs for <a href="https://github.com/jamesgpearce/BaconOff/blob/master/web.js#L100">starting</a>, <a href="https://github.com/jamesgpearce/BaconOff/blob/master/web.js#L121">listing</a>, and <a href="https://github.com/jamesgpearce/BaconOff/blob/master/web.js#L136">playing</a> games quickly followed, and views on the client side emerged to allow <a href="https://github.com/jamesgpearce/BaconOff/blob/master/client/app/views/friends.js">competitor</a> and <a href="https://github.com/jamesgpearce/BaconOff/blob/master/client/app/views/chooseActor.js">actor</a> selection, as well as the game&#8217;s <a href='https://github.com/jamesgpearce/BaconOff/blob/master/client/app/views/home.js'>home screen</a>.</p>
<p>We added the <a href="https://github.com/jamesgpearce/BaconOff/blob/master/views/home.ejs#L47">Facebook JavaScript library</a> relatively late in the day to allow competitor selection and request; (in retrospect we should have based the whole app around this library from the start &#8211; what were we thinking?). And then tried, and failed, to make the frictionless sharing of the game progress <a href='https://github.com/jamesgpearce/BaconOff/blob/master/client/app/app.js#L77'>post to the timeline</a>: I just couldn&#8217;t find the relevant permissions settings in the last 30 seconds before we went on stage. This was a shame, because we&#8217;d had the nouns and verbs configured ages before!</p>
<p>At somewhere approaching 1am, we finally got to demo the app, and for those two minutes it more or less worked. There was only one hack required to make the walkthrough work: I&#8217;d been working on the assumption that players would be keyed by name, while Dave (and, it turns out, Facebook) that they would be keyed by ID. A small <a href="https://github.com/jamesgpearce/BaconOff/blob/master/client/app/app.js#L46">hardcoded line</a> covered that up &#8211; albeit at the expense of making every game ever appear to be against Dave himself. With that in mind, I&#8217;ll decline to link to a live running version. Screenshots only <img src='http://tripleodeon.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><img src="http://tripleodeon.com/wp-content/uploads/2011/11/bacon4-266x500.png" alt="" title="bacon4" width="250" height="469" class="alignnone size-large wp-image-653" /><img src="http://tripleodeon.com/wp-content/uploads/2011/11/bacon5-266x500.png" alt="" title="bacon5" width="250" height="469" class="alignnone size-large wp-image-654" /></p>
<p>So yes, in retrospect, far too ambitious. Hacking time was supposedly limited to 6 hours, and we&#8217;d needed a few more than that. I rather wish now that we&#8217;d just done a Social Compass app and stuck some avatars on top of a simple <a href="http://tripleodeon.com/2011/10/taking-a-new-device-api-for-a-spin/">webkitCompassHeading</a> event handler or something. We weren&#8217;t expecting to win anything (there&#8217;s no doubt the well-prepared entries were far superior <img src='http://tripleodeon.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ) &#8211; and let&#8217;s just say that this was an expectation firmly met.</p>
<p>But it was a lot of fun being on the other side of the stage for once. And it&#8217;s interesting to see how far you can get on something completely new in a short time period if you put your mind to it. I guess that&#8217;s the whole point; code quality be damned&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2011/11/bacon-off/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Of Sites and Apps</title>
		<link>http://tripleodeon.com/2011/09/of-sites-and-apps/</link>
		<comments>http://tripleodeon.com/2011/09/of-sites-and-apps/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 23:13:17 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=621</guid>
		<description><![CDATA[Users probably don&#8217;t care what&#8217;s a web site and what&#8217;s a web app. But I believe web practitioners should, if only to know when certain best practices apply, and when they don&#8217;t. But does an established distinction exist between the two genres of experience? Not as far as I know. Is it to do with [...]]]></description>
			<content:encoded><![CDATA[<p>Users probably don&#8217;t care what&#8217;s a web site and what&#8217;s a web app. But I believe web practitioners should, if only to know when certain best practices apply, and when they don&#8217;t.</p>
<p>But does an established distinction exist between the two genres of experience? Not as far as I know. Is it to do with creation versus consumption? Linkability? User experience? Or the architecture underlying the way they are built?<br />
<span id="more-621"></span></p>
<p>Personally I think there <em>is</em> a way to clearly delineate the two types of experience, but I&#8217;m also sure it&#8217;s not the only way to do so, and that the distinctions are very likely to vary with individual&#8217;s perspective. I&#8217;m unabashedly trawling for debate.</p>
<p><code>&lt;tldr&gt;</code></p>
<p>There&#8217;s one notable result of the disruption that mobile is wreaking upon the way we think about the web. The blogosphere, the conference circuit and various online communities &#8211; not to mention boardrooms up and down the country &#8211; are abuzz with hypotheses regarding the &#8220;One True Way&#8221; to do something, the &#8220;Dawn of&#8221; this, or the &#8220;Death of&#8221; that.</p>
<p>No doubt I&#8217;m a part of this. It&#8217;s quite fun. (Although let&#8217;s be honest, none of us really has a clue about how mobile&#8217;s going to play out eventually.)</p>
<p>In the real world, such binary proclamations are less useful than we like to think. Building mobile and web experiences for real users, real business &#8211; and with real constraints of many kinds &#8211; is not at all easy. Being buffeted around by voguish black-and-white philosophies (or even the outmoded ones) is of reduced benefit when you&#8217;re really trying to navigate the shades of gray in between.</p>
<p>One of the shadiest boundaries to have to consider when using web technologies is that netherworld that lies between &#8216;web application&#8217; and &#8216;web site&#8217;. As far as I can tell, there aren&#8217;t established definitions that help us decide what is one and what is another &#8211; let alone a decision tree that developers and designers can follow to decide what sort of experience they should deliver to their users in different circumstances.</p>
<p>On one hand, the differentiation between these two things seems rather academic. If a user can access what I want them to access, and can do what I want them to be able to do, then who cares how we label that experience? It&#8217;s the web right? (Stop reading now.)</p>
<p>But again, this belies the subtlety of the real world, and especially in mobile. It&#8217;s 2011: iPhone-plus-four. Users want apps. Marketers want apps. Boardrooms want apps. This is, we&#8217;ve been trained to believe, the way in which we enhance our phones&#8217; capabilities and access information in elegant, consistent ways. We can assert as much as we want that users should only be using their devices&#8217; web browsers, but apps sell, and will continue to.</p>
<p>Of course, many of these apps are written with native technologies, and distributed via non-web-based stores. This article is not about them: they are likely to become evolutionary dead-ends. But if the web is to succeed as a distribution medium &#8211; and as a stack of technology &#8211; it will have to rise to match the expectation that&#8217;s been set. It will have to provide what is needed to create and deliver app-like experiences, just as well as it can classical site- and document-based content.</p>
<p>The good news is that smarter people than me have long seen this coming. Although much of HTML5 (the markup specification) is about improving the semantic qualities of web documents, HTML5 (the suite of related APIs and technologies) is unashamedly focussed on enabling web applications of increasing complexity. And with browser vendors now competing on such metrics as JavaScript performance and API completeness (rather than how well they support the &lt;aside&gt; tag or somesuch), it seems we should expect to see ever more advanced web apps in the future.</p>
<p>Nevertheless, in frequent discussions about the mobile web, its best practices, and its tools, you&#8217;ll hear many arguments qualified with clauses like &#8220;oh, but things are different if you&#8217;re building an app&#8221; or &#8220;this is a better technique for traditional sites&#8221;. I know, because I do too.</p>
<p>And so, as we enter conference season again, I thought it might be interesting to see if there&#8217;s any consensus about what these two things even are, and how we can differentiate between them. What is a mobile web app? And when is it not a mobile web site?</p>
<p>For me, there are a few possible vectors that we can consider.</p>
<p><strong>Creation versus Consumption</strong></p>
<p>Imagine a large structured collection of interlinked documents, where the user is essentially limited to a read-only interaction (give or take the odd comment form or search box). There&#8217;s no doubt that such a thing should be classified as a site. Blogs, news sites, academic papers &#8211; these are clearly the heartland of the classical web. Online stores too? Probably.</p>
<p>But what about micro-blogging services? Photo-sharing? Online email clients, document editors, IDEs even? Games? It seems debatable as to whether one should classify twitter.com as a site or an app (especially on a mobile device), but I am most certainly using an application when I&#8217;m logged into GMail, Google Docs, or playing Angry Birds &#8211; let alone working in some web-based data admin interface.</p>
<p>Interestingly, this second category of experiences all seem to be read-write (or at least, highly interactional). So can we classify sites as being read-only and apps as being read-write? That certainly seems simple enough: sites are to consumption as apps are to creation.</p>
<p>Does this feel right? One problem here is that there are some beautiful and enjoyable app-like experiences &#8211; Flipboard comes to mind &#8211; which are clearly oriented towards consumption. (But then again, maybe the logic is backwards here… perhaps Flipboard is what the web <em>site</em> of the future should look like, though Gawker&#8217;s infamous app-like blog felt clunky). And how would you classify Facebook? Entirely user-generated content, but it still looks and feels quite like a site.</p>
<p><strong>Linkability</strong></p>
<p>If you are launching an experience from a desktop or homescreen icon, it is easy to feel that you are in a sandboxed and closed environment whose boundaries are explicit and inescapable. If you start your experience by entering a URL into a browser, conversely, you&#8217;re more likely to feel that you are at the start of journey &#8211; one where every link clicked can immediately take you to another page or another site or another domain, across the web&#8217;s endless interlinked landscape with no boundaries.</p>
<p>So does this serve as a way to distinguish between site and app? Most native apps certainly do have impermeable boundaries: outbound and especially inbound. Even the iPhone Twitter app opens up links in a modal, embedded web view rather than spawning a new Safari window (much to <em>my</em> frustration, at least).</p>
<p>But web apps? Need these be silos? No, of course not. They&#8217;re still running in a browser, and (unless in hybrid environment) hanging off a URL like any web site does. There&#8217;s no reason for a web app not to contain links that lead you off to other parts of the web, either in new browser tabs or the present one. While reliable deep-linking back into web apps seems to be less commonplace, this is more a function of implementations and browser&#8217;s fragmented History APIs than some fundamental flaw in the web&#8217;s architecture. (I never shared purists&#8217; distaste of hash-bangs, for example. These are a symptom of developers trying to make this inbound linkability and bookmarkability work for single-page web apps: fixing the web, not breaking it.)</p>
<p>So, like others, I&#8217;d definitely hold up linkability as a huge advantage of web apps over native apps &#8211; but not as a reliable way to distinguish between web apps and web sites.</p>
<p><strong>User Experience</strong></p>
<p>Another way we might classify apps and sites is by assessing the user interface and experience presented. What are the visual cues that an app&#8217;s an app, and a site&#8217;s a site?</p>
<p>The use of fixed toolbars is certainly an obvious one: at the top, containing a title and maybe a back button; at the bottom a series of large tab-navigating buttons within easy thumb-reach. This is a UI/UX paradigm that, pioneered by iOS, emerged entirely from the native application world, and which, before 2007, had absolutely no precedent in the classical or mobile web worlds.</p>
<p>Ditto disclosure lists. Ditto sliding transitions between master and detail records. Ditto action sheets, spinners, and momentum-based scrolling. Ditto even the disablement of pinch &amp; zoom on document-like content (controversial to some, and yet understandable if you argue that viewport zooming was merely the browser&#8217;s way of dealing with legacy, not-made-for-mobile web content in the first place).</p>
<p>Many developers work hard to bring these platform behaviors in their web apps. And many web frameworks work hard to make it easy for them to do so. (My employer is one of those, of course.) Many rightly blanche at the thought of slavishly mimicking a particular operating system &#8211; nothing looks dafter than iOS pinstripes in an Android browser &#8211; but the point is that many of these generalized UX characteristics are highly suitable for one-handed, touch-based interactions. No-one will claim that legacy desktop web sites (often replete with tiny mouse-centric sidebar menus and table layouts) can ever match a dedicated app-like user experience. Responsive web sites can indeed improve this greatly, with navigation often flowing to the top or bottom of documents for certain screen sizes. But still, these sites are rarely mistaken for apps.</p>
<p>Because the visual appearance is the &#8220;I somehow just know this is an app&#8221; argument, and one that users might particularly relate to, I do give the UI/UX distinction a lot of credence. But still, it&#8217;s a very fuzzy boundary. What if my site displays a fixed toolbar, but no back button? What if my list looks like hyperlinks instead of tappable disclosures? What if I style plain scrolling instead of momentum? This is a question that the likes of jQuery Mobile have pondered too, in an attempt to follow a site-like, progressive enhancement philosophy. Nevertheless plenty of developers are undoubtedly going to describe the results as apps.</p>
<p><strong>Architecture</strong></p>
<p>So this leaves us looking for a more technical distinction. Is there an architectural, boxes-and-arrows argument that might clarify the difference?</p>
<p>The web we&#8217;ve known and loved for almost 20 years &#8211; undoubtedly a web of sites! &#8211; is unashamedly thin-client in design. Web servers do all the heavy lifting, hosting the storage, business logic, and the construction of the user interface that the user sees. Indeed it is surprising that we&#8217;ve had to suffer so much browser inconsistency over the years considering that all they&#8217;ve had to do is turn a stream of <code>&lt;</code> and <code>&gt;</code> into pixels.</p>
<p>But the rise of the use of AJAX was a clue that this architecture wasn&#8217;t always particularly elegant. A user clicks a link to another page on your site? That might mean a whole set of HTTP connections (again), a blocked server thread (again), a clutch of database connections (again), the execution of a bunch of business logic (again), the generation of a whole new slab of markup (again), and its dispatch back across the wire (again). And that&#8217;s all before expecting the browser to re-render the entire user interface (again).</p>
<p>I love URLs, hyperlinks and SEO as much as the next man, but that&#8217;s some price to pay to simply display a new record of content.</p>
<p>On the other hand, consider an architecture in which the browser is given far more autonomy and responsibility. Think &#8220;AJAX++&#8221;, perhaps, where not only fragments of the DOM are elegantly updated, but where the entire application can reside and execute in the browser.</p>
<p>The big breakthrough here, of course, has been HTML5&#8242;s storage APIs, which allow JavaScript in the browser&#8217;s environment to persist reasonable amounts of keyed data throughout or between sessions. This finally brings honest statefulness to our previously stateless browser clients.</p>
<p>On top of this, mature JavaScript runtimes and frameworks happily allow the creation of robust business logic to be applied to this data. DOM manipulation, made reliable and fast by contemporary browsers (and commoditized by libraries for others) means that you can programmatically construct and manipulate entire user interfaces in the browser &#8211; in the extreme case, bootstrapping them up from a <code>&lt;body/&gt;</code>-like document whose main purpose is merely to include a <code>&lt;head&gt;</code> of the linked resources required to execute.</p>
<p>This is the world of the thick web client &#8211; or &#8216;Rich Internet Application&#8217; in slightly out-moded nomenclature. A world in which patterns like MVC can be used again to describing client-side behavior, as well as a server-side technique. With this approach, once a client-side application has loaded its resources and is up and running, it can function more or less independently of the server that originally provided those resources, and creates and maintains a DOM that looks very different to that originally sent in the HTML&#8217;s markup.</p>
<p>(One might wish to argue that GMail is really just a site comprising a set of documents. Conceptually, perhaps. But comparing the app&#8217;s view-source with an inspected DOM tree will present a dramatically different perspective.)</p>
<p>With perhaps the exception of simple games, these applications nearly always need to bind back to some sort of web-based data API. As required, though, they can then easily cache that offline in their own data stores, greatly increasing the responsiveness and user-experience of the application, and making the prospect of continued offline operation a reality. This is a bold new step for the web. Not the web as constantly humming HTTP-pipes, but undoubtedly the web as stack of standardized, open technologies, working in interesting and evolutionary new ways.</p>
<p>I don&#8217;t want to give the impression that I feel this type of architecture should be used for all web experiences, nor even that it&#8217;s easier to build. Creating apps this way can be a daunting experience for many. Using imperative APIs may seem like a step too exotic next to the familiarity of declarative markup-based documents generated from a server. Your mileage will most certainly vary, and definitely some sorts of experience are better suited by one approach, others by the other. No binary proclamations implied.</p>
<p><code>&lt;/tldr&gt;</code></p>
<p>But the point is that perhaps this is the watershed that we are looking for: a relatively clear definition between web site and web application.</p>
<p>The former we can define as an experience constructed on a thick server, delivered, with declarative markup, to thin browser clients, which then render what they&#8217;re told. Sprinkle on some progressive enhancement to maximize the user-experience and increase the chances of delivering a suitably degraded experience to legacy browsers.</p>
<p>The latter, on the other hand, is an experience constructed on a thick browser client, from imperative instructions dispatched, probably only once, from a thin server (or, in the case of a hybrid app, even no server at all). The philosophy of progressive enhancement survives &#8211; perhaps better characterized as &#8216;feature detection&#8217; in this programmatic environment &#8211; although such apps often assume a certain higher baseline of browser capability. Local storage is utilized, MVC-like patterns are followed, concerns of data, logic and presentation are completely separated, and markup, if present at all, might be used merely for templates to be applied to that data.</p>
<p><strong>So&#8230;</strong></p>
<p>&#8230;yes, I&#8217;m a developer. I think in boxes and arrows. But as a relatively unambiguous classification criteria, this final, architectural distinction works best for me. Assuming you agree that such classification matters at all (in particular to those developing such experiences), how does this suit as a working hypothesis?</p>
<p>Discuss, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2011/09/of-sites-and-apps/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Whoops and hashbangs</title>
		<link>http://tripleodeon.com/2011/06/whoops-and-hashbangs/</link>
		<comments>http://tripleodeon.com/2011/06/whoops-and-hashbangs/#comments</comments>
		<pubDate>Wed, 01 Jun 2011 07:42:26 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Observations]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=606</guid>
		<description><![CDATA[Three people in the last week have told me I should be blogging more. Flattered, and probably more helpfully than leaving nuggets of half-baked comments on everyone else&#8217;s, I&#8217;ll do my best. I dust off the cobwebs by apologizing for a tweet in which I misattributed Scott Jehl. No thanks to strange avatar positioning, I [...]]]></description>
			<content:encoded><![CDATA[<p>Three people in the last week have told me I should be blogging more. Flattered, and probably more helpfully than leaving nuggets of half-baked comments on everyone else&#8217;s, I&#8217;ll do my best.<br />
<span id="more-606"></span><br />
I dust off the cobwebs by apologizing for a <a href="http://twitter.com/#!/jamespearce/status/75709304145063937">tweet</a> in which I misattributed Scott Jehl. No thanks to strange avatar positioning, I thought he&#8217;d made a <a href="http://danwebb.net/2011/5/28/it-is-about-the-hashbangs#comment-7617">provocative comment</a> about the destiny of URLs on a post about everyone&#8217;s favorite topic, the hashbang.</p>
<p>(Hopefully I&#8217;m not the only one who can barely see <code>#1e1e1e</code> on <code>#141414</code>)</p>
<p>It did sound out-of-character from a champion of jQuery projects, and perhaps I was tempted to acknowledge the comment because it seemed such an extreme position from him. Sorry Scott!</p>
<p><img src="http://tripleodeon.com/wp-content/uploads/2011/06/quote-500x129.png" alt="" title="quote" width="500" height="129" class="alignnone size-large wp-image-607" /></p>
<p>But onto the comment itself. Why did I take a shine to it? It certainly takes a provocative stance.</p>
<p>&#8220;We are long past the point where URLs have any utility&#8221; is strong language. I of course enjoy the benefits of links and URLs myself every day, and I&#8217;m sure the <a href="http://dakliegg.wordpress.com/">commenter</a> does too: bookmarks, links, emailed or tweeted, the ability to return through a browser&#8217;s history, open new browser tabs with target content and so on. All very useful. All very <a href='http://www.w3.org/Provider/Style/URI'><i>cool</i></a>.</p>
<p>But does this mean that the URL is so sacred we can&#8217;t discuss its role and relevance in the real world? Think about whether it&#8217;s actually doing its job? Wonder whether it&#8217;s productive to shield it from the creative ways in which the web is evolving? And, as this commenter did, consider whether search engines are in fact coping with these changes effectively?</p>
<p>(Heretical to most people&#8230; but the sort of thing I like to think about &#8211; probably <i>for</i> that reason, actually. And what else are blogs for, anyway?)</p>
<p>So, yes, yes; URLs are used as a key for locating documents and resources across the web. That is all well and good. But I&#8217;m thinking; what happens when the web hosts things other than documents and resources? Like applications? Like games? Like physical objects? What happens when we need to serve humans based on <i>other</i> signals, such as their location, the time of day, their context, their intent?</p>
<p>It might <i>just</i> be possible, as the commenter asserts, that a single string-based identifier is not, in fact, sufficient to describe the infinite things that a 21st century, multi-dimensional web can do, offer, and represent.</p>
<p>I&#8217;m not completely sure. But I am convinced (and excited) that the web is evolving in these sorts of ways. Client-side applications, for example, seem to be a perfectly valid and compelling architectural way to use web technologies. And yet what role does the URL play there? Obviously as an entry point to the app as a whole, but then what? Does Tim Berners Lee&#8217;s plea require me to use a URL to describe every possible state, every view and every data point within it?</p>
<p>Documentistas would have it so. I can&#8217;t possibly build anything for the web without every piece of it being addressable like a document. Users must be able to deep-link into any <strike>docu</strike> state of my application. These URLs must return content to robots too &#8211; because where would we be without web crawlers? &#8211; and of course it all needs to degrade nicely for legacy browsers and screen readers. In fact, I may as well just fake the whole thing with server-side markup and progressive enhancement anyway. Many do.</p>
<p>But if I&#8217;m an applicationista, I create true client-side web applications, probably programmatically. I use little, if any, content-bearing markup, and I provide a suite of complex functionality to users, and pull in content from server- or cloud-based APIs in my own particular way. I acknowledge that my application needs to be accessible somehow, but in the corresponding state machine, the concept of a linkable document can quickly become tenuous, if not entirely inappropriate. Yes, I could conceivably use URLs to describe the finite states of a game of tic-tac-toe. But is there a http://angrybirds.com/level4 ? Or a http://angrybirds.com/level4/just-before-the-red-bird-hits-the-big-block ? Not that I know of.</p>
<p>If this web of applications is our new operating system, I see URLs as our command line switches. They can open apps, and sometimes drop you into well-understood states within that app. But by no means is the developer obliged to let any user reproduce any arbitrary state within it. A desktop developer can choose to let users launch a classic native application with certain pre-defined states &#8211; start this tool with a particular file open, for example &#8211; but does so in a very controlled and discoverable way. No native OS I know mandates that an application&#8217;s command line switches must be capable of describing all of its possible states. So why should the web?</p>
<p>In reality, certain web apps will benefit from deep-linkability, but many do not at all. And just because a large part of the web (the documenty bit) holds URLs self-evident and axiomatic might not mean that a different, growing part of the web (the applicationy bit) must do so too. Nick Morgan, admittedly <a href='http://skilldrick.co.uk/2011/05/the-end-of-progressive-enhancement-revisited'>opining on a subtly different topic</a>, states:</p>
<blockquote><p>The problem is that because everyone building stuff online is using the same technologies, there can be a tendency to think that there is one true way of using those technologies, independent of what they’re being used for.</p></blockquote>
<p>And this is the crux. We might all be using web technologies (HTML, JavaScript, CSS and the like), but in radically different architectural configurations, and best practices for some may not be good rules for others. What this touches on might be the primary root cause of the hashbang debate (if not also others): the web is being used in challenging and unexpected ways and we&#8217;re finding it hard to re-examine practices and principles that were intended for a different age.</p>
<p>Yes, hashbangs are ugly. A hack. Sometimes they&#8217;ll need to be replaced with judicious use of the HTML5 History API. But other times they&#8217;ll need to be removed altogether: &#8220;<i>it depends</i>&#8220;.</p>
<p>But I believe that their usage &#8211; and the debate that has raged over that usage &#8211; tells us more about the culture of the web and those who create things for it than it does about syntactic purity or semantic elegance. It has shown us that we still find it hard not to think about the web in terms of documents, and that a web of applications can seem strange and opaque. And maybe that we are in a tighter symbiosis with search engine crawlers than we&#8217;d like to admit. Is that <i>really</i> what is meant when we&#8217;re told we risk breaking the web?</p>
<p>(It might be no co-incidence that our greatest cognitive dissonance occurs when we see something that probably should have remained document-based turned into an application, such as Gawker&#8217;s blogs. I notice that the vehemence of this debate never erupted over the non-linkability to arbitrary internal state of my GMail inbox, or to my high score on <a href='http://entanglement.gopherwoodstudios.com/'>Entanglement</a> for example. But I&#8217;m trying not to miss the wood of the web&#8217;s ambition for the trees of one particular implementation.)</p>
<p>Probably drawing ire, or confusion, from most at this point, I guess I leave it there. Please file under &#8216;verbose trolling&#8217;, and yes, for a developer, I&#8217;m veering dangerously close to amateur anthropology.</p>
<p>But let me finish with the commenter&#8217;s radical assertion that search engines &#8216;have long given up on indexing the web&#8217; &#8211; crazy, surely: they still seem to do a great job with documents.</p>
<p>But applications? I&#8217;m not so sure. He might be on to something here. We&#8217;ve clearly got a long way to go in terms of describing and indexing application state, purpose and functionality on the web &#8211; without resorting to human curation. I&#8217;ve heard of these things called app stores, for example&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2011/06/whoops-and-hashbangs/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>A Web of Sync</title>
		<link>http://tripleodeon.com/2010/12/a-web-of-sync/</link>
		<comments>http://tripleodeon.com/2010/12/a-web-of-sync/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 04:52:52 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=586</guid>
		<description><![CDATA[I&#8217;m excited about how the rise of HTML5 (and related technologies) will change the way we think about the web, and how they will further encourage developers to build richer applications instead of mere document-oriented sites. (At Sencha, for example, we spend a lot of time thinking about what this really means, and how it [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m excited about how the rise of HTML5 (and related technologies) will change the way we think about the web, and how they will further encourage developers to build richer applications instead of mere document-oriented sites.</p>
<p>(At Sencha, for example, we spend a lot of time thinking about what this really means, and how it changes the skills, tools and frameworks we&#8217;ll all need to be effective web practitioners)</p>
<p>But here, I&#8217;d like to consider three particular changes that are happening, and one particularly overlooked impact they might have.<br />
<span id="more-586"></span><br />
The first is the rise of powerful application architectures on the client side. Sencha has added Model-View-Controller support in both Ext JS 4 and Sencha Touch, for example, and this makes it possible to implement entire data schemas, rich business logic, and well-structured user interfaces &#8211; entirely on the client side. (Other frameworks are following a similar path: SproutCore, JavaScriptMVC and so on)</p>
<p>Secondly, the way in which HTML5 provides support for local and offline storage makes the autonomy of these apps a real possibility. Viewing, filtering and manipulating data can still be performed in the browser, even when completely disconnected from the server (or the entire network, in the case of a mobile device that loses coverage).</p>
<p>Finally, there are the possibilities of being able to use Javascript on the server-side of the web. The rise of interest in node.js, for example, is largely prompted by the opportunity to be able to use the same programming language throughout the entire web stack.</p>
<p>But such changes mean that this stack is changing shape.</p>
<p>Historically, the entire logic of delivering web-based services to browsers was built on the server-side. Databases, security layers, business logic, user interface creation &#8211; all of this was within the realm of the web server, and the browser merely took the resulting HTML and dumbly rendered it for the user.</p>
<p><img style='border:1px solid #999' src="http://tripleodeon.com/wp-content/uploads/2010/12/Web-of-Synchronization.0011-500x319.png" alt="" title="Web of Synchronization.001" width="500" height="319" class="alignnone size-large wp-image-593" /></p>
<p>Of course, this is incredibly inefficient: the entire stack is executed (and a whole page of HTML generated) for almost every single user interaction. To mitigate this, web developers turned to AJAX &#038; AHAH to start placing more of the user interface logic in the client&#8217;s runtime environment, and to reduce the size of the payloads involved. The stack started to span both the server and client sides of the picture.</p>
<p><img style='border:1px solid #999' src="http://tripleodeon.com/wp-content/uploads/2010/12/Web-of-Synchronization.002-500x319.png" alt="" title="Web of Synchronization.002" width="500" height="319" class="alignnone size-large wp-image-594" /></p>
<p>But with client-side MVC and support for local storage techniques, we can take this stack evolution a whole step further. With Sencha Touch, for example, an application constructs its entire user interface from scratch, and can synthesize the entire business logic, validation ruleset, and storage schema that would have traditionally been encapsulated on the server side.</p>
<p>Now, islands of independent data on each and every user&#8217;s device might make for a useful service, but it is far more likely that most applications will continue to operate in conjunction with a server &#8211; which, with the appropriate layer of security to protect access to it, will provide a central storage repository.</p>
<p>Our stack has now been neatly split in two.</p>
<p><img style='border:1px solid #999' src="http://tripleodeon.com/wp-content/uploads/2010/12/Web-of-Synchronization.003-500x319.png" alt="" title="Web of Synchronization.003" width="500" height="319" class="alignnone size-large wp-image-595" /></p>
<p>(Note that, in the same way that we&#8217;ve long learnt to run both client-side and server-side validation of data submitted from HTML forms, it will probably remain wise to mirror business logic on both sides of the network to prevent inconsistency. While the rise of Javascript on the server theoretically makes it possible to do this with one set of common code, in reality, most server stacks will remain non-JS based for some time.)</p>
<p>All well and good. But in one very particular respect, an architecture like this is deeply ambitious. We have added a significant new programming challenge into the mix: and that is one of data synchronization.</p>
<p>When the browser is merely displaying read-only HTML or AHAH, the definitive copy of the business data is one place only: the server. But in this new architecture, we have the same logical data in two places &#8211; and, assuming we&#8217;re allowing users to interact with their copy of it, quite possibly off-line, we have to deal with the matter of keeping the two (or N) data sets consistent.</p>
<p>At a protocol level, this is simple enough. We can easily use JSON to transmit data bidirectionally over an HTTP wire, and Ext JS and Sencha Touch&#8217;s model store classes, for example, take care of all the plumbing for us. But when we should do so, what the payload should be &#8211; and how we reconcile any conflicts between client and server &#8211; can quickly become interesting design questions.</p>
<p>Consider a web-based corporate price list application, build using a client-side MVC pattern, and providing up-to-date information about a company&#8217;s products to its mobile salesforce. On its first instantiation on a mobile device, say, such an application might easily pull the entire list of product records from the server over JSON and store them locally for fast, possibly off-line, access.</p>
<p>So far, so easy. But of course the records might frequently change on the server: the company creates new products, discontinues old ones, and often changes their prices. How should the &#8216;create&#8217;, &#8216;delete&#8217; and &#8216;update&#8217; operations be applied to the mobile device&#8217;s version of the data? Should it regularly refresh the whole data set again? Should it request all changes since the last sync and then incrementally apply those changes to its local copy? If certain data is not updated for a certain length of time, should the client application mark it as stale?</p>
<p>These are already thoughtful decisions for the application developer to have to make.</p>
<p>But now imagine that the company&#8217;s product managers are given more powerful rights within the same application, and they can actually edit the product descriptions on their mobile devices. When connected, these changes can be immediately sent directly back to the server. How can we ensure that other users&#8217; apps can have that change broadcast to them?</p>
<p>What about when the product manager is off-line, perhaps editing the portfolio on a plane? Should the application prohibit updates to the local data? Preferably not, but if changes can be made, how should the application poll to see when it is reconnected, and send those changes back in the most efficient way?</p>
<p>Taking it to extreme, what happens when two product managers edit the same pieces of data? What happens when each have added a new product to which their client applications have assigned the same supposedly unique ID? The system needs to reconcile those potentially conflicting changes &#8211; and very quickly this becomes a non-trivial task.</p>
<p>In the broader computing world, these challenges are common and have been frequently, and successfully, addressed. Many proven solutions exist for synchronization in the realms of distributed file systems, versioned source control, disk, database and site mirroring and so on &#8211; and even to manage our MP3 collections. But what is new is that this will soon becoming a challenge that web developers will need to tackle, and it is a challenge that might be unfamiliar and daunting to many.</p>
<p>In the general case, of course, there is no single approach that will answer all these questions. Effective synchronization across a &#8216;split stack&#8217; architecture will depend very much upon the sort of data that is being manipulated and what the application is setting out to achieve.</p>
<p>Frameworks will certainly provide us with all the tools we need to implement the choices we make. But considering these synchronization-related scenarios and use-cases will be an increasingly important part of bringing compelling applications to users in increasingly diverse contexts. Reconciliation will lie at the heart of how we bring complex applications to life &#8211; not just an after-thought.</p>
<p>The web is no longer one of documents or of simple uni-directional data: it is fast becoming a web of synchronization. And I fear it might not be as easy as we think. As developers, we all need to go into this new world with our eyes wide open and be prepared for new challenges around the corner.</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2010/12/a-web-of-sync/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Sencha Touch + DeviceMotion APIs (= a small plastic toy)</title>
		<link>http://tripleodeon.com/2010/12/sencha-touch-devicemotion-apis-small-plastic-toy/</link>
		<comments>http://tripleodeon.com/2010/12/sencha-touch-devicemotion-apis-small-plastic-toy/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 06:38:03 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=574</guid>
		<description><![CDATA[Here at Sencha Towers, we&#8217;ve been having a bunch of fun with the new accelerometer &#038; gyroscope APIs in the iOS4.2 web browser. Rob Dougan has put together a tilt-controlled list and Ariya Hidayat a box of marbles. Both require an updated iPhone or iPod Touch (although Ariya&#8217;s also works on a MacBook Pro if [...]]]></description>
			<content:encoded><![CDATA[<p>Here at Sencha Towers, we&#8217;ve been having a bunch of fun with the new accelerometer &#038; gyroscope APIs in the iOS4.2 web browser.<br />
<span id="more-574"></span><br />
Rob Dougan has put together a <a href='http://b.rwd.me/'>tilt-controlled list</a> and Ariya Hidayat a <a href='http://ariya.github.com/js/marblebox/'>box of marbles</a>. Both require an updated iPhone or iPod Touch (although Ariya&#8217;s also works on a MacBook Pro if you use the Chrome browser).</p>
<p>The APIs are pretty easy to use, and seem to follow the W3C (<a href='http://dev.w3.org/geo/api/spec-source-orientation.html'>draft</a>) standards.</p>
<p>I thought I would have a go to, and so I wrote a <a href="http://tinyurl.com/ioslide">small Sencha Touch app</a> that mimics one of those small sliding puzzles we all had as kids &#8211; but where the tiles are moved not with touch gestures, but by sliding the pieces under gravity.</p>
<p><img src="http://tripleodeon.com/wp-content/uploads/2010/12/ioslider-500x266.png" alt="" title="ioslider" width="500" height="266" class="alignnone size-large wp-image-575" /></p>
<p>From a Sencha Touch point of view, I&#8217;ve tried to use a best-practice application structure, and both the grid and the tiles are Ext.Panels (which makes them easy to treat in an object-oriented way and, in the case of the tiles, instantiate arbitrarily).</p>
<p>I have set up Ext.EventManager listeners for devicemotion and deviceorientation events, and fortunately, the callback can access the underlying browser event to get the motion-based properties I need.</p>
<p>The tiles themselves are placed on the grid using CSS transforms, rather than top/left positioning, along the lines of:</p>
<pre>Ext.Element.cssTransform(this.getEl(), {translate: [x, y]});</pre>
<p> This makes coding the sliding movement unbelievably easy: I simply have to change the transformation to where I want the tile to move to, and then</p>
<pre>-webkit-transition:-webkit-transform .8s ease-in;</pre>
<p>does the gentle slide. Wow. Transitions and transforms have been a spectacular epiphany for me in the last few months.</p>
<p>One catch with web-based tilt control: tip the device more than 45 degrees, and you might find yourself switching between portrait and landscape mode. I don&#8217;t know of a way to disable this in Mobile Safari.</p>
<p>The issue with this is that the co-ordinate system of the device&#8217;s physical orientation does not rotate, but the web page does. So in my case, I check the window&#8217;s current rotation and subtract the appropriate multiple of 90 degrees so that the elements still slide in the direction expected for the device&#8217;s physical position.</p>
<p>To test it out, get an iPhone or iPod Touch with iOS4.2 installed. Put the device level on a horizontal surface, go to <a href="http://tinyurl.com/ioslide">http://tinyurl.com/ioslide</a> &#8211; then tilt the device about 15 degrees in various directions to make the tiles slide.</p>
<p>Also feel free to look at (and be tempted to improve!) the code. Small, simple, and good fun: let me know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2010/12/sencha-touch-devicemotion-apis-small-plastic-toy/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>CSS3 goes walkabout</title>
		<link>http://tripleodeon.com/2010/10/css3-goes-walkabout/</link>
		<comments>http://tripleodeon.com/2010/10/css3-goes-walkabout/#comments</comments>
		<pubDate>Wed, 27 Oct 2010 23:29:10 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=548</guid>
		<description><![CDATA[Yesterday, Sencha released Sencha Animator: a tool designed to build CSS3-based animations. Like a few others today, I thought I should get familiar with it, and gave it a whirl this morning. My artistic genes don&#8217;t even pass their unit tests&#8230; so if I can make something work (admittedly with some help from Preston Blair), [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, Sencha released <a href="http://www.sencha.com/products/animator/">Sencha Animator</a>: a tool designed to build CSS3-based animations.</p>
<p>Like <a href="http://notes.sencha.com/post/1418349616/sencha-animator-bouncing-ball-demo-11-45">a few others</a> today, I thought I should get familiar with it, and gave it a whirl this morning. My artistic genes don&#8217;t even pass their unit tests&#8230; so if <em>I</em> can make something work (admittedly with some help from <a href='http://minyos.its.rmit.edu.au/aim/a_notes/p_images/walk_2_legs(side).gif'>Preston Blair</a>), then anyone can.<br />
<span id="more-548"></span><br />
<img src="/wp-content/uploads/2010/10/sencha_animator-500x356.png" alt="" title="sencha_animator" width="500" height="356" class="alignnone size-large wp-image-561" /></p>
<p>If you have a WebKit-based browser like Chrome, Safari or their mobile brethren, you should be able to see the results of my efforts in an &lt;iframe&gt; below, or on the <a href='/wp-content/uploads/2010/10/divman.html'>standalone page</a>:</p>
<p><iframe src='/wp-content/uploads/2010/10/divman.html' style='border:none;width:320px;height:320px'></iframe></p>
<p>It&#8217;s somewhat scary to know that I&#8217;m basically drawing line-art with bordered &lt;div&gt; elements, but certainly it&#8217;s fluid and reliable enough on all the appropriate browsers I&#8217;ve tried.</p>
<p>I have no idea what it looks like on non-compatible browsers. For now, I daren&#8217;t think.</p>
<p>But the same page works like clockwork on suitably (that is, &#8216;highly&#8217;) capable mobile browsers. This screenshot is from the iPhone4 emulator:</p>
<p><img src="/wp-content/uploads/2010/10/divman_iphone4-362x500.png" alt="" title="" width="362" height="500" class="alignnone size-large wp-image-558" /></p>
<p>Help yourself to my <a href='/wp-content/uploads/2010/10/WalkingMan.anim'>.anim file</a> if you want to use this skeleton for your own animations.</p>
<p>Some say that using CSS3 for animation is going to be a standards-based way to replace Flash, and it may well become so at some point. Others say that it means we&#8217;re set for another decade of bad splash screens and corny animations. That may also be true &#8211; but you don&#8217;t ban paintbrushes just because there are bad painters.</p>
<p>Anyway, for now, I had a lot of fun. I&#8217;m excited to have seen a glimpse of what CSS3 Animations are capable of; even if they&#8217;re certainly not something I would ever have wanted to craft by hand: view source to see what I mean.</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2010/10/css3-goes-walkabout/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Modernizr on the server-side</title>
		<link>http://tripleodeon.com/2010/10/modernizr-on-the-server-side/</link>
		<comments>http://tripleodeon.com/2010/10/modernizr-on-the-server-side/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 15:25:00 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=537</guid>
		<description><![CDATA[The modernizr-server library is a way to bring Modernizr browser data to your server scripting environment. There are a host of emerging techniques for adjusting web content to suit different types of browsers. The current vogue seems to be to do as much of it as possible on the client-side: media queries, progressive enhancement, adding [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href='http://github.com/jamesgpearce/modernizr-server'>modernizr-server</a> library is a way to bring Modernizr browser data to your server scripting environment.<br />
<span id="more-537"></span><br />
There are a host of emerging techniques for adjusting web content to suit different types of browsers.</p>
<p>The current vogue seems to be to do as much of it as possible on the client-side: media queries, progressive enhancement, adding CSS body classes, and so on.</p>
<p>These are all cool, and hit a resonance with those who deal entirely with the front-end of a web site, and who prefer CSS (and a little Javascript) to Python, Ruby, PHP and the like.</p>
<p>In my opinion, this approach won&#8217;t <i>always</i> cut it. I&#8217;ve already <a href='/2010/10/not-a-mobile-web-merely-a-320px-wide-one/'>pointed out</a> that the users of radically different devices might want downright different things. Sometimes the differences between browsers are just too great to be able to deal with once the page has reached the client. And dealing with structural changes to a site&#8217;s information architecture based on browser capabilities gets messy, fast.</p>
<p>(Imagine if my site had a conditional a &#8216;photo upload&#8217; feature that I wanted to place in the site&#8217;s menu for mobile devices that supported it. Do I have to feature test &lt;input type=&#8217;file&#8217;&gt; on every page, simply so I can add or remove nodes from the menu&#8217;s DOM? Ugh.)</p>
<p>So anyway, sometimes it&#8217;s far better to have had the server emit the best content in the first place &#8211; or at least as close as possible.</p>
<p>With this in mind, I&#8217;ve a new project called <a href='http://github.com/jamesgpearce/modernizr-server'>modernizr-server</a>.</p>
<p><a href='http://modernizr.com'>Modernizr</a> itself is a great way to find out about your user&#8217;s browser capabilities. However, you can only access its API on the browser itself, which means you can&#8217;t easily benefit from knowing about browser capabilities in your server logic.</p>
<p>To address this, the modernizr-server library is a way to bring Modernizr browser data to your server scripting environment. For example, in PHP:</p>
<pre><code>&lt;?php

    include('modernizr-server.php');

    print 'The server knows:';
    foreach($modernizr as $feature=&gt;$value) {
        print "&lt;br/&gt; $feature: "; print_r($value);
    }

?&gt;

The server knows:
canvas: 1
canvastext: 1
geolocation: 1
crosswindowmessaging: 1
websqldatabase: 1
indexeddb: 0
hashchange: 1
...</code></pre>
<p>Exactly the same feature detection is available through this (PHP) API on the server as is available through the (Javascript) API on the client.</p>
<p>Currently, there is only a PHP implementation of the server-side API, but other languages would be easy enough. Stay tuned to the project for more (and let me know what might be a priority, or fork!).</p>
<p>For instructions on how to use, and information about how it works, you&#8217;re encouraged to consult the <a href='http://github.com/jamesgpearce/modernizr-server/blob/master/README.md'>readme</a>. Also this is a young project, so please use in high-traffic production environments with due caution.</p>
<p>Your feedback is welcome! Hope it&#8217;s helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2010/10/modernizr-on-the-server-side/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>monomi: mobile middleware for node.js</title>
		<link>http://tripleodeon.com/2010/10/monomi-mobile-middleware-for-node-js/</link>
		<comments>http://tripleodeon.com/2010/10/monomi-mobile-middleware-for-node-js/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 18:56:47 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=483</guid>
		<description><![CDATA[monomi is node.js middleware that provides tools for handling mobile (and other types of) browsers. It relies on the excellent Connect layer, and is easy to install with npm. Currently, monomi analyzes incoming HTTP requests to detect which type of browser they come from. Default values are &#8216;desktop&#8217;, &#8216;tablet&#8217;, &#8216;touch&#8217;, and &#8216;mobile&#8217; (meaning non-touch), and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/jamesgpearce/monomi">monomi</a> is node.js middleware that provides tools for handling mobile (and other types of) browsers.<br />
<span id="more-483"></span><br />
It relies on the excellent <a href="http://github.com/senchalabs/connect">Connect</a> layer, and is easy to install with <a href="http://github.com/isaacs/npm">npm</a>.</p>
<p>Currently, monomi analyzes incoming HTTP requests to detect which type of browser they come from. Default values are &#8216;desktop&#8217;, &#8216;tablet&#8217;, &#8216;touch&#8217;, and &#8216;mobile&#8217; (meaning non-touch), and the type is put into the request.monomi.browserType property.</p>
<p>The order of preference for the detection, as well as the algorithms used, can all be optionally overridden when the middleware is instantiated.</p>
<p>It&#8217;s early days for the project&#8230; I have plans to allow the middleware to adapt the outgoing content to be appropriate for the detected device &#8211; although this needs to be sensitive to the asynchronous philosophy of node.js</p>
<p>Try it, fork it, experiment, have fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2010/10/monomi-mobile-middleware-for-node-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Analytics With Python, Django, ASP.NET, Java, and node.js</title>
		<link>http://tripleodeon.com/2010/08/mobile-analytics-with-python-django-asp-net-java-and-node-js/</link>
		<comments>http://tripleodeon.com/2010/08/mobile-analytics-with-python-django-asp-net-java-and-node-js/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 06:42:30 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=380</guid>
		<description><![CDATA[A few weeks ago, the PercentMobile team came to me to see if I could help write some new libraries for them. Contemporary web and mobile web sites are written on a vast array of different platforms… and obviously the more that PercentMobile supports, the better. Something I love about programming is that there are [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, the <a href="http://percentmobile.com">PercentMobile</a> team came to me to see if I could help write some new libraries for them. Contemporary web and mobile web sites are written on a vast array of different platforms… and obviously the more that PercentMobile supports, the better.<br />
<span id="more-380"></span></p>
<p>Something I love about programming is that there are so many languages to choose from &#8211; why restrict yourself to learning or becoming an expert at one when the same problems are also being solved in other, sometimes better, ways? Each language or platform has strengths and weaknesses of course. But I believe that understanding the differences &#8211; and more often, the similarities &#8211; makes one a better programmer.</p>
<p>So, generous polyglot that I am, I took the challenge, and plunged in.<br />
(Sign up for the free PercentMobile service to get the libraries described in this post.)</p>
<h2>Python &amp; Django</h2>
<p>I love <a href="http://python.org" target="_blank">Python</a> &#8211; its readability, its libraries, and its overall philosophies. In a web server environment, Python can be used in a fairly raw way, behind a generic Web Service Gateway Interface (WSGI), but there are also a number of powerful web application frameworks using the language &#8211; most notably <a href="http://djangoproject.com/" target="_blank">Django</a>. PercentMobile want to provide painless Django support, but also to make sure that other Python server environments were not precluded.</p>
<p><code>percentmobile.py</code> is the single file that provides everything you need.</p>
<p>If you are running code in a WSGI environment, you will have a handle to the WSGI environment. This is normally called <code>environ</code> by convention, and is passed in to your application via your top-level WSGI callable. To make the PercentMobile tracking code work, you need only make one call to the <code>percentmobile.tracker_cookie_insert</code> function. It returns two values: the cookie that you’ll need to set in the HTTP response headers, and the HTML that you should insert into your page.</p>
<p>Say, for example, you had a very simple WSGI app. This responds to requests with an HTTP 200 status code, a single header and some simple HTML:</p>
<pre><code>def my_app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type','text/html')]
    start_response(status, response_headers)
    return ["Hello world"]</code></pre>
<p>To add PercentMobile tracking to this code, you need to firstly import the tracker library of course, and then call the <code>tracker_cookie_insert</code> function:</p>
<pre><code>import percentmobile
cookie, insert = percentmobile.tracker_cookie_insert(environ, '1234555')</code></pre>
<p>(Of course you should replace the final string with your own site ID!)</p>
<p>The <code>cookie</code> return value is actually a dictionary of the different parts needed to construct its string serialization. This will allow you to splice together multiple cookies, or alter the expiry time, path scope and so on. To convert the dictionary to a string, and to get the Set-Cookie header sent back in the request headers, the following code will suffice:</p>
<pre><code>cookie = "%s=%s; expires=%s; path=%s" % (
    cookie['name'],
    cookie['value'],
    cookie['expires'],
    cookie['path']
)
response_headers = [('Content-type','text/html'), ('Set-Cookie', cookie)]</code></pre>
<p>Finally, you need to make sure the HTML fragment, in the <code>insert</code> variable, gets placed in the HTML response:</p>
<pre><code>return ["&lt;html&gt;&lt;body&gt;Hello world %s&lt;/body&gt;&lt;/html&gt;" % insert]</code></pre>
<p>And that’s a wrap. The whole, PercentMobile-tracked WSGI application looks like this:</p>
<pre><code>def my_app(environ, start_response):
    cookie, insert = percentmobile.tracker_cookie_insert(environ, '1234555')
    cookie = "%s=%s; expires=%s; path=%s" % (
        cookie['name'],
        cookie['value'],
        cookie['expires'],
        cookie['path']
    )
    status = '200 OK'
    response_headers = [('Content-type','text/html'), ('Set-Cookie', cookie)]
    start_response(status, response_headers)
    return ["&lt;html&gt;&lt;body&gt;Hello world %s&lt;/body&gt;&lt;/html&gt;" % insert]</code></pre>
<p>Pretty easy, huh? Well, not as easy as tracking an app if you’re using the amazing Django framework! Contained in the same <code>percentmobile.py</code> file is a class that can be used as Django middleware. It uses the same underlying function as the WSGI implementation, but also takes care of the headers and insertion for you.</p>
<p>Assuming you’ve placed the library file in your Python or Django path, you simply need to add two lines of code in the settings file. Firstly add the <code>percentmobile.PercentMobileDjangoMiddleware</code> class to your list of middleware:</p>
<pre><code>MIDDLEWARE_CLASSES = (
    ...
    'percentmobile.PercentMobileDjangoMiddleware'
)</code></pre>
<p>And secondly, add your PercentMobile site ID to the settings file too:</p>
<pre><code>PERCENTMOBILE_SITE_ID = '1234555'</code></pre>
<p>Um… that’s it. The middleware will intercept the request, figure out the cookie that will need to be sent in the response, create the insertion code, and place it just before <code>&lt;/body&gt;</code> in the response. You’re golden. I love Django.</p>
<h2>ASP.NET: C# &amp; VB.NET</h2>
<p>Switching over to another world altogether, let’s take a quick look at the <a href="http://asp.net/" target="_blank">ASP.NET</a> implementation of the tracking code. One of the great things about .NET is that you can choose between all sorts of different languages to write your applications and pages in. I decided to write the tracking library in C#, but you can use it declaratively in your page code, or programmatically from C#, VB.NET, or any other supported language.</p>
<p>The library is implemented as a User Control &#8211; that is, as a .ascx file. You need to download and add <code>PercentMobile.ascx</code> to your web application project.</p>
<p>To embed the tracking logic into a page (or probably preferably, a master page), you simply register the user control as residing in that file:</p>
<pre><code>&lt;%@ Register TagPrefix="pm" TagName="Tracker" Src="~/PercentMobile.ascx" %&gt;</code></pre>
<p>And then embed the control straight into the .aspx file contents, wherever you want it to be:</p>
<pre><code>&lt;pm:Tracker runat="server" SiteId="1234555" /&gt;</code></pre>
<p>So a simple, tracked .aspx file might look something like this:</p>
<pre><code>&lt;%@ Page Language="C#" AutoEventWireup="true" %&gt;
&lt;%@ Register TagPrefix="pm" TagName="Tracker" Src="~/PercentMobile.ascx" %&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;&lt;title&gt;Hello World&lt;/title&gt;&lt;/head&gt;
    &lt;body&gt;
        &lt;form id="form1" runat="server"&gt;
            &lt;div&gt;Hello World&lt;/div&gt;
            &lt;pm:Tracker runat="server" SiteId="1234555" /&gt;
        &lt;/form&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>To be honest, this is so simple that I would expect most people to use the control declaratively. But if, for some reason, the control needs to be inserted programmatically, that’s pretty easy too. You need to use the <code>Reference</code> directive, instead of <code>Register</code>, at the top of the file, but otherwise it’s not much harder. Here, we’re using VB.NET to programmatically achieve exactly the same result as above:</p>
<pre><code>&lt;%@ Page Language="VB" AutoEventWireup="true" %&gt;&lt;%@ Reference Control="~/PercentMobile.ascx" %&gt;

&lt;script runat="server"&gt;
    Private tracker As PercentMobile.Tracker
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        tracker = CType(LoadControl("~/PercentMobile.ascx"), PercentMobile.Tracker)
        tracker.siteId = "1234555"
        form1.Controls.Add(tracker)
    End Sub
&lt;/script&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;&lt;title&gt;Hello World&lt;/title&gt;&lt;/head&gt;
    &lt;body&gt;
        &lt;form id="form1" runat="server"&gt;
            &lt;div&gt;Hello World&lt;/div&gt;
        &lt;/form&gt;
    &lt;/body&gt;
&lt;/html&gt;

</code></pre>
<p>(It should be fairly straightforward to see how to do this in other .NET languages &#8211; PercentMobile includes some examples in their install instructions.)</p>
<h2>Java</h2>
<p>Onwards. Let’s take a look at the tracking code for <a href="http://java.com" target="_blank">Java</a>. There are numerous ways in which Java can be used for web or application server environments. To keep things simple, I decided that supporting JSP was more or less the most familiar and reusable approach.</p>
<p>JSP doesn’t enjoy the rich page event model that I was able to use in ASP.NET to intercept headers, write cookies, and insert HTML, all with one include. <code>&lt;jsp:include&gt;</code> is OK for adding the HTML snippets, but wouldn’t let me access the HTTP headers. <code>&lt;jsp:forward&gt;</code> does, but would only work if you weren’t planning to emit any HTML of your own after the tracking code &#8211; something of a radical assumption.</p>
<p>So I settled for an approach where an include <em>directive</em> creates an instance of an inner <code>PercentMobile</code> class defined within the JSP class. To cut a long story short, this means you merely add a reference to the library file at the top of the JSP file:</p>
<pre><code>&lt;%@ include file="percentmobile.jsp" %&gt;</code></pre>
<p>And then call the track method on that instance, somewhere within the page:</p>
<pre><code>&lt;%percentMobile.track("1234555");%&gt;</code></pre>
<p>The included JSP file takes care of instantiating the <code>percentMobile</code> object and giving it references to the request and response stream. This means it can read and write cookies, and later emit HTML. Your tracked Hello World in Java then? It’s as simple as this:</p>
<pre><code>&lt;%@ include file="percentmobile.jsp" %&gt;
 &lt;html&gt;
  &lt;body&gt;
    Hello World
    &lt;%percentMobile.track("1234555");%&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<h2>node.js</h2>
<p>OK, OK. Python, ASP.NET, Java. No big deal, right? That’s all so 2003 or so, right?</p>
<p>Well, there’s an alternative future for web server technologies. It’s one that’s blazingly fast, lightweight, event-driven, and… where you write your server logic in Javascript.</p>
<p><a href="http://nodejs.org/" target="_blank">node.js</a> is one of the most exciting things I’ve seen for a long time, and I know I’m not alone. Fresh, fashionable, and somewhat unproven, admittedly, it’s had a lot of gushing coverage. But since it turns the web server model (almost literally) inside out, I do believe there’s something important going on.</p>
<p>Would it be possible to write a web app with node.js and still have it tracked by PercentMobile? My challenge.</p>
<p>I decided to rely on <a href="http://howtonode.org/connect-it" target="_blank">Connect</a>, a middleware framework for node.js, which, if you are writing web applications, provides a whole host of other helpful web logic. Using Connect to create a simple node.js app is extremely easy:</p>
<pre><code>var Connect = require('connect');
Connect.createServer(
  function (req, res, next) {
    res.simpleBody(200,
      "&lt;html&gt;&lt;body&gt;Hello World" +
      "&lt;/body&gt;&lt;/html&gt;",
      {
        "Content-Type": "text/html"
      }
    );
  }
).listen(88);</code></pre>
<p>To add PercentMobile tracking to this application firstly requires you to pull in the PercentMobile module:</p>
<pre><code>var PercentMobile = require('./percentmobile');</code></pre>
<p>(Where the <code>percentmobile.js</code> file has been placed in your node.js environment or in the common modules location.)</p>
<p>The module needs to be initialized as a piece of Connect middleware in the createServer function:</p>
<pre><code>PercentMobile.init('1234555')</code></pre>
<p>There are then two module functions, <code>cookie</code> and <code>html</code>, which both take a reference to the response object, and which return the cookie string and HTML to insert, respectively. These can be used in Connect’s <code>simpleBody</code> function, for example, meaning that our tracked application is as simple as this:</p>
<pre><code>var Connect = require('connect');
var PercentMobile = require('./percentmobile');
Connect.createServer(
  PercentMobile.init('1234555'),
  function (req, res, next) {
    res.simpleBody(200,
      "&lt;html&gt;&lt;body&gt;Hello World" +
        PercentMobile.html(res) +
      "&lt;/body&gt;&lt;/html&gt;",
      {
        "Content-Type": "text/html",
        "Set-Cookie": PercentMobile.cookie(res)
      }
    );
  }
).listen(88);</code></pre>
<h2>That’s a wrap</h2>
<p>So that’s it. A whistle-stop tour of the new languages and frameworks supported by PercentMobile. I’d love to hear your feedback on how easy (or hard!) these new APIs are to use.</p>
<p>And, oh… who will be the first to build a mobile web app on node.js? <img src='http://tripleodeon.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2010/08/mobile-analytics-with-python-django-asp-net-java-and-node-js/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WhitherApps</title>
		<link>http://tripleodeon.com/2010/08/whitherapps/</link>
		<comments>http://tripleodeon.com/2010/08/whitherapps/#comments</comments>
		<pubDate>Sun, 08 Aug 2010 03:10:20 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Mobile Web]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://tripleodeon.com/?p=363</guid>
		<description><![CDATA[Why spend your life recompiling native client apps when you have HTML5 and the mighty mobile web at your disposal? WhitherApps sets out to debunk some contemporary mobile myths. WhitherApps is a bandwagon-busting experiment. I believe there are far too many native client apps which could have been far better written as mobile web apps. [...]]]></description>
			<content:encoded><![CDATA[<p>Why spend your life recompiling native client apps when you have HTML5 and the mighty mobile web at your disposal? <a href="http://whitherapps.com">WhitherApps</a> sets out to debunk some contemporary mobile myths.<br />
<span id="more-363"></span><br />
WhitherApps is a bandwagon-busting experiment. I believe there are  far too many native client apps which could have been far better written  as mobile web apps. What I&#8217;m trying to do with the project is take a few particularly obvious examples, apply a little reverse-engineering, and rewrite them, warts  and all, with web technologies.</p>
<p>I&#8217;m focussing on native client apps that are free to download. These  wouldn’t have suffered commercially had they been written this way in  the first place. Obviously, I’ll also focus on feasible genres of apps. No 3D games  or background apps, for example. To start with, informational media apps  (such as newspapers and broadcasters) will be in the spotlight.</p>
<p>But otherwise, I may not need to pull too many punches. Offline  access? Through the wonders of HTML5, that should be OK. Native device  API access? Well, BONDI and proprietary libraries permitting, I’ll have  a go – and there’s always PhoneGap too.</p>
<p>Each post on the site will be a walkthrough (or part of a walkhrough)  of the process. As I get my hands dirty, from the protocol-sniffing  to the pixel-jiggling, you can follow the steps I took.</p>
<p>Stay tuned and wish me luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://tripleodeon.com/2010/08/whitherapps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

