“Moving There”: Property Listings Mashup (Rewired State)

I recently attended Rewired State with several fellow Osmosofties. Our group (Simon, Fred, Jeremy, Robbie and myself) developed a little mashup called Moving There (and a couple of other things not described here).

After the demos, our mashup was mentioned by a representative from DirectGov as one of several projects they’d like to work with, perhaps to sponsor further work.

The idea was to overlay government-related data on property listings sites. I’ve been moving house right now, so this is very much an itch which I’d very much like to scratch.

Typical properties listings sites like RightMove show a list of properties matching your search criteria (shown below).

There’s a lot of things they don’t show you too, like upcoming building works, local schools, crime stats, vandalism. All these things are available in one form or another on websites, some operated by the government and others by third parties.

One part of our work involved taking in a postcode and producing useful info about it, so we came up with a little library for that. We also made some attempt to normalise these metrics, so we came up with a “coolness factor” between 0 and 1. This is very crude, but we feel it’s useful when comparing stats to say “schools have a coolness factor of 0.3 and crime prevention is 0.6″ rather than “schools have an average pass rate of 48% and there are 142 crimes per week”. In other words, a standard coolness factor measure goes some way towards helping you compare apples with oranges.

But the real product concerned itself with mashing up a properties listing site. After entering a location, you get back listings as well as charts showing the “coolness” factor according to the various stats. Well, that’s the theory; in this case, it’s just one stat (fixmystreet local incidents, e.g. vandalism) per property. And the UI isn’t particularly slick either! I’m just presenting where we got to when the time ran out on the day!

A few notes on the technology. We made use of JQuery for the usual infrastructural stuff. We used Google’s geo-coding API to map street name and suburbs into a postcode. The postcode info demo and the final mashup are actually a file-based web app, i.e. it runs off a file:// URI. We debated several models for the mashup’s architecture; in retrospect, we spent a lot of time re-building the property search’s UI and it might have been better to go with a Greasemonkey overlay, at least for proof-of-concept.

Javascript, Rebranded

I’m listening to Steve Yegge’s talk on branding from last years OSCON.

He talks about how languages are branded, e.g. “Java” is enterprise. One of his main points is that brands are “const identifiers”, i.e. it takes an entire generation to change brand perception, so it’s often more effective to simply re-brand. e.g. GTE had a poor brand, so they tried a self-deprecating ad campaign, which backfired, and subsequently re-branded to Verizon.

He then mentions Javascript has a branding problem, because it represents “browser” and “toy language” and “damnit, I gotta learn Javascript” and it’s the language no-one wants to use. He also notes the name itself isn’t great either, nor the rhino imagery. (I’m not sure why Steve assumed many programmers would associate Javascript with rhinos; the Rhino product and O’Reilly cover weren’t really promiment enough to do that; rhino ain’t camel!). I don’t agree with this premise. Javascript has actually become at least somewhat cool in certain communities, pretty quickly. Not the obvious ones like Rails and general web 2.0 fanboys/girls, but also PHP and Perl folks who would have previously been uninterested in it.

Anyway, he leaves the issue open and implies Javascript needs to be re-branded. But isn’t the point here that Javascript, for most and intents and purposes, already has been re-branded, like sometime around February, 18, 2005? It now shares its name with that of a domestic cleaning product, Dutch football team, and Greek God. For most people, Javascript became cool and worthy the day Ajax was coined; and Ajax encapsulates most of what is meant by Javascript. Of course, the two aren’t strictly synonymous, but when you set out to learn Ajax, you’re predominately learning Javascript. Go read a day or two of Ajaxian news and the vast majority will involve Javascript at some level.

Javascript has already been rebranded. In fact, I’d go so far as to say “Ajax” was one of the most successful rebrandings in software history.

Paleosocial Patterns

Wolf Logan’s talking about paleosocial patterns (TOOLS Web 2.0 Patterns workshop). Very cool.

Marking – making permanent, public, marks. Dog marking its territory, “I was here” graffiti. e.g. blog comments, forums, guestbooks. Being obnoxious gets the comment noticed more.

Pointing – indicating resources to others, can be with opinions. Reputation will dictate how much people care. e.g. Reviewing/rating sites, Digg.

