Roll on Rest On Ruby On Rails

It’s good to hear Rails 1.2 is all about embracing REST. Working with Ajax has helped me really appreciate the benefits of REST, and it all fits in with the Rails mindset quite nicely. Right now, we have URLs like

/user/update/5

whereas REST would have it as

/user/5

and then POST in the details – the nature of the method (“POST”) tells you it’s an update. Alternative we could send in a message with DELETE method if we wanted to delete user 5 instead. (In practice, there will be a slight hack to do this, involving a hidden field, because most browsers can only upload POST and GET).

By piggybacking on the commonly accepted conventions of REST, there will be even more “convention over configuration” embodied in Rails. And even greater division between RESTians and SOAPians. If nothing else, it’s a smart way to attract people who get REST and repel those who push SOAP ;-). (Software Engineering Radio recently quipped SOA is now just a pure acronym (just like KFC, AOL, Ajax) … it’s not simple, object-oriented, or ?accessible.)

Flexible Templating/Layouts With Rails

Rails’ layout mechanism follows the standard pattern embodied in Sun’s J2EE patterns and familiar to users of Struts and other frameworks. The page template outputs the main content, and it’s automatically wrapped by a generic template (as opposed to the earlier SSI-style paradigm, where each page manually includes headers, footers, etc.). There’s always a complication with this pattern, which is that the page author usually wants to influence some aspects of the wrapping as well.

For instance, you’re writing books.rhtml for an E-Commerce site. You’re obviously going to set the main content – a list of books – but you also want to influence the wrapping, such as: change the page title (in the doc head), highlight “books” in the side menu, etc.

With many frameworks, you have to jump in to an XML file to influence the wrapping, which often means no-one bothers, and usability – not to mention search engine optimisation – suffers as a result…all pages end up with the same title and meta-information, and you’re probably downloading extra Javascript because you’ve made it the same for all pages.

Rails makes it quite easy, and being Rails, there’s no funny config files to mess with…it’s all code. The layout template is parsed after the main content, so the main content can set any variables, and the layout template can make use of them.

For example, standard-layout.rhtml says:

  1. <html>
  2.  
  3. <head>
  4.     <title><%= @page_title || "My App" %></title>
  5. </head>

Then, each page gets to choose its own title, e.g. books.rhtml:

  1. <% @page_title="Book Bargains" %>
  2.  
  3. <!-- Main content for books -->
  4. <h1>Lots of Books Today!</h1>
  5. ....

It’s easy to make Javascript (and CSS) flexible. The main layout loops through each specified script:

  1. <% (@scripts||[]).each do | script | %>
  2.     <script type="text/javascript" src="/javascripts/<%= script %>.js"></script>
  3. <% end %>

(Some people might prefer Rails’ script_include tag instead of manual script tags.)

Then, the page can optionally indicate the Javascripts it needs

  1. <% @page_title="Book Bargains" %>
  2. <% @scripts = ["dojo", "util", "books"] %>
  3.  
  4. <!-- Main content -->

Ajax Programming Patterns – Podcast 3 of 4: “DOM Population” and “Code Generation and Reuse” Patterns

The third podcast in this series of Ajax Programming Patterns. The 29-minute podcast covers five patterns. As with the previous podcast, there is reason for concern about the audio quality herein. Firstly, three patterns on DOM population – taking server response data and displaying it or storing it in the DOM:

The second group of patterns (representing a different chapter in the Ajax Design Patterns book) are a couple of generic Javascript patterns to make the code more maintainable and portable:

Dojo Gotcha – Initialization with window.onload

I’ve been playing with Dojo, specifically the rich text editor, and came across a Gotcha in setting up the whole thing, which isn’t documented too clearly. Specifically, Dojo needs its own window.onload – if you have your own window.onload (as you probably do if you need any initialisation), it will conflict with Dojo!!!

The solution is described here (though it seems Dojo changed a property name a few months ago, from baseRelativePath to baseScriptURI). This is working for me – in my HTML:

  1. <head>
  2.     <title>My App</title>
  3.     <script type='text/javascript'>
  4.             var djConfig = {
  5.             baseScriptURI: "/ddq/js/dojo/",
  6.           isDebug: true
  7.         };
  8.     </script>
  9.      <script type="text/javascript" src="/javascripts/dojo.js"></script>
  10.      <script type="text/javascript" src="/javascripts/myapp.js"></script>
  11. </head>

