Server-side Javascript: Hope and opportunity

Update: See also http://mini.softwareas.com/why-server-side-javascript

Dion’s cartoon resonated with me:

Resonated because only last night I was thinking it’s about time I actually started playing with server-side Javascript, and wrote my first, extremely dumb, AppJet app. I will hopefully make it, like, actually do something at some stage.

I’ve discussed the potential of server-side Javascript before, and the more I think about, the more I like it. Javascript is a sophisticated language and, by now, a language very familiar to many professional web developers.

The real gap is in server-side frameworks and hosting. There’s no “killer app” Javascript server, a la what Rails did to Ruby. I haven’t even heard of most of the SSJS frameworks listed in Wikipedia. Furthermore, try finding a virtual host that supports Javascript! You would practically need one that support Java, so you can run Rhino or whatever, and few virtual hosts do that. At least Python and Ruby were running on many virtual hosts before Django and Rails showed up. For that reason, the model pursued by AppJet seems worthy. If they can come up with a solid virtualisation environment for Javascript, they may be on to a big winner. They could be the BEA or JBoss of 2015 (2010 seems a bit early for all that!). And if the rumour is true they’re using Scala, they’ll get doubleplus-coolness votes for language selection.

CSS Coding Style and the Unbearable Tendency for People to Adore Whitespace in their Source Code

CSS coding style doesn’t get a lot of play. Most people are happy to stick with the convention of one property per line, like this:

  1. #score {
  2.   background: yellow;
  3.   width: 12em;
  4.   border: 1px solid orange
  5.   padding: 2em;
  6.   margin: 3em 0;
  7.   display: none;
  8. }

I, for one, can’t stand that style. I’m heavily biased towards information-dense coding styles, which don’t have much whitespace. People mechanically argue “oh but whitespace is so important etc” as if we were designing a modern art installation. Well, whitespace is indeed essential, but you have to discriminate between a touch of elegant whitespacing for the sake of clarity, and “oh dear! My 80-column row seems to have just 12 characters on it. Come to think of it, every row on my 30-inch Cinema Display has 12 characters on it.” Seriously, I don’t know why anyone would use an 80-column terminal anymore, unless they enjoy coding on their iPhone. I tend to think 120 or 160 is ideal; any more than that and most people won’t be able to see the whole thing without moving their head. Anyway, I’ll be conservative and assume 80 columns. The average end column in the above code snippet is roughly 15, which means in your scrawny 1975 80-column terminal, you’re filling 20% of it with information and 80% with whitespace.

There’s an old figure that says the average programmer codes 10 lines per day. It’s obviously not a very accurate figure and maybe it was meant to include all the non-programmers on the project or something, but the point is interesting, as there’s probably some reasonably consistent LOC per developer figure (obligatory mutatis mutandis caveat). Seizing on this historical figure, Bruce Eckel said a while ago (paraphrasing) “if I only get 10 lines a day, I want them to be good ones”.

That’s why I favour information-dense coding styles. As a programmer, you’re supposed to be an expert user who spends all day in front of the same system. This is a typical example of a situation which demands a “Sovereign Posture”. It’s an expert system. When people long for glorious pastures of whitespace, they’re ignoring the fact that with sufficient practice, they’ll be virtually as proficient at reading and writing a more information-dense style, and vastly more efficient by having so much more code available at any time. It’s the same reason why Real Programmers commit to learning Unix and Vi or Emacs; if you’re going to spend decades working in this environment, why wouldn’t you spend a few days committing to the most efficient tools available?

For the record, I still have plenty of whitespace in my programs, but when there is a decision to be made between one popular convention and another, I almost always go for the one which reduces whitespace. I have enough faith in programmers’ pattern-detection skills to know that in time, they will be fine with either style, but the one with less whitespace will always give them more bang for their Cinema Display buck.

Back to CSS. Here’s how I’d format the above snippet:

  1. #score { background: yellow;  border: 1px solid orange;
  2.              width: 12em;  padding: 2em;  margin: 3em 0;
  3.              display: none;
  4. }

