Daily Archives: July 3, 2010

Adding a New Feature to Shiding for Learning

In this exercise, we add a new feature to Shindig. I may have jacked-in at the wrong place – but this will get you started.

First we move into the feature directory:

cd features/src/main/javascript/features

Create a new directory named learning and put three files into it.


gadgets['learning'] = (function() {

    return {
       getContextLabel : function() {
            return 'SI124';
        getContextName : function() {
            return 'Social Computing';
        setOutcome : function(data) {
            alert('setOutcome belongs here');


This creates our client code and defines three methods in the client. For now they are simple stubs to keep life simple.


var tamings___ = tamings___ || [];
tamings___.push(function(imports) {
  ___.grantRead(gadgets.learning, 'getContextLabel');
  ___.grantRead(gadgets.learning, 'getContextName');
  ___.grantRead(gadgets.learning, 'setOutcome');

I am a little foggy on this file – it basically works with Caja to make sure that you are explicit as to what you want to really expose to JavaScript callers.


    <script src="learning_client.js"/>
    <script src="taming.js"/>
    <script src="learning_client.js"/>
    <script src="taming.js"/>

This file names your feature and defines the source files that make it up.

Then edit the file features.txt and add a line:


There is a way to do this using a script, but for now, lets just jack-in directly.

At this point you need to rebuild Shindig. And you might get syntax errors during the build which you need to fix. Somehow the Javascript for features is compiled / processed at mvn time and put into a more run-time format.


once it compiles and installs, start Jetty again

mvn -Prun

And navigate to http://localhost:8080/samplecontainer/samplecontainer.html

You should see the “Social Hello World” gadget. Now lets edit this file:

vi ./target/work/webapp/samplecontainer/examples/SocialHelloWorld.xml

And add two lines:

   <Require feature="osapi"></Require>
   <Require feature="learning"></Require>
   <Require feature="settitle"/></Require>

   gadgets.window.setTitle('Social Hello World');
     var hellos = new Array('Hello World', 'Hallo Welt', 'Ciao a tutti',

This requests that the container load the new learning feature and then we call the learning feature when the JavaScript starts up in the gadget and you should see the dialog box pop up once you save the SampleHelloworld.xml and do a refresh.

Up next – talking to code inside the server…

Next post in the series

Getting Oriented with Shindig (i.e. Shindig Hacking for Dummies)

First check out a copy of Shindig from Apache.

svn checkout http://svn.apache.org/repos/asf/shindig/trunk/ shindig

Then compile it. The first compile will take a long time and will download a lot of artifacts. You will want to be on a quick network connection


If your compile fails a unit test, try mvn -Dmaven.test.skip=true

You can also take a look at the BUILD-JAVA file in the main directory if you are having problems getting it to compile.

Then start the Jetty server:

mvn -Prun

You best friend will be the Shindig Getting Started page – it has lots of hints on what to do to explore your container.

We will just hack a single bit of a gadget running in the sample container so click here:


You should see the “Social Hello World” gadget. Now lets edit this file:

vi ./target/work/webapp/samplecontainer/examples/SocialHelloWorld.xml

And make the following change:

   gadgets.window.setTitle('Social Hello World');
   alert('Hello Chuck');
     var hellos = new Array('Hello World', 'Hallo Welt', 'Ciao a tutti',

You should see your little alert box when the page refreshes. That is the end of “getting started”.

Note that the SocialHelloWorld.xml file gets overwritten each time you recompile Shindig – so keep your modifications handy elsewhere to reapply after each mvn install – I like editing the gadget in target because then I just keep doing a refresh.

To shut down the Jetty server, simply kill it (i.e. press CTRL-C in the command window on Mac/Linux).

Now here is a little weirdness when you change the gadget code. I am never sure what exactly is needed to really do a full refresh. Here are the things I generally try:

  • Press Refresh in the Browser
  • Press the “Reset All” button
  • Clear the browser history if all else fails and your changes don’t seem to be getting reloaded

It seems as though there is *lots* of caching going on at several levels and you have to take increasingly drastic measures to get past it as you drop your code bits in.

Next post in the series.

Playing with Shindig/OpenSocial Adding a New Feature and a Service

I have been talking recently with folks at the Open University (UK), Open University of Catelonia, Ian Boston from Sakai 3, and a few other organizations about the emergence of an “OpenSocial Learning Gadget”. We had a nice Gadget BOF at the Sakai Conference in Denver where Ian Boston (also a Shindig committer) gave a little tutorial on Shindig Architecture and how to add a Shindig feature and plug Shindig into something like Sakai.

It seemed really clear and obvious and it felt to me that there was a nice way forward to build a Shindig feature (i.e. extension) to define a learning gadget and perhaps line up all of these disparate efforts across vendors and projects and make it so a “learning gadget” could run in any LMS that had Shindig with the learning extension.

So two weeks ago with some help from Ian, I downloaded the source to Shindig and started banging around with Shindig. Ian helped me a lot and the Apache Shindig developer list also gave me some wise advice at key moments where I would get lost and confused.

I had three goals in mind as I went through the Shindig code:

(1) Add a “feature” – an extension loaded into the browser that makes an API available to the Javascript code running in the widget.

(2) Add a run-time server-side service to support the feature – the code of the client-side feature would call this server-server API/service to retrieve things like course name, role of current user, set outcomes, etc. I need do find out how to write a service and register it both in the server Java code and in the client JavaScript code.

(3) Bang around until I understood the security model and the provisioning and launching of gadgets from the container (i.e. the LMS)

I also wanted to explore how the SPI (Server Program Interface) pattern worked in Shindig. Pluto 1.1 used the SPI pattern and it was really well done and made it really straightforward to add JSR-168 support to Sakai 2 back in the 2.4/2.5 days.

Part of my investigation was to take notes as I went along and possibly propose a general capability for Shindig list to add these features without touching any core Shindig code. It may be tricky because even though there is Javascript, there is compile and run-time bits needed.

Along the way, I banged away at Apache Shiro – the generic Authentication and Authorization project. I found Shiro kind of interesting and I particularly liked its feature where Session can exist even if a web browser is not involved in the interaction. In one of my early explorations, I tried to hack Basic LTI Provider code in to Shiro and came up with some ways to improve the plug-ability of Shiro – but then I realized it had little to do with what I was investigating with Shindig – so I dropped my Shiro investigation and went back to Shindig.

I am happy to report that Shindig is pretty cool and well structured internally. It was pretty easy to find all of the necessary places to plug my code in. It is not all too well documented and it is not set up to add features or services without modifying source code.

I promised to write someShindig documentation regarding how this all worked which I will do in a couple of blog posts over the next week after I clean up the code a bit to make it more presentable.

Next post in the series.