A step forward

August 6th, 2008

We were looking at the engines plugin for a while and despite all the flame wars around it, Me and Raphael were somewhat convinced that it would be needed somehow in future.

I kept trying installing it but failed. So a little context here, we ported our application from Rails 1.2 to Rails 2.02. And it was this version which we “freezed” under the vendor directory. And installing engines plugin on that version was failing.

From my past development experiences, and from observing some colleagues for a while in my career, I’ve a nature of being very lean and mean about things. If something simpler gets the job done, I’ll not think about intellectually appealing solutions even if they offer more. So this nature kept me from trying to install engines plugin as though it was needed but it was not blocking our way so far. So in my view, I kept making progress on other things.

For last two days, I was working to make it possible to extend with more data types then available by default. For this, we had a vision of using plugins. I again thought about engines plugin and failed. As I said earlier, it was not blocking so I moved on. But this evening, Raphael was working with engines and he told me that he has them up and running! I was really happy to know this as this meant a whole lot new range of possibilities!

So here I’ll outline the steps that Raphael did in order to install the rails plugin:

First of all, Its better that you move to Rails 2.1.0 and not only that, also freeze your application to this version.
You need to install rails if its not already the case:

$ gem install rails # So that you have latest version installed.

Next from root of your application, You need to unfreeze your previous version of rails if any:

$ rake rails:unfreeze # Remove previously frozen version if any.

Next you need to freeze the version of rails from your gems into your application:

$ rake rails:freeze:gems # Will freeze rails application under vendor/rails

Also, you need to update the scripts of rails. This is needed because this updates the plugin script which in turn enables you to install plugins from git repositories. And its somewhat mandatory to do this for installing engines plugin!

$ rake rails:update:scripts # Would update scripts

So far you are done with updating rails and freezing it under vendor/rails. I’d recommend that you run your tests rigorously after this to be sure everything is fine.

So next step is that of installing engines plugin. So that’s simple:

$ ruby script/plugin install git://github.com/lazyatom/engines.git

Next you need to alter your config/environment.rb a little bit so that engines plugin is able to modify the core of Rails. For that, Add following line just before the require statement of Rails itsef:

require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')

And you are good to go! I’d say again run the tests to check if all working well. And if so, Congratulations!
I promised to write about Globalite further, short on schedule, so that’s for some other time!

Regards,
Mohsin Hijazee

YourOwnDB!

July 31st, 2008

Hello World!

Well its not the usual hello world program but some blog entries might also start with this phrase! And if in doubt, this entry is the proof!

We are working on MyOwnDB that’s obvious! But title says YourOwnDB? No we are not renaming it at all, rather its to convey that if it is in your own lingo, its more yours!

So actually I’m talking about the localization. I’d not rephrase all about the importance of localization of software especially if its the one like MyOwnDB.

When we started with MyOwnDB, it was Rails 1.2 and there was no suitable localization solution around. So in order to get the job done, we started out on our own and we wrote a plugin for us. The plugin was nice, we could localize, even it was crafted to be dual ended enabling translators to add more languages for the interface if any.

But it was heavy. It had its own database to hold languages, translations and others. And this means another database have to be taken care of in deployments, releases and all the matters!

When we ported the application to Rails 2.02, many good localization solutions were on the scene. After a little discussion and evaluation between me and Raphael, we agreed to pick Globalite as our choice. The transition was quite smooth. We wrote a ruby script that dumped our database containing UI translations to YAML format expected by Globalite, wrote a simple wrapper method around the Globalite translation method in order to reduce the transition cost involved and all started working fine!

Next was making it possible to switch UI language from the interface, so that was also simple and we were easily able to do that.

So in a nutshell, Its simple to localize MyOwnDB in your language and if you want to see it in your own language, please let us know.

Well how exactly we did that, that’s a matter which needs little recalling and not only that, I leave it for a separate blog entry!

Regards,

Mohsin Hijazee

A new home!

July 24th, 2008

Today we migrated the myowndb application to new hardware. This change brings multiple benefits.

One of them is that the server hosting the app until now was getting old. MyOwnDB was started more than 2 years ago now, and has been running on the same server since the launch. Although it’s a good indication that you don’t need high-end hardware to run this app, more recent hardware will let us improve performance, and bring more CPU intensive features.

