BabaJS – Javascript Template Engine

April 26, 2011

What is BabaJS

BabaJS is an open source Javascript template engine/manager.

The basic concept is: Template + Data = HTML

Here is a simple example:


<!-- user template -->
<div class="user">
    <span>< %=data.userName%></span>
	< %IF data.hasPic %>
	    <img src="<% return 'http://imgs.mydomain.com/'+ data.userPic; %/>" />
	< %ELSE%>
	    <span>Add User Pic</span>
	< %ENDIF%>
	<span>User Friends:</span>
	< % var myUserName = data.userName; %>
	< %LOOP for( var i=0; i< data.friends.length; i++ ) %>
	    <div class="friend">User < %=i%></div>
		< % return this.includeTemplate("friend", window.getFriend( data.friends[i] ) ); %>
	< %ENDLOOP%>
</div>

<!-- friend template -->
<div class="friend">< %=myUserName%> is friend with < %=data.userName%></div>

Javascript code to generate the HTML:


BabaJS.generateHTML({
    templateName:"user",
    requires:["friend"],
    ready: function(html){
        document.getElementById("test").innerHTML = html;
    },
    {userName:"me",
    hasPic: true,
    userPic: "me.jpg",
    friends:["amir","baba","daniel","mia","yael"]}
);

The template manager will fetch the template and its dependency templates and will call the ready callback when the HTML is ready.

or you can just do something even simpler like so:


var html = BabaJS.generateHTML("<div>< %=data.userName%></div>",{userName:"me"});
document.getElementById("test").innerHTML = html;

It is as simple as that. but you can do so much more with BabaJS – so in this case RTFM is worth it.

Why I Developed it?

While developing a social network at Crytek i did a research at the current javascript templating engines out there. While there were some good solutions, like PURE and EJS, non of them were good fit for my requirements, so i started developing something very simple by my own. I decided to make it an open source project since I wanted to share it with the developing community and thought that maybe there are others that may benefit from it and aren’t happy with the existing solutions.

Main Features

  • Sub Templating – you can include additional templates from other template as much as you like.
  • Dependency Management – BabaJS keep track about dependencies between templates and  JS and CSS files to make sure all are loaded when needed.
  • Fast – BabaJS compiles the templates in order to achive fast execution.
  • Template Stack Variables – BabaJS allows you to define variables in the template tags and access them from anywhere in the template or from included templates.
  • Text Based - BabaJS is doing text manipulation and doesn’t work on the DOM elements, thus allowing it to work on Node.JS as well.
  • Template Manager – BabaJS is not only a template engine, but also a manager that provides API to add/remove and create dependencies between templates.

Continue Reading »

Bookmark and Share

Implementing Autocomplete jQuery Plugin for Textarea

March 7, 2011

We all know the auto-complete feature. We use it in google search, when google tries to suggest our search term, and you probably saw it in many other sites which implemented the auto-complete for their own use. Most of the auto-complete out there are implemented in a text field, where the user has one line and usually its for a small amount of text.

But what do you do if you want to have auto-complete in a textarea?

This is where things get a little complicated and most websites decided not to implement this feature. Some sites, like Twitter has implemented a simple auto-complete feature for textarea. In this implementation they decided  to show the auto-completion outside of the textarea and without dynamic positioning, so the drop down menu is always at the bottom of the text area no matter where you type.

While this implementation does the job, i was hoping to see a more “sexy” auto-complete like i’m used to from windows apps, where the drop down menu appears right next to the current word that the user is typing.

I searched around and couldn’t find anything interesting implemented like i wanted, so i asked a few of my friends and they just said it can’t be done – can’t be done? i said – challenge accepted!

Basic Concept

I decided to implement a jquery plugin to allow auto-complete for textarea. In order to achieve this behavior i decided to create a clone of the textarea,  but instead of using a textarea i will use a div element, where for each line in the textarea i will replaced by a div element, where the line of the cursor will be used as a span so i could get the span width in order to understand where the cursor is. Here is a prototype i built in order to demonstrate the basic concept of the implementation:

While you are typing a text in the text area i’m building a clone of the textarea data on the left column.
Note: This demonstration doesn’t work on Internet explorer (but the plugin support IE in a basic way).

Challenges

When i started to design this concept i faced a few challenges in mind:

  • How to get the cursor position
  • How to clone the textarea taking into consideration all the styling that may apply to it
  • How to deal with line breaking an line wrapping.

Continue Reading »

Bookmark and Share

Create your own AjaxStore with XMLHttpRequest Level 2

January 23, 2011

One of the most interesting things to me that HTML5 has introduced is the XMLHttpRequest Level 2, and more specific the cross-origin requests.
Up until now the browser vendors enforced cross-origin requests due to security reasons. The only way for a web page to talk to another web page outside of its domain was either to use all kind of black magic XSS, or to use browser plugins, like greasemonkey.
Now, thanks to the Cross-Origin Resource Sharing (CORS), you can talk to web pages outside your origin.

Web Origin

An origin is a subset of the URL address. Origin is made up from the scheme (http or https…) the host (www.amirharel.com) and the port (8080).  So, for example the followings are all different origins:

  • http://amirharel.com
  • https://amirharel.com
  • http://blog.amirharel.com
  • http://amirharel.com:20

On the other hand, origin ignores the URL path so all these URLs has the same origin:

  • http://amirharel.com/test/domsomthing.html
  • http://amirharel.com/test2/dommorestuff.php?param1=user&param2=pass

HTML5 will use this origin in several APIs, like the postMessage and the WebSockets.

Talking to a stranger

Whenever you will try to make a request to a page outside of your origin, the browser will add to the request header the origin of your page and will wait to see if the server authorize your request.

Actually, the CORS specification request that for sensitive actions an OPTION  pre-request must be sent to the server by the browser to see if the action is supported and allowed. So, the browser will send an additional OPTION request and will wait to see if the server recognize the origin as an authorized request.

Let’s see an example headers:

Request header

POST /main HTTP/1.1
Host: www.amirharel.com
User-Agent: Mozilla 5.0
Referer: http://www.amirharel.com/
Origin: http://www.amirharel.com

Cache-Control: no-cache

Response header

HTTP 1.1 201 Created
Transfer-Encoding: chunked
Date: Mon, 24 Jan 2011 07:00:00 GMT
Content-type: text/plain
Access-Control-Allow-Origin: http://www.amirharel.com
Access-Control-Allow-credentials: true

Building an AjaxStore

This CORS opens up new and interesting concepts for front-end development. The most important one to me, is the ability to shift more logic and computation to the client from the server. If up until now we required to fetch some data from a third party vendor , we had to do it using our servers due to the cross-origin limitations. Sometimes it make sense to allow the server to do this kind of work, but sometime it only becomes a bottle neck and burden the server with tasks it doesn’t really have to do.

My front end philosophy is “Less-Server Please” , which means that whenever we can and it makes sense, shift logic from the server to the client, and to make servers as light and efficient as possible. I just think of it like this: you already have users – let’s use their CPU!

Up until now implementing this philosophy was possible within the origin of your site.  Yahoo introduced some interesting concept with YQL to allow you to query web sites out side of your origin from the client side, but I’m not aware of big players used that service with production sites.

Anyway, with the XmlHttpRequest level 2, it’s possible, as long as the server support it by sending these headers back.

We all know about the concept of web services , which introduced us with all kind of bad words, like “WSDL” and “SOAP”. This concept of web services is now available to client side as well, as i call it – the AjaxStore.

The AjaxStore concept is less interesting to me to develop (since its a server side development) rather more interesting to consume as front-end developer. The concept is that we have web services that support XmlHttpRequest level 2 for cross-origin to allow clients to interact with these services. Lets see an example

AjaxStore – The Horrorscope Service

The horrorscope is a web service for giving a user its horoscope with a horror twist.  Let’s see an example of an open service.

This PHP code is just an example of a CORS services that allow all origins

<?
$origin = $_SERVER['HTTP_ORIGIN'];
header('Access-Control-Allow-Origin: ".$origin);
header('Access-Control-Allow-credentials: true');

echo getUserHorrorscope();
?>

and let’s see the client side code:

var xhr = new XMLHttpRequest();

xhr.onload = function(e){
alert(xhr.responseText);
};
xhr.onerror = function(e){
alert("something bad happend, but not to you...");
};
xhr.open("GET",http://ajaxstore.amirharel.com/horrorscope.php?sign=gemini",true);
xhr.send(null);

You can try it yourself by sending an ajax request to : http://amirharel.com/labs/ajaxstore/hscope.php

Now let’s say you have a service that predicts the lottery numbers and you only want to allow it to payed customers, then you could just check the origin with a white-list to authorize it.

Summary

The CORS is a powerful tool and should be used to preform tasks that your server doesn’t add any value to you more then just a bridge to the outer world. In general, HTML5 features (WebWorkers, WevSockets…) are providing more tools for the front end engineers to shift more logic from the server to the client side and to build powerful applications that uses more the users resources and less the application servers.

I can’t wait to see what kind of AjaxStores will pop-up in the near future.

Bookmark and Share

Beware of the prototype properties

December 14, 2010

First of all I’m sorry that I haven’t wrote for a long time, I’ve been busy, but since I realized that is never going to change (at least not before the kids will move out of the house) I better continue write post even when I don’t have time. So I guess the post will be shorter and maybe less esthetic(usually it means more English mistakes), but it’s better than nothing, right?

So, a few updates.

1) I released a firefox addon – web-exposed – you should check it out
2) I did a very cool event with Israeli & Palestinians – Startup Weekend Tel-Aviv. Here is a cool video we did.
3) I started a new job which required relocation to Frankfurt Germany. I joined Crytek to their web development team and working on a cool social network project.