Competing – comparing self to others, ranking is dynamic Some people approach competition for their own value; others for their social value. Special case of marking – marking yourself – but with an element of objective measurement e.g. online gaming sites, xbox live, popularity contests.

Storytelling – describing sequence of events, often about yourself Different stories for different social groups e.g. blogs, journals, youtube

Grooming – small, ritualised, social interactions – can happen quickly and without much planning, Culturally bounded. Repeated frequently depending on relationshps. “Purring” – e.g. “how are you?” – don’t care, but it’s the purring that happens that makes it a grooming behaviour. The info transfer doesn’t matter, just that the event happened. e.g. friending, twitter, majority of IM content

Hunting – tracking, locating, acquiring resources. Serendipity plays a big part. Successful hunting leads to pointing – tell people what you found. e.g. web search, link following.

Wolf points out hunting and grooming are always the two critical patterns that are noted.

A Video Sharing Website based on Web 2.0 Patterns

We’ve done a little group exercise at the TOOLS web 2.0 patterns workshop. Designing a video website, with heavy emphasis on mashing up, e.g. show videos from youtube, grab recommendations from netflix, grab friend lists from Facebook, etc.

Here’s the full feature list (click for full image):

And the design:

We eventually identified features, at back end and front end, and listed similar sites where on might get inspiration for each feature. Interestingly, when you do this with web 2.0 sites, you end up realising you could actually implement the feature by actually using this service.

Dragos has transcribed the list we came up with (partly visible in the photo above):

Day 1: Design Exercise

Problems + Solutions (1) [MM - these were back-end features]
-Key-value store: Amazon Dynamo/S3, BigTable (Google)
-Streaming: Hulu, YouTube streaming (not Flash)
-Client time synchro service: NTP, MMORPG
-Social network integration services: Oauth, OpenID/Passport
-Mash-up engine: PopFly, Yahoo! pipes
-Monetization (social cash -> $, analytics, instrumentation): AdSense, witkey.com, SiteMeter, Elance

Problems + Solutions (2) [MM - these were front-end features]
-Video: Vimeo, Nicovideo.jp, Jaman.com
-Mood: Musicovery, Yahoo! IM, Nabaztag.com
-Friend states: Twitter
IM: Facebook/MySpace, Twitter, Shoutbox
-Recommendations: Tuneglue, Netflix, Facebook