In myapp.js:

  1. dojo.require("dojo.event.*");
  2. dojo.event.connect(window, "onload", myappInit);
  3.  
  4. function myappInit() {
  5.     alert("Okay, here we are in the old window.onload and it's still running :-)");
  6. }

It might be a good idea for the Dojo crew included some explanation of this in the standard heres-how-to-setup-dojo.js-intro docs. Maybe someone with in-depth knowledge of Dojo could infer that window.onload must be used by Dojo, but the average programmer taking Dojo a spin won’t.

Links:

Dojo. Awesome framework. Bring on the doco.

More Adventures in Firefox Extension Land: Submitting to Mozilla

I recently explained how I created my first Greasemonkey script as an experiment, then converted it to a standalone Firefox plugin/extension/add-on using an automated tool. Official homepage here. The experiment continues, as I subsequently submitted it to Mozilla, and it’s now been approved as an official plugin.

I’ve been curious about the process people go through to submit an official extension, so here’s the rundown.

1. Upload XPI File

Standard upload of the XPI file, which contains all the plugin contents.

2. Provide Metadata

… such as my name, the extension’s homepage, and so on. (Why isn’t this info just packaged inside the XPI file? Actually, some of it is already in that file anyway.)

One interesting thing here is that I get to choose the category it goes in (although I guess the approver could change it later on). Note also that there’s no help about the categories on this page, so I think there’s a large risk that developers will probably be inconsistent. Not bashing Moz about this, but I do think they could make it easier for end-users to locate plugins if they encouraged consistent labelling – I’ve sometimes trawled through 5 or 6 pages trying to find a plugin within a particular category.

3. Wait for Approval

An official Mozilla person must now look it over, which is a reassuring security measure. (Complain all you want about Ajax and its tabloidistically alleged “security holes”, but the open-source nature of web architecture is extremely compelling from a security perspective.)

After about thirty hours, I received an email that the plugin had been approved. And now it’s available from Mozilla, ID 2816.

If you told me I was cluttering up the space of extensions with this trivial 7KB contribution, I’d say you’re probably right, but then what’s the harm in lots of extensions, as long as it’s easy to locate the one you want. (UserScripts.org, the GM repo, does that to great effect with the power of tagging, and a wiki would make it even more useful.) Not everyone wants to set up GM and maintain the scripts, even those who are savvy enough to know about extensions.

In summary, Greasemonkey and associated tools make it easy, bordering on trivial, for anyone with basic Ajax knowledge to create a standalone Firefox extension. Of course, it will be functionally limited to GM-type page munging, but it’s still a lot easier than I had imagined.

Ajax Programming Patterns – Podcast 2 of 4: Browser-Server Dialogue Patterns

Continuing from the previous podcast (cough 12 weeks ago), more programming patterns. Unfortunately, this recording (and the next one) went pear-shaped. Sorry. I do, however, recommend them to those of you who’ve been wondering what an Ajax talk would have sounded like in crackly 1930s recording technology, and one in which the speaker has a severe cold. FYI The level was too low and it didn’t correct very well…maybe one day, I’ll re-record, but for now I’d prefer to just get them out there as they have been sitting in the libsyn archive for many weeks.

The 40-minute podcast covers the following patterns:

  • Call Tracking Accommodate busy user behaviour by allocating a new XMLHttpRequest object for each request. See Richard Schwartz’s blog entry.Note: Pending some rewrite to take into account request-locking etc.
  • Periodic Refresh The browser refreshs volatile information by periodically polling the server.
  • Submission Throttling Instead of submitting upon each Javascript event, retain the data in a local buffer and upload it periodically.
  • Explicit Submission Instead of submitting upon each Javascript event, require the user to explicitly request it, e.g. submit upon clicking a button.
  • Distributed Events Keep objects synchronised with an event mechanism.
  • Cross-Domain Proxy Allow the browser to communicate with other domains by server-based mediation.

Click to download the Podcast. You can also subscribe to the
feed if you want future podcasts automatically downloaded - check out the
podcast FAQ at http://podca.st.

This podcast covers six patterns on Browser-Server Dialogue: Call Tracking, Periodic Refresh, Submission Throttling, Explicit Submission, Distributed Events,

Thanks for your feedback since last time. Good, bad, or ugly, it’s all welcome – in the comments for this podcast or [email protected]