What I do is group similar attributes on each line. I’m pragmatic about the precise rules. If it’s just a handful of properties, I’ll stick them all on the same line. If there’s more than that, then typically I’ll have one line for appearance (colour, fonts, etc.), another for layout, and possibly more for other things like display settings or detailed positioning. You also don’t need whitespace between each rule either, so you can often end up with a whole sequence of related one-liner rules:

  1. /******************************************************************************
  2.    SCOREBOARD
  3.  *****************************************************************************/
  4. #scoreboard { background: black; color: white; }
  5. #homeTeam, #awayTeam { color: pink; text-align: right; position: absolute; }
  6. #homeTeam { top:20px; left: 120px; font-size: 8em; }
  7. #awayTeam { top:80px; right: 120px; font-size: 5em; }
  8. ...
  9.  
  10. /******************************************************************************
  11.    ARENA
  12.  *****************************************************************************/
  13. .player { color: #f99; }
  14. .runner { color: #99a; }
  15. ...

This format is not only denser but also easier to comprehend as related properties are grouped together. The typical one-line-per-property format tends to include a random jumble of properties; rarely does any thought go to the order in which the properties appear.

Another thing that helps with CSS brevity is learning shorthand formats. Use “border: 1px solid orange” instead of “border-width: 1px; border-style: solid; border-color: orange”. Use “margin: 3em 0;” instead of “margin-left: 3em; margin-right: 3em;”, and so on.

The Little Bug that Could: Firebug Book Chapter

<gush> Firebug is awesome. Joe Hewitt is a legend.

As I’ve said before, Firebug is among the most usable software tools ever developed. I don’t just mean compared to other software development tools. I mean against all user-facing software. It’s single-handedly improved my Ajax productivity by at least 100% (that’s my estimate when making changes to larger Ajax code bases). It’s made Ajax development much easier to get into for newbies and a much more pleasurable place to be for all developers. </gush>

So I’m pleased to announce I’m writing a chapter about the bug in the upcoming Sitepoint text, The Art & Science of JavaScript”. To be published by Sitepoint and with coauthors Simon Willison, Christian Heilmann, Ara Pehlivanian, Dan Webb, Cameron Adams, James Edwards, and others. I can’t talk about timelines, but you’ll notice the Amazon entry above is stating January ’08.

Would you like to review the chapter? Drop me a line – [email protected]

As well as explaining the various parts, I’ll be sharing tips on when to use different features and how to get the most value out of them. Here’s an outline:

* Meet the Bug
  What is Firebug, when to use it, overview of functionality, how it has
    impacted modern web development.·
  What's missing at time of writing (other browsers, cookies)

  • Installing Firebug

    Downloading and installing the plugin, opening it up and enabling it for certain sites. Windowed vs docked mode

  • Firebug Anatomy and Idioms

    Overview of sections in the Firebug window

    Idioms - point out that most things are cross-linked, searchable, and editable. Options menu.

  • The Console

    Introduces a sample application used throughout the chapter, then introduces the console (logging, errors, running JS commands).

  • Viewing and Editing Your App on the Fly

    • HTML
    • Including Layout and Style
    • Mention Inspect option in popup menus.
    • CSS
    • Javascript
    • DOM
  • Debugging Your App

    • Breakpoints and tracing
    • Watches
    • Stack trace in the console
  • Performance Tuning Your App

    • "Net" tab
    • Profile button
    • YSlow
    • Reference Related Tools below
  • Related Tools

    • Firebug Lite

    • YSlow

    • Microsoft Script Debugger

    • Other Firefox Extensions

    Brief list of a few other useful/alternative extensions, e.g. Web Developer Toolbar, Measure-It, Stylish

Firebug Wishlist

Just mailed Joe Hewitt a couple of suggestions for the bug.

Hi Joe,

A couple of firebug suggestions.

(1) Search

On the Ajaxian interview, you mentioned people have trouble locating and knowing about the existence of Search. (Me too.) Redesigning the layout will help, but I'd also suggest retaining the standard alt/control-F shortcut somehow, as I'm sure a lot of your power user audience will be trying to use that and failing.

More generally, any redesign probably ought to somehow integrate Firebug  search into Firefox search, e.g. use keyboard focus to decide which of the two is searched.

Bonus points if Firebug search cycles through all tabs :) .

(2) One word: cookies!

Cheers,
Michael

Drag a custom window with Adobe Air

Quick tip. Been playing with Adobe Air recently and was trying to let the user drag a "systemChrome="none" transparent="true" around. The definitive Air reference has an example that shows how to close and minimize, but not how to move it. And all the examples I could find are Flash-based rather than the HTML/JS/Ajax approach I’m taking (along with some forum posters who were as confused as I was). Based on the Flash examples and the close/minimise pattern, it turned out to be this simple:

javascript

  1. document.body.onmousedown =
  2.         function() { window.htmlControl.stage.window.startMove(); }

The only thing wrong with GoF Design Patterns is …

Jeff Attwood recently pointed out the difference between Gamma et al’s Design Patterns and Alexanders’ equivalent and outlined a critique of the former which characterises it as “replacing actual thought and insight with a plodding, mindless, cut-and-paste code generation template mentality”.

First, I want to note that the critique above surely defies belief to anyone who has used the patterns in practice. Patterns like the GoF design patterns are grammar for software architecture. If you search the technorati archives from when grammar emerged many millennia ago, you will probably find one or two bloggers was bemoaning the loss of creativity that this concept of sentence structure will cause. Fortunately, sense prevailed and now writers can be creative about the things that matter and not have to micromanage those that don’t. The progression of any discipline involves a cycle experimentation followed by optimisation followed by explicit statements of best practice (patterns), spiralling upward in level of abstraction. If I was so inclined, I’d go make a T-Shirt on CafePress that says “Patterns Take You Higher” with a picture of Bob Marley refactoring to Template Method.

So the GoF patterns are perfectly choice by me. The main problem with them is not the content per se, but the fact that most software developers think that pattern==GoF pattern and pattern language==the 23 patterns by Gamma et al. (1995).. If there’s ever a sequel, it would double the number of patterns in the universe according to these folks! In fact, there are thousands and thousands of documented design patterns out there, in the realm of software alone. (Admittedly, the most popular realm for design patterns, though there are still plenty of patterns for other disciplines too.)

This perception is silly.

Why do software patterns != GoF patterns? We can expand out from the GoF patterns in several dimensions (even staying within the realm of software):

  • Architectural Paradigm Even with patterns of high-level software structure, like GoF, we can model different architectural paradigms. GoF is all about general-purpose OO architecture; if you wanted to work with functional or logical languages such as Haskall or Prolog, you would need different kinds of patterns.
  • Application Type GoF patterns apply to the general structure of any medium+ scale architecture. There is still a wealth of advice to be gained from studying existing applications of the same type as you’re working on. This could be web server design, in-browser script design (like some of the Ajax patterns), mobile phone design, etc. For instance, the various J2EE patterns around, which were probably the second best known category of patterns in the industry (trailing GoF by a long margin though).
  • Perspective People see software from different perspectives; GoF patterns see it from that of a technical architect working close to the ground. You can also see patterns from the perspective of a user experience designer (usability patterns), project manager (software development process patterns), business analyst (business process patterns), programmer (coding idioms), etc. In this paper, we explained how patterns for usability alone could have all sorts of representations.
  • Domain The GoF patterns apply whether you’re working in banking, gaming, or web design. But each of those fields have their own idiosyncracies and fortunately there are pattern languages which capture them.
  • Opinion Even if you aim for the same problem space as Gamma and colleagues looked at, you will have your own views on the correct solutions. Patterns are opinionated, not objective, so your patterns will differ from theirs. As time goes on, any static set of patterns will naturally become less valid – it’s a testimony to Gamma et al that the patterns remain so very useful 12 years on (that’s a 256-fold increase in processing power according to Moore’s Law, and industry transition from C++ through Java and .Net through to Javascript, Ruby, and Python). Still, they’re not perfect; Singleton anyone?

One of the reasons the Gamma patterns are so successful is the fact that they apply so universally. However, this also leaves room for other patterns to come in and provide more specialised support.

Ajax Patterns has certainly been subject to this misconception; one review liked the content but prefers not to see it as a real pattern book – “Anybody who has read a real design pattern book and then read this book will soon feel the artificiality. ” Another refers to Gamma et al as “I read the original ‘Design Patterns’ book” and states “Those that read the original book will understand that packaging these topics as design patterns is insulting to those that know the value of actual design patterns. “. After many years of explaining usability patterns, I had anticipated these concerns with an appendix explaining the difference, but moreover explaining that it’s the content that matters most. There is also a perception that “Patterns” in the title sells more copies; all I can say is “I wish” as that buzzword went out the window around 2002. It’s called “Ajax Design Patterns” because they are, well, Ajax Design Patterns.

Bill Sanders gets it and recently discussed this phenomenon:

Buried in Appendix C (pg 605), Mahemoff distinguishes his use of design patterns from that of GoF, but it is not the kind of place that most developers are going to look when they pick up a book about Design Patterns. Likewise, Mahemoff uses the inside front and back covers to list the Ajax design patterns. On the one hand, anyone who reads those pattern names is going to know that this book is not about the kinds of design patterns GoF examine. On the other hand, the fact that the patterns are listed there, just like the GoF book, is a sincere form of flattery in the form of imitation.

Bill makes a good point about the Appendix C content being buried. Actually, relating the second point back to the first, I had in mind the similar statement by Gamma et al about Alexander’s patterns and their relevance, which also appears at the end. Still, in a pattern book, I’m not sure where to put something meta that won’t be buried; I’m sure the preface and intro are read about as much as the appendices. And I’ve certainly discussed the issue online before.

As for the covers, I liked the idea from GoF as well as Fowler’s UML Distilled book, and was particularly insistent on this because O’Reilly couldn’t do page cross-referencing.

Mahemoff is quite right in noting that the “original” design pattern book is Christopher Alexander et al’s town planning and architecture patterns book from the 1970s.(In fact in the Foreword to GoF’s DP book, Grady Booch mentions Christopher Alexander’s work.) However, common usage of design patterns in the context of computer programming has come to mean the kinds of patterns GoF talks about. Head First Design Patterns is a good example. No one was disappointed because they were surprised by the meaning of design patterns. Common usages in a given context come to have a specific meaning. In the world of quilt-making, design patterns mean something entirely different than in programming, and so no one is surprised when they get a book called Quilt Design Patterns and find out that there’s nothing about the Creational, Structural, Behavioral Design Patterns. However, in the world of programming, that is exactly what can (and did) happen in the case of Ajax Design Patterns, despite the fact that no less than Ralph Johnson reviewed parts of it.

(Emphasis mine) Yep, if you published a book of music patterns, there’d be no confusion. Still, I think our industry misses out because of this confusion. In an ideal world, there would have been 2 or 3 equally big hits at the same time, to get people’s mind around the fact that patterns are everywhere, not confined to the one (albeit excellent) text (I was going to call it “bible” but the one time I met John Vlissides, he told me he didn’t like it when his colleagues called it that :)). As it is, there’s the big ‘un, a few prominent others – typically in similar “high-level architecture” style to that one (e.g. the J2EE books, the POSA series and some of Fowler’s work), a bunch of books which used “pattern” for the hype value, and thousands of other books and one-time papers and blog entries. At one stage, Ward Cunningham was going to work with Microsoft to build PatternShare, a kind of meta-repo for all things pattern, which may have changed things, but apparently it never happened and the site is now down.

