Software As She’s Developed

Mahemoff’s Podcast/Blog - Web, Programming, Usabilty from the Author of ‘Ajax Design Patterns’ (AjaxPatterns.org)

Software As She’s Developed header image 1

“Can’t Open Your E-Mailbox? Good Luck.” Actually, Make Your Own Luck

October 6th, 2008 · No Comments

New York Times has a popular article about an important topic: getting locked out of your webmail account:

LOGGING on to Gmail or other e-mail service has become a routine of daily life, completed without a thought. What would you do, however, if you woke up tomorrow, plugged in your user name and password as you always do, but then received an unfamiliar message: “User name and password do not match”? If you’re a Gmail user, what you’ll want to do after a few more unsuccessful, increasingly frantic attempts is to speak with a Google customer support representative, post haste. But that’s not an option. Google doesn’t offer a toll-free number and a live person to resolve the ordinary user’s problems.

The gist is, if you want GMail with the assurance you won’t get locked out, pay up $50 a year for support.

$0/year is very reasonable, but there’s a way you can do it for free, and quite simply. You just sign up for Google Apps for Your Domain (note: I’m not a shareholder nor an affiliate, just a fanboy). The catch is you have to own a domain, but (a) they are damn cheap, around $7/year for .coms; (b) it doesn’t even have to be a .com; some other endings like spam-infested .biz and .info are even cheaper; (c) you may already own a domain anyway. (A friend recently showed me a great little website some had put together for his business, with its own domain, but the email was a yahoo! address - more professional to match it to the website ne?)

With Google Apps for Your Domain, you point your DNS server’s MX at Google. If you’re locked out, you can point your MX at another mail server, perhaps your SNS registrar provider as most of them provide some rudimentary support. And you’re unlikely to be locked out anyway, because you can post a special message on a website on your domain, to prove you control it, which will reset the domain admin password. This is all offered free of charge.

Admittedly, this is not a mom-and-pop solution. It’s obviously requires some tech knowledge to own a domain and point its MX somewhere or post a message to it. But certainly doesn’t require hardcore geek-fu either, just a little savvy and willingness to try things out and follow some instructions. If you already own a domain, you may as well go this route over just using a plain GMail/Yahoo account. it’s great piece of mind to know that you, and only you, are the master of your own domain!

→ No CommentsTags: SoftwareDev

Vale SOX? Obligatory Sarbanes-Oxley Mention

October 2nd, 2008 · 1 Comment

I can’t let the current credit crunch / financial crisis / Wall St meltdown pass without mentioning the Sarbanes-Oxley Act, aka SOX.

I feel compelled to do so because I haven’t seen it mentioned once in the mainstream media during the past fortnight of turbulence, and yet it should have at least played some role in reducing the likelihood and impact of an event like this. Otherwise, it was a waste of effort.

Searching Google News for “Sarbanes-Oxley” just now yielded about a half-dozen results. One is from 2006, one is a letter, one is about Sarbanes’ son’s bailout vote. Not much. The only relevant article I found:

The pain felt in middle America was so intense that Congress enacted legislation to clamp down on such errant behaviour. The Sarbanes-Oxley Act of 2002 imposed stricter levels of disclosure on public company boards, management and accounting firms. It was hailed at the time as a breakthrough in regulating errant corporate behaviour. But it should come as no surprise that about a year ago, during the height of the most recent boom, US regulators were coming under intense pressure to dilute parts of the legislation. Sarbanes-Oxley, the argument went, had cost Wall Street its coveted position as the world’s financial hub. The high cost of compliance with the legislation had seen international focus shift to London.

The article goes on to explain why it might be not so relevant to the current situation, which is completely dominated by the banks:

The latest crisis has emerged from a different area - the lax prudential regulation of America’s banks. Housing loans were pushed on to people who had a history of default. That’s the definition of subprime.

So it’s not a case of “this is exactly the kind of thing SOX was meant to prevent”. It’s more subtle than that - SOX is only public companies, and not all banks are public; SOX covers all types of companies, not banks which have particularly complex financial characteristics; SOX is about control and reporting, and does not place specific constraints on levels and forms of credit risk.

Nevertheless, many banks are public companies and public companies must comply with SOX (even if the system is developed in the UK…as long as it operates in the USA, it must comply, that’s my legally dunce understanding of the matter). Sarbanes still applied in banks from around 2003. I was working on one project where “pulling up your SOX” was a constant non-functional force lurking in the background of many major design decisions. So, for example, if we were to choose an in-memory database, what would happen to the auditing facility in the event of a sudden crash, would this cause a violation of SOX?