Podcast: Ajax Patterns Announcements

Quick announcement podcast (5 minutes):

  • Ajax Patterns podcasts – programming patterns parts 2 and 3 – to be uploaded shortly
  • Book has been published
  • Recent AjaxPatterns.org updates

Teleporter – From Greasemonkey to Self-Contained Extension

<

p>My previous post outlined Domain Teleporter, a first attempt at a GM script. Continuing the experimentation (as I have a comlpetely different real example in mind), I wanted to see how easy it was to create a self-contained FF extension from the GM script … I figure there’s a significant population who have FF and can’t or don’t want to install Greasemonkey, even if this leads to a functionally trivially extension.

<

p>Converting a Greasemonkey script to a Firefox extension was stupidly simple, thanks to an online tool, Anthony Lieuallen’s User Script Compiler. I’d read about it a while ago, and assumed there must be some catch, but the conversion was indeed child’s play … enter your name and homepage, cut-and-paste the script, and submit. The XPI pops out immediately as a binary download.

<

p>FWIW, the extension is published here; I used htaccess in the distro directory to ensure it will be an installable download (so it can be installed immediately, as opposed to saved locally) as follows:

AddType application/x-xpinstall xpi

The Richer Plugin pattern talks about the importance of FF extensions and the like.

BTW The extension is Amazon Teleporter, not Domain Teleporter, because there’s no longer any way to change the default “Amazon*” domain for which it applies – GM supports that sort of thing as a built-in feature; whereas an extension would have to implement it manually … a lot more work, requiring a custom-made options dialog and a persistence mechanism.

Domain Teleporter – Greasemonkey Script

Update: As an experiment, converted this into a Firefox extension (Blog Article, Extension homepage)

DomainTeleporter, my first Greasemonkey script, is related to this blog post from last April:

If you shop at Amazon.co.uk, you’re often out of luck when it comes to reader comments. So I often find myself editing the URL, switching back and forth between .co.uk and .com. Luckily, this transatlantic adventure usually works out, as the crazy Amazon IDs match.

Domain Teleporter flips the location between .com and .co.uk, retaining the rest of the URL. It would be nice to make it more generic – switch to an (quasi) TLD – but that would require more regexp parsing than was necessary here. Incidentally, I’d like to see a JS library that munges URLs – extract out the domain, the path, etc.

The script is configured to only run on Amazon, but you might find it useful with other sites too, in which case, change the applicable domains using the GM dialog.

Writing the GM script was fairly straightforward, began by copying Mark Pilgrim’s “Hello World”. It’s standard JS for the most part, but there was one gotcha: events don’t usually work with the usual, portable, solution of “control.onclick()” – you get a “component not found” error. You must instead use addEventListener().

What browsers do developers use?

Jeff Attwood points out that on w3schools, a huge majority of developers are still using IE.

About 60% IE and 25% Firefox. Amazingly 2.3% are still using Mozilla (why?). Unfortunate that 60% of developers aren’t using IE … but the reality is many don’t have much choice…they’ll be working in corporate-standard windows environments, where IE already exists and Firefox must be installed, if they have permissions to do so. Furthermore, Firefox won’t necessarily work due to firewalls and proxies. And then there are the developers who won’t install Firefox because they haven’t heard of it, are MS fanboys (yes they exist), or will get into trouble for doing so.

All of which means they’ll miss out on some of the best development tools around … including the insanely useful and popular Firebug.

FWIW AjaxPatterns must have a savvier audience ;-).

  • IE 46.8%
  • FF 36.2%
  • Moz 4.1%
  • Opera 2%
  • Safari 1.8%
  • ITunes … 0.4%
  • Konq 0.3%
  • NS 0.1%

Incidentally, were you paying attention? Let me repeat that

  • ITunes … 0.4%

:-)

That’s because one of the most popular hits is http://ajaxpatterns.org/feed/future-of-web-apps.xml, the bootleg feed I set up to serve the Future Of Web Apps conference (which onlty released individual MP3s). It’s popular not because people keep downloading it, but because so many people subscribed to it to get all the MP3s in one hit, then never unsubscribed. When Russell Beattie wanted people to unsubscribe to his blog, he started posting annoying animated GIFs. I guess the audio equivalent would be to start posting chalk-screeching noises, or better still, blast out a dozen “Ice, Ice, Baby” enclosures.