Crafting the SAPO Campus platform, a thousand pixels at a time.
Latest posts

High Performance Javascript - dealing with JSON

No Widget is an Island

Designing Email - Part II

Designing Email - Part I

The amazing "widget" object

The Facebook Witch Project

SAPO Campus keynote from OSL Unesco demonstration session

SAPO Campus session at the UNESCO OSL Seminar

SAPO Campus - Eden Seventh Open Classroom Conference

SAPO Campus leaflet for the UA freshmen


Janeiro 2011

Novembro 2010

Fevereiro 2010

Dezembro 2009

Novembro 2009

Outubro 2009

Setembro 2009

Julho 2009

Maio 2009

Abril 2009

Março 2009

Fevereiro 2009

Dezembro 2008

Novembro 2008

Outubro 2008

Setembro 2008

Quarta-feira, 16 de Dezembro de 2009
The amazing "widget" object

The UWA widget object

When developing widgets in conformity with the UWA spec, there is a seminal Javascript object which makes the UWA environment available, exposing essential methods that handle widget events, grab preference values and modify the widget's HTML. I'm talking about the widget object. This handy page lists every method readily available to use in the widget object.

What about my platform?

All these methods and callback functions, as useful as they are, are also very platform agnostic (hey, it's a good thing), thus failing to cover the particular interesting moments of a platform such as our very own PLE. I'm talking about basic stuff here, such as a widget knowing whether it was hidden, shown or closed.

Ok, that's all fine and dandy, but how about a solution? After fighting a somewhat uphill battle trying to access an iFrame's DOM (not the HTML per se, but rather its Global javascript objects) in a way that did not crash in certain browsers (ahem), I finally settled on this little line of (slightly ugly) code:

Armed with this code, I could now access random iFrames and have them execute arbitrary code (maniacal laughter ensues). So I decided it would be cool to let widgets implement some PLE specific functions, allowing developers finer control over how their widget reacts to specific platform events. The functions should be declared in your widget, inside the widget object. They're not required though, so if you have no need for a specific function (or all of them), it's cool, I guess. Not that I care. Hm. Anyway, here's the complete list:


This method is triggered when a user resizes columns in the platform. Since this causes the widget to resize as well, you might need to perform complicated Math equations or stuff. I don't know, just saying.


Unsurprisingly, this method is fired when the user hides the widget body using the little collapse button on the left of the widget chrome. This is useful if, for example, you need to stop a Flash movie in case the user hides the widget.


In 99% of cases, and if you're not CUI - Coding Under the Influence, you should use this method to undo anything the onHide() method did. It fires when the widget is uncollapsed and is thus once again visible to the user.


This method is triggered when a user deletes your widget (if your widget is awesome, this will never happen). Once again, use this to stop Flash movies or timed function executions.


The reverse of onClose(), this is triggered when the user undoes the delete action (yay, the user loves your widget again!).

Published by bruno-abrantes às 16:09

Sábado, 12 de Dezembro de 2009
The Facebook Witch Project

Sadly, this tale does not end with every one of the main characters being killed/kidnapped in the woods by a crazy hermit/ghost/monster. I say sadly because that movie ending is so awesome every other movies should be ashamed not to end the same way. Anyway, I digress.

A couple of days ago, our team decided it would be sweet to get some Facebook loving in our newly-launched PLE in the form of a widget. Upon discovering there's a great Facebook widget in the Netvibes Ecosystem, I giddily smiled and immediately thought we'd have a fully functional widget in under 15 minutes. Oh boy, was I wrong.

Telling our local widget to directly load the Netvibes widget remotely proved to simply not work. So I downloaded the code and ran it locally. Eventually, I found an if statement that seemed to be the culprit, and, upon stripping it from my code, the Facebook Connect badge finally appeared. And then all hell broke loose.

The Netvibes Facebook widget, very sensibly I might add, uses its own API key, which I later found out is actually tied to a specific domain ( in this case). Put simply, when accessed from our domain, Facebook Connect would go down in flames. Not about to give up, I registered a new Application at Facebook and got our own API key. Yay, now Connect worked! Well, not really. Since our widget runs in an iframe, I couldn't get Connect (which opens in it's own popup window) to tell the iframe that yes, it was ok to login the user.

After trying to fix the issue for what seemed to be hours I finally gave in to the frustration and officially broke up with Facebook. While she is indeed hot, she was way too high maintenance for a simple guy like me.

I was kind of heart broken (let's face it, it wasn't that long a relationship) when I met Facebook's younger, hotter sister. If you're beginning to feel lost in the girl metaphor, I'm talking about Facebook's iPhone Web App, which was the way folks with iPhones and iTouches accessed Facebook before the awesome native app came. In fact, this iPhone Web interface was so damn cool I figured I just had to have it.

In about five minutes I had a functional widget that displayed the iPhone Facebook page inside an iframe (which itself is inside an iframe... get it? I know, I know, it's ok). This was already pretty awesome, but still not anything near my usual awesomeness level, so I quickly tried to get to second base (there it is again, the metaphor!) with this new, hotter girl who didn't seem to mind me embedding her inside weird, deprecated HTML elements.

Second base means, of course (aren't you reading? Get with the program!), designing an auto-login system. With the widget the way it was, users had to login every single time they loaded the SAPO Campus PLE, which is no good in my book. So, i quickly hacked together some Javascript (plus some PHP magic provided by José which is far too complicated for me to make fun of) to automatically fill the login fields with information the user supplied in the widget options menu and click the button. Did I mention it did all of this automagically? Oh, baby, now we were getting frisky.

Then Internet Explorer crashed our party (I guess a sock on the door knob really isn't all that universal anymore). The iPhone interface would not load at all in any version of IE (gasp!). It's okay, IE, I understand. After all, this web app is specifically tailored to work in Webkit browsers (although Firefox doesn't seem to mind), so I really didn't expect you to just be cool and hang out with the rest of us. It turns out this beauty of a mobile web app has a cute cousin who, although slightly older and way less hotter, actually works in every browser alive today (and what does that say about you, Two lines of browser sniffing code later and voilá, a working Facebook widget! IE users are served the traditional Facebook mobile interface, while other browsers get the shinier iPhone interface. Most of Facebook's funcionality is available in both versions, though.

Oh yeah, here are a few images of the new widget in action:

You should also be able to date Facebook's hot little sister very soon. I just finished testing (cause these days you just have to get tested before diving into anything serious), and our server wizard is making sure the widget goes live without a hitch. Look for it under Categories->Social in our Add Content menu!
tags: ,

Published by bruno-abrantes às 00:41

Sexta-feira, 4 de Dezembro de 2009
SAPO Campus keynote from OSL Unesco demonstration session
Rethinking Open and Social Learning and institutional supported technologies: the case of SAPO Campus
View more presentations from Carlos Santos.

Published by bruno-abrantes às 19:16

About us
Janeiro 2011








todas as tags

subscrever feeds