Plack helps with Javascript development too

Posted on December 19th, 2009 in Comp, Javascript, Perl by Patrick

Today I was debugging a Javascript bug in ExtJS + AIR, and I wanted to check rendering in another browser. I created a static html file with the minimal javascript test case embedded in it, but then realised that I needed to load in the ExtJS files from somewhere. With other JS libraries you can use freely available CDNs for this sort of thing, but because ExtJS has funky ideas about licensing, this isn’t an option. What I needed was a quick and easy way to serve up the ExtJS files, which were sitting in a folder on my computer, over http. This sort of thing happens frequently with custom code too, when you attempt to create a static (minimal test case) version of a live site.

Plack has a really neat solution to this problem.

Following a tip from day #5 of Miyagawa’s Plack advent calendar, serving up the current directory over http is as simple as this Perl one-liner:


$ plackup -MPlack::App::Directory -e 'Plack::App::Directory->new

Plack::Server::Standalone: Accepting connections at http://0:5000/
$ plackup -MPlack::App::Directory -e ‘Plack::App::Directory->new’Plack::Server::Standalone: Accepting connections at http://0:5000/$ plackup -MPlack::App::Directory -e ‘Plack::App::Directory->new’
Plack::Server::Standalone: Accepting connections at http://0:5000/
# Or if you need the files over port 80:
$ sudo plackup -MPlack::App::Directory -e ‘Plack::App::Directory->new’ -p 80
Plack::Server::Standalone: Accepting connections at http://0:80/

Or if you need the files served over port 80:


$ sudo plackup -MPlack::App::Directory -e 'Plack::App::Directory->new' -p 80

Plack::Server::Standalone: Accepting connections at http://0:80/

Tarpo now on GitHub

Posted on November 30th, 2009 in Air, Comp, Javascript by Patrick

Tarpo Logo

At about 11pm on the night before I headed off for the States, Ted the Vet and I sat down to talk Tarpo.

In case you’re wondering, Tarpo is an open source, cross platform Data Management desktop application for Dog Health programs in rural and remote Indigenous Australian communities, written entirely in Javascript.

The last time I blogged about Tarpo was way back in April 2008, and since then I haven’t really touched the code, but in the meantime Ted and his team of helpers have used it to record several thousand House Visits, Medical and Surgical Cases as part of the Maningrida Dog Health program.

Several other Veterinarians have started expressing interest in using Tarpo for their own Dog Health programs, and needless to say, we’ve accumulated a long list of bugs and feature requests over the past 18 months. So this afternoon, with a bit of spare time up my sleeve, I decided to get the ball rolling again.

Tarpo now has a proper project page, which you can visit at: http://pdonelan.github.com/tarpo

As you can see from the url, the code now lives on GitHub. Apart from the front page which has the all-important “Install Tarpo” button, the most important page on the GitHub project page is the Issue Tracker, which I’m hoping Ted and other Vets will use to report all Bugs and Feature requests. With a bit of luck, that will also make it easier for other developers to get involved too.

With these things in place, I started attacking the bit rot. Firstly I had to install Aptana and the Adobe Air plugin, which took several hours and reminded me how much I prefer doing development in Padre! On a side note, I spent a few hours trying to think if there was some way I could rewrite the entire app in Perl (I like Javascript in a twisted sort of way, but I’d rather ditch Adobe Air since it’s a proprietary framework) – but in the end I decided to stuck with the existing architecture, at least for now.

I though about doing it as a wxPerl app (like Padre), but I’d hate to lose the HTML widget set that ExtJS gives me.. hmm that gets me thinking (help me out if you’re reading Gábor or any of the other Padre gurus..) does wxPerl have a modern embedded browser that I could use? Maybe webkit-based one..? Then the backend could be rewritten as a standalone Plack-powered webapp and I’d have all of CPAN at my disposal.. hmm maybe that’s too ambitious, but it does feel like the sort of thing you *should* be able to do with Perl..

I didn’t have much time left to do any real coding after that, except for updating a few dependencies so that Tarpo at least starts up ok on the latest version of Adobe Air (a small victory). But at least now in a position to start attacking the ticket list, which means that real progress can’t be too far off..

WebGUI Carousel Wobject

Posted on April 6th, 2009 in Javascript, Perl, WebGUI by Patrick

Carousel Wobject

There’s a new wobject coming in the latest WebGUI beta (version 7.7.3), called Carousel. On the surface, it’s a nice little integration between WebGUI and YUI, but below the surface it’s a great multi-purpose tool for rendering content dynamically in Javascript or Flash.

It’s a common requirement to want to display rich text via Javascript or Flash. For example you might have a clickable diagram that shows different text depending on what part of the diagram a user clicks on.

Giving content managers access to the dynamic text can be rather cumbersome. In the worst case scenario the text is hard-coded in the Flash or Javascript source, out of reach of the content manager. Better solutions are where you have a bunch of editable Articles or Snippets that the Flash or Javascript reads from.

None of these solutions are very satisfactory though, because as far as the content manager is concerned the dynamic object is a single asset, and they really want a simple way to edit all of the text elements from the same place.

