



Nowadays, if you are working in IT industry, it is really important to know something about web 2.0 or at least pretend to know something. The great thing about web 2.0 is that nobody can really give it a clean clear definition. Therefore, you can put the web 2.0 hat on anything and you won’t get into any trouble.
Anyway, Social Tagging has been a popular web 2.0 technology for a while and has been widely used by quite a few photo sharing web sites. In nutshell, a piece of content doesn’t really have a lot of information or value by itself. For example, you have a picture of a beautiful model dressing in bikini and posing on a sunny beach. Well, the picture looks great but for other users they have to see it to know what the picture is all about. It is apparent that we must provide ways to enrich the content with context information for things like content search, content categorization, content reuse etc. One traditional approach is to build taxonomy and associate it with content. That is more like top-down approach which means in most scenarios the content owner or administrator will provide the context information. For social tagging, it takes the bottom-up approach which means the context information will come from the content users. That is web 2.0 all about, collaboration. If we use the picture as example, we can have multiple people viewing it and all providing tags such as Beach, Beautiful Woman, Sunny and so on. The tag list can keep growing with more people viewing it and contributing the tags. And people can tag it with same tags which shows the voting and ranking of the picture. Now you can see the clear advantage of letting the users to provide context information.
So, this sounds like really cool stuff. Let us start a little project and build a simple social tagging system using Alfresco Web script.
Let us called it “Poor Man’s Social Tagging”.
The goal of the project is to build a system
1) Allow content users to contribute tags to pictures.
2) For each picture it provides statistical information such as total number of unique tags, total number of tags, most popular tag etc.
3) Show the tags in a fashion that user can easily see the differences of times it has been tagged.
4) Allow searching picture by tag.
5) Provide the list of most popular tags.
6) And we will do it in two hours.
Again, we will keep it simple. We will use following tools
1) Alfresco 2.1
2) Textpad
3) Firefox with firebug plug in.
And we will mount Alfresco repository as shared drive so that we can create web scripts within Alfresco directly.
First, we need to figure out the Data Models for our social tagging project. Alfresco provides very sophisticate and flexible modeling capabilities for modeling content meta-data. Here is the snippet of the model XML file.
<types>
<type name=”st:socialtag”>
<title>Social Tag</title>
<parent>cm:content</parent>
<properties>
<property name=”st:keyword”>
<type>d:text</type>
</property>
<property name=”st:count”>
<type>d:int</type>
</property>
</properties>
</type>
</types>
<aspects>
<!– Definition of Aspect –>
<aspect name=”st:socialtaggable”>
<title>Social Taggable</title>
<properties>
<property name=”st:mostpopularkeyword”>
<type>d:text</type>
</property>
<property name=”st:mostpopularkeywordcount”>
<type>d:int</type>
</property>
<property name=”st:totalnumberoftags”>
<type>d:int</type>
</property>
<property name=”st:totalnumberofcounts”>
<type>d:int</type>
</property>
</properties>
<associations>
<child-association name=”st:contains”>
<source>
<mandatory>false</mandatory>
<many>false</many>
</source>
<target>
<class>st:socialtag</class>
<mandatory>false</mandatory>
<many>true</many>
</target>
<duplicate>true</duplicate>
</child-association>
</associations>
</aspect>
</aspects>
From the above model XML file, you can see we will model Tag as Alfresco document with two additional properties, keyword for tag name and count for keeping the total number of the times the tag has been used. We also setup a new aspect, socialtaggable, which we will add it to all pictures. The new aspect not only includes the properties for statistical information but also has the child association which allows us to associate tags to the pictures. Keep in mind, that every time we add a new tag to a picture, we create a new copy of the tag. So we can maintain counters of tagging for individual pictures and all pictures separately.
Once the model is ready. We can copy the model XML file and its bootstrap XML file to Alfresco extension folder. In order to use Alfresco Web Client to test the new content type and new aspect, we also need to change the web client configuration file, web-client-config-custom.xml which is also under the Alfresco extension folder. Once they are in place, we restart Alfresco to pick up the changes.
For this project, we will create a “Social Tags” space under Company Home. We then create a subspace, “Tags”, which will be used to hold all tags, and another subspace, “Pictures”, which will be used to hold all pictures. Since it will be Social Tagging, all users will be allowed to create tags and modify pictures properties. We need to add “Guest” user as “Content Collaborator” for the space “Social Tags”.
With all the setup done, we now need to write our web scripts. For this project we will have three web scripts.
Picture List script In the front end, it provides a sortable list of pictures and dialogs for showing and adding tags. It will also provide link to the top tag list. In the back end, it will execute query to get the list of picture and for new picture, it will also add the socialtaggable aspect to it and filter the list with a particular tag if the search-by-tag parameter is provided. Here is the snippet of the back-end JavaScript
// Get the list of nodes from DM
var luceneSearchStr = “( PATH:\”/app:company_home/cm:Social_x0020_Tags/cm:Pictures/*\” ) AND ( TEXT:”+ q+”)”
var nodes = search.luceneSearch(luceneSearchStr);
for (var i=0; i<nodes.length; i++)
{
var node = nodes[i];
logger.log(”Node path is “+ node.path);
if (node.hasAspect(”st:socialtaggable”) == false)
{
node.addAspect(”st:socialtaggable”);
node.properties["st:totalnumberofcounts"] = 0;
node.properties["st:mostpopularkeywordcount"] = 0;
node.properties["st:mostpopularkeyword"] = “”;
node.properties["st:totalnumberoftags"] = 0;
node.save();
}
Tag Adding Script This script takes the tags from the Picture List scripts. If the tag doesn’t not exist, it will create a new one. Otherwise, it will update the counter of the existing tag. It will then associate the tag with the picture. If the association is already there, it will simply update the tag counter for the picture. Otherwise, it will create a new association. Here is the snippet of the back-end JavaScript
var tagsFolder = companyhome.childByNamePath(”Social Tags/Tags”);
// Get the list of tags
var tags = newtags.split(”;”);
for (var i=0; i< tags.length; i++)
{
var tag = tags[i];
var searchResults = companyhome.childByNamePath(”Social Tags/Tags/”+tag);
if ( searchResults != null) {
// If the tag exists, Get the tag
var existingtag = searchResults;
existingtag.properties["st:count"]= existingtag.properties["st:count"] + 1;
existingtag.save();
} else {
// Otherwise, create a new tag
if ( tagsFolder != null ) {
var newtag = tagsFolder.createNode(tag, “st:socialtag”);
newtag.properties.description=tag;
newtag.content=tag;
newtag.properties["st:keyword"]=tag;
newtag.properties["st:count"]=1;
newtag.save();
}
}
// If the tag has already been associated, simply increase the count.
// Otherwise, create a new child association
var childNodes = node.childAssocs["st:contains"];
var foundtag = false;
if ( childNodes != null ) {
for (var j=0; j < childNodes.length && !foundtag; j++) {
var loopNode = childNodes[j];
if (loopNode.properties["st:keyword"] == tag ) {
loopNode.properties["st:count"]= loopNode.properties["st:count"] + 1;
loopNode.save();
foundtag = true;
}
}
}
if ( !foundtag ) {
//If the association is not there, create a new one.
var child = node.createNode(tag, “st:socialtag”, “st:contains”);
child.properties.description=tag;
child.content=tag;
child.properties["st:keyword"]=tag;
child.properties["st:count"]=1;
child.save();
}
// Populates the stats
childNodes = node.childAssocs["st:contains"];
node.properties["st:totalnumberoftags"] = childNodes.length;
var count = 0 ;
var maxcount = node.properties["st:mostpopularkeywordcount"];
var mostpopulartag = node.properties["st:mostpopularkeyword"];
//Update the most populate tag
for (var k=0; k < childNodes.length ; k++) {
var currentNode = childNodes[k];
if (currentNode.properties["st:count"] == 0) {
currentNode.properties["st:count"] = 1;
currentNode.save();
}
if ( currentNode.properties["st:count"] > maxcount) {
maxcount = currentNode.properties["st:count"];
mostpopulartag = currentNode.properties["st:keyword"];
}
count = count + currentNode.properties["st:count"];
}
node.properties["st:totalnumberofcounts"] = count;
node.properties["st:mostpopularkeywordcount"] = maxcount;
node.properties["st:mostpopularkeyword"] = mostpopulartag;
}
//Save the node
node.save();
Tag List Script. This script provides a sortable list of all existing tags.
For the overall UI, we will continue using the DoJo package shipped with Alfresco. We will mainly use the FilteringTable widget and Dialog widget.
Now let us register the three web scripts with Alfresco and hit the front page.
http://localhost:8080/alfresco/service/socialtag/document/list.html
One more thing, the authentication setting for all scripts are set as Guest. So you can just login as guest/guest to try out our Poor Man’s Social Tagging.
I think you gotta love Web Script since it makes so many things look so easy. For a relatively “superficial” developer like Dr. Q., it only takes him about two hours to build a not-so-shabby Social Tagging system.
So for better developers like you, you can definitely build much cooler stuff using Alfresco.
If you want to check out this little project, here is the zip file(Social Tagging).
Again, you need to
1) Setup the custom model (core\config\alfresco\extension).
2) Register three web scripts (webscripts\source\org\alfresco\demo\wslib\socialtag) and add the three dojo images(core\webapp\images\dojo) to tomcat\webapps\alfresco\images\dojo.
3) Setup three folders as described above and upload some pictures.
Here are some screen shots. Enjoy!