Some Emerging Themes
-Taxonomy of social networks
-Social profile aggregation: InfoCard
-Integration of services transparent from user
(Tim O'Reilly’s innovation by assembly)
-Privacy (who sees what)
-Biggest pile wins
-Cooler than thou 

OpenSocial: A Beautiful Platform for Server-less Web Development

It’s belatedly dawned on me how OpenSocial makes a great server-less Ajax platform. When you create an OpenSocial gadget, you’re building a lil Ajax app that performs much coolness that would normally require a server, but doesn’t. Effectively, you’re delegating the duties of the gadget’s host environment. All you have to do is write a single XML file and host it somewhere. In fact Google Gadget Editor gives you an editor to write it in and a place to host it.

In fact, this is so good that if I was teaching someone Ajax in 60 minutes or less, I would consider getting them to write a gadget. It’s that simple. Previously, I might have got them to write a static HTML file, with embedded Javascript and CSS, but now they can do the same thing and benefit from server-side features too, features they never had to install. This is like getting the usual benefits of the DOM and the Javascript API, but with much more. You’re getting both a set of APIs, just like when you use JQuery or Prototype, but you’re also getting a server which many of those APIs rely on. So it’s a true platform.

By the way, I’m assuming you’re using XML content type, not URL. XML content type is the way forward, especially as we move to a Caja world. XML gadgets will get you the richest functionality. URL gadgets are only suitable for legacy concerns, and in some cases, accessibility.

So you’re using XML content type, which means the entirety of your Ajax app lives in one file. What does an OpenSocial platform provide to your little XML gadget spec?

  • Persistence. The most important thing is you can save application data. You can serialise any state you care to persist, and then store it as a hidden user preference. This is really neat. It means you can write a TODO gadget, for example, and ensure all the TODO tasks will be saved, but without having to store them on your own database and without having to build a persistence layer around it. And of course, the platform will (theoretically) provide the necessary security to ensure users only see their own tasks.
  • Preferences. You can easily let users customise your app via the preference API. For free, you get form fields to let users state their preferences, with drop-downs for enumerated types. And of course, the preferences are persisted without any effort on your part.
  • Content Fetching. It gets even better. On-Demand Javascript is often bigged up as the way to get data from third parties. But thanks to OpenSocial’s remote fetching APIs, it’s just as easy to grab content via the containers Cross-Domain Proxy. This means you can get any internet content and call any API, not just those specifically designed for cross-domain browser calls. There are also value-adds here, e.g. caching, scheduling periodic updates, converting feed data of any format into a consistent JSON structure.
  • Identity and Social Networking. Ah yes, the almighty “social” in OpenSocial. On the right platform, your server-less Ajax app can get info about the page owner and the page viewer, and their friends. Friends and social stuff and knowing whose page it is, that’s cool and all. But what’s really exciting here is much simpler than that – it’s simply IDENTITY. What matters most is: With a single API call, you get an ID for the guy viewing your gadget!!! You didn’t have to handle registration, password reminder links, etc. etc., and go through all the associated security questions around it. All the usual stuff you have to do if you want to know who’s using your application. It’s all *free* to you, gadget developer. (Downside is your company doesn’t “own the user”, so your gadget will never get you pina coladas on the beach at noon and an environmentally-conscious hybrid vehicle to sip frappachino grandès in.) With this user handle, you can also save a hashmap of information about the user, persisted by our friend the server.
  • Many other services. Each platform is free to provide any number of features beyond the required API; this is how platforms compete against each other in the OpenSocial world. “Feature” is actually the term used for a particular set of browser and server services, e.g. “dynamic height” – the ability for a gadget to update its height – is a standard OpenSocial feature. Notifications – the ability for gadgets to add little notes to the top which the user must manually clear – well, that’s a custom feature iGoogle provides but others don’t. So anyway, there are lots of these features and your gadgets get them for free. In most cases, they are just libraries which you could also get for free by using Scriptaculous or whatever…but still, with OpenSocial, it’s really, really, easy! No download or installation. (Although it must be said that with library CDNs like Google’s new effort, you can also use many Ajax libraries without installation too. The difference here is that at least some of these features are tied to server-side services as well.)

So, these days, OpenSocial may well be the easiest way for a newbie to learn Ajax, and for any developer to get an Ajax app up and running. I actually think we need more tools and services to allow standard Ajax apps – not gadgets – to get up and running fast too. After all, the UI in OpenSocial is based on a widget/gadget model, and this is a mini web app running on a bigger page. Nowadays, we have canvas gadgets, which are bigger, but still not so big and run inside another web page. What if you took the same cloudish platform principles and applied it to a big old Ajax app, occupying the entire page and with its own URL (though probably coming from the platform’s domain). You can sort of do that already by looking at the content of the gadget iframe, but it’s not designed for that purpose…and if it was, you could do some interesting stuff.

For instance, I envisage a simple-to-use cloud storage system based around principles of Persevere and CouchDB, and for limited use, it could even allow anonymous access. I’ll perhaps demo all this at some stage.

What is OpenSocial?

I just realised there’s no good executive summary for OpenSocial. Every resource fluffs about the “social” aspect and forgets about the UI aspect. The UI aspect, essentially a gadget specification, is just as important as the social aspect, notwithstanding its absence from the “OpenSocial” brand name. I’m not a fan of the name “OpenSocial” for this reason, though I acknowledge it does have more attention-grabbing bling than “open social widget framework 1.0″. In any event, it’s regrettable that most commentators gobble it up hook, line, and sinker; as evidenced by their almost exclusive focus on the social angle.

With no further ado, here’s my attempt at a one-paragraph summary of OpenSocial …

OpenSocial Executive Summary

OpenSocial is a standard for “mini” web apps, called “gadgets”, which are designed to be embedded other websites. The standard informs developers who wish to write portable gadgets, i.e. those which work in any OpenSocial environment; and likewise, it informs developers who are creating such environments. It defines an XML format for applications, typically containing the user interface (HTML/CSS/Javascript) as well as metadata, e.g. author, gadget size, and preferences. In addition, OpenSocial defines a number of APIs, so that gadgets can invoke services such as changing the gadget height and fetching remote content. One particularly important class of APIs are those of a social nature. These enable a gadget to access data and run services related to the user who is viewing the gadget, or the user whose web page the gadget is embedded in. For example, the gadget can – subject to security settings – find a person’s name and location, traverse their social network, and invite them to install an application. Access to social data is not limited to gadgets, however, as OpenSocial also provides a RESTful variant of the social API, suitable for any kind of net-enabled client. OpenSocial was launched by Google in November, 2007, and is to be managed by the non-profit OpenSocial Foundation.

Widget/Gadget Containers: What are they good for?

Ajax, AjaxPatterns, Gadgets, OpenSocial, Shindig, Web, Web 2.0, Widgets

Background

Widgets are small “mini websites”, typically self-contained blocks of content, on a larger web page (with Ajax Design Patterns, I referred to them by the nom du jour Portlets). They are used in a couple of ways:

  • Embedded in a normal web page. For example, my blog currently contains a BBC weather widget and a “Twitter Badge” showing my latest tweets. Widgets embedded in this way are combined by the publisher, often with some manual HTML coding (script tags), and are usually a sideshow affair.
  • Combined within a widget container (aka “widget portal”, “Ajax homepage”). Websites such as iGoogle and NetVibes are primarily designed as widget aggregators, allowing an end-user to construct a personalised page for themselves. They are the Ajax/Web 2.0 successors of the “My <whatever>” hype (My Yahoo!, My Excite!, etc.) of the mid-to-late ’90s. To some extent, a social networks like Facebook fits into this category too, with the proliferation of applications available to users to embed on their homepages. And as Facebook in particular illustrates, widget containers are not always private “productivity tools”, but may also be available to a user’s friends or the general public. Indeed, the more conventional widget containers have recently started allowing users to make their public portals, which starts to move them in the territories of CMS and social networking.

Well, this is an article is about widget containers. Specifically, I’m currently compiling a list of typical features you’d expect to see in widget containers, so if this post sounds stream-of-consciousness, well, it sort of is.

Anatomy of a Widget (well, Gadget and OpenSocial) Container

A good place to start is the breakdown of functionality for Shindig, the new Google-supported Apache project to build a reference implementation for the OpenSocial standard. OpenSocial is heavily intertwined with the whole idea of widgets and widget containers, since it’s basically Google Gadgets + standardised social networking APIs. Hence, Shindig is essentially the high-profile open-source project involving a widget container. Shindig has been broken into four parts:

  • Gadget Container JavaScript — core JavaScript foundation for general gadget functionality (read more about gadget functionality). This JavaScript manages security, communication, UI layout, and feature extensions, such as the OpenSocial API.
  • Gadget Server — an open source version of gmodules.com, which is used to render the gadget xml into JavaScript and HTML for the container to expose via the container JavaScript.
  • OpenSocial Container JavaScript — JavaScript environment that sits on top of the Gadget Container JS and provides OpenSocial specific functionality (profiles, friends, activities).
  • OpenSocial Gateway Server — an open source implementation of the server interface to container-specific information, including the OpenSocial REST APIs, with clear extension points so others can connect it to their own backends.

That’s a very useful overview, though I’m looking more at specific features which generally cut across at least some of these parts. For example, gadget preferences. These are part of the container Javascript because there is a UI to change the preferences, they are part of the gadget server because it must initialise the gadget according to preferences, and they are part of the server because they must be persisted.

Feature List

First cut at a feature list (# indicates not directly available in iGoogle)

Gadget Preferences

  • Preference defaults
  • User can set preferences
  • Publisher can set preferences when embedding widget on a page
  • Preference variable types: string, enumerable (set by dropdown, set by combobox), boolean, list, location, etc
  • Preference persistence: by database against session vs. in cookie
  • Preferences persisted for anonymous user (Lazy Registration)
  • Gadgets can access preferences via API, consistent access regardless of content type and embedding model
  • # Gadget can be notified of preference changes, so that it’s not necessary to reload the entire gadget/page after each change

Gadget Appearance

  • Gadget appearance customisable by publisher
  • Gadget appearance customisable by user
  • # Round corners, shadows, background images (e.g. Schmedley has all of these)

Gadget Content Type

See Widget Content Type article * HTML – from container provider’s domain * URL – from gadget provider’s own domain * # Inlined – embedded on container. This implies a security model, e.g. Caja

Container Appearance

  • User can change gadget skin, header, footer, background, widget preferences via constrained mechanism (ie can’t change everything; e.g. config file or UI)
  • Publisher can change look and feel via HTML/CSS
  • Gadget themes available, with gallery, for pre-defined configurations
  • Animation used for features such as preference setting and expand/collapse of widgets
  • Drag-and-drop shows preview of page appearance after drop

Container Layout

  • Multi-column (usually 3) vs. freestyle
  • Gadgets can be dragged around the page, displacing other gadgets
  • Tabs allow for multiple layouts
    • Tabs can be renamed
    • Gadgets can be dragged into tabs

Gadget Manipulation

  • Gadgets can be added
    • by URL (with security warnings etc)
    • from Gallery (see Gallery below)
    • by cloning a gadget on user’s page or someone else’s public page or external page
  • Gadgets can be removed
  • Can limit singleton gadgets to one instance per container

Gadget Gallery

  • Gadgets displayed and rendered with metadata embedded in gadget spec, e.g. thumbnail image, author, etc.
  • Gadgets can be browsed by category, date added, etc.
  • # Users can tag gadgets and gadgets can be browsed by tags; tag cloud; etc
  • Users can rate gadgets
  • # Users can recommend gadgets to their friends
  • Users can comment on gadgets

Gadget-To-Gadget Communication

  • Gadgets can communicate with each other (Google PubSub)

Gadget Size

  • # Gadget content can be expanded and collapsed (BBC Beta Homepage)
  • Gadgets can be dynamically resized

Content Sharing

  • Container can be made public (what happens to personalised widgets?)
  • Container can be shared with “friends” (how are friends decided)
  • Users can invite/permit/disallow friends to use their container

Gadget Services

  • Proxying service
  • Caching service (extends proxying service)
  • OpenSocial (or generic social networking) service
  • # Advertising service – Gadgets can serve as ads with revenue model
  • # Financial service – Gadgets can charge for services (subscription, one-off, etc.)

Admin Functions

  • Admin function to tweak gadget/theme rankings, scrutinise/moderate/eliminate gadget/theme submissions, etc
  • Admin function to view metrics, e.g. number of page views, popularity of gadgets, back-end service usage (e.g. proxying and OpenSocial calls)
  • Admin function to manage users (provide support, ban, etc.)

Where Do Widgets Come From? A Look at Widget/Gadget Content Types

Ajax, AjaxPatterns, Gadgets, Google, Web, Web 2.0, Widgets

Background

A while back, I walked through a Google Gadget I made called Digg Roundup, which simply shows Digg headlines and can be customised on topic and popularity. In my quest for an uber-simple tutorial, one thing I skipped on was content type, the subject of the present muttering. There are several content types possible, each with distinct implications for the page architecture and where the gadget sits within it. Below I’ll explain the options and help you understand how to decide between them.

A gadget is always expressed as some XML sitting at a URL somewhere on the net. When a developer uploads a gadget to Google, all they do is indicate their server location where the gadget is hosted. So a user’s iGoogle homepage is really just a bag of URLs (with layout and preferences for each). Anyways, the gadget is really a mini web page, and inside the gadget XML is a content tag that describes the HTML, CSS, and Javascript that makes up this page. The tag has a type attribute (i.e. <content type="xxx">) and there are three types available…

Three Content Types

html (<content type=”html”>)

All the page content is included in the XML file. It’s just like your standard web page HTML; it contains the (initial) HTML body from top to tail (sans enclosing <body> </body> tags), and CSS and Javascript, which can be inlined or linked, just like a normal web page. The content will be served in an iframe and Google will wrap its own html content around it. In particular, Google will look at other info in your XML file and output html code at the top, such as pulling in libraries and setting up preference data. Incidentally, Google won’t add any visual wrap around the widget at this stage; that is the responsibility of the container, which could be iGoogle, Ning, or any standalone web page that chooses to render the gadget.

Although the XML is held on your own server, the iframe will ultimately be served from a Google subdomain as its source. e.g. gmodules.com/blahblah. If you look at iGoogle, you’ll see the source is actually something like 50.gmodules.com/blahblah. The point of the “50″ is that each gadget on a page comes from a different subdomain, thus isolating gadgets on the same page from each other for security reasons (there are ways around that restriction for consenting gadgets).

The main differences between a <htm> gadget and a normal web page is that your content must be static – the XML file cannot be generated on the fly by your server, because Google will cache it. Think of this kind of gadget as a single file that describes your gadget in isolation, which you could mail around or stick on a USB key. The dynamic behaviour comes from the fact that you can link to external CSS and Javascript (which could be generated on the fly) and, moreover, you will typically be making remote calls once the application is running (either on startup, due to a timer, or in response to system events).

url (<content type=”url” href=”myserver.example.com/…”>)

url. This could alternatively be called “external” or “hosted”. You simply provide a URL on your own web server and deliver up the gadget content from there. Specify “example.com” and the user will see an iframe pointing to “example.com”. The content for url gadgets must be dynamically generated, the exact opposite of html gadgets, which are always static. This is due to the way these gadgets use

html-inline.

This is no longer supported, but it’s worth knowing because (a) the contrasting model helps you understand the other models; (b) older gadgets, as well as Google’s own gadgets, are still able to use this model; (c) Google says they might allow special cases through in the future; (d) other containers do support this model (NetVibes anyway). In contrast to the previous types, inlined gadgets are not contained in an iframe; they are served as plain old HTML embedded into the fabric of the page. Just some content in a div.

A Note on Preferences

Persistent preferences are a key feature of widgets. Just a quick note that preferences work slightly differently on html vs url widgets (and inline, but I didn’t look into it).

With html widgets, the preferences are set as part of the HTML wrap around your widget’s HTML. ie some Javascript variables are set up.

With url widgets, the iframe source URL includes some CGI parameters expressing the preferences (e.g. up_storyAmount=5).

Either way, though, Google’s preference library abstracts this detail. As long as you declare a dependency on the library, it will be included and will let you access preferences the same way.

Decisions, Decisions: Which content type to use?

So that’s the definitions. Let’s look at the capabilities of each and understand how we might make decisions on which model to use.

Inline or IFrame (content-type=html/url)?

Firstly, inlined (html-inline) versus iframed (html and url), assuming inlined is an option for you. Living in the same DOM means that inlined gadgets can talk to each other; dead simple cross-gadget communication is a key benefit of the inlined model. Furthermore, gadgets and the main portal page can talk to each other. You can change the Google logo, for example, or put up a lightbox effect across the entire page.

Not too surprising that raw inlined gadgets were banned; the security risks are high. e.g. An inlined gadget that asks for your gmail credentials would end up storing username and password in global page space, which means a second gadget could simply read that data and upload it somewhere. You could also screw with iGoogle’s branding, which Google PR probably didn’t appreciate and could lead to phishing attacks. Google could rely on code reviews to minimise the risk of inlined gadgets, but that’s a very manual, unscaleable, approach, and users can in fact add gadgets from any URL (although they made it a lot harder to do that a few months ago; AFAICT you need to use the developer gadget in order to add a gadget that’s not in the catalogue). Maybe inlined gadgets will come back if a product like Caja proves itself worthy of automatically sanitising web apps. It’s a hard problem, but there are some good benefits to be had if widgets can live safely together on the same page and domain.

In summary, choose inlined only if you need the extra functionality available and only if you have assessed the risks of tampering from third-party widgets.

IFrame from widget server (content-type=html) vs IFrame from your own server (content-type=url)

Second and really the key decision you have to make with Google Gadgets today, html versus url. Reason to choose “html” content type over “url” content type:

  • Javascript API. You can use the full Gadget Javascript API with no effort – you don’t even have to include a script tag because iGoogle injects it for you. With the “url” type, using the Gadget Javascript API is a hassle – you have to dynamically generate the script tag, which is not only a bit of scripting effort, but forces you to generate your iframe from a script. Furthermore, cross-domain restriction means that even if you do pull in the API, you can’t use the remoting support (the _IG_Fetch* functions for proxying and caching).
  • Cross-gadget communication. You can run cross-gadget communication using the Pub-Sub framework.
  • Resources. Google serves it for you, which saves bandwidth and maintenance costs. In fact, you will have zero bandwidth costs if your widget functionality is either self-contained (e.g. a calculator) or only hits third-party services (as opposed to your own servers’ services).
  • Popularity. Pure speculation, but you’re probably more likely to be featured in Google’s gadget gallery as they can inspect everything about your application’s workings (except for any remote calls back to your server).
  • Inline-like. If inlined widgets do make a comback, you’ll have an easier migration path.

Reasons to choose “url” content type over “html” content type:

  • Full page refreshes. Because it’s coming from an external iframe, you can do traditional, non-Ajax, programming. ie. User clicks on link to see a new page. User submits a form. Page auto-refreshes. With this type of widget, you could write a perfectly working gadget without knowing a button of Javascript.
  • Personalisation and Security. You can make XHR calls from the widget directly to your own server and make use of any cookies that have been set up. e.g. If the user has already logged into your main web app, then you widgets will be able to present personalised data. With “html” widgets, you would only be able to make use of cookies using cross-domain JSON, and cross-domain JSON is unsafe. You could possibly do it more safely using the cross-domain iframe fragment identifier hackFacebook’s new JS lib works that way – but I haven’t investigated it.
  • You can easily host the widget as a standalone web page (though it’s largely pointless and will look silly unless you pull some CSS madness).

Want to Learn More?

Dynamic Favicon Library Updated

Ajax, AjaxPatterns, Favicon, HTML, Javascript, Web, Web 2.0

I updated the favicon library a while ago, for a couple of projects I haven’t released for various reasons. Anyway, Phil asked me about it, so I thought it’s a good time to package it up and release it properly. And in the process wrote up Taking Browser Tabs Seriously which has also been on the backburner.

The main point of this library is to update the favicon via Javascript, but at a higher level, its main objective is to provide some support for notifying the user of events in another tab. For example, if you start playing music in another tab, you can make a one-liner call to change the favicon to a sound. Or if you really need to alert the user, you can start animating it.

See the original post for more info. The new features are:

  • Scrolling title. The window/tab title scrolls. (Title blink is coming. No, really!)
  • Stop functions. unanimate() and unscroll() will stop animation and scrolling, respectively. Previously you had to do stop animation indirectly, by calling change().
  • Rails/Scriptaculous style options Changed config to be fn(mainarg, optionalHash). Read the library or demo source to see the details.

Demos:

API (also in the code):

javascript
< view plain text >
  1. favicon.change("/icon/active.ico", "new title"); // Cancels any animation/scrolling
  2.     favicon.change("/icon/active.ico"); // leaves title alone. Cancels any animation.
  3.     favicon.change(null, "new title"); // leaves icon alone. Cancels any scrolling.
  4.  
  5.     favicon.animate(["icon1.ico", "icon2.ico", ...]);
  6.     favicon.animate(["icon1.ico", "icon2.ico", ...], {delay: 500} );
  7.       // Tip: Use "" as the last element to make an empty icon between cycles.
  8.       // Default delay is 2000ms
  9.     // animate() cancels any previous animation
  10.  
  11.     favicon.scrollTitle("new title");
  12.     favicon.scrollTitle("new title", { delay: 200, gap: "------"} )
  13.       // delay is delay between each scroll unit
  14.       // gap is string appended to title (default: "      ")
  15.     // scrollTitle() cancels any previous scrolling
  16.  
  17.     favicon.unscroll();
  18.  
  19.     favicon.unanimate();

Maybe in another two years, I’ll update it again. The main enhancement would be to combine it with audio notifications (with or without Flash, depending on the browser). So you could make a single call that (a) changes favicon; (b) scrolls the title; (c) plays a sound. Now that will get their attention!!!