Sunday, 6 December 2009

A Click Heat Map plugin for ruby on rails applications

Hi Rubysts,

I've just finished my first contribution to the Ruby on Rails community this evening.
This contribution is actually the repackaging of the click heat map generator included within cannoli into an easy-to-install and deploy ruby on rails plugin.

If you take a look at cannoli you observe that it is based on ruwa web analytic ruby on rails app. I didn't need all of these together.
So... Did I manage to do something better? I believe that it is only rarely the case for something to be in every aspects better than something different. In this particular case I would say that I have made a piece of ruby on rails building block which is less than cannoli but it can be extremely easily incorporated in your Rails ( >2.3.2 ) application.

It has it's own requirements:
  • you need Rmagick installed
  • you must have Rails 2.3.2

Maybe you want to improve your sites web usability.
In order to install the plugin:
  • ./script/plugin install git://github.com/orbanbotond/click_heat_map.git
From the click_heat_map plugin directory (not from rails root)
  • rake db:migrate:click_heat_map
Then you need to put and adapt this code into your templates:
< src="'/javascripts/overlay.js'" type="'text/javascript'">
< src="'/javascripts/clickmap.js'" type="'text/javascript'">


put this html code into your templates you want to measure:
< id="prova" style="margin:auto;width:800px;height:1px;">

And finally, you reached the point where you want to deploy your rails app using capistrano.
Maybe you ask yourself how capistrano knows how to migrate your plugin to the remote server.
Well...
In my case I put the installed plugin under version control and Capistrano just copied to the remote server.
I also created a file named
20091130000000_create_heat_map_clicks.rb:
require 'vendor/plugins/click_heat_map/lib/db/migrate/20091130000000_create_heat_map_clicks.rb'
This way capistrano creates the tables needed by the plugin on the remote server by running "cap deploy:migrations".

Finally the result makes me happy :)

Wednesday, 4 November 2009

A quick fix for swfir and prototype incompatibility



Hi,

Some of you might know about a small and smart library called swfir. This library intends to extend some of the limitations of classic html images. It can rotate the images and it can draw some fancy borders and fancy shadows around the borders and so on. I like the library despite the fact that it's not perfect. It's not compatible with prototype. :(

Here is a small patch that I posted to the authors and hopefully a new release will come out which will support prototype :)

Untill then you can use the patch from here:

@@ -569,7 +569,11 @@
Flash Vars
*/
var varString = "";
- for(va
r key in this.params){ varString += ("&"+key+'='+ this.params[key]); }
+ for(var key in this.params){
+ if("function" != typeof(this.params[key])){
+ varString += ("&"+key+'='+ this.params[key]);
+ }
+ }
Rendering before:

Rendering after:


Wednesday, 10 September 2008

Subversion 1.5.2

Hi all,

It's a long time I haven't written about anything.

Yesterday I reinstalled the latest (1.5.2) svn onto my leopard. It was a challenge for me to install from source into the right place: /usr/bin;/usr/lib. This way I have only one svn on my machine the latest (actually the best) one :).

There is a new feature I have wait a lot. It makes software development easier when I want to try something unusual on another branch, and finally want to reintegrate into my trunk.
It is much easier to handle than the old method for merging:

svn merge --reintegrate http://tralalala/branches/3

Here are the steps needed to install it:
  • Download the sources svn and svn-dep.
  • /configure CFLAGS='-arch x86_64' APXSLDFLAGS='-arch x86_64' --with-ssl --with-sasl=/usr/lib --prefix=/usr >c.out
  • make
  • make check (this is optionally, however I like to see all the tests passed :))
  • sudo make install
I installed with neon because I wanted to add http repository access. Here are the steps which need to be performed right after download if you want to compile with neon:
  • Move neon from svn-dep into the unpacked svn directory. This way even neon will be compiled and installed with svn.

Wednesday, 13 February 2008

Upload progress bar by streaming JSON

Have you ever dealt with the problem of making an upload progress bar?
If you did, then it's time to continue reading.

I wanted to make one using javascript.
Basically, there are two alternatives:
  • The simpler one is to make periodic ajax requests to a url. That url must return the received_size/ total_size pair. All you need to do is to update your progress bar in the browser. This solution works in all those browsers which support AJAX. The disadvantage is that the browser will usually receive the (received_size/totoal_size) data pair delayed. So the progress bar won't show you the real progress.
  • The second option would be to use streaming. Instead of periodically polling the server, we should make one single request, and the server would stream the receive_size/total_pair data back to the browser.
I like this streaming alternative much more because it gives you a better UI experience.
Let me give you some hints on the streaming alternative.
  • The simplest and the secure way is to stream sequences of '<script type='text/javascript'>updateProgressBar(total, received)</script>' back to the browser. The returned javascript will be automatically executed in IE 6.0, Firefox, Safari and Opera. You can find a solution for this at Ry Dahl's article. However it works in a lot of browsers it's not the most elegant solution because you need to hardcode updateProgressBar in the server configuration file.
  • A little bit more elegant solution is to stream JSON expression like {"total_size": 10, "received_size": 0}; {"total_size": 10, "received_size": 1}; {"total_size": 10, "received_size": 2}; ...
If you are streaming JSON expressions you need to write a javascript function which updates the progress bar according to the last JSON slice. You can do this using this javascript utility. This script periodically checks the received content and calls your updateProgressBar function passing the last received JSON slice to it. Unfortunately this script doesn't works with the latest prototype library.

The shortest and the most elegant alternative is to use the "onInteractive" AJAX callback function. By using this callback we don't need to periodically check the response. It is called every time when new data arrives to the browser.
Look at this beautifull code:
new Ajax.Request('/upload/progress', {
pos :0,
onInteractive: function(obj) {
var slice = obj['responseText'].slice(this.pos)
var jsonFormat = slice.substring(0,slice.length - 2);
var json = jsonFormat.evalJSON();
updataProgressBar(json.totalSize, json.receivedSize);
this.pos = obj['responseText'].length + 1;
},
});

Unfortunately this callback doesn't work in Opera neither in IE.
And I didn't find any w3 recommendation for enforcing the browsers to implement it. :(

Let me summarize the opportunities and how are they supported on different browsers:

Opera latestFirefox 2.0.0.2WebkitSafariIE 6IE 7
Periodic Ajax callsokokokokokok
Streaming <script> tagsokokokokokok
Streaming JSON, using Ry's javascriptokokokoknot workingnot working
Streaming JSON, using onInteractionnot workingokoknot workingnot workingnot working

So I need to keep up hacking till AJAX standard is born and implemented... :))