Another system I was looking at working on involved the treasury operation of a prominent American bank, where SOX was a big driver for them to streamline the performance of the system that comes out with a single, very important number: the bank’s overall position.

It’s vastly beyond the scope of this blog to explain away the crisis or even SOX’s (non) effect on it. What I can say, though, from a software perspective is that it feels like yet another standard that’s complex enough, and enforced enough, to drive substantial effort, while being high-level enough to not necessarily be very useful, at least not in cases where the intent was already there.

Alistair Cockburn wrote to the effect, “show me the methodology, and I’ll show you the methodologist’s fears”. We might well apply this to standards and regulations too.

SOX can be very closely tied back to Enron and related collapses and the fear of a repeat incident. However well-intentioned, there are two problems with standards that emerge from fear: (a) forcing someone to not follow the same strategy as that which led to a collapse…is no way to guarantee a similar collapse won’t take place again, for there are many alternative strategies they may take; if you retrospectively try to do what would have prevented recent incidents, you can expect your standard to be gamed hard by those using alternative strategies; (b) even if you can prevent a repeat incident, at what cost? Many times, the constraints you place on creativity and the degree to which your standard crushes human spirit and consequently inhibits progress, these costs may well outweigh the benefits.

Whether these problems were causes by SOX is a topic for debate. But as the world readies itself for a whole new set of controls - many of which will affect your daily work and mine, dear software reader - one can only hope there is big ups on some fair dincum contemplation and ixnay on the knee jerk, eh.

→ 1 CommentTags: HumansAndTech

An OpenSocial Sketch

September 28th, 2008 · No Comments

My fellow Osmosoftie Paul Downey made this bodacious sketch when I ran through my @Media Ajax presentation on OpenSketch:

If you haven’t seen his handiwork before, he has a great talent for this distinctive style of text. Check them out. He also created The Web Is Agreement (I made a little remix of it into a full page version.)

→ No CommentsTags: HumansAndTech · SoftwareDev

Reflections from a TiddlyWiki Tiddler and Thoughts on a Guide for Web App Development with TiddlyWiki

September 21st, 2008 · 4 Comments

I’ve recently begun working on a project with Osmosoft, which I’ll announce Real Soon Now, and have got my hands dirty with TiddlyWiki to the point where I’m now able to make at least some useful functionality. You effectively get an MVC framework for free with TiddlyWiki, so as a power developer, I can see how it could let you build a certain type of app quite rapidly. Even without too much knowledge, you could use it for prototyping quite easily, just by knowing the key extension points. I figured it would be worth capturing my reflections to date.

There’s a lot of documentation around on TiddlyWiki, and also some good support resources in the form of Groups and IRC. What I’d like to see in addition to that is a guide for people writing “verticals” - web apps building on TiddlyWiki, rather than incremental enhancements. And also it would be good to see a cookbook or pattern collection covering the main types of plugins.

The other issue I’ve had, while I’m brain-dumping, is that plugin exceptions are caught at some point, with an error message shown, and not propagated, so they don’t turn up in Firebug. I need to look into this more as I think there are ways to get better diagnostics. I would also like to get a better understanding of the startup and shutdown lifecycle. As explained in my last post, there are some techniques you can use to hook in at certain stages, though no direct support.

I’ll have an initial stab here at the kind of thing I’d like to see in a developer guide, and refine it massively at a time when I’m less of a green Tiddler, maybe on a wiki. I’m really not qualified to say too much at this stage, but I want to capture it while it’s fresh on my mind. Note there’s already a lot of good material along these lines on the TiddlyWiki wiki.

Development Process

The simplest way to work is directly inside the TiddlyWiki. Locate shadow tiddlers under the “more” tab and edit them. And create new tiddlers, tag them as “systemConfig”, and stick your plugin code inside them. Each time you change it, hit reload. That’s a nice, simple, way to start off.

For serious development, there are better options. (Which I’m about to start learning.)

Extending TiddlyWiki into a Custom Web App