That’s it for the updates, if you survived so far i guess it can only get better from here (or would it…)

The Prototype

In Javascript each function has prototype properties that refer to an object. Whenever you create a new instance of this class this reference is being set to the new created instance by the javascript engine. Whenever a method is called on the object the javascript engine search the method in the object and if it doesn’t find it, then it searches the prototype chain for this method.
This basic behavior enables javascript inheritance, but this is where it gets tricky, and most developers don’t really know – the prototype is being used by all instances of the function!!!
Let’s review the following code:


function myClass(){}
myClass.prototype = {
//declaring some public methods
	method1: function(){alert("method1");},
	method2: function(){alert("method2");},

	//declaring some public properties
	myName: "some name" ,
	myArray: [1,2]
};

Do you know what’s wrong with this code?
Let’s run some code and see the bug that hides in this declaration:


m1 = new myClass();
m2 = new myClass();

alert( m1.myName );
alert( m2.myName );
m1.mtName = "i changed the name";
alert( m1.myName );
alert( m2.myName );

If you ran the code or can guess what happen you won’t notice anything strange. At the beginning both instances have the same value and after m1 changed the myName m2 still have the correct value.
so far so good. Now let’s examine the following code:


alert( m1.myArray.toString() );
alert( m2.myArray.toString() );
m1.myArray.pop();
m1.myArray.pop();
alert( m1.myArray.toString() );
alert( m2.myArray.toString() );