We designed the new Wobject specifically for this scenario. The Edit Screen of the wobject allows content managers to add as many rich text editor (RTE) boxes as they like (dynamically, a la FilePile). These RTEs are displayed one after the other on a single screen, allowing the content manager to edit all of the text in a single place. For each RTE, the content manager can also specify a unique ID.

carousel-edit

By default, the template for the Carousel wobject renders your RTE items into an attractive YUI Carousel widget:

carousel-view

The Wobject template does this by looping over all of the RTEs and generating markup expected by the YUI Carousel widget. This has the nice side-effect of allowing your widget to gracefully degrade in non-js browsers.

Taking a step back, we have a WebGUI wobject that lets us manipulate a collection of RTEs. The only part of the wobject specific to the YUI Carousel is the template. Let’s have a look at it:

<div class="yui-skin-sam">

...

<tmpl_if item_loop>
<div id="<tmpl_var assetId>">
<ol>
 <tmpl_loop item_loop>
	<li class="item" id="<tmpl_var itemId>">
 <tmpl_var text></li>
</tmpl_loop></ol>
</div>
<script>
 YAHOO.util.Event.onDOMReady(function (ev) {
 var carousel = new YAHOO.widget.Carousel("<tmpl_var assetId>", {
 isCircular: true,
 numVisible: 1,
 animation: { speed: 0.5 }
 });
 carousel.render(); // get ready for rendering the widget
 carousel.show();   // display the widget
 });
 </script>

</tmpl_if></div>
</script>

We can just as easily create our own template to do something else with the data. Returning to our original example, say you want to use the RTE text in a Flash diagram. All you have to do is change the template to output the contents of each RTE into a textarea dom element, styled to be hidden from view, with the id attribute set to the RTE unique id. Then, your Flash (or Javascript for that matter) can easily read in the rich text via DOM methods (e.g. document.getElementById(RTE_unique_id).value) and display it dynamically and/or do whatever it likes with it.

For example, we might use a template such as:


<tmpl_loop item_loop>
 <textarea id="<tmpl_var itemId>" style="visibility: hidden;"><tmpl_var text></textarea>
 </tmpl_loop>

The only coordination required is that the person deploying the wobject would need to know how many text blocks the flash/javascript expects, and what unique ids to use.  For some flash/javascript widgets you could ignore unique ids altogether by adding a special class attribute to the generated textareas and then using a class selector to dynamically select all matching textareas on the page.

This should make it easier to use dynamic flash/javascript widgets in WebGUI whilst still retaining the power and ease of use of a content management system.

The curse of console.log

Posted on April 3rd, 2009 in Javascript, Music by Patrick

Here’s a common scenario, you’re on-site demonstrating some fancy new Javascript interface you’ve written, only to discover that some part of it that was working so beautifully on your dev box inexplicably breaks. hmm you think, must be a bloody IE bug. You try it in Firefox.. it still doesn’t work, what the?!

Later that day you get home and on a hunch run a quick search through your source tree:

> ack  ‘console.log’
www/extras/wobject/Survey/dd.js
96:console.log(destEl);

The culprit is Firebug’s console.log() function. The damn thing is just too handy. So handy that a few years ago the collective web development community abandoned alert() as the #1 debugging weapon of choice. Now we all use console.log(). Forget the firebug debugger, nobody can be bothered bringing up their js source in the script tab and clicking the break button or setting a watch variable, that’s like, 4 clicks too many man! Whack in a of console.log(a, b, c)s and it’s all there, plain as day in the firebug console, ready to be clicked on and examined further  in the DOM tab.

Until you forget that not everyone in the world runs firebug. Hard to believe, I know. But actually, the problem occurs for anyone who hasn’t got the firebug console turned on for YOUR SITE. The problem being of course that you probably always have the firebug console turned on for your site, but no-one else in the world does. So the likelihood of being bitten are pretty high.

Of course, there are lots of workarounds. One approach is to just define console.log as an empty function (and while you’re at it, you may as well define all the other Firebug functions too):


if (!("console" in window) || !("firebug" in console)) {
 var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
 window.console = {};
 for (var i = 0, len = names.length; i < len; ++i) {
 window.console[names[i]] = function(){};
 }
}

In my case the code was part of a drag and drop method used in WebGUI. And like all sane web projects, WebGUI oursources its cross-browser Javascript concerns to a library (in our case YUI). And it turns out YUI has a perfectly good logger of its own, guaranteed to be available on any page that YUI is loaded onto. Hello YAHOO.log();

Now, “YAHOO.log” is 1 letter shorter than “console.log”, so why does everyone end up using console.log() all the same? Maybe they don’t like typing in upper-case. More probably they noticed that when they use YAHOO.log(‘blah’); nothing appears in the firebug console. What gives? Well, you need to tell YAHOO to pass on log  messages to the console, that’s what. Type the following line first, and everything will work out just fine:


YAHOO.widget.Logger.enableBrowserConsole();

Of course, that’s a lot more letters than just typing console.log(), and what’s more you need to use YAHOO.lang.dump() to serialise objects passed to log() (no nice firebug object examination), which admittedly is a lot less fun. But it does mean a little less broken code in production.

Next Page »