Another benefit is that with the migration, we took the opportunity to streamline the deployment of new versions. Our goal is to bring new enhancements very regularly. Watch out this space!

We hope you like it. And as usual, looking forward to hear from you, e.g. by filling the form below, provided my MyOwnDB :-)

Freedom in the cloud

July 1st, 2008

Richard Stallman, the founder of the Free Software Foundation, launched a call for action concerning freedom and privacy in the cloud.

"This is a post about freedom. The freedom to keep your data for yourself and the freedom to run free software. You should be able to reclaim and enjoy these freedoms also when using web applications.", he claims. Stallman goes on promoting the Affero GPL, the exact license we are using to release the code behind MyOwnDB!

We believe MyOwnDB is ready to join AGPL suite of web applications that provide tools for the most common needs.

Stay tuned!

Slow Awakening

June 3rd, 2008

Hi all!

Yes! MyOwnDB is not dead. It doesn’t even smell funny. While it has been quiet here for some time, in the background a lot of work has been done by an expanded development team. Two important milestones will be reached soon

  1. Dedomenon, the core of MyOwnDB, gets a complete REST API making it the easiest web database to use in your mashups
  2. we are so proud of our code that in a couple of weeks we will release it in it’s full glory under the Affero GPLv3 license. Now you can be absolutely sure your data will never be captured.

Enjoy!

YUI-ext grid and context menus

February 26th, 2007

I recently had the opportunity to use YUI-Ext for a little application. I’ll focus on the creation of the context menus for the grid. If you’re discovering YUI-Ext’s layout approach, more information is available from Jack Slockum’s blog in Exploring Cross-browser Web 2.0 Layouts with Yahoo! UI and Cross-browser Web 2.0 Layouts (Part 2) and Ajax Feed Viewer 2.0.

I’ll illustrate what I learned with a little useless app (code is in javascript.js), which lets you rate fries for different countries. As belgian fries can only be good, the context menu will only propose to rate them as good. However, for other countries, you can rate fries as bad. (Yes, this example is that useless…).
I’m working with a grid whose data comes from an XML file. This XML file contains a list of countries in this format:


1
Belgium
http://www.belgium.be

Which result in this datamodel definition:

dataModel = new YAHOO.ext.grid.XMLDataModel({
                            tagName: 'item',
                            id: 'id',
                            fields: ['country', 'url']
                            });

and this column model:

var colModel = new YAHOO.ext.grid.DefaultColumnModel([
      {header: "Country", width: 100, sortable: true},
      {header: "URL", width: 250, sortable: true, renderer: formatURL},
]);

The URL column has a renderer set: this is a function which allows you to format the data in the column. Here’s the URL renderer:

function formatURL(val) { return '‘+val+’‘;}

A renderer can also be used to display fixed content. Eg, if you want to display the text “Delete” in a column, you can simply use this renderer:

function deleteText(val) { return 'Delete';}

For this example I store the list’s items in the file items.xml, so here’s how I load the data:

dataModel.load('items.xml');

Now we can create the grid:

var grid = new YAHOO.ext.grid.Grid('my-grid', dataModel, colModel);

I created a function onContextMenu which is set as listener to the “rowcontextmenu” event:

grid.addListener('rowcontextmenu', onContextMenu);

This method prevents the default behaviour:

e.preventDefault();

If you don’t, you get the browser’s default context menu. Even with this call, Firefox 1.5 displays its own context menu.

As the context menu to display depends on the content of the first column, it then extracts this value. The best way I found to do this is:

grid.getSelectedRows()[0].childNodes[0].childNodes[0].innerHTML;

(In my app, I could not base the decision on the row’s id, which could be the better choice if possible)

According to the value extracted, the context menu to display is retrieved, its position is set, and it is shown:

this.context_menu = this.belgium_menu;
YAHOO.util.Dom.setXY(YAHOO.util.Dom.get('belgiummenu'), e.getXY());
this.context_menu.show();

Both context menus are built similarly, at the start of the onContextMenu function, and stored in a member variable so that the next time is it called, it can reuse the menu built eaarlier. Here’s how the menu is defined for rows with ‘Belgium’ in the first column:

if (!this.belgium_menu)
{
        var aMenuItems = [
                { text: "Rate Belgian Fries as Excellent" },
                { text: "Rate Belgian Fries as Excellent" },
        ];
        this.belgium_menu =new YAHOO.widget.ContextMenu(’belgiummenu’,
                {
                        itemdata: aMenuItems
                }
        );
        this.belgium_menu.clickEvent.subscribe(onBelgiumSelect, this.belgium_menu, true);
        this.belgium_menu.render(document.body);
}

The menu is constructed by settings the items it should display, and then we subscribe a method to its click event. In this listener taking 3 arguments, you can simply have a switch statement to act differently depending on which menu entry was clicked:

                  function onMenuChoice(type, args, menu)
                  {
                              switch(args[1].index){
                                        case 0: //First entry
                                                break;
                                        case 1: //Second Entry
                                }
                  }

Accessing temlpate variables in tests

February 18th, 2007

In your tests, you can easily access variables defined in your templates as:

@response.template_objects["key"]

and here’s a concrete example:

assert(@response.template_objects["user"].errors.invalid?(”password”)

Upgrade to Rails 1.2 notes

February 13th, 2007

As I was looking to upgrade applications to rails 1.2, I wrote down all changes I had to do, and post those here in the hope it can be useful to anyone. I have skipped rails 1.1 for some apps and upgraded from rails 1.0, so some (all?) of the points could be from differences between rails 1.0 and 1.1.

The first thing is that apparently the name of model classes have to be named very precisely, and there’s now a check to see the class was loaded correctly. This caused a problem for the class I had defined in the file app/model/user2address.rb. I (or the generator?) had named the class User2Address, and rails 1.2 checks if the class User2address was loaded (note the capitalisation difference of the a of address). This problem was corrected by simply adding one line:

User2address = User2Address

I’m using the tablefunc contrib of Postgresql, and this requires to define some functions (implemented in a C library) in the database. For the tests to run fine, and have the necessary functions available, I needed to run rake db:test:clone_structure to prepare before running the tests.

I had to delete and reinstall the seleniun on rails plugins.

rm -r vendor/plugins/selenium*
script/plugin install http://svn.openqa.org/svn/selenium-on-rails/selenium-on-rails

I used the String.random method from the nano, now facets library. This seems to not be available in the facets gem I installed, so I reimplemented it myself.

I had to replace some assert_tag tests conditions from a string to a regular expression. Seems it was checking on substrings, but doesn’t anymore.

I had a boolean attribute of a model I used as o.boolean? and I’ve had to adapt it as o.boolean!=’f’ (as I’m using Postgresql)

The image_tag helper now adds an asset_id at the end of the src, resulting in something like

. This can be found at action_view/helpers/asset_tag_helper.rb line 214 (for the whole call stack, in order: lines 185, 155, 200, 212). I guess this is done to avoid caching problems. The part added is either the environment variable ENV["RAILS_ASSET_ID"] or the File.mtime result. This change made that I had to adapt some tests to make it work fine again. I had tests that included the src of the image tag generated. I adapted the tests to work with regexps on the src check:

 :src => Regexp.new("/images/icon/big/use.png(\\?\\d+)?")

That’s it, all tests pass again. I hope this can help some people out there encountering the same problems

Understanding javascript’s prototype member

February 6th, 2007

After looking Douglas Crockford’s talks about javascript, I started experimenting to really understand javascript’s prototype. If you have downloaded the presentation’s slides, this is an illustration of slide 27. I’ve worked with the javascript interpreter included in the JDK6, based on Rhino. If you do this, just run $JAVA_HOME/bin/jrunscript and you get a prompt of the javascript interpreter.

Each javascript function is given a prototype member when it is created. It is through this member that you can easily extend all objects of the same kind at once. For example you can easily extend every string object like this:

String.prototype.myNewMethod = function() { .... }

What intrigued me in the presentation is that you can assign a new object to the prototype member of an existing object. To illustrate this, let’s work with the Gizmo and Hoozit from Douglas’ presentation;

function Gizmo(id) { this.id= id; }
Gizmo.prototype.toString = function () { return ('gizmo ' + this.id); }

function Hoozit(id) { this.id = id };
Hoozit.prototype.toString = function () { return ('hoozit ' + this.id); }

First let’s create a Hoozit instance, and identify its toString method:

Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@1201a25
my_hoozit = new Hoozit(1);
my_hoozit.toString();     //returns "hoozit 1" as expected
my_hoozit.toString;       //sun.org.mozilla.javascript.internal.InterpretedFunction@1201a25
my_hoozit.constructor;  //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80

When accessing a function without calling it, the JDK6 javascript interpreter will display its id.
Here we can see that my_hoozit.toString == Hoozit.prototype.toString, and if we update the toString method of the prototype, it impacts the already created instance:

Hoozit.prototype.toString = function () { return ('updated hoozit ' + this.id); }
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.toString();        // returns 'updated hoozit 1'
my_hoozit.toString           //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.constructor     //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80

We see here that if we update the method in the prototype, each instance has the method updated.

Now on to the strange part: as the prototype is a reference to an abject, you can assign an instance of another object to the prototype:

Hoozit.prototype = new Gizmo();
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@fa9cf
my_hoozit.toString(); //returns "updated hoozit 1"

How comes that although the method of the prototype has been changed, the call on the existing object hasn’t been adapted? The thing is that when my_hoozit was created, it has been assigned a prototype member that is a pointed the Hoozit.prototype. When we assigned an instance of a Gizmo to Hoozit.prototype, it didn’t change the pointer of the already instanciated Hoozit, which still points to the initial Hoozit.prototype object. We can see it like this:

my_hoozit.toString       //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.constructor  //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80

You can see that my_hoozit.toString still is the method with “id” c51355.

Now if we instanciate a new Hoozit, its prototype member will point to the current Hoozit.prototype:

second_hoozit = new Hoozit(2);
second_hoozit.toString(); //returns "gizmo 2"
second_hoozit.toString    //sun.org.mozilla.javascript.internal.InterpretedFunction@fa9cf

If I adapt the Hoozit.prototype, it will only affect the second_hoozit, and not my_hoozit:

Hoozit.prototype.toString = function () { return ('again updated hoozit ' + this.id); }
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1

my_hoozit.toString();         // returns "updated hoozit 1"
my_hoozit.toString            //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355

second_hoozit.toString()   //again updated hoozit 2
second_hoozit.toString     //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1

Now, if you had a toString method to the second_hoozit, it is added to the object itself:

second_hoozit.toString=function(){ return "my second_hoozit method"}
second_hoozit.toString      //sun.org.mozilla.javascript.internal.InterpretedFunction@1bd4722
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1

In standard javascript you don’t have access to an instance’s prototype, though with mozilla you can access it through the __proto__ member. This lets us illustrate further:

second_hoozit.toString                //sun.org.mozilla.javascript.internal.InterpretedFunction@1bd4722
second_hoozit.__proto__.toString //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
Hoozit.prototype.toString            //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
my_hoozit.__proto__.toString     //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355

I hope this helped you understand the mechanism behind javascript’s prototype.

PS: Special thanks go to Richard Cornford and Isaac Schlueter for their answers in com.lang.javascript!

Enhance your javascript knowledge online!

February 3rd, 2007

Until now I’ve been using javascript as a simple language to get Ajax features, but as I used it I discovered interesting features and got really interested to know more. As the JDK 6 has rhino included, you can also use javascript and get access too all Java libraries, which makes javascript knowledge even more interesting.

A really great resource to know more about the power of javascript and how to use it effectively is the series of presentations by Douglas Crockford made available online by Yahoo. There are 3 presentations splitted in 3 or 4 videos each:

  • The javascript programming language is a presentation of the origin of the language, how it evolved, and explains some design errors in the language and why they’re in the standard
  • An Inconvenient API: The Theory of the Dom was the presentation that captivated me the least, though you’ll get some interesting info out of it.
  • Advanced javascript is really very interesting and not to be missed if you want to know how to exploit the language’s power. The second video has a part about debugging, and explains how to get the Microsoft Office javascript debugger which seems to be the best solution to debug in IE, although you’ll see it’s not easy to find. The third video talks about performance, minification, JSON.

It’s really great to have this available online for free. You get access to a javascript training of high quality. Well done Yahoo!