The way to extend TiddlyWiki is not to take a TiddlyWiki and start hacking the source. You can do anything you want to do via the following techniques:

  • Edit Shadow Tiddlers Shadow tiddlers are special tiddlers used to configure the TiddlyWiki. When you open a shadow tiddler and edit it, it saves as a regular tiddler. The original shadow tiddler remains, mainly as a safeguard, but becomes irrelevant. (I mention this because you might think there’s a cascading effect, where the regular tiddler is run before or after the shadow. In fact, the regular tiddler simply replaces its shadow from the perspective of configuration.
  • Make Plugins A plugin is a tiddler tagged “systemConfig” and containing some code. The code will be executed when the wiki loads, since TiddlyWiki’s built-in startup sequence looks for tiddlers marked SystemConfig and executes their content.
  • Include Plugins Include plugins from elsewhere if they are useful. You import a plugin via the PluginManager tool, accessible from Backstage. Or by cutting-and-pasting into a new “systemConfig” tiddler.
  • Change Options Options such as Auto-Save also affect your application’s behaviour. You can set them programatically using config.options at startup. Alternatively, if you have retained the options control in the sidebar, set options there and save the page.

In addition, you may find you need more than one TiddlyWiki file to build up your web app. You might end up with a separate file for each key functional area. (I haven’t seen this done, but a guide could explain how to pull in plugins and tiddlers from a common place. Possibly building on TiddlyWeb.)

Which Shadow Tiddlers to Customise?

Here’s a list of shadow tiddlers you might want to customise for your app:

  • SiteTitle - the contents of this tiddler are used in the header. This is an example of an uber-simple shadow tiddler. When you begin to build a vertical, you will want a header that reflects the name of your app. Similarly, you can set SiteSubtitle and SiteURL tiddlers.
  • StyleSheet - the “StyleSheet” tiddlers lets you add some CSS rules to enhance or redefine the existing CSS based look and feel. This is a slightly more complex form of appearance customisation than the previous point. You probably don’t want your app to look like a carbon copy of the original TiddlyWiki, so use these tiddlers to theme it. There are some other style-related tiddlers, like StyleSheetColors and StyleSheetLayout, but it’s not recommended that you change them, because if you ever upgrade the TiddlyWiki core, any new styling will be ignored. So if there are things you want to change in those tiddlers, just create the CSS rule inside StyleSheet and it will take precedence. There is also a ColorPallette tiddler referenced by StyleSheetColors, which you *can* modify safely, and it lets you change the color scheme. In general, you won’t need to override StyleSheetColors directly - ColorPallette should be sufficient.
  • PageTemplate - the HTML for the entire page. An even more complex way to customise your app, by changing the raw page structure. Note the way this tiddler “pulls in” content other tiddlers. You can therefore change the appearance not just by changing PageTemplate, but by changing those included tiddlers. We’ve already met a couple of them - SiteTitle and SiteSubtitle - which simply contain a word or few in most cases. Others you’ll noticed here are MainMenu and Sidebar to reflect further options which are always present in your app.
  • DefaultTiddlers - a list of the initial tiddlers that show up when the page is loaded. In a web app, this would typically be a blurb, maybe embedding a video or image, and links to other tiddlers. The kind of thing you’d see in any web app, really. In this sense, TiddlyWiki provides you with a basic, customisable, layout scheme.
  • etc.

What Kind of Plugins to Create?

Here are some examples of plugin styles:

  • Macro - Your plugin defines a macro. Users include the macro as <<macroname>> inside a tiddler, and your macro is invoked, and it typically spits out some content. You can easily make your macro apply inside all tiddlers by including it in ViewTemplate.
  • Hijacking (aka Monkey Patching) - changing the behaviour of some code that’s already in the application - either core TiddlyWiki code or another plugin you’ve imported. (Could expand this with specific things that are changed)
  • Startup behaviour - Some code executed on startup.

Architectural Principles

  • Reuse - where a plugin already exists, don’t reinvent the wheel. Reuse it. Likewise for core TiddlyWiki components. If possible, hijack (aka monkey patch) to extend it rather than directly hacking it. (Open-Close Principle).
  • Modularity - Plugins build on each other. Don’t write a single “big bang” plugin for your entire app. Break things down into logical units.
  • Flexibility - keep the app open to further customisation from users. For example:
    • Content inside special tiddlers - Instead of hard-coding values, consider pulling them in from special Tiddlers, just like the way SiteTitle and SiteSubtitle shadow tiddlers are used. This way, a power user could easily change the value by modifying the tiddler. If it’s content to be included somewhere, you would usually want to run wikify(tiddler.text) against the tiddler content, so the user can include TiddlyWiki markup. A useful concept here is “slices” - this mechanism lets you include content from just part of a tiddler, not the whole thing. See how StyleSheetColors uses ColorPallette for an example.
    • Javascript inside special tiddlers - Most apps have critical algorithms which power users - if sufficiently authorised - might like to update (”strategy pattern” type modules). Isolate such code into special tiddlers, so someone can change those critical parts of your code without having to dive into the whole thing. If your core code has the right functions available, the tiddler content might be a kind of internal domain-specific language.
    • Favour macros over plugins which just charge in and change stuff. For example, if you were writing a comments plugin. The brute force approach would be to bolt on a comments area to every tiddler. But you could achieve the same thing by creating a comments macro, and then updating ViewTemplate to run the macro (ie adding < > to ViewTemplate). Power users could then have more flexibility in several ways: (a) they could remove comments or alter where they appear; (b) they could use a plugin like TaggedTemplateTweak to ensure comments only appear for certain tiddlers; (c) they could customise the way comments are handled using parameters to the comments tag (assuming your macro accepted parameters).

Key Classes and Functions

Here’s a guide to the most important classes ( (More complete guide on TiddlyWiki internals).):

  • Tiddler - the data model for a single tiddler - its title (tiddler.title), content (tiddler.text), last modifier, etc.
  • TiddlyWiki (~aka “store”) - a collection of tiddlers. Typically, there is just one TiddlyWiki on the page containing all Tiddlers, called “store”. Due to certain hard-codedness, it’s not worth creating a separate TiddlyWiki - just use “store” to create, retrieve, update, and delete Tiddlers (the “CRUD” functions).
  • Story (~aka “story”) - a view showing zero or more tiddlers. The main display area you see on the standard TiddlyWiki page is a Story called “story”. So use “story” to add and remove tiddlers being viewed.
  • (possibly others)
  • window - for completeness sake, I’ll note that there are certain “global” (i.e. window) functions worth knowing about.

Let’s look at how those classes give our web app a model and view.

First, the model. How is CRUD handled?

Tiddlers are the atomic model unit in TiddlyWiki. You can inspect the contents using tiddler attributes:

  • tiddler.title, tiddler.text, tiddler.fields, tiddler.tags. These are the title (which also acts as ID), content, custom fields map, and tags for a tiddler. To access slices, use getTiddlerSlice(). Note that shadow tiddlers aren’t real instances of “Tiddler”, so use getTiddlerText() to retrieve them and inspect their text. (There are also properties tracking creation, modifier, etc.)
  • tiddler.set()
  • -update several features of a tiddler at once.

So the “U” in CRUD - Updating - is handled primarily by setting its values.

As for creation, reading, and deleting - these go against the collection of tiddlers on the page, viz. the “store” object (an instance of TiddlyWiki). The key functions are:

  • Creation - store.createTiddler(various, args, mostly, optional) - makes a new tiddler. You might then customise it further with tiddler.set(). You might also want to display the tiddler, once created, with story.displayTiddler(title).
  • Reading - store.getTiddler(title) - retrieves a tiddler by title.
  • Updating - see above
  • Deleting - store.deleteTiddler(title) - deletes a tiddler by title.

You persist these changes by calling:

  • saveChanges() - save changes to disk (remember, TiddlyWiki runs on a file:/// URL - using cunning manipulations normally exclusive to file:/// URLs, it modifies itself with the updated data)

Next, the view. This is mainly handled by manipulating the “story” global (as well as customising general structure and look-and-feel using the many appearance-related shadow tiddlers). You will probably want to show and hide tiddlers dynamically:

Some important global functions:

  • wikify() - converts a string of marked-up TiddlyWiki content to HTML. (e.g. wikify(”xyz”) becomes <b>xyz</b>.)
  • createTiddlyElement - just a generic utility function to help create DOM elements (notTiddlyWiki-specific, but appears a lot if you’re creating content via DOM manipulation).

Cookbook

  • Introducing a New Tiddler
  • Using Slices
  • Running Code on Startup
  • Turning Auto-Save on
  • etc etc

Testing

Using JSpec, building a test vertical etc.

→ 4 CommentsTags: SoftwareDev

Tiddlywiki Plugin Authoring: Detecting onload

September 17th, 2008 · 1 Comment

Tiddlywiki plugins load on startup, early on in the whole boot sequence. I was wondering how to detect when elements are on the page and got some good advice in #tiddlywiki.

Turns out there's no hooks, but a kind-of-hook is macros' init() function. I didn't want to use this, since I'm not creating a macro, though it would have been possible to create a "fake" macro - ie one that's not intended to be called, but just does something in its init(). However, I went for the more general solution - hijacking (monkey-patching) restart():

JAVASCRIPT:
  1. var origRestart = restart;
  2. window.restart = function() {
  3.   origRestart();
  4.   ... some code which can assume elements are on the page ...
  5. }


mmahemoff: hi, i'm writing a plugin that needs to load as soon as the page is ready...is there an event handler for that?
mmahemoff: specifically, my PageTemplate contains an element and I want my plugin to do document.getElementById("element")
Ace_NoOne: mmahemoff: well, there's a ticket for those kinda hooks - but no implementation so far AFAIK
Ace_NoOne: a hacky way would be to write a macro that's hidden in (executed by) some PageTemplate element
jayfresh: mmahemoff: there is this:
jayfresh: var startingUp = false;
jayfresh: that's in the global space and is true during main()
jayfresh: and false the rest of the time
Ace_NoOne: FWIW, http://trac.tiddlywiki.org/ticket/484
Ace_NoOne: has some links
Ace_NoOne: specifically: http://www.tiddlywiki.org/wiki/Dev:Startup_Phases mmahemoff: great tips, thanks :)
Ace_NoOne: mmahemoff: macros' init function run after refreshDisplay
mmahemoff: ok, that ought to do it in my case
mmahemoff: in the more general case, it sounds like hijacking restart() is the typical pattern?
Ace_NoOne: mmahemoff: saqimtiaz1 probably knows best
saqimtiaz1: mmahemoff: standard practice is to hijack restart. Not pretty but the best we have right now

(Snipped some discussion related to a separate thread.)

→ 1 CommentTags: SoftwareDev

Frame-Busting Gadgets

September 16th, 2008 · 3 Comments

In the questions after my @media ajax talk, Simon Willison asked about frame busting. If gadgets sit inside iframes, what's to stop them from busting the frame, i.e. replacing the container with another website. I notice he made a similar comment when OpenSocial came out. If a gadget can cause iGoogle to go away in place of another website, it could for example launch a phishing attack by presenting a mock iGoogle login page ("iGoogle has timed out. Please re-enter your username and password.").

At a technical level, there is actually nothing to prevent this. There's no magic in the container. IFrames are about as good as it gets in modern browser for taming the gadgets, but there are still problems with that model, and one of those is the ability for iframes to bust out. I decided to create a demo of this. The gadget is here. You can drop it into iGoogle and see for yourself. Video below:

(Parenthetically, the video is vertical. Why are videos always horizontal on the internets? It's a computer, not a TV! It should be just as easy to embed an dodecahedron video if that's what I fancy at the time.)

At this stage, there's no technical way around this. One possibility would be for the container to do something in the rarely-used onexit() method, which runs just before the new page is loaded. However, as I learned with WebWait, which is also vulnerable to frame-busting, there's nothing you can really do at that stage, and you can't determine if the exit is happening because of a frame-busting event as opposed to the user just typing in a new URL. I suppose onexit() could still be used to log info to the server - if you knew all the times the container exits and which gadgets were present at that time, you might find certain (malicious) gadgets were present more times than you'd expect if they were present randomly. Although, I'm not sure about how reliable it is to make an Ajax call in the onexit(). (In this case, though, it would only need to work some of the time.)

In the future, the technical solution is Caja, if it proves to be production-ready. Caja ensures a safe subset of Javascript, so a container like iGoogle would only ever serve a gadget if it was verified to be safe.

Until then, we have to rely on "social" mechanisms. i.e. user comments in the catalogue and manual checking by container staff. A while ago, iGoogle made it harder to add a gadget directly by URL - you basically have to use the catalogue unless you're a developer. So the catalogue is effectively acting as a whitelist - once found to be malicious, a gadget could be removed. This isn't simple though - gadgets are dynamic and the catalogue is effectively just a list of URLs. A malicious author could have their gadget added to the catalogue and then change it, so the gadgets need constant review - a highly ineffective process.

I also mentioned in the presentation that "html" type gadgets are more recommended than "url" gadgets. This is partly because with html gadgets, the container at least has some idea of what's happening inside the gadget - though not entirely, since the code can still reference external scripts and services. With "url" gadgets, what happens is entirely controlled by an external server.

→ 3 CommentsTags: SoftwareDev

OpenSocial-Tiddlywiki Integration

September 3rd, 2008 · 1 Comment

Go straight to the demo.

Google Gadget TiddlyWiki plugin - a tiddlywiki macro to embed google/opensocial gadgets

I'm at the Osmosoft hackathon and finally got an opportunity to experiment with OpenSocial-Tiddlywiki integration. Specifically, how to embed OpenSocial gadgets in Tiddlywiki. I paired (trio'd?) up with Stuart Race and Tom D'Roza on it. We managed to get something useful up in an hour or two, which is testimony to the simplicity of both OpenSocial and Tiddlywiki. It's only proof-of-concept for now and for some reason doesn't work in IE.

Technically, it's iGoogle integration, not OpenSocial. The gadgets are iframes pointing to the iGoogle gadget server (gmodules.com). That's because right now, it's not clear there are any OpenSocial containers that will serve out gadgets externally in the same way. Of the various live OpenSocial containers, there is really scant information about how to embed the gadgets in an external page. Suffice to say, the code here is virtually identical to what you'd need to embed an OpenSocial gadget - it's simply a matter of changing the endpoint URL from whence gadgets are served.

One concern about this is whether or not Google will be cool with us pointing directly to the iframe. Technically, you're supposed to embed gadgets using a script tag, which will document.writeln() the iframe and its source. I vaguely recall a time last year where we were playing around with direct calls to the gadget, and gmodules saying no. This is possible in theory, if the server was attempting to match each iframe request with a previous corresponding script call. However, I am probably dreaming. It seems to be working fine. In any event, Shindig has no constraint like that, so if we extend this to point to other opensocial servers, or something spun up by an individual, it should work fine.

Usage

With the plugin installed, it's simple to use:

<<gadget http://abowman.googlepages.com/spider.xml >>

or with options:

<<gadget http://www.btinternet.com/~tdroza/gadgets/twitter/index.xml height:400 width:500 border:0 prefs:"up_maxitems=5&up_username=downingstreet&up_feed=http://twitter.com/statuses/usertimeline/" >>

If you're familiar with opensocial you'll realise that the height, width, and border are options to the gadget server telling it how to render the gadget and its chrome; whereas the prefs string contains preferences which the gadget itself gets. All this is optional.

Plugin Code

We began with the Shout plugin whose code I've already documented. It was only a matter of creating an iframe and pointing it - by setting its src property - to "http://www.gmodules.com/ig/ifr?url="+params[0]. And that worked fine, and we had gadgets inside tiddlywiki.

The hard part was parameters, took a little investigation to work out how to handle key-value pair parameters. The plugin code below serves as a simple example for how it's done. It's very similar to the very cool Ruby/Rails idiom which has also been adopted by Javascript libraries like Prototype (obviously, given its Rails association) and JQuery. i.e. mandatory params followed by a hash of optional params. Here, the URL is mandatory, and its proceeded by a set of key-value pairs.

The plugin code:

JAVASCRIPT:
  1. config.macros.gadget = {};
  2. config.macros.gadget .handler = function(place,macroName,params, wikifier, paramString) {
  3. var elem = createTiddlyElement(place,"iframe",null,"greeting","");
  4. var p = paramString.parseParams(null, null, true);
  5.  
  6. elem.src= "http://www.gmodules.com/ig/ifr?url=" + params[0] + "&" + getParam(p,"prefs","");
  7. elem.height = getParam(p,"height","200");
  8. elem.width= getParam(p,"width","300");
  9. elem.style.border= getParam(p,"border","1");
  10.  
  11. place.appendChild(elem);
  12. }


That's it.

Applications

Why would you want to embed a gadget in a tiddlywiki, aside from proof of concept? Well, tiddlywiki is a platform whose applications are many and varied; OpenSocial integration simply enhances the platform so that developers can select from a rich palette of existing gadgets. For example, if your tiddlywiki involves trip planning, pull in a Google Maps gadget.

It also makes for an extremely easy way to collect up a bunch of related gadgets, and optionally have a conversation around them. For example, you could compile your favourite game and toy gadgets into a game tiddlywiki. Remember tiddlywikis are single files, so this becomes a single file game.html which you can mail around, keep on your hard drive, or post to a server. A related usage would be a single tiddlywiki where all gadgets are the same type, but with different preference strings. For example, 10 weather gadgets with different "location" settings.

→ 1 CommentTags: SoftwareDev

The official olympics medal tally is broken. Let’s fix it.

August 18th, 2008 · 2 Comments

This is how the official olympics medal tally looks:

Overall Medal Standings - The official website of the BEIJING 2008 Olympic Games

It's not only the official tally, but the one linked from google each time you type "olympics" and terms like "australia olympics". Thus making it an absurdly popular page at this time. As you can see, the design is reedeeeculous. The thing you want to see the most - total medal tally - is several miles away from the country. It's good they've used alternative shading for odd and even rows, but even so, it's still difficult to see the connection. Especially since the gold/silver/bronze tallies are shown in a different colour.

Did you notice even "open/mixed" gets preferential treatment? Look, I can't even think of an open/mixed event at the olympics. Ballroom dancing? Friendly game of trumps? All I'm saying is, I'd rather see the headline figures first. I don't know how many gazillion dollars the official IT contract went for, but this is what the tally should look like according to table design 101:

Overall Medal Standings - The official website of the BEIJING 2008 Olympic Games

(BTW I also pulled total to the front and emphasised it. Matter of opinion whether to go by total number versus number of golds.)

(The following images are just to record the fact it's linked from Google since it won't be linked much longer.)

olympics - Google Search

australia olympics - Google Search

→ 2 CommentsTags: HumansAndTech

Can’t really get excited about Ecmascript enhancements. Can’t really get disappointed about them either. When it comes to Ecmascript enhancements, I’m all “it doesn’t really affect me much”.

August 14th, 2008 · No Comments

There's some tweets and such like about Ecmascript Harmony today. I also saw a nice demo of Ecmascript 1.7 goods today.

Really, I can't get excited about future versions of Ecmascript and can't get emotionally all in a tangle about the trials and tribulations of Ecmascript. I mean, Javascript is arguably the most popular language in the world, so it's cool to know it's maturing over time. But, you know, I'm only interested in learning about a language (version/dialect) when at least one of the following applies:

  • It can be used in practice, today.
  • Learning it will broaden my mind in some way.

Using it in practice, today? No.

New versions of Ecmascript cannot really be used today, not by me anyway. I mostly write public web apps and enterprise web apps, and in both cases, it's essential to target Internet Explorer. Ecmascript version N is only worth learning when most of the world has abandoned every version of IE prior to that which supports version N. When you see a new specification being mooted, you have about 10 years of thinking music before the spec is actually released (2-4 years), integrated into all major browsers (0-5 years if ever), and moreover, previous versions have died out (5+ years).

Maybe as society accelerates to the singularity, these lengths will become shorter and you'll be able to deploy a new version of Ecmascript three times a week. For now, though, it's fairly pointless from a practical perspective. If you take an agile attitude, why bother investing the time and focusing on something that end up changing or being abandoned altogether?

Okay, this is exaggerated - there are people who can put in practice new versions fairly quickly. Firefox is not only quick to incorporate new versions of Ecmascript, but also happens to be a platform where browser-specific code is sometimes warranted. I refer to browser extensions (and, relatedly, Greasemonkey scripts). If you happen to be writing Firefox browser extensions, you might choose to use Ecmascript as soon as it's baked into Firefox. You'll still be breaking compatibility with previous versions, but Firefox users constantly update anyway. This will continue to be the case for as long as most global enterprises force their workers to install Firefox on the sly. Which will be a long time. So you can happily use the latest Ecmascript if you're writing extensions.

There are also people targeting the Flash platform for whom all this stuff is more important today. Not me, not right now.

The other case, of course, is when you're using Ecmascript outside of the browser. e.g. server-side Javascript (yum!). Entirely valid. But this is still rare.

Learning it will broaden my mind? Not much.

Javascript is a quite interesting language, so new features will be interesting too. But not hugely, since Javascript isn't that different from other dynamic languages. And most Ecmascript enhancements are either trying to mould JS into Python or the Java/C++/C* OO model. So they're not about creating interesting "native" features.

You'd be better off learning something completely different in order to expand your coding brain. Try one of these.

I mean, don't get me wrong

Don't get me wrong. The thought leaders need to be thinking about this stuff and making the long term efforts. But for the average Ajaxer on the street, it's all thirsty fish in the desert sand.

→ No CommentsTags: SoftwareDev

Using 280Slides (Ajax slideshow maker): Real World Experiences

August 13th, 2008 · 2 Comments

I used 280slides.com for a quick presentation today at the London Javascript meetup. (The usual Jobsesque slides - usually one phrase plus an optional image.)

The tool is very cool, as initial reviews suggested, but most of those folks had not used it in a real world situation. The tool has it's complications when you use it for real.

What's good:

  • Looks cool and OSX/Keynote like, but not slavishingly following the desktop in a way which would detract from usability
  • Great sharing and embedding options - can download as ppt, pptx (powerpoint 2007), pdf, and open document...and moreover, can view it full-screen, send it to slideshare, and embed it on a web page.
  • Has all the basic tools you need
  • Has undo and redo with a long history.
  • Supports OSX key bindings, i.e. uses the command key (ie the apple key) instead of what most web apps do, which is to use the ctrl-key even on OSX. (On the whole, there's a need for a really great Ajax/Javascript key event library to do stuff like this automagically.)
  • Can easily do a slick full-screen mode presentation, using the PlainView browser, as noted on the 280slides blog.
  • Supports themes. (Themes is one rare area where the Ajax/web model makes life very easy for developers of desktop-like apps - just change the CSS style. If only life was so simple for the developers of the original desktop-like apps, where CSS-like functionality is usually lacking.)

What could be improved - this is all intended as constructive criticism. The team's effort to date shows they are extremely talented Ajaxers and I have no doubt every one of the following can potentially be rectified in the coming months, provided they have enough will and bandwidth.

  • Cut-and-paste - this one really got me. Cut-and-paste is something we do all the time when making slideshows. The problem here is that elements are pasted directly on top of each other, so you can't tell if it's been pasted or how many times it's been pasted (and you may well have several, as it's likely you'll be hitting command-v a few times, since there's no feedback). This is exacerbated by the delay involved - sometimes takes a second or two to make the paste, so when you try to start dragging the copy, you might instead end up dragging the sole, original, element.
  • AFAICT cut/paste/copy are available only as keyboard shortcuts. There's no toolbar/menu item. This exacerbates the previous problem. With "paste" lacking immediate visual feedback, you'd at least want a button you can click instead of relying on the keyboard shortcut, which feels less assuring (mainly because keyboard shortcuts are still a bit of a novelty on the web). And of course, the other problem is that users aren't aware the keyboard shortcuts are available.
  • Saving - it's not clear if auto-save is present. It certainly should be. They need some sort of status message for this, or an auto-save checkbox (though I think it should always be on).
  • Undo isn't perfect. Sometimes the undo skips the most recent action and instead undoes an action before that. This often happens to be an action on a different slide - it's good that it jumps back to that slide, but you can easily lose your place and makes it difficult to then go and manually undo the action you actually wanted to undo.
  • It's fairly processor-intensive. This isn't really a fair criticism, because it's too much to expect an app like this to be gentle on resources. Still, I did struggle running it on a 3 year old powerbook and that will affect some users. On the bright side, it's very snappy on a newly booted Firefox running on a more modern Macbook.
  • When you select text to change it, the text becomes grey to highlight it - thus making it impossible to see any new colour scheme you've chosen. Whenever I tweaked background or foreground colour, I had to keep unselecting the text, viewing it, and then re-selecting the text and change the colour again.
  • Text blocks don't auto-expand/shrink when you change the text size. You must manually resize.
  • As you'd expect, there's no support for a lot of the more advanced features. Some people would say those features are unnecessary, but personally I do find they do make an impact in live presentations and can often help to convey info in subtle ways. I'm talking about features like shadows, gradients, round corners. I know, it's all just "bling-bling web 2.0 eye candy noise", but really they're essential if your aim is to keep your slides in the visual - rather than literary - realm. Also, there are some more basic features not yet implemented, e.g. borders for images and shapes, and the ability to crop.
  • Images can load quite slowly, and again, there's no progress indicator. Unloaded images are shown just as a grey block, so viewers mightn't be aware that an image is loading in that spot.
  • As I was writing this post, I opened up the slideshow and somehow it added a blank textboxes to every slide. Don't ask me how or why. The existing text somehow had shifted up to the top of the page, and had been resized to one line. I think it somehow had tried to apply a standard slide template (title and main text area), whereas my slides are mostly just one line in the middle of the slide.

Anyway, it's already usable and has huge potential. Long may 280slides rock! I only hope that if they're acquired, the innovation keeps happening.

→ 2 CommentsTags: SoftwareDev