FAIL!
the m1 instance changed the value of the array of the m2 instance, or any other instance for that matter.

Asymmetric Prototype I/O

Since each function has the same prototype object and there could be many instances using this object, the javascript engine enforces asymmetry between reading and writing property value.
When you set a property in the prototype all the instance can read it. once an instance try to write it, javascript creates a local copy of that property and set the value there, so whenever it reads again it will read from the local copy.
This is why our first example worked. The m1 instance changed the myName property and javascript created a local copy with the new value while m2 was still reading from the prototype object.

In the second example we did not set the array but manipulated it, which changed the array object for all instances. If you would have done something like this:


m1.myArray = new Array();

then the new array would have been set only for m1 instance.

If you are not aware of this asymmetric behavior then these kinds of bugs are bound to happen and usually they are hard to track since object data is being changed in instances without you knowing about it – very hard to debug.

My recommendation is to avoid properties in the prototype what so ever. I only set properties in the constructor:


function myClass(){
    this.myArray = [1,2];
}

Don’t say I didn’t warn you.

Bookmark and Share

Implementing Multiple Inheritance in Javascript

June 11, 2010

Update

First of all I have a new logo and favicon – it’s that funky Ninja icon on the top left. It was designed by the gifted designer Liora Darom. I’ll be happy to provide her contact if someone is interested.

It’s been a while since my last post, usually I try to write more often but I had too much on my hands.  One of the cool projects that I worked on is now available, it’s called Web-Exposed. This is a Firefox addon that lets the user see what’s all kind of data about web sites, like Alexa rank, page rank, the owner of the site, and more traffic, SEO and security information. This is one of the cooler things I did in Javascript and 90% of the development was made in pure Javascript (Yipi for the super geek). I think this project deserve a post of its own, so maybe in the next post I’ll write more about the technology inside, but for now you can download and play with it, and I’ll be more than happy to hear from you what do you think and to get some feedback.

