Deep-linking is important. It’s what makes the web so … webby. Usability guru Jakob Nielsen tells us that Deep Linking is Good Linking, and hypertext pioneer Doug Engelbart encourages us to make “Every Object Addressable.”
With the old-web, deep-linking was easy because everything was a page and every page had a URL. In the new RIA web however, a complex web app can fit into a single page, and without some careful programming, we lose the ability to bookmark or share objects and places inside the app.
To get deep-linking in an RIA, we need to store the link info in the hash part of the URL. For example, the Google Docreader team has documented their scheme for deep-linking into ajax-ified documentation. Deep-linking to Flash content with SWFAddress also takes advantage of the hash component of a URL.
In Appcelerator, a convenient way to provide deep-linkable addresses (as well as sane forward-backward button support) is to use Appcelerator Routes to map the hash part of a URL onto an Appcelerator message. Routes have a similar syntax to Ruby on Rails routes, but are entirely client-side.
An example routes definition:
routes({ '#home' : 'r:get.home.request', '#cat/:id' : 'r:get.animal.request[type=cat,id=#{id}]', '#dog/:id' : 'r:get.animal.request[type=dog,id=#{id}]', '#yaps/:fromid/:toid' : 'r:get.messages.request[dogid=#{fromid},catid=#{toid}]', '#hisses/:fromid/:toid' : 'r:get.messages.request[catid=#{fromid},dogid=#{toid}]', });
Now, when someone navigates to http://yourapp.com/pets#dog/fido, the message r:get.animal.request[type=dog,id=fido] will be fired on page load. Inside your UI code, you can react to the response of this message to switch the active section of your app:
<div on="r:get.animal.response[type=dog] then show and bind[dog_info] else hide" style="display: none"> My Cat Friends: < app:iterator on="r:get.animal.request[type=dog] then execute" property="dog_info.cat_friends"> <a href="#cat/#{cat_id}">#{name}</a> (<a href="#yaps/#{my_id}/#{cat_id}">Our messages</a>)<br/> < /app:iterator> <!-- more UI for viewing a dog --> </div> <div on="r:get.animal.response[type=cat] then show and bind[cat_info] else hide" style="display: none"> <!-- UI for viewing a cat --> </div> <div> <!-- another section of the app --> </div>
So, when http://yourapp.com/pets#dog/fido loads, a remote message will be fired, a response (hopefully containing some friends) will return, the iterator will be executed, and links will be generated. If Fido has a cat friend named Milo, we’d get HTML generated (client-side), like this:
<a href="#cat/milo">Milo</a> (<a href="#yaps/fido/milo">Our messages</a>)
Both of those links will fire an Appcelerator message when clicked, as well as changing the hash component of the URL (which is what makes forward/backward usable). Because we’ve set up an else-clause for the dog-ui section (r:get.animal.request[type=dog] then show and bind[dog_info] else hide), if the user clicks the #cat/milo link, the currect section will hide, and the cat-ui section will be shown.
So, with a few lines of declarative javascript, we’ve been able to retain all the webby goodness of deep-linking, and also reap the benefits of Appcelerator’s transparent client/server messaging and client-side templating. Cool, huh?
Popularity: 3% [?]

September 6th, 2008 at 7:40 am
Deep Linkability - for sending/bookmarking links, going forward/backward between links (history) and refreshing link content - is exactly one of those important web 1.0 UI patterns one wouldn’t want to miss in web 2.0 apps
!
Another web 1.0 UI pattern I was missing in web 2.0 apps just recently:
- “Browser form field input history”; that is: Values, which have been typed into a form field before, are NOT suggested later on … This “input value suggest pattern” - e.g. based on former input values - is supported for plain old HTML forms in all browsers; and for a good reason: One just does not want to type in already typed in values - numbers, strings, dates, etc. - over and over again …
IMO deep linkability as well as form field input history are very important patterns for usable UIs ! My questions are now:
- Could there be even more important web 1.0 UI patterns which have been overlooked in web 2.0 UIs ?
- Does Appcelerator support “Browser form field input history” ?
- What about those patterns in widgets leveraged by Appcelerator ?
September 6th, 2008 at 2:13 pm
Hi Kai, glad you liked the article!
Input field history is implemented by the browser, but because I don’t use that feature in my day-to-day web usage, I can’t really comment on how Web 2.0 techniques would affect that feature. My impression was that form auto-fill and input history were based on the “name” attribute of the field, which shouldn’t be any different in a Web 1.0 or 2.0 context. I’ll have to try an example to see what you’re talking about.