Quite apart from the book’s title, Mahemoff, does take up the invitation to contribute to design patterns offered up by GoF and he documents a number found in Ajax. While on a different level and with a different specific meaning than that found in GoF book, Mahemoff provides a wider view of design patterns and has what may be the best Ajax book on the market. It would be a shame if his work is diminished by the title, but among some, especially on the higher end, that may happen. Fortunately, the bulk of the reviews are readers who were looking for a good Ajax book and got exactly what they wanted.

This is where things get even more confusing, because the Ajax patterns (as with just about any other form of software pattern) actually relate to he GoF patterns. They’re different, but not entirely orthogonal. For instance, the daddy of all UI patterns, Observer, is present in patterns such as Virtual Workspace. My attitude is that patterns are there to be referenced and so I will happily reference other patterns from other languages if need be. In my mind, it’s all one big network of patterns (a PatternShare wiki, if you will).

Rails JSON, JSON Rails

<

p style=”clear:both; margin-top: 2em; “> Man, JSON has come out of nowhere! I first came across it amid the Javascript hype in early ’05, now it’s everywhere. Not only in your Ajax apps, but in the On-Demand Javascript APIs of the world.

Sharing an ethic of simplicity with Rails, it’s not surprising these technologies have come closely together, with JSON support now baked into the Rails core. (They would have been even closer together, if only anyone had noticed JSON==YAML early on and merged the two completely.) And yet, the current implementation misses a couple of tricks.

  • Use of “attributes”. According to Rails, a JSON object generally has just a single key, “attributes”. Instead of the simple { :name=>”Pac-Man”, :creator=>”Namco” }, we get (and have to give) { :attributes => { :name=>”Pac-Man”, :creator=>”Namco” }}. That’s not DRY. Not that it matters, but the reason for this is because ActiveRecords internally store persistable data fields in a hashmap called “attributes”. The JSON serialization is therefore faithful to Rails’ internal implementation, while being unfaithful to intuition. Maybe you could argue for “attributes” on the basis that you might one day have a transient attribute with the same name as a persistent attribute, in which case you’d get a clash. But Convention Over Configuration rules this argument out; you can always override JSON serialization behavior in boundary situations.
  • Child attributes This is probably an issue with XML as well. Basically, there is no attention paid to child attributes, i.e. JSON/XML serialization of a HABTM or has_many relationship. You want something like { :name=>”Pac-Man”, :creator=>”Namco”, :high_scores=>[{ :player_id=>1, :score=>99999 }, {:player_id=>2, :score=>88888 }] }, but all you get is the top-level attributes :name and :creator.