Download Web-Exposed



Multiple Inheritance

In the last few days I read and played with PHP 5 object oriented. The more I played with it the more I appreciated the power of Javascript. My dream is to have scalable and powerful Javascript server side engines – a man can dream can’t he? To write the server and the client in the same language, how long do you think that will happen…

Anyway, I wanted to show how flexible the language is and to demonstrate how you can implement multiple inheritance.

Single Inheritance

In my previous post about Javascript inheritance I demonstrated how to use Javascript prototype in order to achieve inheritance.

There is another way to imitate inheritance by cloning all the functions of the super to the sub manually. Lets go over the code:


function Inherit(sub,super){
    var proto = super.prototype;
        for( var f in proto ){
            if( f != "constructor" && typeof proto[f] == "function" ){
                if( sub.prototype[f] == undefined ){
                    sub.prototype[f] = function(){
                        return proto[f].call(this,arguments);
                }
            }
        }
    }
}

As you can see , the function iterate the super prototype and for every function it finds it creates  a matching function in the sub prototype. I added the “constructor” condition since usually the constructor is a regular property of the prototype object with the DontEnum flag  so it doesn’t show up in for..in  loops, but developers can override the constructor and when they do the DontEnum  is also override, so just to make sure i skip the constructor.

The Extend Function

Combining the prototype inheritance and the method I just explain allows us o create multiple inheritance in Javascript. I created the extend function like so:


function extend(sub){
	var supers = [];
	var single = function(sub,super){
		var thinF = function(){};
		thinF.prototype = super.prototype;
		sub.prototype = new thinF();
		sub.prototype.constructor = sub;
		sub.super = super.prototype;
		if( super.prototype.constructor == Object.prototype.constructor ){
			super.prototype.constructor = super;
		}
	}

	var multi = function(sub,super){
		var proto = super.prototype;
		for( var f in proto ){
			if( f != "constructor" && typeof proto[f] == function" ){
				if( sub.prototype[f] == undefined ){
					sub.prototype[f] = function(){
						return proto[f].apply(this,arguments);
					}
				}
			}
		}
	}

	if( arguments.length < 2 ) return;
	single(sub,arguments[1]);
	supers.push(arguments[1]);
	for( var i=2; i<arguments.length;i++){
		multi(sub,arguments[i]);
		supers.push(arguments[i]);
	}
	sub.prototype.callSuper = function(fnc){
		var len = supers.length;
		for( var i=0;i<len;i++){
			var super = supers[i];
			if( (fnc in  super.prototype) && (typeof super.prototype[fnc] == "function") ){
				return super.prototype[fnc].apply(this,[].splice.call(arguments,1));
			}
		}
		return null;
	}
}

The method takes the sub and as many supers as you want. The first thing it does it to make the sub inherit the first super using the regular inheritance method, which I called single. After that the function loops over all the other supers and copy their methods into the sub prototype object using the multi function.

As an extra bonus I saved all the supers in an array and provided a method to call a super method in case the sub has override it. Let’s see some examples how to use it.


function P1(){}
P1.prototype.p1_talk = function(){
	return "P1 talking ";
}

function P2(){}
P2.prototype.p2_talk = function(){
	return "P2 talking ";
}

function SP(){}
SP.prototype.sp_talk = function(a,b){
	return "sp talking with "+a+" and "+b;
}

function P3(){}
extend(P3,SP);

P3.prototype.p3_talk = function(){
	return "p3_talk";
}

function P4(){}
extend(P4,P3);

var p4 = new P4();

function Son(){}

extend(Son,P1,P2,P3);

Son.prototype.sp_talk = function(){
	return "Son override SP talk ";
}

var s = new Son();
//text = "P1 talking P2 talking Son override SP talk sp talking with a and b"
var text = s.p1_talk() + s.p2_talk() + s.sp_talk()+ s.callSuper("sp_talk","a","b");

I haven’t used this code in any of the project that I’m working on, and developed it as an experiment with Javascript object oriented and to win a bet with a friend – so I won a couple of dollars and you got to read something cool – another win-win post.

Bookmark and Share
 
Powered by Wordpress and MySQL. Theme by openark.org