ParisJS #8

(The whole conferences were in french, but as I'm writing every post on my blog in english, I'll write this one too.)

Tonight I was attenting the 8th parisjs meetup. We had the chance to have it hosted at Valtech, in a very wealthy part of Paris, in somptuous quarters and a large room with giant screen (and great pizzas too).

Anyway, this time the meetup was split in two : first part was made of complete talks, while second part only had small lightning talks. With pizza and beer in between.

Wakanda

The first talk was about Wakanda. Wakanda is a complete suite of client/server Javascript which goal is to help create business oriented apps. It is created by the same company as 4D, but this time is completly open source.

The product seemed well done, but kinda monolithic : server side js, client side javascript framework, application studio, debugguer.

I can surely see it used for creating Intranet applications, for some very specific business cases. I have an ambiguous feeling about Wakanda. I think they did a very good job, the whole package seems really neat, the IDE is clear, client/server communication is smooth, etc. On the other hand I'm always suspicious of apps that can do everything.

(Note that I didn't try the product, I only heard about it tonight for the first time and watched a 20min presentation so that's a little light for me to give a precise opinion)

Joshfire Framework

A few months ago, @sylvinus from Joshfire told us that they planned to realease their framework, modeslty named Joshfire.

This is by far the most interesting presentation of the meetup. Joshfire is a javascript framework aimed at working seamlessly between any devices : desktop, mobile, iPad, TV, anything.

It's basic idea is to abstract to its bare bone any interaction. From what I remember, for any "page" you want to define you have to write two JSON structures.

One defines the data tree (what your data is), the other defines the UI tree (how your data can be interacted with). It also ships with some adapters (an adapter is the link between the UI Tree and a specific device).

All you have to do to port your Joshfire app to a new device is to write (or grab if it already exists) an adapter. The main logic and data code is the same for every device, the maintenance is now only focused on any specific device.

Even if the main idea of Joshfire is awesome, their documentation and licensing is even more awesome : the project is already completly documented, with examples and is also completly free and available on github.

CSON, no sorry, JISON

@jie was supposed to talk about CSON, a compressed JSON. But as he already gave a very similar talk (about BSON) at the last

parisnode event, he changed the subject.

I'm not really sure what the real subject of the talk was. I think he mentionned compiling Javascript into Javascript (much like CoffeeScript), but it eventually turned into a Jison demo.

Jison seems to be a tool for automating lexing and parsing languages, to output new code. In effect, this could allow for transforming a custom language into an existing language. CoffeeScript, Haml or Sass works that way : they take a new language as input, and return Js, Html or Css as output.

The advantages are that the custom language is usually much more concise, easy to write and easy to read.

Anyway, this presentation was full of nice quotes :

The language I'm about to show you is totally useless.

Pipe ? What is that ? Oh, you mean the strokes.

The bad thing about Jison is that its documentation is crap

Why does it work ? It was supposed to fail !

Overview of a dev life

This talk wasn't about any new shiny technology. It was about those old browsers and bad habits we had 10 years ago, and how we still managed to make great websites.

This remind me of the "good ol' days" when I discovered the web with FrontPage and ClaraSoft. When IE6 was considered a modern browser.

@molokoloco show us that he managed to simulate ajax using nested iframe, had a website still online and running even after 10 years, was able to code full websites in 3 days, and had read more than 50.000 blog posts. And all that while still using Windows and Dreamweaver.