What to do?

First, I just discovered this extremely helpful library – Jsonifier, which also ships as a Rails plugin. It deals with both of the above problems. There’s no “attributes” chaff and it deals with associated records, even going recursive and letting you navigate from end of a many-to-many into the other. (In my example, you could show the names and ages of Pac-Man high scorers.) You also get to whitelist or blacklist attributes matches Rails’ associations syntax, i.e. :only, :except. Highly recommended, check it out.

Jsonifier, however, is pure to_json – it doesn’t (yet) handle deserialization. To my knowledge, there’s no Rails library that persists both parent and children in one go. There are lots of forum posts about handling multiple checkboxes and the like, and the answer usually involves overriding “children=” or “child_ids=”. I want to do this automatically!

I’ve been working out how to extend ActiveRecord to persist automatigically. I have the following very rough code working in basic situations, although it would need to do some more validation to work in production, among other things. It works on data structures such as the recurisve one above. You must first use a before_filter to convert the incoming JSON string into a Rails structure.

class << ActiveRecord::Base

def recursive_create(params) transaction do collections_by_children = pluck_hash_collections_by_children params new_model = self.create(params) populate_children new_model, collections_by_children new_model end end

def pluck_hash_collections_by_children(params) hash_collections_by_children = Hash.new params.each_pair { |name, value| if value.class==Array hash_collections_by_children[name] = value params.delete(name) end } hash_collections_by_children end

def populate_children(new_model, hash_collections_by_children) hash_collections_by_children.each_pair { |children_name, hash_collection| new_model.send(“#{children_name}”).destroy_all child_class_name = children_name.singularize.camelize child_class = Object.const_get(child_class_name) hash_collection.each { |child_hash| child = child_class.create(child_hash) new_model.send(“#{children_name}”) << child } } end

end

module ActiveRecord class Base

def recursive_update_attributes(params)
  transaction do
    collections_by_children = self.class.pluck_hash_collections_by_children params
    self.update_attributes(params)
    self.class.populate_children self, collections_by_children
    save
  end
end

end

end [/ruby]

Google Gadget API for Ajax Developers

I just made my first Google Gadget – a Digg roundup tool. Here are some quick notes on making a Google Gadget for Ajax developers. I assume you know Ajax and also that you’ve played around with iGoogle as a user.

What’s a Gadget?

  • The gadget is an XML file sitting on your server. In my case, http://ajaxify.com/run/widgets/google/diggroundup.xml. It will get cached, so effectively it must be a static file.
  • The user adds your gadget to their igoogle portal, or codes it into their own website, by specifying this URL (it may be done indirectly – via the gadget registry. You’ll appear in the registry if you’ve submitted your gadget to igoogle.)
  • The gadget is rendered as an iframe, so you have all the usual security constraints which stop you borking the portal and other gadgets. This also means you can’t communicate with other Gadgets other than via than remote calls to a common third-party server (or has anyone tried hooking them together using the iframe-fragment identifier hack? ).

The Gadget Content

  • The XML file contains three main sections: module settings, user preferences, and the iframe content.
  • Module settings (<ModulePrefs>) are the usual demographic stuff – module name, your email, blood type, etc. Mostly optional.
  • User preferences (<UserPref>) are things users can edit by hitting the Edit button. Note that these aren’t dynamic app variables like a user’s search query – they are longer-term preferences like background colour and number of results to show. Each time the user changes then, the entire gadget is reloaded, so you can assume in initialisation that the preferences have already been established, and you don’t need to bother checking if they’re changed. The nice thing about preferences is they’re declarative, so you don’t have to manage input and persistence. You just say “I need a number called resultAmount from the user” (<UserPref name="resultAmount" display_name="No. of Results" default_value="5" datatype="string" ></UserPref>). Later on, you’ll be able to interrogate a prefs object to get back the data.
  • The content. The content is pretty much the “body” part of an IFrame. ie. your html and … you’ll never expect this … the javascript. You probably expected the JS to be in a separate section of the XML file, but you simply include it using an inline script tag (<script tag="text/javascript">the script...</script>, wherever you fancy. The same goes for CSS – just include a <style type="text/css"> section at the start of your script or inline it. So much for unobtrusive Javascript/CSS, but you can and should still separate things out within your page content.

User Prefs example

This is what the user prefs looks like:

It comes from this definition:

  1. <UserPref name="bgColor" display_name="Background Color:" default_value="White" datatype="enum" >
  2.         <EnumValue value="White" />
  3.         <EnumValue value="Pink" />
  4.         <EnumValue value="Aqua" />
  5.         <EnumValue value="Lime" />
  6.         <EnumValue value="Yellow" />·
  7.         <EnumValue value="Orange" />
  8.         <EnumValue value="Black" />
  9.     </UserPref>
  10.    <UserPref name="container" display_name="Story Type:" default_value="" datatype="enum" >
  11.         <EnumValue value="" display_value="All" />
  12.         <EnumValue value="technology" display_value="Technology" />
  13.         <EnumValue value="science" display_value="Science" />
  14.         <EnumValue value="world_business" display_value="World Business" />
  15.         <EnumValue value="sports" display_value="Sports" />
  16.         <EnumValue value="entertainment" display_value="Entertainment" />·
  17.         <EnumValue value="gaming" display_value="Gaming" />
  18.     </UserPref>
  19.    <UserPref name="storyAmount" display_name="No. of Stories:" default_value="5" datatype="string" >
  20.    </UserPref>
  21.    <UserPref name="popularOnly" display_name="Popular Only?" default_value="true" datatype="bool" >
  22.    </UserPref>

and is accessed like this:

javascript

  1. var prefs = new _IG_Prefs(__MODULE_ID__);
  2. message.style.backgroundColor = prefs.getString("bgColor");

Remote Content

  • Your gadget probably takes remote content. Remember it’s a static XML file, so you can’t output such content on the fly – you have to use some kind of web remoting. Because of cross-domain restrictions, you will want to use a Cross-Domain Proxy. (I experimented with direct On-Demand Javascript, but no cigar.) Fortunately, Google provides a nice API for proxying, which also caches the content you’re grabbing. The main call is _IG_FetchContent(url, callbackFunc). The callback function is given the contents of URL. As mentioned in my previous post, this might cause some problems if you need to refresh the cache more than once an hour.

Development Tips

  • igoogle can give some pretty poor error messages when you’re just starting up. If there’s nothing at the URL you specify, you will get a weird XML parsing error rather than a good old 404 warning. I also found if you have certain errors such as a typo in your XML file, igoogle says the gadget doesn’t exist at that URL, even though in this case, it does! For those reasons, be sure to start with Google’s Hello World and work from there!
  • Develop on your server directly. (If the gadget is live, you might make a test copy of it for debugging.) You don’t want to be developing on your local box and continuously uploading/checking it in, because igoogle needs to fetch it from a URL each time you want to test it.
  • The secret sauce is this: The Developer Gadget. This is a special gadget provided by igoogle that, if you include it on your portal, will let you suppress caching of your app, which you absolutely have to do. It also makes it a bit easier to add a new gadget and view the gadget source code.
  • Speaking of gadget source code, you can view the entire gadget XML for any gadget you come across, so take advantage of that and avoid reinventing the wheel.

The Developer Gadget looks like this:

Digg API – Can’t Bust the Cache

It’s often a requirement for an Ajax app to “bust the cache”, i.e. call a service and ensure its response comes direct and not from a cache. For all the talk of fancy header techniques, the easiest way to do it is by appending an arbitrary parameter, typically a random number and/or a timestamp i.e. call service.com/?random=39583483. I use this pattern not just as an Ajax programmer but also as a user; when I suspect my wiki page or blog is cached, I just add an arbitrary parameter and usually get the most recent result.

With Digg API, that’s impossible. I just tried it and discovered you get an unrecognised argument error if you pass in a parameter they weren’t expecting. This is well-intentioned as it will give early failure advice to callers who mistype or misinterpret parameter names. But unfortunately, it has the major downside of breaking this convention and thus breaking compatibility with a large number of toolkits that exploit this pattern.

I discovered this as I was writing a Google Gadget to show Digg stories and when you fetch content with the Google API _IG_FetchContent("http://digg.com/....", callbackFunc, { refreshInterval: 60 }) – the refresh option apparently leads to Google tacking on an arbitrary parameter called “cache” (it’s impossible to be sure as it’s proxied via Google, but the argument to that proxy is the Digg URL with “cache=” on the end). Net effect: I can’t update Digg stories any more than once per hour. The only way I could do it would be to write my own proxy and cache. A lot more work than the one-liner _IG_FetchContent call! Yeah, like that’s gonna happen.

For the Digg API, perhaps they need to introduce an optional “strict” parameter like a compiler offers to give extra debug info. If it’s off, then let anything through.

If HTML Used Convention Over Configuration …

Browsers would automatically pull in CSS and JS according to the filename and I would no longer have to look for an example every time I need a link or script tag.

In the absence of any other spec, /abc/def.html would cause the browser to look for /abc/def.css and /abc/site.css and /site.css. And then it would look for the same, but in JS – /abc/def.js, /abc/site.js, and /site.js. If I had all the time in the world, I’d make an Apache filter to do just that.

This would slow things down a little, but have you noticed – the world is becoming faster? It’s an another example of abundance thinking. Also, if it was a standard, it would not really slow things down as browsers and servers would develop protocols for speeding things up.

So I created a little Ajax web app template to put all the skeleton Ajax code on one page.

HTML

<html>
  <head>
     <title>Hello World!</title>

 &lt;script type=&quot;text/javascript&quot; src=&quot;app.js&quot;&gt;&lt;/script&gt;
 &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;app.css&quot;/&gt;

</head> <body> <h1>Hello World!</h1> <input id="search" name="search" />

</body> </html>

CSS

body { background-color: white; }
div.error { font-color: red; }

search { width: 200px; }

Javascript

function $(id) { return document.getElementById(id); }

window.onload = function() { $("search").onclick = function() { alert("The search begins!"); } }