(Small side note : I praise both @molokoloco and @jie for what they managed to do. I know how easy it is to procrastinate and configure UI, test new tools and IDE instead of getting things done. That didn't seem to be an issue for them.)

mongoDB

This talk was the first in the serie of lightning talks (less than 20mn). It was about mongoDB and how to integrate it in a nodejs app.

As I had never tried nor nodejs nor mongoDB I didn't quite grasp what it was really about. All I get is that in order to get a result from a mongoDB query, one have to go through 3 steps of connection to the DB. In the asynchronous world of nodejs, this doesn't work well, so each step has to fire a callback once executed.

From there, I was lost. There was something about manually calling a callback once initialized, but honestly I didn't get it.

Anyway, I learned from a small talk during pizza time that mongoDB was better than couchDB (performance-wise), and that one have to sacrifice binding to the altar of redundancy to get really fast response time.

Audio demo in less than 1kB. No, 800B. No, wait, 200B

This time the talk was a very fun demo. Using some simple minification techniques, Js was able to play a random music.

This involved encoding the wav file in base64 (taking special care of some chars), and then playing it in an audio tag. Adding a bit of random to play a different note on each loop.

Fun, but interesting.

Some words about the Observer Pattern

This talk was more about theory than practice. Maybe it was the late hour, but it didn't catch my attention as the other did. Maybe someone would re-explain it to me ?

Well, I got the general idea : coding a js snippet that hard code the name of the elements that should react is bad practice because of the maintanability nightmare it cause when elements are removed.

Instead, the speaker advocate the use of a MessageBroker. Some kind of general listener that then dispatch event to element registered to that event (am I right ?).

Then someone in the audience noted that the opposite pattern should work better : that every element registered itself to an event and react when such event is fired (am I still right ?)

Honestly, I really am not sure about this talk, so if anyone could fill the blanks and correct me, I'd be glad.

Sencha and Sencha Touch

I won't go into too much detail on that talk. This was a generic presentation of Sencha (formerly known as ExtJs). I already had the basic understanding of ExtJs (but not the expertise of some of the ExtJs experts in the room), so I was really only half listening.

Sencha is a great product. It is very similar to what Wakanda was showing in the first talk. It is destined to data-heavy applications with lots of numbers, columns, charts, pies, etc.

Sencha Touch is a mobile version of Sencha. It is iOS oriented and emulate the standard UI elements in HTML.

Mozilla Labs

A quick list of the Mozilla Labs projects. I honestly don't remember them all, except Tilt that is a 3D viewer of any web page. It simply calculate the DOM depth and create a pyramid-like structure that you can browser in 3D.

I'm sure that beyond the cool and shiny aspect, it can be useful as a debug/optimisation tool.

Conclusion

Once again, thanks to #parisjs for those talks, always inspiring and a way to meet new people.

For all the new readers, I have an unfixed bug in my comment section : your post can be invalidated if your are using Chrome with an email auto-filler. My custom anti-spam will flag you as spam because Chrome fills an hidden honeypot field.

Working on Wednesday #4 : Rails for Zombies

(I finally managed to update Ubuntu to the 10.10 version, configure Unity to make it more usable, and I'm not ready to start the RoR tutorial I wanted to start last week.)

I used vim this week (instead of nano) for very simple file editing. I will force myself to use only vim on wednesday to really learn it. I plan to completly drop Komodo Edit once I'll be familar enough with vim to gain more time than I lose.

Rails for Zombies

Anyway. I finally get to start the Rails for Zombies tutorial. And here is what I learned.

There are two distinct things I'm going to learn here : Ruby and Rails. I discovered that I was already familiar with a lot of basic concepts of Rails, thanks to cakePHP. Model and table convention, model relationships (belongs to, has many, etc) were exactly the same.

Ruby on the other hand was new. But also very interesting. No need to add () after a method to call it when no args are passed, possibility to chain method of the same object (much like jQuery) and the use of dynamic (yet strongly typed) vars.

The first part of the tutorial (basic CRUD) was easy. I didn't find how to make a complex SQL query like this (cake) one :

$Zombie->find('all', array(
'order' => array('Zombie.graveyard' => 'ASC', 'Zombie.name' => 'DESC'
));

I guess it's just a matter of time before I learn how to to do in Rails anyway. I saw that there was more "advanced" method (much like the cake find method) that would surely allow such finding.

Part 2 : Validation and Relationships

The second part of the tutorial was more about models. Validation rules were pretty much the same as those of cakePHP. But the Ruby syntax makes it more concise.

I couldn't find how to retrieve the validation errors when saving an object using the create method (no problem when manually calling save, though).

I enjoyed being able to create binded instances by simply adding the binded element to the model. Not very clear isn't it ? Here some code to explain it better. The last two lines have exactly the same effect :

class Zombie < ActiveRecord::Base
end
class Weapon < ActiveRecord::Base
belongs_to :zombie
end
Weapon.create(:name => "Rocket Launcher", :zombie_id => 2)
Weapon.create(:name => "Rocket Launcher", :zombie => Zombie.find(2))

Later on, I had to select all weapons binded to a specific Zombie. I was able to find the a specific zombie using any of the two following commands :

z = Zombie.where(:name => "Ash").first
z = Zombie.find(:first, :conditions => { :name => "Ash" })

Then, I wanted to find the weapons binded to this zombie. First I tried the following command :

Weapon.where(:zombie_id => z.id)

Obviously, this worked. But I wanted to test some more of the Rails magic. So I tried something along the lines of what I did in the previous chapter and tried to use my z var directly instead of z.id.

Weapon.where(:zombie => z)

This didn't worked. Well, I guess I'll also learn why later on. But one even more weird thing is that the following command did work even I'm not really sur why ?

Weapon.where(:zombie_id => z)

That's all I did today (well I also did some more Mercurial and Dingux testing, but that wasn't really work)

Alternate content with SWFObject

SWFObject allow a web developer to add an alternate content in place of the swf file is the user doesn't have flash installed.

In the case of a web app this is great to provide your user with a link to the Adobe website. You then tell your users Flash is needed and provide a link for them to install it.

Unfortunatly, if for one reason or another the swf file you try to load is unreachable (maybe your host is down ?), SWFObject will display the same alternate content. Meaning that a user with a perfectly correct Flash version will see an error message telling him that he does not have Flash when in fact the error is on your side.

That's not very user friendly and makes you look bad.

So, to fix this, I added two error messages as alternate content :

<div id="alternateContent" class="alternateContent">
  <div class="noFlash message">It seems that you do not have the Flash player installed. Please install it, by <a href="http://www.adobe.com/go/getflashplayer" target="_parent">following this link</a>.</div>
  <div class="error404 message">Sorry, we were unable to load the game. Please try again in a few moments.</div>
</div>

Then, in CSS I decided to hide them both :

.alternateContent .message { display:none; }
.alternateContent.noFlash .noFlash { display:block; }
.alternateContent.error404 .error404 { display:block; }

And finally, in Javascript I checked for the current Flash version. If it's equal to zero, it means that Flash is not installed, so I display the noFlasherror message, otherwise, I guess it's a 404 error and display the other message.

var flashVersion = swfobject.getFlashPlayerVersion(),
  alternateContent = $('#alternateContent')
;
// Displaying one message or the other
if (flashVersion.minor=='0') {
  alternateContent.addClass('noFlash');
} else {
  alternateContent.addClass('error404');
}

This is not bulletproof : I only test for two cases. And a better solution would also have been to put the error message dynamically using Javascript instead of polluting the HTML markup with contradictory text.

SWFObject must be included in the <head>

We just discovered a strange behavior on one of our test VM (one without Flash installed). I don't know how we've missed it before.

When embedding the main flash file of our application, the alternate content wasn't displayed to players. In fact it seemed to be displayed very briefly then disappear.

I had correctly embeded it with the static publishing method and added a call to swfobject.registerObject to soften the edges. I remembered it working correctly in my tests, so I quickly made a small test case.

It occurs that the alternate content was corretcly displayed if I removed the swfobject.registerObject call and only used the static publishing.

I also found that everything worked fine if I called the swfobject.js file in the head, but started to bug when I moved it at the end of the page.

As I didn't want to add a call to a .js file in my head, I google a bit and I finally found that one have to call swfobject.switchOffAutoHideShow(); right before theswfobject.registerObject call. This seems to fix things by not hiding the alternate text

Edit

I spent some more hours trying to debug the last corner cases. We had a user using Firefox 3.5.3 with Flash 10.0.42.34. Using SWFObject, we required at least version 10.1. Unfortunatly, the app was still loading, but was buggy because of features not present in the user flash version.

After some tests, I discovered that the swfobject.js code MUST be included in the <head> of the document (well, before any .swf in the page, so better put it in the <head>).

Doing so, you won't even need the previous fix (swfobject.switchOffAutoHideShow()).

I would have loved putting it at the end of the page, with the others JS files, but I guess I won't have a choice here.

Working on Wednesday #3 : The long path to get it done

This morning I started reading a lot of online blog post, framework description and other webdev material online I had in my bookmarks. After reading them, I saved them on my pinboard account to find them easily later.

Lot of good JS and CSS framework/libraries in there, I hope to be able to test them soon.

I also check my mailbox and respond to mails from my normal job. I shouldn't. I'm on a day off, I have to force myself to completly cut out those external calls.

Now, let's the work begin

Anyway, I finally finished the vimtutor. I still have a some difficulties to remember the mapping of the basic hjkl movement keys (I always want use k to move down instead of j). However, I feel confident enough in it to try writing my new code in it.

So, I headed to the Rails for Zombies tutorial. I thought it was free but the "win $5 worth of online teaching" / "next course costs $5" make me doubt it a little. Well, we'll see.

After registering to it, I wanted to save my login and password to KeePass as I always do.

Unfortunatly, KeePass on my Ubuntu machine works by using mono, and the keyboard interaction weren't that good (caret is slightly misplaced, inputs lags before getting displayed, text selection is weird). So I thought "Hey, let's see if there is a new version". Big mistake.

It appears that there was indeed a new version, a real one, with apt-get and stuff while mine was some hackish install I manually made a few month ago.

But wait, this means manually adding a ppa directory. No big deal, I trust the author. What ? Still doesn't work ? Hmm, I see. I need mono 2.6, and I only have 2.4.

What ? 2.4 is the latest available version on Ubuntu 10.10 ? You mean I must upgrade to 11.04 ? Hmm. Why not. I'll have to do it eventually, so let's go.

So I ran all my updates, to have the most up to date system. Unfortunatly, language-pack-gnome-fr doesn't want to upgrade so the OS upgrade isn't displayed.

Wait, what am I doing ?

And that's when I remember that my initial wish was to learn Ruby on Rails and that I was now on the road to upgrading my whole operating system. That is not exactly speaking procrastination, but it makes me do so much other things that my initial goal that I really looks like it.

I finally managed to purge my packets, upgrade to 10.10 and then to 11.04. But this took me 4 hours, and now it's 11PM and I guess I won't start this rails tutorial today, after all.