You are on page 1of 182

Widget development for Sakai

Project presented by
Olivier Janssens

To achieve the certificate of Bachelor


New Media and Communication
Technology

Year: 2009-2010
Olivier Janssens Sakai 3 2009/2010

1 Foreword

1.1 Who am I?

I’m Olivier Janssens and I’m a student New Media and Communication technology. I’ve
started my course in 2007. I’ve chosen to do nMCT because I’ve always been interested in
everything related to computers. This interest started in highschool where I did Accounting
and Informatics.

I’m particularly interested in web technology so this is why I’ve chosen the specialization
Web technology in my last year. I’m also quite adventures so that’s why I did my internship
at the Centre of applied research in educational technology at the University of Cambridge.

1.2 CARET

CARET1 was founded to support the work of researchers, teachers and their students. CARET
has a wide variety of project currently running from developing a learning platform (Sakai) to
collection space (A Collections Management Systems to cover every activity and process
which a museum undertakes upon the objects in its care). It’s an origination which is
committed to the principles of open source software and the development of robust
applications.

It’s basically a unit focused on learning and research technologies at the University of
Cambridge. Essential innovation is a creative process that endeavors to solve problems by
exploring a range of ideas and concepts. CARET really cares about establishing a creative
space where talented people can bring their ideas into being and realize the potential of
their discoveries.

Caret was also given a European Schoolnet’s eLearning award in 2005 for the Personal
Demons project. The Plant Sciences team supported by CARET won first prize in the SAGE
awards for the most outstanding “research into practice” education project in 2007.

1.3 Usage of this document

This document describes what I have done during my internship in CARET and is meant to
help future developers to develop on Sakai. It explains a wide variety of concepts and
functionalities that can be found in the current Sakai version

1
CARET: Centre for applied research and technology

Chapter: Foreword I
Olivier Janssens Sakai 3 2009/2010

1.4 Special thanks

To Christian Vuerings and Simon Gaeremynck who assisted me and thought me everything
I know about Sakai.

To Jill Vandendriesche for making this international internship at CARET possible.

To Michael Gaillez for reading and correcting my reports and thesis.

To Katy Cherry for finding us accommodation to live.

To the CARET OPS team for providing us with Macbooks and all the technical help we
needed.

To Stephanie Sanders for being our contact person .

Chapter: Foreword II
Olivier Janssens Sakai 3 2009/2010

2 Summary

2.1 Sakai 3

Sakai is one of the projects that is currently under development in Caret. It’s a learning
environment which is used at 200 universities in the world. This document will assist
developers on developing different kinds of functionalities for Sakai. Everything in Sakai
works with widgets. But what are widgets? Widgets are a part of a bigger project that work
on their own. E.g: The twitter widget, this is a widget that allows to user to access twitter
from Sakai. In Sakai there are widgets for everything.

There are 2 kinds of widgets in Sakai. The dashboard widgets, that can be found on the
dashboard of Sakai (homepage) and those who can be used inside the sites of Sakai. The site
part of Sakai allows users to create their own site inside Sakai. These Sites will have the Sakai
layout but all the content will be filled in by the user. This content can be text and widgets.
(Examples of site widgets: Googlemaps, youtube, Comments, Polls , ...).

Sakai consists of 2 parts. The front-end and the back-end. The front-end is entirely written in
HTML, JavaScript 2and CSS3. Then there is the back-end which is written entirely in java. This
document will explain everything about developing for the front-end. It contains how to
develop widgets for the dashboard, sitepart, prototype development, making skins for Sakai
and External widgets for Sakai (Widgets that are not included in the Sakai domain, like on,
iGoogle4, Windows 7, Mac ).

It starts with the basics, from how to setup up a local Sakai instance, how to use git5 for
version control and how to collaborate with quite a lot of people on 1 big project. Then how
to develop a simple dashboard widget. Every step is explained here too. How the HTML
6
structure should be , how JavaScript & JQuery 7works. And even a brief explanation of how
the Sakai back-end works.

When the basics of Sakai are explained there’s an explanation on how to develop a more
advanced widget for flickr. A lot of pages are dedicated to usability with images. So that the
user doesn’t have to wait too much when they are watching pictures. New technologies like
drag and drop are explained here too.

Apart from widget development there’s also a part dedicated to prototype development.
This will explain how to develop a prototype for the Dashboard pages of Sakai. And how the
prototype development process works.

2 prototype-based object-oriented scripting language


3
Cascading StyleSheets
4
5
A versioning tool, to manage projects
6
HyperText Markup Language
7 jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling,
animating, and Ajax interactions for rapid web development.

Chapter: Summary iii


Olivier Janssens Sakai 3 2009/2010

But because Sakai isn’t only operational in its own domain there is also an explanation for
how to develop widgets for the OSx8 dashboard, Windows7 sidebar, facebook 9and igoogle.
This whole document will give any kind of developer a good start and help throughout the
development procedure on Sakai

8
OSx: Apple Operating System
9
Facebook: Social Networking Site

Chapter: Summary iv
3 Glossary
3akai-ux
The Front-end of Sakai3 ......................................................................................................... 3
Ajax
Asynchronous JavaScript and xml. ....................................................................................... 22
Apache
Foundation for open-source software project....................................................................... 5
API
Application programming interface ....................................................................................... 5
CARET
Centre for Applied Research and Technology ......................................................................... I
CSS
Cascading StyleSheets ........................................................................................................... iii
DOM
Document Object Model ...................................................................................................... 11
facebook
Social Networking Site........................................................................................................... iv
fluid
Fluid builds user interfaces, designs commonly used interactions, teaches others how to
build good user-centred designs, and works with other software projects to integrate
our solutions into their applications. ............................................................................... 29
git
A versioning tool , to manage projects ................................................................................. iii
HTML
HyperText Markup Language ................................................................................................ iii
igoogle
The personalised dashboard page of google (www.google.co.uk/ig) .................................. iii
Internationalization
To make the application in multiple languages ................................................................... 10
JQuery
jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing,
event handling, animating, and Ajax interactions for rapid web development. .............. iii
JSlint
www.jslint.com, this is a validator for JavaScript ................................................................ 12
json
JSON (JavaScript Object Notation) is a lightweight data-interchange format ....................... 7
JST
JavaScript Template ............................................................................................................. 27
Nakamura
The Back-end of Sakai3 .......................................................................................................... 3
OSGi
The OSGi framework is a module system and service platform for the Java programming
language that implements a complete and dynamic component mode........................... 5
OSx
Apple Operating System........................................................................................................ iv
Olivier Janssens Sakai 3 2009/2010

plist
property list files................................................................................................................... 85
REST
Representational State Transfer ............................................................................................ 5
RSS
most commonly expanded as Really Simple Syndication) is a family of web feed formats
used to publish frequently updated works ...................................................................... 50
ssh
Secure Shell or SSH is a network protocol that allows data to be exchanged using a secure
channel between two networked devices ......................................................................... 2
W3C
The World Wide Web Consortium ......................................................................................... 9
widget
A visually seperate element that lives on its own , but can interact with apis.................... 10
XPath
the XML Path Language, is a query language for selecting nodes from an XML document.
.......................................................................................................................................... 20

Chapter: Glossary vi
Olivier Janssens Sakai 3 2009/2010

4 Index
1 Foreword ............................................................................................................................. I
1.1 Who am I? ..................................................................................................................... I
1.2 CARET ............................................................................................................................ I
1.3 Usage of this document ................................................................................................ I
1.4 Special thanks .............................................................................................................. II
2 Summary ........................................................................................................................... iii
2.1 Sakai 3 ......................................................................................................................... iii
3 Glossary .............................................................................................................................. v
5 Sakai Introduction .............................................................................................................. 1
5.1 What is Sakai................................................................................................................ 1
5.2 Sakai in Action.............................................................................................................. 1
5.3 Who is using Sakai ....................................................................................................... 1
5.4 So how does Sakai work behind the screens?............................................................. 3
5.4.1 3akai-ux (Front-end) ............................................................................................ 3
5.4.2 Nakamura (Back-end) ........................................................................................... 5
6 Dashboard Widget development ....................................................................................... 6
6.1 Make your very own branch ........................................................................................ 6
6.2 Creating the necessary files ......................................................................................... 7
6.2.1 The JavaScript file ................................................................................................. 8
6.2.2 The CSS file ........................................................................................................... 8
6.2.3 The HTML file ....................................................................................................... 9
6.3 Registerering your widget ........................................................................................ 10
6.4 Important JavaScript code standards ........................................................................ 10
6.5 Difference between jQuery and jQuery in sakai ....................................................... 11
6.6 jQuery plug-ins........................................................................................................... 12
6.6.1 Implementing a jQuery plug-in .......................................................................... 12
6.7 How to get data from a form ..................................................................................... 13
6.7.1 .val() .................................................................................................................... 13
6.8 Saving data................................................................................................................. 14
6.8.1 So how does json work:...................................................................................... 15
6.8.2 How to make an object ...................................................................................... 16
6.8.3 Saving data in Sakai ............................................................................................ 17
6.9 But now how can you access al this stored data? ..................................................... 21

Chapter: Glossary VII


Olivier Janssens Sakai 3 2009/2010

6.9.1 CRUD ................................................................................................................... 22


6.9.2 Ajax ..................................................................................................................... 22
6.10 Displaying data ....................................................................................................... 27
6.10.1 JST ....................................................................................................................... 27
6.11 Editing .................................................................................................................... 29
6.11.1 Fluid infusion ...................................................................................................... 29
6.11.2 Inline editing with combo boxes. ....................................................................... 30
6.11.3 Deleting .............................................................................................................. 31
6.12 Summarize: ............................................................................................................ 32
7 Prototype development ................................................................................................... 33
7.1 The file structure: ...................................................................................................... 36
7.2 JQuery Accordion....................................................................................................... 36
7.3 How this is done: ....................................................................................................... 38
7.4 Layout ........................................................................................................................ 39
7.4.1 Draggable and droppable plug-in....................................................................... 42
7.5 Text widget ................................................................................................................ 43
7.6 Implementing other widgets ..................................................................................... 50
7.6.1 Sortable plug-in .................................................................................................. 52
8 Site widgets development ................................................................................................ 55
8.1 The flickr Widget ........................................................................................................ 56
8.2 Registering the flickr widget ...................................................................................... 56
8.3 What is a proxy file ? ................................................................................................. 58
8.4 Why use a proxy file ?................................................................................................ 59
8.4.1 How this is done ................................................................................................. 59
8.4.2 How to deploy a proxy service ........................................................................... 60
8.5 How to make an image gallery with caching. ............................................................ 62
8.5.1 Next: ................................................................................................................... 64
8.5.2 Previous: ............................................................................................................. 66
8.6 The difficulties: .......................................................................................................... 66
8.7 Second image gallery ................................................................................................. 67
8.8 Drag and drop ............................................................................................................ 67
8.8.1 How this is done: ................................................................................................ 70
8.9 Sidebar gallery ........................................................................................................... 72
8.9.1 Next and Previous: ............................................................................................. 75
8.10 Delete ..................................................................................................................... 75

Chapter: Glossary VIII


Olivier Janssens Sakai 3 2009/2010

8.11 Saving ..................................................................................................................... 77


8.12 Rendering the gallery in the site ............................................................................ 78
9 Sakai Site Skins ................................................................................................................. 80
9.1 Creating a Skin ........................................................................................................... 80
9.2 How to start ............................................................................................................... 81
10 Bugs in Sakai ..................................................................................................................... 83
11 Mac Widgets..................................................................................................................... 84
11.1 How to start developing a Mac widget .................................................................. 85
11.2 Accessing Sakai from a Mac widget ....................................................................... 86
11.3 Log-in ...................................................................................................................... 89
11.4 Recent Messages.................................................................................................... 90
11.4.1 Displaying the message ...................................................................................... 92
11.5 The widget flip ....................................................................................................... 93
11.6 Profile information. ................................................................................................ 94
11.7 Chat ........................................................................................................................ 95
12 Windows 7 widget .......................................................................................................... 106
12.1 Login ..................................................................................................................... 107
12.2 Recent message ................................................................................................... 110
13 iGoogle widget ............................................................................................................... 111
13.1 What is an iframe ................................................................................................. 111
14 Conclusion ...................................................................................................................... 113
15 Sources ........................................................................................................................... 114
16 Appendix............................................................................................................................. 1
16.1 Appendix A: How to develop for Sakai on MAC. ..................................................... 1
16.1.1 Programs needed to develop: .............................................................................. 1
16.1.2 Getting started ..................................................................................................... 1
16.1.3 Repository ............................................................................................................ 1
16.1.4 Commit ................................................................................................................. 1
16.1.5 Branch................................................................................................................... 1
16.1.6 Getting a local version of 3akai-ux (frontend) ..................................................... 2
16.1.7 Make a key for your online repository ................................................................. 2
16.1.8 Getting 3akai-ux in your remote repository ........................................................ 3
16.1.9 Get the remote repository locally ........................................................................ 3
16.1.10 Getting a local version of Nakamura (backend) ............................................... 4
16.2 Appendix A: Development for Sakai3 on Windows computers .............................. 1

Chapter: Glossary IX
Olivier Janssens Sakai 3 2009/2010

16.2.1 Downloading and installing the right packages ................................................... 1


17 Appendix C : Weekly Reports: ............................................................................................ 1
17.1 Report Week1: Monday 8 March – Friday 13 march .............................................. 1
17.1.1 Log ........................................................................................................................ 1
17.1.2 Summary .............................................................................................................. 2
17.2 Report Week2: Monday 15 March – 19 Friday march............................................ 4
17.2.1 Log ........................................................................................................................ 4
17.2.2 Summary .............................................................................................................. 4
17.3 Report Week3: Monday 22 March – Friday 26 march ............................................ 7
17.3.1 Log ........................................................................................................................ 7
17.3.2 Summary .............................................................................................................. 8
17.4 Report Week 4: Monday 29 March – Friday 1 April .............................................. 10
17.4.1 Log ...................................................................................................................... 10
17.4.2 Summary ............................................................................................................ 11
17.5 Report Week 5: Monday 5 April – Friday 9 April ................................................... 12
17.5.1 Log ...................................................................................................................... 12
17.5.2 Summary ............................................................................................................ 13
17.6 Report Monday Week 6: 12 April – Friday 17 April ............................................... 15
17.6.1 Log ...................................................................................................................... 15
17.6.2 Summary ............................................................................................................ 16
17.7 Report Monday Week7 : 19 April – Friday 23 April ............................................... 17
17.7.1 Log ...................................................................................................................... 17
17.7.2 Summary ............................................................................................................ 18
17.8 Report Week 8 : Monday 26 April – Friday 30 April .............................................. 19
17.8.1 Log ...................................................................................................................... 19
17.8.2 Summary ............................................................................................................ 20
17.9 Report Week9: Monday 3 May – Friday 7 May ..................................................... 22
17.9.1 Log ...................................................................................................................... 22
17.9.2 Summary ............................................................................................................ 23
17.10 Report Week 10: Monday 10 May – Friday 14 May .............................................. 25
17.10.1 Log................................................................................................................... 25
17.10.2 Summary ......................................................................................................... 26
17.11 Report Week 11: Monday 17 May – Friday 21 May .............................................. 29
17.11.1 Log................................................................................................................... 29
17.11.2 Summary ......................................................................................................... 30

Chapter: Glossary X
Olivier Janssens Sakai 3 2009/2010

17.12 Report Monday 24 May – Friday 28 May .............................................................. 33


17.12.1 Log................................................................................................................... 33
17.12.2 Summary ......................................................................................................... 34
17.13 Report Week 13: Tuesday 1 June – Friday 5 June ................................................. 36
17.13.1 Log................................................................................................................... 36
17.13.2 Summary ......................................................................................................... 37
18 Appendix D: Project fiche ................................................................................................... 1

Chapter: Glossary XI
Olivier Janssens Sakai 3 2009/2010
Olivier Janssens Sakai 3 2009/2010

Sakai 3
Olivier Janssens Sakai 3 2009/2010

5 Sakai Introduction

5.1 What is Sakai

Sakai is an Open Source Collaboration and Learning Environment, which is in enterprise use
at 200 Universities around the world with over a million users who use Sakai daily in their
teaching and learning

5.2 Sakai in Action

5.3 Who is using Sakai

A lot of educational institutions, in production settings ranging from 200 to 200.000 users. A
few examples of educational institutes that are using Sakai: Australian National University,
California State University, Catholic University of America, Columbia University, Hong Kong

Chapter: Sakai Introduction 1


Olivier Janssens Sakai 3 2009/2010

University of Science and Technology, Johns Hopkins University, Oxford University, Yale
University and many more.

Chapter: Sakai Introduction 2


Olivier Janssens Sakai 3 2009/2010

5.4 So how does Sakai work behind the screens?

Front-end Back-end

3akai-ux10 Nakamura11

5.4.1 3akai-ux (Front-end)

3akai-ux is the front-end of Sakai this is basically everything you can see. The front-end is
written in XHTML 1.0 Transitional, CSS and JavaScript.

The JavaScript libraries are:

- Fluid infusion
- jQuery 1.3.2
- JST
- TinyMCE
- Plug-ins
- JSON

10
3akai-ux: The Front-end of Sakai 3
11
Nakarmura : The Back-end of Sakai 3

Chapter: Sakai Introduction 3


Olivier Janssens Sakai 3 2009/2010

5.4.1.1 Example of the front-end

JSON JST Result


{ XHTML <div><!-- <div>

“userid” : “ojtwist”, <p> <p>

“firstname”:”olivier” ${userid} Ojtwist

“lastname”:”Janssens” </p> </p>

} </div> </div>

Chapter: Sakai Introduction 4


Olivier Janssens Sakai 3 2009/2010

5.4.2 Nakamura (Back--end)

Nakamura Consists of Apache JackRabit with Apache sling on top of Apache JackRabbit.
JackRabbit

Apache 12Jackrabbit is a fully conforming implementation of the Content Repository for Java
Technology APIi. A content repository is a hierarchical content store with support for
structured and unstructured content, full text search, versioning, transactions, observation,
and more. More information will be given later on.

Apache Sling is an innovative web framework that is intended to bring back the fun to web
development.

5.4.2.1 Apache Sling in five bullets points

- REST 13based web framework


- Content-driven,
driven, using a JCR content repository
- Powered by OSGi14
- Scripting inside, multiple languages
languag (JSP, server-side
side javascript, Scala, etc.)
- Apache top level Open Source project
projec

12
Apache: Foundation for open-source
source software project
13 Rest: Representational State Transfer
14
OSGI. The OSGi framework is a module system and service platform for the Java programming language
la that
implements a complete and dynamic component mode

Chapter: Sakai Introduction 5


Olivier Janssens Sakai3 2009 - 2010

6 Dashboard Widget development


To develop on Sakai a local Nakamura & 3akai-ux are needed. To get this on a Mac see
apendixA, on windows see appendix B.

The Sakai dashboard:

All these slots are Widgets; in this chapter I’ll explain how to develop such a widget.

6.1 Make your very own branch

When developing a widget it’s required you make your own branch with Git for this widget,
so it won’t interfere with other components. Making a branch is done by :

Git branch <branchname>

Chapter: Dashboard Widget development 6


Olivier Janssens Sakai3 2009 - 2010

(e.g : git branch todo)

Git checkout <branchname>


(e.g git checkout todo)

6.2 Creating the necessary files

When developing on Sakai there are a lot of strict rules to be followed, one of these rules is
the file structure.

lib: all the JavaScript libraries


CSS: all the CSS files
JavaScript: the only self written JavaScript file, this file should be the same name as the
widget.
bundles: All the JSON 15files for internationalization

The HTML file for the widget has to be in the root folder of your widget

15
JSON (JavaScript Object Notation) is a lightweight data-interchange format

Chapter: Dashboard Widget development 7


Olivier Janssens Sakai3 2009 - 2010

6.2.1 The JavaScript file

The JavaScript should always begin with:

The Sakai variable is of the name spacing. If there’s already a Sakai namespace that one
should be used, else a new one is created:

- Tuid : This parameter defines the widget, this is a unique id for the widget
- Placement: The url for the widget (This has changed during my internship and isn’t
used anymore)
- showSettings: This is not needed for a widget that runs on the homepage, but this is
basically a Boolean to see if the widget is in the settings mode or not. ( more info on
this later)

6.2.2 The CSS file

CSS code should be cross-browser, avoiding browser dependent hacks and rules, and should
be organized into logical blocks in relation with the mark-up which they affect.

Core / Main CSS file names should follow the HTML page name with "sakai" at the beginning:
search.html --> sakai.search.css

Here are 2 common organizational patterns you can follow:

• CSS structure following the structure of HTML


• Functional division: Layout, Typography, Colors etc...

Chapter: Dashboard Widget development 8


Olivier Janssens Sakai3 2009 - 2010

6.2.3 The HTML file

HTML should be well formatted valid XHTML 1.0 Transitional, and should pass W3C
16
validation. All HTML mark-up should have comments for all of the containers regarding
what they hold, even if they are empty. Because the empty divs are often filled dynamically.

Example :

16
W3C. The World Wide Web Consortium

Chapter: Dashboard Widget development 9


Olivier Janssens Sakai3 2009 - 2010

6.3 Registerering your widget

For a widget to function in Sakai it has to be registered in widgets.js, this file can be found at
/3akai-ux/dev/_configuration/widget.js

The widget is registered like this:

Explanation:

-Description: This is some explanation about the widget


-i18n: Internationalization 17files. These are the paths to the JSON files that contain
the translations of the text in the widget
- id: an id that is given to the widget
-name: the name of the widget
-personalportal: This variable determines if it will be shown in the Sakai goodies on
the dashboard.
-url: the URL where the html file of the widget can be found

Now if you go to your localhost 18you normally will see your widget. It is possible you don’t
see your widget here. A few things can cause this, first check widgets.js and make sure all
configuration parameters are correct.

If the widget 19still isn’t displaying on the Sakai homepage there is probably a problem with
the file mapping. To check this head over to the configuration manager20. Select the
resource providers in the combo box and there you’ll see the paths to dev and devwidget.
Here you can see how the fsresource mapped the folders. If the paths aren’t correct, correct
them and then you should be able t see the widget on the homepage. For more information
see appendix A.

6.4 Important JavaScript code standards

17
To make the application in multiple languages
18 http://localhost:8080/dev/index.html
19
A visually seperate element that lives on its own , but can interact with apis.
20
http://localhost:8080/system /console.configMgr.

Chapter: Dashboard Widget development 10


Olivier Janssens Sakai3 2009 - 2010

First of all, the frontend is written in jQuery/JavaScript. But what is jQuery?

“jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing,
event handling, animating, and Ajax interactions for rapid web development.”21

To start with:

Explanation: With this line code you make a variable of the whole widget. A jQuery variable
should always start with a “$”. If used properly you will only modify DOM 22elements inside
this element. This is done because 1 widget can be placed on the page multiple times.

How to address an id or class:

HTML:

<div id=”todo_subject”>
<p>text<p>
</div>

JavaScript:

Var <variablename> = $(“<id of the html component”, variable where


the div can be found in);

Example:

So in this case a variable is made of the “todo_subject” div inside the widget.

Why not do it the easy way like addressing the id every time you want to access or modify it
?

e.g : var $subject = $(“#todo_subject”).val(); // Just getting the


value of the div and storing it a variable

This case is not very efficient, because the div is being addressed every time and put in the
cache. And if there is another widget using this id, you might address the wrong div. So in
the good way (first example) the id gets cached only once and the right div is always
addressed.

6.5 Difference between jQuery and jQuery in sakai

Normally when writing jQuery you start with:

21
http://jquery.com
22
DOM: Document Object Model

Chapter: Dashboard Widget development 11


Olivier Janssens Sakai3 2009 - 2010

But in Sakai external JavaScript files are used. These are loaded after the html. This is why it’s
a certainty that the HTML is loaded. At this point an init function can be made:

Now it’s possible to start writing JavaScript code. The init function is best called at the
bottom of the JavaScript file for JSlint23 validation.

6.6 jQuery plug-ins

In Sakai jQuery 1.3.2 and a lightweight version of jQuery-ui 1.7.2 are included. During my
internship these have been upgraded to 1.4 and 1.8, other libraries might be required for the
necessary plug-in. When using a library that is not included in Sakai you’ll have to add it to
the lib folder in the widget folder.

When using a library, this line has to be added at the bottom of the JavaScript file. (change
flickr with the name of the widget you are developing), else Sakai won’t load this file.

6.6.1 Implementing a jQuery plug-in

I will give an example of the date picker plug-in. For this plug-in the jQuery-ui library is
needed, so no need to download an extra library because this is already included in Sakai.

The date picker:

Html:

<input type="text" class="datepicker" >

Javascript:

23
www.jslint.com, this is a validator for JavaScript

Chapter: Dashboard Widget development 12


Olivier Janssens Sakai3 2009 - 2010

$todoDatepick.datepicker({});

And at this point the datepicker works. But there are also a few optional parameters that can
be set:

Disabled

Disables (true) or enables (false) the datepicker. Can be set when initialising (first creating)
the datepicker.

altField

The jQuery selector for another field that is to be updated with the selected date from the
datepicker. Use the altFormat setting to change the format of the date within this field.
Leave as blank for no alternate field.

buttonImage

The URL for the popup button image. If set, buttonText becomes the alt value and is not
directly displayed.

These are just a few examples of the jQuery datepicker parameters, but there are many
more. These can be found in the jQuery datepicker API24.

6.7 How to get data from a form

6.7.1 .val()

Now that the first plug-in has been implemented it’s time to see how to get data from the
form. This is fairly easy. For example:

Html:

<input type="text" class="datepicker" >

If the user has selected a date with the datepicker the value will be filled in the input box.
Now to get this value you simply have to do : .val();

Example:

Var todoDate = $todoDatepick.val();

Don’t forget that this variable has been declared globally at the top of the JavaScript file.

var $todoDatepick = $(".datePick", $rootel);

.html:

24
http://docs.jquery.com/UI/Datepicker

Chapter: Dashboard Widget development 13


Olivier Janssens Sakai3 2009 - 2010

Another way to get a value is by doing .html().

Example :

<div id=”todo_div”>
</div>

Javascript:

Var todoDiv = $todoDiv.html();

6.8 Saving data

Now that we can get data from the html we can for example save the data. To save the data
we first need to make an object from the data. You might wonder why we need to make an
object from the data. This is because all data is saved as nodes in the back-end. These nodes
can be compared to a file with properties. More explanation about this will follow. To
understand this, first JSON has to be explained

Json (Javascript Object Notation) is a lightweight data-interchange format. It is easy for


humans to read and write. It is easy for machines to parse and generate. The best way to
understand Json is to compare it to XML. Example:

The same data in xml:

Chapter: Dashboard Widget development 14


Olivier Janssens Sakai3 2009 - 2010

6.8.1 So how does json work:

String:

"name" : "value"

Array

[ value, value, ....]

Object

“name”:object

Chapter: Dashboard Widget development 15


Olivier Janssens Sakai3 2009 - 2010

6.8.2 How to make an object

Var json;

json = {

"id":"",

"subject": "",

"doBy": "",

"priority": ""

};

Now you can combine getting data from html and making an object:

json.subject = $todoSubject.val();

json.doBy = $todoDateId.val();

json.priority = $todoPriority.val();

Chapter: Dashboard Widget development 16


Olivier Janssens Sakai3 2009 - 2010

6.8.3 Saving data in Sakai

Sakai’s backend consists of an apache jackrabbit server, an Apache Sling server and an
apache lucene server.

To summarize :

Sakai backend

Apache Sling

Apache Jackrabbit

Apache Lucene
6.8.3.1 Lucene

Lucene is an indexing and search technology. Lucene allows you to upload any kind of file
and lucene will make it searchable.

6.8.3.2 Apache JackRabbit

Jackrabit is an implementation of the java content repository (JCR). Jackrabbit allows the
user to store data in nodes. Nodes are basically folders with properties. These folders have
properties where the actual data is stored in.

Example :

Chapter: Dashboard Widget development 17


Olivier Janssens Sakai3 2009 - 2010

All these folders are nodes and have properties. And these properties have values. The
actual data is either stored in files or a database.

JCR basically is a spec that defines how the repository works. So Jackrabbit works Hierarchal.
Example:
Node
car
Properties
brand : Chevrolet
name: Impala
year: 1967
awesomeness: 11/10

Chapter: Dashboard Widget development 18


Olivier Janssens Sakai3 2009 - 2010

JackRabbit also has access control. So you can define which parts the user can access.
Example :

This user has access to the private, public message, contacts and calendar parts.

Chapter: Dashboard Widget development 19


Olivier Janssens Sakai3 2009 - 2010

This user hasn’t got that much access as you can see.

The access control also works with time. For example a calendar event will only be exposed
after a certain date.

Jackrabbit can also work with queries (XPath & SQL) for example:

Xpath25:

//*[@Title = "Mathematics"]

SQL:

SELECT * FROM nt:base WHERE Title = 'Mathematics'

JackRabbit also has versioning. So there can be multiple versions of a node.

For example :

Just like in git you can make a branch.

25
XPath: the XML Path Language, is a query language for selecting nodes from an XML document.

Chapter: Dashboard Widget development 20


Olivier Janssens Sakai3 2009 - 2010

6.9 But now how can you access al this stored data?

This is done by apache Sling. Sling is on top of Jackrabbit and it exposes the data to the HTTP
layer. This is basically the HTTP API. To expose the data to the http it maps the nodes with a
URL. A user can surf to a URL and see the data in whatever format he wants (json, xml, html,
text, etc...)

For example :

http://localhost:8080/sites/dummy-site/_widgets/id806796423/googlemaps.json.

So here you have the googlemap node. It has properties like : mapsize,mapzoom,lat,lang
etc...

Json view:

In html :
http://localhost:8080/sites/dummysite/_widgets/id806796423/googlemaps.html

In txt :
http://localhost:8080/sites/dummysite/_widgets/id806796423/googlemaps.txt

Chapter: Dashboard Widget development 21


Olivier Janssens Sakai3 2009 - 2010

You can also add a selector, for example: .infinity.json. This will show you all the data from
the nodes underneath the node you do .infinity.json on.

6.9.1 CRUD

POST
- Update something
GET
- Retrieve something
DELETE
- Delete something
PUT
- Create a file in the repository

The sling Servlet takes care of all this operations. So you can just do a POST to
http://localhost:8080/sites/dummy-site/_widgets/id806796423/googlemaps to store
data. Or do a get to http://localhost:8080/sites/dummy-
site/_widgets/id806796423/googlemaps.json. To get the data. In Sakai everything is
done with Ajax.

6.9.2 Ajax

Saving and storing data is done by doing an Ajax call to a certain URM to the back-end. To
understand this I’ll have to explain what Ajax is. Ajax 26stand for Asynchronous JavaScript
and xml. So as you see it’s asynchronous, this means that a web application can retrieve or
post data to or from the server asynchronously. Asynchronously means that when a request
is done that the application will continue and will not wait for a response. In Sakai the jQuery
method for Ajax is used.

26
Asynchronous JavaScript and xml.

Chapter: Dashboard Widget development 22


Olivier Janssens Sakai3 2009 - 2010

6.9.2.1 How to make an ajax call

$.ajax({
url: pref_url,
type: "POST",
data: data,
success: function(){
getTodolist();
}
},
error: function(xhr, status, e){
console.log("error");
}
});
})

Some explanation is required here:

url

First of all an Ajax call needs a URL. This is the URL where you can get or post or put the data.
In this case I just dynamically created an URL. The eventual URL is:
http://localhost:8080/todo/admin/todo

Type:

Then a type is required. This is basically what the Ajax call has to do. You have 4 methods:
GET, POST, PUT and DELETE. There are many more. But these are supported by the back-
end.

POST: To store data (update)


GET: To fetch data (read)
PUT : To update date (create)
delete: to delete data (delete)

Data
Data is often just an object like described before

Success

This describes which function will be executed when the Ajax call has been successfully
completed.

Error

This describes which function will be executed when the Ajax call fails. This can also just be a
code line to log the error.

Chapter: Dashboard Widget development 23


Olivier Janssens Sakai3 2009 - 2010

After this Ajax call the data will be stored successfully in a node with properties on the
server. To check this you can just navigate to you URL and type “.json” behind it. Make sure
you have installed a browser plug-in to view Json.

Another way to save data is using the build in functionality of Sakai.

6.9.2.2 Sdata.preference.save(postUrl, jsonArray, sendDataComplete)

This method is quite handy, since you don’t have to write the Ajax call yourself. What this
method does: It will save the data in the back-end in several nodes depending on the data.
This will be done in a tree structures. Example:

An array filled with Json objects:

Make an empty array


jsonArray = [];

Add the object to the array, and this object’s key will be the id of the object
jsonArray[json.id] = json;

Now you can use:

sdata.preference.save(postUrl, jsonArray, sendDataComplete)

The postUrl is the same like before, and the sendDataComplete is a function that will be
executed when the Ajax call is successful.

The big difference between this method and a normal Ajax call is that with this method a
treestructure of nodes will be made. So the jsonArray is In fact an object that contains other
objects.

So a node todo will be created and underneath that will be other nodes with the name of
the todo item and in those will have attributes with the data.

For example :

When just posting you’ll have a URL like this:

http://localhost:8080/todo/admin/todo.json

in this node you’ll find all the data posted to this URL.

But when using the treestructure you have URLs like this

http://localhost:8080/todo/admin/todo/firsttodoitem.json

http://localhost:8080/todo/admin/todo/secondtodoitem.json

So for every todo item a resource (node) is created. And to see all the data in 1 json file
you’ll need to do.

Chapter: Dashboard Widget development 24


Olivier Janssens Sakai3 2009 - 2010

http://localhost:8080/todo/admin/todo.infinity.json

This is : url/resource/selector/extension

6.9.2.3 Sakai.api.Widgets.saveWidgetData(tuid,json,callback)

This method has been added during my internship. This method is basically the same as the
sData.prefrence.save but it also converts arrays to objects.

6.9.2.4 Sakai.ap.Widgets.loadWidgetsData

This is a method to retrieve data from a widget. The big difference with these new methods
are that you don’t have to give a url anymore. You just have to pass the unique id of the
widget (tuid). Because of this a unique URL will be created.

Now that we can post data we’ll retrieve data:

6.9.2.5 Retrieving data:

Retrieving data is done by doing an Ajax call to a certain path where we previously posted to.

For example:

Chapter: Dashboard Widget development 25


Olivier Janssens Sakai3 2009 - 2010

The parameters here are the same as in the post. The only difference here is that no data
will be passed. But you receive data when the call is completed

As you can see the URL also consists of an selector (.infinity), this function is designed to get
all the todo items. So a call is done to the .infinity.json

Chapter: Dashboard Widget development 26


Olivier Janssens Sakai3 2009 - 2010

6.10 Displaying data

When the Ajax call is completed you get an object that contains data in Json format. This is
not usable so it has to be converted to an object, this is done by doing:

evalJSON converts the Json string into an object , in this case the response.

During my internship this has been changed. If the server responds with application/json,
jQuery will immediately parse it to Json.

In this example the object is stored in the variable parseglobal with the key “all”. Now it is
possible to access a todo item by doing parseglobal.all.todoItem

Now it’s possible to render the data in html. In Sakai this is done by using JST.

6.10.1 JST27

Sakai uses the trimpath library for this. This is a lightweight open-source component that
allows you to do template based programming. This is basically a way of rendering data into
html. The way it’s done:

In this example:

- $todoTasks is a variable :

#todo_tasks can be found in the html :

This is an empty div where de template will be rendered in.

- $.Template.render is a global variable that will render the template into the html
- todoTemplate is a global variable that can be
found in the html:

27
Javascript Template

Chapter: Dashboard Widget development 27


Olivier Janssens Sakai3 2009 - 2010

In this case it’s quite a lot of HTML. But that doesn’t matter. The html inside the div
of the template always has to be in comments so <!—html code -- >.

pagingArray: This is just an object with a key like :

So now you can do :

<div><--!

{for todo in all}

<p> My todo task {todo.subject} </p>

{/all}

Chapter: Dashboard Widget development 28


Olivier Janssens Sakai3 2009 - 2010

</div><--

So you can address the object with the key and then just loop through every object in
the object and use the properties.

When this is rendered you’ll get just plain HTML in your browser.

6.11 Editing

So now that it’s possible to show data in Sakai, it’s time to do some editing. I’ve chosen to
use Fluid infusion to do the editing.

6.11.1 Fluid infusion

Fluid infusion 28is a javascript library that allow the user to do inline editing. A basic example
is plain text. Clicking on the text will transform the text into a textbox. The can then change
the text and by clicking outside the textbox it’ll transform back into plain text.

The same goes for a datepicker.There is a date and when the user clicks on the date a
datepicker appears.

Though the datepicker and the combo box functionality of Fluid Infusion isn’t quite ready yet
so this is not very handy to use.

6.11.1.1 How to use fluid infusion

Javascript:

The fluid infusion library is already included in sakai3, so you can just use it. The id passed
here is an id given to a top level element. In my case it’s a form. But this can be any element
(li,div , etc)

Html:

Top level element:

28
Fluid builds user interfaces, designs commonly used interactions, teaches others how to build good user-centered designs, and
works with other software projects to integrate our solutions into their applications.

Chapter: Dashboard Widget development 29


Olivier Janssens Sakai3 2009 - 2010

The item containing the element that has to be editable has to have “flc-inlineEditable” as
class and then the element itself should have the “flc-inlineEditable-text” class.

When this is done the text should be editable.

6.11.2 Inline editing with combo boxes.

Because the inline editing with combo boxes isn’t quite ready yet I’ve decided to write it
myself. In my case I had a number shown and when the user clicks on it a combo box
appeared.

How to do this:

I had a hidden combo box and a p tag that was shown.

Then a mouse click event that will hide the div and show the combo box. It’ll also gets the
value from the div and set the value of the combo box to that value.

Chapter: Dashboard Widget development 30


Olivier Janssens Sakai3 2009 - 2010

Then what is left is an event to show the div again and hide the combo box. This is done in
an onBlur event. This event gets triggered when the element looses focus .basically when
the combo box isn’t in focus anymore.

This function will also immediately save the data to jcr.

6.11.3 Deleting

Now the only thing left is deleting an object. This is fairly easy. Because every node (object)
has its own URL. You just need to do a post to that URL with an extra operation :delete.
Example:

Chapter: Dashboard Widget development 31


Olivier Janssens Sakai3 2009 - 2010

As you can see no data is passed, except for an extra operation. I’ve designed this function
so the user can delete several items at once when the clicks on the delete button, that’s why
the Ajax call is in a for each loop.

6.12 Summarize:

Ajax call Data gets Ajax call


Javascript Display data
stored in
code (PUT/POST) (GET) (js)
jackrabbit

Chapter: Dashboard Widget development 32


Olivier Janssens Sakai3 2009 - 2010

7 Prototype development
Now that the basics of Sakai have been explained it’s time for something more complex:
Prototype development. Prototype development starts with an idea. Someone has a great
idea to improve Sakai, so the concept has to be tested if it’s viable. In my case another
developer had an idea and had drawn a paper prototype. This was given to me and I was
asked to implement this.

Before explaining the prototype I should explain how the site part of Sakai works:

One of the features of Sakai is that a person can make his/her own site within Sakai. A site is
made via the “My Courses & Sites” widget.

Then when the site is made, the user can add pages to the site:

And here you can find the dashboard pages. A dashboard page is the homepage of the site.
Just like the Sakai dashboard.

Chapter: Prototype development 33


Olivier Janssens Sakai3 2009 - 2010

The paper prototype :

Chapter: Prototype development 34


Olivier Janssens Sakai3 2009 - 2010

Chapter: Prototype development 35


Olivier Janssens Sakai3 2009 - 2010

The prototype was designed to test a new way to build dashboard pages. The user basically
drags and drops widgets into the page. So even the title or text component are widgets. The
user should then be able to fill in details and save the page.

7.1 The file structure:

So the html file for the sitepages can be found at:

3akai-ux\dev\_skins\original\original.html

And the site_admin.js that contains all the logic about the site pages can be found at:

3akai-ux\dev\_javascript\site_admin.js

7.2 JQuery Accordion

So at the moment all the page functionality is in site_admin.js. I started with hiding the
element that weren’t necessary anymore:

Chapter: Prototype development 36


Olivier Janssens Sakai3 2009 - 2010

This is done by :

When this is done it’s time to add the menu. I’ve chosen to do this with the JQuery plugin :
Accordion. This is a plug-in with animation. How this works:

The user clicks on a title in the menu and underneath the title some space slides open and
there is text. If the user clicks on another title the previous space that opened gets closed
and another space gets opened.

Chapter: Prototype development 37


Olivier Janssens Sakai3 2009 - 2010

7.3 How this is done:

First of all the jQuery accordion isn’t included in Sakai so it needs to be downloaded. You can
quickly download it from the jQuery ui website.

HTML:

There has to be a top level element with a unique id. Then the titles of the accordion (in the
example they are black) have to be a tags. And then there should be a div with whatever
content you want. In my case it’s an ul.

7.3.1.1.1 Javascript:

When this is done the accordion will work. Some CSS is needed to make it look like this.

Chapter: Prototype development 38


Olivier Janssens Sakai3 2009 - 2010

7.4 Layout

One of the requirements of the prototype was that it would be possible to drag and drop
widgets into the layout. First of all a layout is needed. The first thing to do is to bind a click
event to the elements in the Accordion.

So there the blue item is clickable.

This is done by :

I’ve added an id to the list items so I can see which layout I should render.

Chapter: Prototype development 39


Olivier Janssens Sakai3 2009 - 2010

Now when the user clicks on a list item the id is retrieved. And based on this id the HTML is
rendered and appended to the page.

The render method here has a different name from the one used in the todo widget but they
work exactly the same.

The template that is rendered:

HTML:

JavaScript:

When the template is rendered it will look like this (again some CSS is required here):

Chapter: Prototype development 40


Olivier Janssens Sakai3 2009 - 2010

Other templates are quickly made and those will be rendered instead of the previous
template because $mainContentDiv.html() is used.

Chapter: Prototype development 41


Olivier Janssens Sakai3 2009 - 2010

7.4.1 Draggable and droppable plug-in

To make the elements in the accordion drag able I’ve chosen to use the jQuery draggable
plug-in and to make the layout drop able I’ve chosen to use the jQuery droppable plug-in.
I’ve chosen these 2 plug-ins because they’re made to work together and because they give
you a lot of freedom. You can use a lot of events for example before dragging, when
dragging, after dragging, just before dropping etc…

7.4.1.1 Implementation:

Javascript:

This is quite ugly javascript code a better way is :

$(‘li’,$dashboardSecondAccordeon).draggable({helper:’clone’});

This will make the list items drag able. Now the only thing left to do is to implement the
droppable plug-in so it can be dropped.

Javascript:

Html:

The main-content-div is the container where the templates are rendered for the layout. So
all the divs in this container are droppable.

When this is done the user can drag a list item and drop it in the layout. What is left to do
now? Well when the user drops a list item, a widget should be rendered because at this
moment only an list item will be placed in the drop able area and this is not what was
required. So first off all a widget has to be written. I wrote 2 widgets: 1 for the title

Chapter: Prototype development 42


Olivier Janssens Sakai3 2009 - 2010

And 1 for the text itself:

I’ll explain how the widget for the text works:

The widget has to have 2 modes. An edit mode and a preview mode. :

Edit Preview

7.5 Text widget

The textwidget has to be put in devwidgets and has a JavaScript, html and CSS file.

We’ll start by registering the widget in widgets.js :

As you can see very few options are required as this is a very simple widget.

The html (textfiel.html):

Chapter: Prototype development 43


Olivier Janssens Sakai3 2009 - 2010

The HTML exists of 2 parts, a part that is shown and a part that is hidden. The part that is
shown has a text area an input box so the user can enter a text size, 3 buttons. 1 to set the
text to bold, 1 to set the text to italic and 1 to switch to the other mode (save).

The hidden part exists of a p tag to display the text and a button to switch the mode and 1 to
delete the widget.

JavaScript (textfield.js):

So as before the widget has to have all the elements that were previously mentioned:

Chapter: Prototype development 44


Olivier Janssens Sakai3 2009 - 2010

Thought the placement isn’t necessary anymore.

Because of CSS only the edit part will be shown at the start the rest has display:none. The
edit mode has some buttons and a text field to change the text we’ll start with that:

The font size: This gets executed every time a key is pressed, that way the user can see the
result immediately and doesn’t have to press a button to submit. A brief explanation: the
$(this) object contains the object the user clicked on this is the italic button. So we need the
parent to get the “.textfield_edit_mode” div , the second parent isn’t really necessary. In
that div we need to find the textarea that’s why we do .find(). The .find is a jQuery method
that will search a certain html element or class or id in hierarchy underneath the given
element. This method is quite expensive so it’s better to do :

$(‘.dashboard_textarea’, this.parent())

Then some CSS is added via jQuery this is done by .css(css element, value). This is also a
jQuery method. The element that has to be changed is “font-size” and the value is gotten
from the text field.

Chapter: Prototype development 45


Olivier Janssens Sakai3 2009 - 2010

Bold: Instead of binding a click event to the button the toggle function is used. This function
is quite handy because it will execute the first function on the first click and the second
function on the second click and the first function again on the 3th click. So we don’t have to
write this ourselves. On the first click some CSS is added. This is just the same as before but
then instead of font-size it’s font-style. The same goes for italic.

7.5.1.1 The save:

The save method will first hide the edit div and then get the value of the text area and set it
in the p tag in the preview div. Then it’ll make an object with all the CSS that has been
chosen and set the CSS on the p tag and then it’ll show the preview mode.

7.5.1.2 The edit:

The edit method will get the text from the p tag and set it in the text area and then it’ll hide
the preview div and show the edit div.

The only thing left now is the delete:

Chapter: Prototype development 46


Olivier Janssens Sakai3 2009 - 2010

Because the “this” variable contains the just clicked button I needed to do parent 5 times to
get higher in the hierarchy. This way it’s possible to delete the entire widget.

7.5.1.3 Rendering the widget

When this is written the widget is done and we can go back to site_admin.js to write the
functionality to render the widget when the user drops the widget in the layout.

I’ve written a method that can be used and needs 2 parameters: where and what. So
“where” will be an html element where the widget has to rendered in and the what is the
parameter that contains the html element of what has to be rendered. To get these
parameters :

When adding the droppable plug-in we can use some options. One of these options are the
events. Here I’m using the drop event. This event is fired when an element is dropped. The
function that is executed on the drop has 2 parameters event and ui. In event you can for
example find where the element is being dropped. In ui you can find what is being dragged.
Ui.draggable is the element that is being dragged. This code first checks if the list item
contains something. If it does the text, and the element where it has to be rendered are
passed to “renderHTML”. I only pass text for the “what” because in renderHTML there is a
check to see what should be rendered.

Renderhtml:

The check is an if :

If the user has dropped the textwidget in the layout this code is executed. This code will
append some html to the “where” and then rendered the widget.

To render a widget a div with the id=’widget_widgetname’ is needed to know which widget
should be rendered.

Chapter: Prototype development 47


Olivier Janssens Sakai3 2009 - 2010

Then sdata.widgets.widgetloader.insertWidgets is called. This function can be found in


sdata. Sdata is one of the main Sakai core JavaScript files. All the general methods can be
found here.

The first parameter: Id of the HTML container in which we want to look for widget
declarations.

The second parameter: showsettings. This is irrelevant for this example because this
parameter is a Boolean that determines wither the widget is in settings mode is or view
mode.

The 3th parameter: where the widget data will be saved on the server.

After this code is executed a widget will be render on the layout:

All this is the same for the title widget.

7.5.1.3.1 Context menu:


A context menu is a menu that is shown when the user right clicks on something:

Chapter: Prototype development 48


Olivier Janssens Sakai3 2009 - 2010

How this is done:

The required library: jquery.contextMenu.js

7.5.1.3.2 Javascript:

Html:

The function has 3 parameters:

Action: Which element that has been clicked for example “title”

El: where the right click has happened

Pos: where (x and y position) the user has been clicked.

Chapter: Prototype development 49


Olivier Janssens Sakai3 2009 - 2010

Here the renderHTML is called again, so here you can see that the method is reused.

7.6 Implementing other widgets

This prototype is designed to test a new way of making dashboard pages. One of the
features of a dashboard page is that the user can use any widget in Sakai in it. To illustrate
this we’ll get the RSS 29and googlemaps widget working in the dashboard pages. The only
difficulty here will be that those 2 widgets are normally site widgets and have 2 modes. An
edit mode and a view mode. The edit mode (settings mode) is triggered by changing a
Boolean. This Boolean is in the definition of the widget ‘showSettings’.

Most widgets check if this Boolean is true or false in the init function. IF it’s true the setting
part of the widget is rendered and if it’s false the view part of the widget is rendered. The
developer has no control over this Boolean though. Because it’s set accordingly where the
user is. So if the user clicks on show settings the widget is loaded and the Boolean is true.

RSS widget normally In Sakai:

Settings View

So now in the dashboard prototype:

Javascript:

29
most commonly expanded as Really Simple Syndication) is a family of web feed formats used to publish
frequently updated works

Chapter: Prototype development 50


Olivier Janssens Sakai3 2009 - 2010

Just like before because of the id, the right widget will be generated. The reason why I don’t
use JST here is that the quality of the code isn’t that important. It’s more important that the
prototype is made quickly. A few CSS changes are required here.

Chapter: Prototype development 51


Olivier Janssens Sakai3 2009 - 2010

Edit View

As you can see it’s very easy to adapt widgets to work in the dashboard pages. Now the only
thing left is to implement the functionality so that the widgets can be dragged and dropped
from column to column.

7.6.1 Sortable plug-in

Now to make this items draggable I’ve chosen use the jQuery sortable plug-in. I’ve chosen
this plug-in because it automatically will put everything nicely into place. The normal
draggable and droppable plug-in will not do this.

This plug-in is designed to give the user control over their own lists. So they can sort their list
by drag and drop: example:

Chapter: Prototype development 52


Olivier Janssens Sakai3 2009 - 2010

But as you can see this wouldn’t be handy for the dashboard drag and drop functionality. But
luckily this plug-in has an extra option: connectwith. This option will allow the user to
connect 2 lists and it’ll allow drag and drop between those lists. Example :

So this will allow the user to drag widgets from one column to another.

How this is done:

First of all a new library is required because the sortable library isn’t in Sakai yet.

JavaScript:

This will make the unsorted list sortable. Some options you can add here are:

Revert : If the user doesn’t drop the item where it’s supposed to be it’ll just return to its
original spot.
connectWith: This parameter will allow 2 lists to be connected, so that the user can drag
from 1 list to another. The 3 columns have the same class so the class can be used here.

Other options that aren’t used but could be really handy:

Containment: The user won’t be able to drag the item outside the containment. The
standard value is the body. But in site widgets it’s handy to set the containment to the rootel
( the widget itself).
AppendTo: When an item is being dragged it will always append itself to an element higher
in the hierarchy. Normally this will be the parent. But when there are problems with the z-
index it might be better if it’s appended to the body while being dragged.

Chapter: Prototype development 53


Olivier Janssens Sakai3 2009 - 2010

Though this is a very nice jQuery plug-in, it isn’t that very handy for this purpose. When I
implemented this I often noticed that the drop wasn’t very smooth. I always had to search
where to drop it exactly: But because this is a prototype and not a version that will be used it
doesn’t matter. The prototype is just to illustrate how it should work:

Chapter: Prototype development 54


Olivier Janssens Sakai3 2009 - 2010

8 Site widgets development


Another great part of the sites are that a user can create a normal page and add site widgets.
There are a wide variety of widgets like the googlemaps widget, RSS widget, discussion
widget etc.

The Site part of Sakai is very handy. Because teachers, professors, lectors will be able to
setup up a Site very fast. And on this site they’ll be able to add discussions, polls, videos,
images without knowing anything about HTML.

Chapter: Site widgets development 55


Olivier Janssens Sakai3 2009 - 2010

8.1 The flickr Widget

Like explained in the previous chapter every site widget has 2 modes the edit mode and the
view mode.

I was asked to make a site widget that interacted with the photo sharing site “flickr”. This
widget should give the user the ability to get pictures from a user and view their friends and
get pictures by filling in a tag. I’ve chosen to allow a user to compose a gallery by drag and
drop. This chapter will explain how to flickr widget is build, this means that there is more
information about drag and drop and also quite a lot of information about usability because
of caching.

8.2 Registering the flickr widget

New options:

I18n: internationalization, these json files are all the string in the html that need to be
translated.
img: The image that is shown in the edit mode of the site :

Chapter: Site widgets development 56


Olivier Janssens Sakai3 2009 - 2010

Now that the widget is registered the usual html, JavaScript and CSS files are required. First
of all how the widget will work : A user will be able to enter a name or email from a user and
then the pictures will from that user will be displayed in the widget. Then the user will be
able to make his or her own gallery by dragging and dropping the images from the gallery to
a sidebar. Then the user will be able to save the gallery and this will be put on the site itself..

This plug-in works with the Accordion plug-in so a quick implementation:

Chapter: Site widgets development 57


Olivier Janssens Sakai3 2009 - 2010

This is just the same as in the prototype development chapter.

The options here :

Clearstyle: If set, clears height and overflow styles after finishing animations. This enables
accordions to work with dynamic content.

Alwaysopen: Sakai switched to jQuery 1.4 and in jQuery 1.4 this is deprecated

Active : Set true if a tab should be open

When this is done the widget should look like this :

Now some input fields and buttons should be added so that the user can fill in a name or an
e-mail address.

To request the pictures from a person we’ll need to do an ajax call to a proxy file.

8.3 What is a proxy file ?

A proxy service is an intermediate for doing cross-domain calls.

Chapter: Site widgets development 58


Olivier Janssens Sakai3 2009 - 2010

8.4 Why use a proxy file ?

A proxy file is required because cross-domain calls are nearly impossible, this is because the
XMLHttpRequest object is prevented from calling websites from outside its own domain. The
xmlHttpRequest is an active control and was first used in IE5. The xmlHttpRequest can’t do
cross-domain calls because it could just call a script in one place and then call another script
on another server and it could leave an application open and that in turn could be affected
by all sorts of malicious scripts, hacks and exploits.

8.4.1 How this is done

So for example: When you want to request pictures from flickr you have to do :

http://api.flickr.com/services/rest/?method=flickr.people.getPublicPhotos&api_key=e1ad8a
2c0cdcad2a3263b904e4a901ad&user_id=48506601%40N03

But when using a proxy service a call is done to : http://localhost:8080/getPublicPhotos.json

So instead of doing a direct call to another domain, a call is done to a service in the back-end
on the same domain which will then do the call.

getPublicPhotos.json will look like this :

Options :

sling:resourceType : sakai/proxy (defines in sling that this is a proxy file)

sakai:request-proxy-endpoint : The URL where you want to do a proxy request to

sakai:request-proxy-method : Define which HTTP method you want to use GET / POST / PUT
/ OPTIONS / HEAD

sakai:title The title of your proxy service

sakai:description The full description of your proxy service.

sakai:shortDescription A short description about what the proxy does.

Chapter: Site widgets development 59


Olivier Janssens Sakai3 2009 - 2010

sakai:parameters The parameters you can use, also define which parameters are required
require
or optional

So this file gets added to the back-end.


back

8.4.2 How to deploy a proxy service

The file should be added to


open-experiments/slingtests/osgikernel/bundles/proxy/src/main/resources/SLING
experiments/slingtests/osgikernel/bundles/proxy/src/main/resources/SLING-INF/content/var/proxy/
INF/content/var/proxy/

Then connect to the server (this can be done in finder by doing cmd + k) and remove:
/var/proxy/

Then redeploy the proxy bundle


cd open-experiments/slingtests/osgikernel/bundles/proxy/
experiments/slingtests/osgikernel/bundles/proxy/

mvn clean install –Predeploy

Because
ecause of OSGI modules it’s possible to redeploy
redep parts of the back-end
end without restarting
the back-end

8.4.2.1 Calling the proxy

The workflow:

• Fill in username or password

• Request user details (the userid is


required to get the pictures of a person)

• Request the pictures based on the userid

To do this 3 proxy files are required.

Get the userdetails based on the username:

Chapter: Site widgets development 60


Olivier Janssens Sakai3 2009 - 2010

Get the userdetails based on the email:

And then get the pictures based on the userdetails:

Deploy these proxy files like described before

Chapter: Site widgets development 61


Olivier Janssens Sakai3 2009 - 2010

8.5 How to make an image gallery with caching.

How the flickr API works: For example the user has 300 pictures, when you do a call you
have to specify how many images you want to have at once, for example 5. Then which
page. So if you request the first page you’ll get the first 5 of the 300. If you request page 2
you’ll get pictures 6 -10 and so on.

So one of the options is to display 5 pictures and when a user clicks next just request the
next five pictures. And then when previous is clicked request the previous ones. But the
stupid thing here is that you’re requesting images that you already requested previously. So
a better option would be to keep these and display them when they’re requested. To
illustrate:

The first request will be to get 10 images. The first 5 will be shown and the next 5 will be
hidden. So when the user clicks on next that the user doesn’t have to wait.

So here you can see the 10 images and only 5 are shown.

S = Shown

H= Hidden

Then when the user clicks on next the next 5 will be shown and the previous 5 hidden.
During this switch 5 new images will be requested and those will be hidden.

Like described before every 5 images are a page. So at the start 2 pages are loaded and page
1 is shown. Then when the user clicks next 3 pages are loaded but only page 2 is shown. This
goes on and on until for example all the images are loaded. Then when the user clicks on
previous the previous page will be shown and the current page will be hidden. In this case
there won’t be any requests anymore. This will increase the user experience of the image
gallery.

How this is done in code:

The start:

Chapter: Site widgets development 62


Olivier Janssens Sakai3 2009 - 2010

So this function will do an Ajax call to the proxy file. The parameters are userId (to get the
pictures from a user). Then the api_key , you can get this from the flickr website and this is
specified in a config file in the back-end. The page (this is 1 because it’s the start). And then
per_page. So here is specified that 10 images will be requested at once. Since I’m only
displaying 5, these are 2 pages.

In the success of this Ajax call the function showPicturesFromPersonStart is called and the
response is passed to this function. In this function the gallery will be rendered:

Explanation:

- $flickrKeyPersonGallery.children(‘ul’) is just a div with a unordered list.

Then the template :

And the data: here the function makeImageGallery is called. This function will basically build
an image source based on the attributes of the picture object that is found in the response.

The url looks like this:

Chapter: Site widgets development 63


Olivier Janssens Sakai3 2009 - 2010

When this is done 10 pictures are displayed. Now the only thing left to do is hide the 2nd
page of images.

$(‘img’,$flickrKeyPersonGallery) will get all the images in the gallery (10 images).

Then a slice is done; a slice works like this .slice(start,end). So basically the first page has to
be shown so here its: .slice(0,5). And to illustrate in with some filled in values:

$(‘img’,$flickrKeyPersonGallery).slice((1 – 1) * 5,(1*5)

So now the first 5 images are shown.

8.5.1 Next:

On the next click an Ajax call will be done to get the next 5 pictures:

Chapter: Site widgets development 64


Olivier Janssens Sakai3 2009 - 2010

So in this case page will be 3.

On the success showpicturesFromPerson is called and the response is passed.

Then the 5 images are appended to the gallery:

Then the page that is shown will be hidden and the next 5 who have previously been loaded
will be shown. So for example the user was on page 1 and clicked on next. Then page 3 will
be added (so now there are 15 images in the gallery). Page 1 will be hidden and page 2 will
be shown.

To illustrate: $(‘img’,gallery).slice((1 – 1 ) * 5, (1 *5)).hide()  is in fact slice(0,5).

Chapter: Site widgets development 65


Olivier Janssens Sakai3 2009 - 2010

To illustrate: $(‘img’,gallery).slice(1 * 5, (1 + 1) *5)).show()  is in fact slice (5,10)

8.5.2 Previous:

Previous is very similar to the next, but there is 1 difference. No Ajax call is required
because the previous images are already on the page but there just hidden. So the code is:

To illustrate:

$(‘img’,$flickrKeyGallery).slice((2 – 1 ) * 5, (2 *5)).hide()  is in fact slice(5,10).

$(‘img’,$flickrKeyGallery).slice((2 – 2 ) * 5, ((2 – 1) *5).hide()  is in fact slice(0,5).

The only difference here is that the current page is 2 instead of 1 because the user is on page
2 obviously.

8.6 The difficulties:

When the user has been through the gallery and back for example: there were 10 pages and
the user has been to page 10 and back to page 1. In this case all the images are loaded. So
when the user clicks on next no request should be done to get the next images because
they’re already loaded. So a check is required, this line will also include a check to see if the
user is on page 9. In this case no Ajax has to be done either:

if ((($('img', $flickrKeyGallery).slice(((currentPageKey + 1) * 5), ((currentPageKey + 2) *


5)).length) && (($('img', $flickrKeyGallery).slice(((currentPageKey) * 5), ((currentPageKey + 1)
* 5))).length)) || (currentPageKey + 1 === totalPages))

So for example the user is on page 3 and all the other pages are loaded: This will check if
page 3 + 1 and page 3 + 2 exists. If they both exist, no Ajax call is done.

Chapter: Site widgets development 66


Olivier Janssens Sakai3 2009 - 2010

8.7 Second image gallery

All of the above was an explanation how to get the public pictures of a person. Now to get
the pictures tagged by a keyword. (e.g. Type in flower and you get pictures of a flower)

This is very easy since there’s only 1 function that has to be called.

http://api.flickr.com/services/rest?method=flickr.photos.search

So again a proxy file has to be created for this method. The extra parameter here is the tag.

The rest is exactly the same to display the pictures. So a lot of code can be reused here.

8.8 Drag and drop

Illustration:

The drag and drop is fairly easy to implement. Here I’ve chosen to implement the sortable
plug-in again. Other good solutions would be the reorder plug-in from fluid infusion. (This
one is used on the Sakai dashboard, it’s very similar to the iGoogle page).

Chapter: Site widgets development 67


Olivier Janssens Sakai3 2009 - 2010

The only thing that has to be added here is the sidebar. The sidebar is just a div with an
unordered list in it.

Then the plug-in implementation:

The object:

With these options the user is only allowed to drag images from the horizontal bar and not
the other way around.

It’s very easy to implement this but there are some difficulties related to this:

If the user drags and drops an image only 4 images are displayed in the gallery. So when the
5th image is dropped the previous 4 should be hidden and the one that is dropped should be
shown. This isn’t that difficult either. But the real difficulty is in that when all the from a
normal gallery are dropped into the sidebar, this means that there are no images left to fill
up the empty space so an Ajax call has to be done to get new images. And this has to be in
sync with the paging.

Chapter: Site widgets development 68


Olivier Janssens Sakai3 2009 - 2010

To illustrate:

You can see here that there’s an empty space in the gallery, this should be filled.

Chapter: Site widgets development 69


Olivier Janssens Sakai3 2009 - 2010

8.8.1 How this is done:

This function is executed when the image is dropped. The function to focus on is
droppedImage

The first check is that the user is on the last page. If the user is on the last page the next and
previous button should be hidden.

The second check is to see if the next page exists (and any images left on that page).

The length can vary from 0 to 5. If it’s greater than 5 the next image should be shown.

To illustrate: $(‘li’,imageGallery).slice((2*5) – 1, (2 * 5). This will select the 10the image. This
might be confusing since an image just has been dragged so you might think the 11th image
should be selected. But this is not true, since the sortable plug-in deletes the images from
the gallery where it has been dragged rom. So the 10th image is the next image in this case.

Chapter: Site widgets development 70


Olivier Janssens Sakai3 2009 - 2010

So now 5 images are shown again. The only thing left to do now is update the total amount
of pages. Because this can change when a user drags a lot of images.

If the 2nd check is false (this means there are no images left to display) new images should be
requested.

Important:

The only difference here is that another variable is used for the page. In the Ajax call for the
next the currentpage was used. But this parameter is in sync with the page you get from
flickr. But the newPage is in sync with the page that is displayed. So you can be on page 2 in
the gallery. But in fact you are on page 6 of flickr. This happens when a lot of images have
been dragged. It’s very important to see the difference between the images that have been
requested and those who are displayed to get the paging right.

Then this function is executed:

This function will append the just requested images to the gallery and show the first one of
those 5. Because only the next 5 are added to the gallery the next will still work like it
should. Even a better thing to do there is to get the next 10 pictures. Then the user wouldn’t
experience no delay at all.

Chapter: Site widgets development 71


Olivier Janssens Sakai3 2009 - 2010

8.9 Sidebar gallery

At this point it’s possible to drag images into the sidebar. But they would just stack. So a
gallery is required here too. This is done in the checkAmountImages function that is also
called on the drop.

How this works:

First of all there is a check. This is too see if paging should happen. Only 4 images are
allowed to be displayed at once. So when image 1,2,3 or 4 are dropped no paging should
occur. But when the 5th image is dropped the previous 4 should be hidden the current page
and total pages should be incremented and the 5th image should be displayed.

Then there is another check. Because when the user has dropped a lot images and start
paging the user can drop images wherever he/she wants. At this moment I’m going assume
the user allows drops an image on the last page. Another check is required here :

This is to make sure that the user is on the last page. ( For example page 1 of 1, or 2 of 1).

At this point it’s known that the user is on the last page and that more than 4 images are
dropped. So the 4 images that are displayed should be hidden

A second page is created now, the paging elements should appear on the page. This only
may happen once so this is checked by a Boolean. If it’s the first time a page is created (More
than 4 images are dropped) the paging will be rendered and the current page and total
pages have to be incremented

Chapter: Site widgets development 72


Olivier Janssens Sakai3 2009 - 2010

Because the current page and total pages are 0 at the start they have to be incremented
again.

This was the easy part because at this point it’s know what will happen. But now comes the
tricky part. E.g : When the user has dropped a lot of images and there are 6 pages in the
sidebar, but the user is on page 1. At this point 4 images are displayed and it’s possible to
add pictures to this. I chose to solve this by hiding the last image.

To illustrate :

Chapter: Site widgets development 73


Olivier Janssens Sakai3 2009 - 2010

So in this case the user drops the image in between image 2 and 3. Because of this picture 3
will become picture 4 and the dropped picture will become picture 3. And picture 4 will
become hidden.

This is done by:

Chapter: Site widgets development 74


Olivier Janssens Sakai3 2009 - 2010

This code will loop over the list items and check if they are shown. Then save the last shown
image. If there are more than 4 images shown, that last image that just has been stored will
become hidden. And because of this a new page will be created.

8.9.1 Next and Previous:

The next and previous are just the same as in the previous galleries. The only difference here
is that there are only 4 images displayed.

8.10 Delete

The sidebar is a representation of the images that will be saved. These images will be
displayed in the site part of Sakai. So this implies that all the CRUD operations should be
implemented. I’ve chosen to implement the delete as followed: When the user hovers over
an image in the sidebar a little x appears in the upper right corner:

How this is done:

On the mouseover:

Chapter: Site widgets development 75


Olivier Janssens Sakai3 2009 - 2010

The x (an image) is rendered and appended to the image. Then a click is bound to the image
so that it’s possible to delete the image.

Then the mouse out :

Here a check has to be done if it exists. If it does, the image is removed.

The delete is quite tricky because if a user deletes an image while they are on page 1 of 4
another image has to be displayed:

So the first thing that will happen is the deletion of the parent of the x image (since it’s
appended to image).

Then the code will loop over all the images and check which ones are visible and get the last
visible image.

Then a check is done to see if there are any visible items left, if there are more than 0 left an
image will be displayed else 4 will be displayed at once, this happens when the user has

Chapter: Site widgets development 76


Olivier Janssens Sakai3 2009 - 2010

deleted all the images that are displayed, you can compare this to clicking on the previous
button.

When the user is on page 1 the paging will be hidden too.

At this point the flickr widget is almost done. 1 thing is left to do : Save the images and
display them in the site.

8.11 Saving

The save functionality is triggered when the user clicks on submit. The save functionality is
very similar to the save functionality in the todo widget.

This code will loop over every image in the sidebar and make an object of it. The objects get
stored with a unique id.

Then the new save method in Sakai is called to save the data:

Chapter: Site widgets development 77


Olivier Janssens Sakai3 2009 - 2010

8.12 Rendering the gallery in the site

When the widget is loaded a Boolean is passed. To see in which view the user is. The settings
or the view mode. In this case the user will be in the view mode:

Then an Ajax call is done to get the images from the server, this is done with a new function
in Sakai.

On the success a gallery will be rendered. This is just the same as in the settings view. The
only difference here is that no Ajax calls are required because all the images are already
loaded.

The result looks like this:

Chapter: Site widgets development 78


Olivier Janssens Sakai3 2009 - 2010

Here you can also see that there are little icons underneath the image gallery. These allow
the user to visit the flickr site of the picture itself. These images get rendered together with
the gallery. Then a click is bound to them. On the click the user gets redirect to a URL based
on the picture id.

This is the entire flickr widget. The widget is complex and took me about a month to make. It
has around 2000 lines of JavaScript code and is currently in the Master branch of Sakai.

Chapter: Site widgets development 79


Olivier Janssens Sakai3 2009 - 2010

9 Sakai Site Skins


I’ve already talked about the site part of Sakai. This is where users can create their own sites
within Sakai. It’s also possible to create skins for these sites. Sakai currently has 2 skins. 1
default one and one for the Cambridge University. It’s possible to change these skins in the
site appearance part.

It’s also possible to make your own Skins.

9.1 Creating a Skin

Creating a skin isn’t very user friendly, and this is not done so often. I was asked to make a
skin for the Cambridge Integrated Knowledge Centre. This is the engineering department of
the university. The skin wasn’t a working version but it illustrated how it would look. It also
gave the people from the CIKC an overview how easy it is to edit content within Sakai.

Chapter: Sakai Site Skins 80


Olivier Janssens Sakai3 2009 - 2010

9.2 How to start

I started by adding an extra skin option to the site appearance page. To do this a new folder
has to be created under /dev/_skins. In this folder there has to be a html file, a logo
(cikc.png) and 2 folders. In these 2 folders the CSS files and images are stored.

To do this I copied the original skin from Sakai and renamed the files.

Now the only thing left to do is register the skin in config.js. This file can be found under
dev/_configuration/

Here these lines have to be added:

When this is all done you’ll be able to see the skin in Sakai. And you’ll be able to switch
between skins. Now you can edit the cikc.html however you like to make the site look like
you want. I won’t describe how I did this because this was just a minor JavaScript changes
and a lot of HTML and CSS changes.

End result:

Chapter: Sakai Site Skins 81


Olivier Janssens Sakai3 2009 - 2010

Chapter: Sakai Site Skins 82


Olivier Janssens Sakai3 2009 - 2010

10 Bugs in Sakai
Like every project, Sakai has some bugs. When a developer discovers these bugs they report
them on a site 30. Then developers can assign these bugs to themselves or others.

When fixing a bug a new branch is required and when the bug is fixed the branch should be
merged into your own master. This is done by :

Git checkout master

Git merge <branch name>

When this is done a pull request can be made to the lead of the UX code. By doing this you
ask the lead to merge your master branch into his master branch. Which is the main UX
repository. This can be done on Github.

This is a very handy way of solving bugs, because of this no one will try to solve the same
bug. And when you’re not able to solve it you can un-assign yourself. It’s also a good way to
keep the master branch of the UX code clean.

30
http://jira.sakaiproject.org

Chapter: Bugs in Sakai 83


Olivier Janssens Sakai3 2009 - 2010

11 Mac Widgets
Sakai is not meant to be accessible only by a site. It’s meant to be much bigger than this.
There for I was asked to develop a widget for the Mac dashboard. This is how the Mac
dashboard looks like:

The dashboard is an application for Mac. It’s used to host little applications known as
“widgets”. This was first introduced in Tiger. It’s a semi transparent layer that is invisible to
the user unless activated by clicking its icon in the dock. These widgets can be moved around
freely around the dashboard.

These widgets have some neat effects. They can flip. So you can see the front and the back
of a widget. And when a widget is placed on the dashboard there’s a ripple effect.

Chapter: Mac Widgets 84


Olivier Janssens Sakai3 2009 - 2010

I was asked to make a widget that would interact with Sakai. I had to implement
functionalities
es like: recent messages, profile and chat.

11.1 How to start developing


develop a Mac widget

A Mac widget is built in HTML, CSS and JavaScript. So this isn’t very different from the
standard widgets in Sakai. The only thing that has to be added is a .plist 31file. Plist
Pli files are
files that store serialized objects. They are used to store user’s settings, information about
bundles and applications. A plist file can be compared to an XML file.

So the file structure of a Mac


ac widget looks like:

My Sakai

mySakai.html

mySakai.css

mySakai.js

Default.png

icon.png

My Sakai.plist

As you see 2 images are required too. 1 image that’ll determine the size of the widget (the
background image) this is default.png. And then there’s the icon.png. This icon will be used
displayed when the user wants to add a widget. (At
( the bottom of the dashboard).

31
property list file

Chapter: Mac Widgets 85


Olivier Janssens Sakai3 2009 - 2010

The plist file:

Explanation: A key is as a property and a value can be given to the property. For example:
here you have AllowFileAccessOutsideOfWidget. This property will allow or decline access to
other files. I had to put this on true because I needed to access the Sakai JavaScript files.

Then you have AlllowNetworkAcces, this was required too because I had to be able to access
an up and running Sakai on the internet. Else the widget would be pretty useless. Then there
are some other properties which explain themselves and are not that important.

When all files are created it’s time to show some html and JavaScript.

11.2 Accessing Sakai from a Mac widget

A normal Widget in Sakai runs inside the Sakai domain. 32. But a Mac widget isn’t it this
domain. It’s run from a local machine. 33. So when this widget is run no core Sakai JavaScript
files are loaded. There for I needed to load them myself dynamically. I’ve chosen to do this in
a separate JavaScript file because I had to reuse this code later on for my Windows 7 widget
and iGoogle widget. But more on that later on.

First of all I defined the domain at the top of the JavaScript file, so that when the widget is
deployed a developer can easily change the domain to their running Sakai domain34.

32
http://localhost:8080/devwidgets/widgetname
33
C://Users/oj218/Sakai/3akai-ux/devwidgets/mac
34
E.g: www.3akai.sakaiproject.org

Chapter: Mac Widgets 86


Olivier Janssens Sakai3 2009 - 2010

When this is defined I made a 2 dimensional Array of the URLs and the kind of files they are
(css or js).

When the array is constructed it’s time to load them. They are loaded by just adding a script
element to the HTML file. The tricky part here is that they have to be added synchronously
because if they are added asynchronously it’s possible that 1 file that is loaded is dependent
on another file that isn’t loaded yet. And then there will be errors.

Chapter: Mac Widgets 87


Olivier Janssens Sakai3 2009 - 2010

So first of all I create an object of the head element. This is all done in JavaScript because the
JQuery library isn’t loaded yet. Then there’s a check to see if it’s a JavaScript file or CSS file.
Because the CSS files have a different tag and because the CSS files are allowed to be loaded
asynchronously because they haven’t got any dependencies.

Then a script or link tag is created and the required properties are filled in. Now the only
thing to do is append them to the page. Here’s where I make it synchronously. Because the
next script tag is only created when the recently script tag is fully loaded.

Then the counter is incremented so the next URL is used and here’s also a check to see if it’s
not the last URL in the array.

After this all the JavaScript and CSS is nicely loaded.

Chapter: Mac Widgets 88


Olivier Janssens Sakai3 2009 - 2010

11.3 Log-in

When I started working on this widget I planned on using the Sakai log-in.
log in. The log-in
functionality in Sakai uses a cookie, unfortunately cookies are not allowed in a Mac widget.
So another solution had to be found. The solution: The user would surf to SakaiSak and login. In
Sakai he/she would generate a token. This token has to be copied and then pasted in the
Mac widget. This token has to be placed in a new header field in every request done to the
back-end,
end, so that that the back-end
back can see that it’s an authorized
horized request. Workflow:

• Go to Sakai & Login

• Generate a token & copy it

• Fill in the token in the Mac Widget

Example :

Because there is no official login system in the widget (except for getting a token, but this is
outside the widget), I could immediately skip to getting the recent messages. When the
users fills in a token a clicks on the submit button the recent message are requested from
the server.

Chapter: Mac Widgets 89


Olivier Janssens Sakai3 2009 - 2010

11.4 Recent Messages

As you can see the recently filled in token is passed to this function. Then some parameters
are required.

- Box : Which box to check (inbox, outbox)


- Category : These can be invitations, messages, chatmessages
- SortOn
- sortOrder

These parameters are put in 1 object via the jQuery param method. This method creates a
serialized representation of an array or object. This is suitable for use in a URL query string or
Ajax request.

Then the Ajax call:

URL: This URL is specified in the configuration file of Sakai.

beforeSend: This is an event that is triggered just before the Ajax call is done. In this function
I create a new request header with the name of “x-sakai-token” and the value is the token
that the user copy pasted in the widget. By doing this the Ajax call will be authorized.

success: The rendering of the recent messages.

The display of the recent messages is pretty straight forward. First there’s a check if more
there are more than 7 recent messages. If there are , only the last 7 will be kept in the array.

Chapter: Mac Widgets 90


Olivier Janssens Sakai3 2009 - 2010

Then the template is rendered with this array by JST. Because some of the titles from the
message are too long, they have to be shortened. I do this by replacing all the chars after the
40th char by “...”.

The html:

JavaScript:

Chapter: Mac Widgets 91


Olivier Janssens Sakai3 2009 - 2010

11.4.1 Displaying the message

Now that all the titles are displayed it’s time to display the message itself. I allow the user to
see the entire message by clicking on the title. This is fairly easy to do. I’ve added the
message to the list item but it’s hidden. When the user clicks on the title I hide all the recent
message and get the title and message from the HTML. I put this text in an object an render
it in the html.

I also add a scroll bar, the reason I don’t use the standard overflow:auto; this is because the
apple scroll bar look much nicer.

The end result:

Chapter: Mac Widgets 92


Olivier Janssens Sakai3 2009 - 2010

11.5 The widget flip

One of the visual effects of the Mac widget is the “flip”. This flip allows you to use the front
and backside of the a widget. This is done by a few apple JavaScript libraries.

The code :

This code is provided by apple and I just optimized it. These functions use functions of the
apple libraries to hide the front for example and show the back and meanwhile do a
transition. These functions are called on the submit (when entering a token). And then
there’s a button in the right top corner to flip it whenever the user wants.

Chapter: Mac Widgets 93


Olivier Janssens Sakai3 2009 - 2010

11.6 Profile information.

The recent messages are done now, another aspect that seemed nice to add to the widget
was to allow the user to see his/her profile information. This is fairly simple. The first thing to
do is make an Ajax call to get the profile information:

As you can see here I’m not doing “var getProfileInformation = function(), instead I’m using
JavaScript name spacing just like in Sakai. I’m doing this because I created a file for every
functionality that is present in the widget. All the functions that are called from another
JavaScript file are done by namespacing. This is because else if there are other JavaScript
files with the same names for functions, the wrong one might be called.

Every big website uses namespacing (e.g. facebook). This is very handy, because it’s looks
similar to object orientated programming. How it looks in DOM inspector in firebug:

Except for the namespacing this is a common Ajax call to system/me with the extra header
that is required to do authorized calls.

Chapter: Mac Widgets 94


Olivier Janssens Sakai3 2009 - 2010

Because during my internship jQuery was updated I don’t have to do evalJSON anymore to
convert the string that is in JSON format to an object. This is done by jQuery now before the
data is returned to the front-end. This is only done if the content-type is application/json in
the response:

When the object is passed HTML is rendered by JST. Now the profile information is
displayed.

End result:

11.7 Chat

Another functionality I was asked to implement was the chat functionality. Currently there’s
a chat in Sakai and it can be compared to the Facebook chat.

This chat works with a polling mechanism. This means that you have to poll every other
second to check if there are chat messages. This is quite an expensive operation that’s why
in Sakai, you have first have to poll another service to see if there’s a chat message and then
do another request to get the chat message.

I started by getting the online users.

Chapter: Mac Widgets 95


Olivier Janssens Sakai3 2009 - 2010

This Ajax call is done every 5 seconds. The data that is returned contains all the contacts.

Then based on this data object a template is rendered, this template will show a number of
how many people that are online. Not yet the online contacts themselves.

Then an array is constructed of all the online users, because some of the users can be online
and displayed offline. Or just be offline.

Then a template is rendered with all the online users. If there are no online users the chat
isn’t rendered.

Chapter: Mac Widgets 96


Olivier Janssens Sakai3 2009 - 2010

Here the click events are bound too. A click to show and hide all the contacts. And a click on
the user itself to start a conversation with the user.

Now to start a chat. This is done in the function “startChat”.

This function will open a frame in the chatbar where the chat message will be shown and
where the user can type a chat message. Here a check has to implement so that there only
can be 1 chatframe for every user. If there’s no conversation open yet. One should be
created. But here we have to make sure that the frames don’t stack so to solve this. I get all
the current conversations and multiply this by 150 (the width of a chat frame) and assign this
value to the left property of the recently rendered chat window.

When this is done an actual conversation can be started. The user can enter a message in
the textbox now and press enter to send a message. This is done by binding a keypress event
to the textbox. Then a check has to be done which key has been pressed. If it’s an enter the
message can be constructed.

Chapter: Mac Widgets 97


Olivier Janssens Sakai3 2009 - 2010

Now some data has to be gathered. First of all to whom the message have to be send. This
can be found in the HTML of the chat box.

Then the text (messages itself):

Now to be able to let the back-end store the message we have to put it in a certain format.

There’s nothing special about this, and the properties are quite clear. This format is used for
every kind of messaging in Sakai ( invitation, message, chat). Because this is a chat message
no subject has to be given.

When this is done it can be send to the back end.

Chapter: Mac Widgets 98


Olivier Janssens Sakai3 2009 - 2010

The URL will look like 35. The data that is returned is the chat message itself. So this has to be
appended to the chat box.

This function will check if the chat box exists and then render a chat message in HTML. This
message will be appended to the chat box.

Now a chat message has been sent. Now it’s time to receive the chat messages.

This is done by the function checkNewMessage. This function is called when the user has
friends online. This function is executed every 3 seconds and it checks if there’s an update.

35
http://localhost:8080/_user/admin/message.create.html

Chapter: Mac Widgets 99


Olivier Janssens Sakai3 2009 - 2010

The response will look like this:

Only if the update is true another Ajax call is done to get the chat message.

This function will get the unread chat message from all the online people. (Can be found in
the previously constructed array). The max amount of chat message is 1000.

Chapter: Mac Widgets 100


Olivier Janssens Sakai3 2009 - 2010

When these are gotten the template is rendered. Because every chat message is returned a
check has to be done; For example if you are logged in as admin and send a message to
another user. This message will be returned too. But instead of from :Admin the html has to
show send from “me”. There for another check :

Then the message has to be appended to the html:

Chapter: Mac Widgets 101


Olivier Janssens Sakai3 2009 - 2010

As you can see here, a check is done, to see if the chat window is already open or not. If it
isn’t a new one should be rendered. This happens in “getUserInformation();. This function
will get the profile information and then render de html.

The same render function is called here as in the previous part where the user starts a
conversation.

The end result:

Chapter: Mac Widgets 102


Olivier Janssens Sakai3 2009 - 2010

Now to allow the user to have multiple conversations at the same time I’ve chosen to
implement paging.

The paging can be compared to the paging in the flickr widget. The only difference here is
that the paging only shifts 1 chat frame.

Some explanation: on the previous I show the next chat windows, shift the position of the
2nd window and hide the first one. For the next it’s the other way around. The checkpaging()
will then check if any arrow should be hidden or not.

End result:

Chapter: Mac Widgets 103


Olivier Janssens Sakai3 2009 - 2010

The only thing left to do now is the delete functionality. The special thing about the delete is
that the windows have to move dynamically. So for example if the left chat window gets
deleted. Then another window should be shown if there is any. If there is no window left.
The right one should shift into place.

The code:

Chapter: Mac Widgets 104


Olivier Janssens Sakai3 2009 - 2010

The comments in the code speak for themselves. It’s basically a check to see if the first or
second chat frame gets deleted. Then there are checks to see which chat windows should be
shown. When this is done the Mac Widget is completely done.

Chapter: Mac Widgets 105


Olivier Janssens Sakai3 2009 - 2010

12 Windows 7 widget
Apart from the Mac widget I was also asked to make a windows 7 widget. These widgets
don’t run in a special application but just on the desktop. They have a very similar file
structure to the Mac widget but instead of a plist file they have an XML file.

W7
w7i.html

w7.css

w7.js

Default.png

icon.png

gadget.xml

The xml file :

Chapter: Windows 7 widget 106


Olivier Janssens Sakai3 2009 - 2010

The xml has the same purpose as the plist file in the Mac widget.

The same file like in the previous chapter can be used to load the JavaScript files. The only
diffrenc here is the check to see if the file is completely loaded.

This is just an event that gets fired every time the readystatechanged. When it’s loaded the
next url can be loaded.

12.1 Login

The big difference between a Mac and Windows 7 gadget is that a windows 7 gadget allows
you to use cookies in the widget. So this means that the Sakai login methods can be used.
First of all a login form is needed on the page. These are just 2 textboxes and a submit
button.

Then it’s possible to get the values from the form:

This function will immediately get all the values from the form and make a JSON object of
them.

Then it’s possible to create a normal object from it to pass to an Ajax call to perform the
login.

Chapter: Windows 7 widget 107


Olivier Janssens Sakai3 2009 - 2010

When this is executed another function is called to see if the login was successful. This is
done to /system/me. In syste/me you can find all the information of the user that is
currently logged in .

Chapter: Windows 7 widget 108


Olivier Janssens Sakai3 2009 - 2010

When the login failed the userid will be anonymous instead of the username previously
entered.

This check is done after the Ajax cal:

Chapter: Windows 7 widget 109


Olivier Janssens Sakai3 2009 - 2010

When these steps are done the user is logged in and it’s possible to get the recent messages.

12.2 Recent message

The recent messages are exact the same like in the Mac widget.

The end result :

Chapter: Windows 7 widget 110


Olivier Janssens Sakai3 2009 - 2010

13 iGoogle widget
An iGoogle widget is a widget that is displayed and runs within the iGoogle dashboard. To be
able to use the iGoogle page you need to head over to iGoogle 36. These iGoogle widgets are
pretty easy to make because they are all iframes.

13.1 What is an iframe

An Iframe is an inline frame that contains another document. So because of Iframes you’re
able to display web pages from another domain inside your own website.

The dashboard:

You can develop an iGoogle widget in any programming language you want and on any
framework. I chose to make a widget in Sakai and then display it in the iGoogle dashboard.
An iGoogle widget exists of an xml document. You can’t put a project that is run on localhost
directly on iGoogle. So the solution for this was: Put the XML file on an online domain 37. And
have some kind of redirect in the XML document to where the html file exits on the
localhost.

36
http://www.google.com/ig
37
Ojtwist.be

Chapter: iGoogle widget 111


Olivier Janssens Sakai3 2009 - 2010

When this is done you are able to develop the widget just like the Mac widget or Windows 7
gadet . There is no new code involved here and the normal Sakai login can be used.

Chapter: iGoogle widget 112


Olivier Janssens Sakai3 2009 - 2010

14 Conclusion
Sakai is a large collaboration project; it is a project that requires a lot of dedication from
quite a lot of people. During my internship this became very clear to me. It’s not difficult to
work with a lot of people, but it requires a lot of structure. Not only in code, but also in files,
comments and documentation.

There are so many ways to write code, you can do it fast, mostly this will result in bad code
or code that isn’t efficient. Or you can do it slow and very efficient. One of the key elements I
learned in CARET is that the code should be well structured, efficient and readable. These
are not the only requirements to work on a project as Sakai. Another requirement is to be up
to date with the latest technology, as technology always evolves.

It’s also important to challenge yourself. You have to put the bar high when developing. Not
so high that it is consider to be impossible but high enough that it will be a challenge and will
improve the user experience. And when some parts are not possible to realise it’s not a
shame to try another approach. I’ve learned this when developing my flickr widget. I had put
the bar quite high. It’s was a tremendous challenge but eventually I succeeded. It took me
quite some time though.

In school you learn quite a lot about programming. You learn to program in different ways
and in different programming languages. Here CARET gives an extra value. Not only is the
way you program important but also the user experience and the usability. It’s not to choose
the easiest way but the way that gives the user a good experience. If you are lucky those two
ways coincide. To achieve this, you constantly have to question your application and think
“Is this clear enough for the user”,” Will the user understand this”, “Is this well designed”.

Another thing I’ve learned during my stay in Cambridge is that the internet has unlimited
possibilities. It goes further than just websites, data sharing and RIA applications etc. I’ve
learned this during the development of the Mac dashboard widget, Windows 7 gadget, and
the iGoogle gadget. 2 of these widgets work in a desktop environment but interact with
Sakai. Which allows the user to chat , read messages and see their profile in a few seconds.
This adds a lot to the user’s experience to Sakai. It’s not just a site, it‘s much more than that.

The main thing eventually is that Sakai 3 will be used by a lot of people. And that it has to
work perfectly. So a lot of work has to be done. Even in the 3 months of my internship I’ve
added just a little bit to Sakai. But it’s not all about adding things to Sakai. It’s also about
testing new technologies and concepts. I’ve witnessed this by developing a prototype for
Sakai. I made a prototype of a new way the dashboard pages should work. This is something
I really enjoyed because the way of making a prototype doesn’t matter. I could make it how I
wanted and it just had to be made quickly.

My stay at CARET has thought me a lot, how to be a better programmer, how to work with a
lot of people, the possibilities of the web, to challenge myself ... I recommend every nMCT
student to try to get an internship at CARET because they will learn a lot and enjoy it very
much.

Chapter: Conclusion 113


Olivier Janssens Sakai3 2009 - 2010

15 Sources
John Wiegley Git from bottom up, 2 Dec 2009
URL: http://ftp.newartisans.com/pub/git.from.bottom.up.pdf

Apache Foundation
URl: http://en.wikipedia.org/wiki/Apache_Maven

Oskar Nagy Sakai 3 UX Development Guidelines and Information, 31 May 2010


URL:
http://confluence.sakaiproject.org/display/3AK/Sakai+3+UX+Development+Guidelin
es+and+Information#Sakai3UXDevelopmentGuidelinesandInformation-
MainGuideline

The jQuery Project , 2010


URL:http://jquery.com/

Sonatype, 2010
URL: http://www.sonatype.com/books/mvnref-book/reference/installation-sect-
windows.html

The Apache Software Foundation, 2010


URL: http://www.apache.org

Christian Vuerings, Sakai 3 UX Prototype development ,01 June 2010


URL:
http://confluence.sakaiproject.org/display/3AK/Sakai+3+UX+Prototype+developmen
t

Ray Davis, Faster UX development on Nakamura, 13 April 2010


http://confluence.sakaiproject.org/display/KERNDOC/510+Faster+UX+development+
on+Nakamura

Christian Vuerings, The Nakamura proxy service, 20 May 2010


URL: http://confluence.sakaiproject.org/display/3AK/The+Nakamura+proxy+service

Chris Ullman, Calling Cross Domain Web Services in Ajax , 29 December 2010
URL: http://www.simple-talk.com/dotnet/asp.net/calling-cross-domain-web-
services-in-ajax/

Flickr, The App Garden, 2010


URL: http://www.flickr.com/services/api/

Wikipedia, Dashboard (Software), 2010

Chapter: Sources 114


Olivier Janssens Sakai3 2009 - 2010

URL: http://en.wikipedia.org/wiki/Dashboard_(software)

Wikipedia, Property List, 2010


URL: http://en.wikipedia.org/wiki/Property_list

The jQuery Project, jQuery.param(), 2010


URL: http://api.jquery.com/jQuery.param/

jQuery, Datepicker, 2010


URL : http://jqueryui.com/demos/datepicker/

JSON ,2010
URL: http://www.json.org/

Simon Gaeremynck, Sakai Back-end


URL: http://docs.google.com/present/view?id=dc8pdw46_119d25dd4hc

JQuery, Sortable, 2010


URL: http://docs.jquery.com/UI/Sortable

jQuery, Draggable, 2010


URL: http://docs.jquery.com/UI/Draggable

jQuery, Droppable, 2010


URL: http://docs.jquery.com/UI/Droppable

Peter michaux, JavaScript Namespacing , 14 June 2008


URL: http://michaux.ca/articles/javascript-namespacing

Chapter: Sources 115


Olivier Janssens Sakai3 2009 - 2010

16 Appendix

16.1 Appendix A: How to develop for Sakai on MAC.

16.1.1 Programs needed to develop:

- GIT
- Maven
- Aptana Studio

16.1.2 Getting started

First of all some extra info about git is needed. Git is a free distributed revision control, or
software source code management project with an emphasis on being fast. This basically
means that with GIT you’ll be able to work with several people on the same project without
having to share files.

How does this work ?

First of all a few terms should be explained :

16.1.3 Repository

A repository is a collection of commits, each of which is an archive of what the project's


working tree looked like at a past date. So this means that a repository consists of your
project but not only the current version of your project but it also contains the previous
versions of your project.

16.1.4 Commit

A commit is a snapshot of your working tree at some point in time. So if you change
something in your project you can do a commit so your repository contains the latest version
of your project.

16.1.5 Branch

Normally when you just create a repository you are on the “master” branch. This can be
compared to a timeline of all commits. But then when you create another branch , there will
be another timeline of commits.

Chapter: Appendix 1
Olivier Janssens Sakai3 2009 - 2010

Git makes it very easy to collaborate, but to make it even easier github has been created.
What is Github? Github is an online project service hosting, so basically a site where you can
c
store your repository. This makes it very easy to collaborate on a project with your
colleagues.

16.1.6 Getting a local version of 3akai-ux


3akai (frontend)

First of all a Github account is needed (www.github.com).


( ). When your Github account is
created it’s very necessary to add a key to your account so you’re the only one who can
modify your online repository.

16.1.7 Make a key for your online repository

To create the key

$ ssh38-keygen -t rsa -C
- "your email"

Then you’ll have to give in a passphrase ( remember this very well, because you’ll need it
later on)

Navigate to where your key was saved and look for id_rsa.pub. Copy paste the key from
the file.

38 Secure Shell or SSH is a network protocol that allows data to be exchanged using a secure channel between
two networked devices

Chapter: Appendix 2
Olivier Janssens Sakai3 2009 - 2010

So now you have a key. The only thing left to do is head over to github and add the key:

Github.com  Account Settings  ssh public key . Add the key you just copied.

To see if this all worked you can do $ ssh git@github.com and you’ll see if it works or
not.

16.1.8 Getting 3akai-ux in your remote repository

Head over to the http://g:( srry kgithub.com/oszkarnagy/3akai-ux and it.


Forking is actually creating making a copy of another master branch.

So here you can see where the repository is being forked . (Black line is oskarnagy, green is oj218)

16.1.9 Get the remote repository locally

First of all make sure you have a file to work in. In this case “Sakai” will be used. It will
contain 2 subfolders, “3akai-ux” and “open-experiments”.

Git clone git@github.com:<your username>/3akai-ux.git

(e.g. git clone git@github.com oj218/3akai.ux.git)

With this command you get all the 3akai-ux files locally.The only thing left is to check if the
file is up to date. This is done by adding a reference to oskarnagy’s repository to you remote
repositories.

git remote add oszkarnagy git://github.com/oszkarnagy/3akai-ux.git

By doing this you’ll be able to address this repository fairly easy. The only commands left are
:

git fetch oszkarnagy

git checkout master

git merge oszkarnagy /master

By doing these commands oszkarnagy’s branches will be fetched (so the whole repository).
An then when the merge is executed the local master gets updated. When you have done
this you have a local version of the frontend (3akai-ux)

Chapter: Appendix 3
Olivier Janssens Sakai3 2009 - 2010

16.1.10 Getting a local version of Nakamura (backend)

Now that you’re setup with the front-end, you need to get the back-end to run it on. To
install a local version of Nakamura maven is needed. Maven is a software tool for java
project management and build automation. Maven is used to build java projects, it comes
with predefined targets for performing certain well defined tasks such as compilation of
code and its packaging. Maven also dynamically downloads java libraries and Maven plug-
ins.

When maven is installed a maven.rc file is created (often in the home directory). If it’s not
created you can create it yourself, make sure it has the correct extension. Add this line to
maven.rc

MAVEN_OPTS="-Xmx900m -Xms168m -XX:PermSize=256m -XX:NewSize=64m"

This line specifies the memory Nakamura is allowed to use

Move to the Sakai folder in the terminal and execute this command:

git clone git://github.com/ieb/open-experiments.git

With this command the Nakamura server will be downloaded. The only thing left then is to
build the Nakamura project. By doing:

cd open-experiments/slingtests/osgikernel

mvn clean install

Now the Nakamura server can be started by navigating to the osgikernel again (see previous
command) and doing:

Sh tools/run.debug.sh

When the Nakamura project is built it gets the latest version of the UX code from git. But
when doing front-end developing it’s quite handy to keep the front-end and back-end
separated. So this basically means that all front-end developing has to be done in the 3akai-
ux folder and not the 3akai-ux project that was downloaded when the Nakamura server was
built.

Nakamura is still using the recently downloaded UX. To separated this the /dev and
/devwidget folders will have to be mapped to urls of the folders on your local machine.

This is done by downloading the fsresource jar.


(http://people.caret.cam.ac.uk/~cv268/sakai3/fsresource/org.apache.sling.fsresourc
e-0.9.3-SNAPSHOT.jar) and then executing this command:

Chapter: Appendix 4
Olivier Janssens Sakai3 2009 - 2010

cd /opt/sakai/open-experiments/slingtests/osgikernel/tools

./startux.sh -j /opt/sakai/org.apache.sling.fsresource-0.9.3-
SNAPSHOT.jar -d /opt/sakai/3akai-ux/dev -w /opt/sakai/3akai-
ux/devwidgets

An important note here: Make sure the 2 last parameters ( so the path to the dev and
dewidget folders) are correct ( These have to be absolute paths and have to start with a “/”).

Now to test that everything is working head over to


http://localhost:8080/dev/index.html. You’ll notice if the fsresource was successful if any
changes you did in your local front-end actually happen.

Chapter: Appendix 5
Olivier Janssens Sakai3 2009 - 2010

16.2 Appendix A: Development for Sakai3 on Windows


computers

16.2.1 Downloading and installing the right packages

To get git you’ll need to download it from the site39. There you can find an exe with a wizard
that will install git. I’ve chosen to install the unix interface of git since I’m used to the unix
interface from a mac.

Once installed you can start up the ‘Git bash’ utility. I will provide a walkthrough with
screenshots of how to get the repository and the commands you should use.

First create a new directory where all the Sakai code will be stored. Clone the repository
from github into this folder. This will probably give an error on the first try.

When trying to do this an error occurs. The error occurs because we don’t have the
permission to access the repository. In the previous chapter a key was added to the
repository so that only a person with the right key on his/her computer would be able to
access the repository.

So to fix this error another key has to be generated:

39
http://git-scm.com/download
Chapter: Appendix 1
Olivier Janssens Sakai3 2009 - 2010

When this key is made it can add it to our github account This is done by opening the public
key file (id_rsa.pub) and copying the rsa key. Then go to your Github account on the account
settings page on tab ‘SSH public keys’ you can add a new public key and paste the key you
copied. Now you have access with this key ( only from this computer).

If you retry to clone the repository now you will succeed.

Now you can create a branch and fetch the repository. That you can use to develop

When the repository has been fetched you can merge it by doing

Git merge oj218/<branch name>.

When this is done you’ll properly get a message that your version is up-to-date. But it’s
always smart to do this , so you’re sure your branch is up to date.

Chapter: Appendix 2
Olivier Janssens Sakai3 2009 - 2010

To summarize, we’ll fetch another branch:

Chapter: Appendix 3
Olivier Janssens Sakai3 2009 - 2010

So previously we got the recent activities branch and now we got the identica branch. And at
this moment we’re on the identica branch.

A way to verify if all of the above is succesfull, look and your explorer, you will see the
‘recentactivities’ directory but the folders will be empty. Because we are working in another
branch, the recentactivities widget is not present. The ‘identica’ widget, however, is present
and you can view it in explorer. This is certainly no mistake. If the recentactivities widget
would be present that would mean you have created a wrong branch.

Chapter: Appendix 4
Olivier Janssens Sakai3 2009 - 2010

Now that the frontend is in place it’s time to get the backend. The backend consists of
NAKAMURA (Kernel 2) and can be downloaded from Github as well. Navigate to the Sakai
directory where you will install the kernel files. Be careful not to navigate to the the 3akai-ux
directory as this is the frontend, not the backend.

Once in the Sakai directory you can start cloning the open-experiments directory from
Github. There are a lot of files to download so it can take a while to download them
depending on your internet connection.

There is only one more thing we have to do before we can start the server. We have to build
the kernel 2 files. This is done with maven. (More information about maven in the previous
chapter)

To install maven head over to (http://maven.apache.org/download.html). Put the files


somewhere on your computer. The location doesn’t really matter because to be able to use
maven in the command prompt you’ll need to add it to your path variable. You can either do
this via the windows gui or the command line:

Chapter: Appendix 5
Olivier Janssens Sakai3 2009 - 2010

If you test maven out by typing ‘mvn -v’ in the console you should get some decent output
by now.

You might get an error if your JAVA_HOME variable is not set. To check this you can do
“java” in your command prompt. If you get an error you’ll need to install the jdk and add the
JAVA_HOME to your system variables. To install the jdk head over to
(http://java.sun.com/javase/downloads/index.jsp).
Then add the path to your JAVA_HOME

Also add the bin path to your path variable:

Chapter: Appendix 6
Olivier Janssens Sakai3 2009 - 2010

Now you can try to build the Nakamura by doing “mvn clean install –
Dmaven.test.skip =true”. With this command the server will be build and the tests to
see if everything works will be skipped. This will save a lot of time, but this is not best-
practice.

You might get an error here. The cause is ‘javac’ which cannot be executed. This means your
system variables are not set the proper way. Try to fix this by checking if you have done the
previous steps right.

When this is done you can try to build Nakamura again:

You can now go ahead and run the server from command line. You might get a security
message from Windows thrown for Java. This depends on the security settings on your
computer and you can just accept the message.

If you open your browser and browse to http://localhost:8080/dev/ you will find that
Sakai is up and running.

Chapter: Appendix 7
Olivier Janssens Sakai3 2009 - 2010

The only step that has to be done is the separation of the backend and the frontend. We do
this with the fsresource bundle. Your server should be running when you attempt this step.

Download
http://confluence.sakaiproject.org/download/attachments/67110032/org.apache.sli
ng.fsresource-0.9.3-SNAPSHOT.jar?version=1 and save it to a convenient location (e.g
your Sakai folder). Then browse to http://localhost:8080/system/console/bundles, click
the ‘browse…’ button and select the downloaded JAR file. Now Press ‘Install/update’.

When the install was successful you will find it in the list of installed bundles. You may have
to refresh your page for this.

Next go to http://localhost:8080/system/console

Click on the ‘Configuration’ tab on top of the page. In the new page you scroll down to the
factory Configurations

Click on the ‘+’ sign next to the FsResourceProvider, a popup will be shown (See below)

Put ‘/dev’ and ‘/devwidgets’ in the first location and the full directory path in the second.
View the screenshot for a more detailed description of how to do it.

If you created those and reload the page you will find them in the list on the top. If not, you
have not saved the input or did something else wrong. Try again in this case.

So there you go, a working Sakai prototype development environment for you to work on in
your Windows environment.

Chapter: Appendix 8
Olivier Janssens Sakai3 2009 - 2010

17 Appendix C : Weekly Reports:

17.1 Report Week1: Monday 8 March – Friday 13 march

17.1.1 Log

Day 1
- Introduction to sakai
- We were divided into 2 teams ( 2 student each)and assigned to make a Todo list
widget. This widget has to be written in HTML/JavaScript(JQuery).
- Setup 3akai-ux (frontend) and 2K ( backend) locally.
- Read Documentation about GIT version control.

Day2
- Setup a remote repository with git , to be able to work with 2 people on 1 project.
- Investigate other widgets.
- Setup basic HTML, CSS, JavaScript for the widget.
- Read documentation about Sakai and development.

Day3
- Implemented a datepicker into the todo widget.
- Write JavaScript to get data from a json file.
- Read documentation about json and communication in Sakai.
- Meeting to discuss progress and coding style rules

Day 4
- Write JavaScript code to post todo items to a json file (post).
- Write JavaScript to add todo items to a json file (put).
- Read documentation about Manipulating Content: The SlingPostServlet
- Meeting to introduce ourselves to everyone in caret.

Day5
- Write the delete functionality for the todo widget
- Read documentation on the operations of the SlingPostServlet ( operation
:delete).
- Help Maxime with the jQuery paging plugin.
Chapter: Appendix C : Weekly Reports:
1
Olivier Janssens Sakai3 2009 - 2010

- Merge my project (delete functionality implemented) with Maxime’s (paging


implemented)

17.1.2 Summary

This week we got an introduction to the Sakai platform. Sakai is an Open Source
Collaboration and Learning Environment which is in Enterprise use at 200 Universities
around the world with over a million users who use Sakai daily in their teaching and learning.

This brief introduction was followed by our first assignment. We were told to make a widget
for Sakai to get accustomed to the Sakai platform and the technologies that are used in
caret. We were divided in 2 teams of each 2 students. My team was assigned to make a todo
widget, this is basically a widget that allows you to save a list of tasks you still have to do.

This widget had to be made with a combination of technologies like HTML, JavaScript ,
Json,jst and css. Before we could start writing code we had to setup a local version of Sakai.
This contains 3akai-ux and 2K. 3akai- ux is the frontend and 2k is the backend. 3akai-ux is
written in JavaScript ,html, ,jst and css . 2k is completely open source based and is basically
an apache jackrabbit with apache sling on top. To get a local version of Sakai running we had
to use GIT to get a version of the latest Sakai. Even though we’ve seen GIT in our lessons, this
was still quite a challenge to do in a real development environment.

When we finally got our local Sakai running, we had to setup a remote repository on github
so we could work on the same project with 2 people. When this was done we started coding.
We started by investigating the other widgets on Sakai and by reading lots of documentation
provided by caret.

When all the documentation was read, I started writing basic html and Maxime covered the
css. Then I started implementing the jQuery datepicker plugin and a column sorter. These
plugins required libraries that weren’t included in Sakai and gave some problems. Christian
advised me to take a look at the poll widget to use the built in datepicker plugin. I managed
to implement this.

After this fairly easy plugin was implemented I started by searching how to post data. We
were told that Sakai’s data is saved in json files, something I’ve never seen before. This was
quite hard to figurer out. Luckily Wednesday we had a meeting with Christian and Simon
where they explained it very thorough.

The next day I implemented the post (so for the first task in the list) and the put ( to add
tasks in the json file) functionality. Even though this probably sounds very basic and easy, it
was fairly hard. Then the last day of the week we made a list of what still had to be done. So
this consisted of validation, delete functionality, paging, adjust css and a sort functionality.

Maxime managed to get the paging plugin working while I wrote the delete functionality.
This was fairly easy since it’s just a POST but with an extra parameter. There was one little
problem with the file structure on apache sling. In the current version of 2K the file structure

Chapter: Appendix C : Weekly Reports:


2
Olivier Janssens Sakai3 2009 - 2010

is made by a hash function (this is fixed in the newer version) and because of this I got some
errors. Simon then advised me to use a different path for the POST/PUT/DELETE.

The deadline for our widget is Monday evening, so Monday we’ll add validation, sorting and
we’ll fix the CSS. Then for the rest of the week we’ll get a new assignment.

Chapter: Appendix C : Weekly Reports:


3
Olivier Janssens Sakai3 2009 - 2010

17.2 Report Week2: Monday 15 March – 19 Friday march

17.2.1 Log

Day 1
- Meeting with Christian about our todowidget.
- Added sorting functionality to the todowidget.
- Validated CSS/HTML/JavaScript.

Day2
- Fixed minor details like, resetting textboxes after submit, change images for the
date picker.
- Start of implementing update functionality.
- Read fluid infusion documentation.
- Use fluid infusion on textbox for inline editing.
- Written code for inline editing on combo boxes.
- Changed data structure so tasks get saved with a unique id in the Json file.

Day3
- Written code for inline editing on a date (Date Picker)
- Written data access code for the update functionality

Day 4
- Merge Maxime’s project (Project where all the bugs are fixed that Christian
mentioned earlier this week in the meeting) and my project (Project where the
update functionality is implemented).
- Read flickr api
- Fix minor bugs

Day 5
- Draw a prototype for my next assignment (flickr widget)
- Started developing the flickr widget
- Implemented the jQuery accordion plugin

17.2.2 Summary

This week we started of with a meeting with Christian. He’d reviewed our code and told us
several things we had to change : Our code had to be more structured. For example before
Chapter: Appendix C : Weekly Reports:
4
Olivier Janssens Sakai3 2009 - 2010

every function we had to write comments of which parameters the function used. We also
had to write more comments to explain how everything works.

We also needed to pay more attention to the indenting and the use of whitespaces because
this could cause merge errors in GIT. Then there were some other minor details that were
easily fixable. But in general he was pleased with our widget so far.

Later on he asked us what our widget is missing and we guessed an update functionality. So I
suggested to implement an update functionality by using a popup screen. Then Christian
suggested to use fluid infusion. Fluid infusion is used for inline editing. For example if you
have a list of words (<p></p>) you just have to click on it and it’ll transform into a textbox
and then you can edit it and save it by clicking outside the box.

So while I was implementing fluid infusion Maxime tried to fix our bugs. Implementing fluid
infusion is quite easy for a textbox so that was done rather fast. But then I had to implement
inline editing for a combo box and date picker. Fluid infusion has these functionalities but
they aren’t very good. So I started writing them myself. For the combo box I had the luck
that something similar was already written in another Sakai widget. But it still took me quite
a while to figure it out and implement it.

Then for the date picker I was on my own since fluid infusion is still in the early phases of
developing this and it hasn’t been written before in Sakai. But eventually I managed to write
it, but again it took me quite a while. So at this point only the data access was left to be
written. Because Json files aren’t like a database there was no option for auto incrementing
ids. So I had to write this myself too.

After this update functionality was written we decided to merge our 2 projects together. But
unfortunately Maxime hadn’t pushed his project to github for 2 days and our 2 projects were
out of sync. So we had to fix merging errors for a whole morning.

When we finally had one solid working project we started testing everything in details to see
if there were any bugs left. So the rest of that day we spent fixing errors. During that day
Christian told us our next assignment. I was told to make a flickr widget for Sakai3. He told
me I was free to design the widget like I wanted. But the purpose of the widget had to be
maintained. First of all this widget isn’t like my previous widget. The previous widget was a
widget for the sakai front-page and the flickr widget is a widget that has to work inside the
site widget of sakai (The site widget is a widget that allows the user to create personal sites
within sakai)

So the purpose of the flickr widget is to allow the user to include a flickr gallery in their site.
Christian warned me that I’ll have to comment every line of code that I’ll write and I have to
get the whitespace and indenting right from the start. So the next day I drew a paper
prototype and showed it to Christian. He was very pleased and excited with the result but he
thought I’d might have put the bar too high.

But he allowed me to try to make it. So I started by reading the flickr api and a few tutorials
on how to develop with the flickr api. Then when everything was read I started coding. The

Chapter: Appendix C : Weekly Reports:


5
Olivier Janssens Sakai3 2009 - 2010

only part I realized this week for the flickr widget was implementing the jQuery accordion
plugin. So next week I’ll continue developing the flickr widget.

Chapter: Appendix C : Weekly Reports:


6
Olivier Janssens Sakai3 2009 - 2010

17.3 Report Week3: Monday 22 March – Friday 26 march

17.3.1 Log

Day 1
- Write proxy files to communicate with the flickr api
- Write the start of the authorization process for flickr
- Figure out how to do the flickr communication when a static page is required for
the callback
- Write a lot of comments

Day2
- Write second part of the authorization process.
- Fix minor remarks

Day3
- Completed authentication & authorization process
- Fix minor remarks
- Implement functionality to request private photos from flickr when logged in.

Day 4
- Implement JCarousellite to display the pictures
- Fix minor remarks

Day 5
- Implement drag and drop functionality to add pictures to an image gallery
- Implement save functionality to save the image gallery server side
- Implement Jsortable plug-in to sort the pictures

Chapter: Appendix C : Weekly Reports:


7
Olivier Janssens Sakai3 2009 - 2010

17.3.2 Summary

So this week I started by writing the proxy files for the authorization process for flickr. This
was fairly easy the only problem that I stumbled upon was that you are not allowed to pass
entire urls through the ajax parameters ,who are passed to the proxy file.

So basically the authentication process works as followed: First a request is required to the
flickr api “flickr.auth.getFrob”. The response of this request will give a frob. A frob basically
authorizes the login session. In the Request to get a frob, the api key, secret and signature
have to be passed along. The api key and secret are given when you register the widget on
yahoo, the signature is a md5 hash you need to make yourself. This hash exists of the api key
and the secret.

Then when you have a frob, the user has to be redirect to the yahoo login page. When the
user is logged in he has to be redirected back to the sakai flickr widget. This was fairly
complicated because when you register a widget on yahoo you immediately have to give a
static callback url, the url of the flickr widget is not static. So I had to find a solution for this.

I came up with the idea to set the callback url to a html page on my own domain that will
redirect the user to sakai. So basically the User gets sent to the yahoo page, in the url that
sends the user to the yahoo page I’ve set an extra parameter that contains a string of the
dynamics part of the sakai url. Then he logs in (here he’ll get a new frob in a querystring)
then he’ll be sent to www.ojtwist.be/toSaki.html. Where the javascript gets the value of the
dynamic part of the url and rebuilds a url so that the user can be redirected to the right page
on sakai.

This was fairly complex to do because I wanted to do this with cookies, but cookies cross-
domain are rather hard. Luckily I could add an extra parameter to the url for yahoo.

So the only thing left now was to convert the frob into a token ( a token is needed to do
authenticated calls to the flickr api). This was done quite fast. So at this point I was able to
do authenticated calls to the flickr api. So I started implementing a functionality so that a
user could get his own pictures from flickr.

At this point I stumbled upon another problem. The photos gotten from flickr are in xml
format and you can’t just put this in a src attribute from an img tag in html. So to do this I
had to work with another site who fixed this problem. When this was fixed I was able to
display the first pictures.

The only things left now were to implement an image gallery and a functionality to save the
chosen pictures. For the image gallery I chose to implement the jcarousellite. This took me
quite a while to implement because the image were rendered with JST and aren’t present on
the page from the start. So this meant I had to find a way to implement the Jcarousellite
after the images were loaded.

When this was done I searched for a way to give the user the option to choose pictures and
then save them. I chose for a drag and drop plug-in. Because of the html hierarchy this was a
Chapter: Appendix C : Weekly Reports:
8
Olivier Janssens Sakai3 2009 - 2010

bit hard. But eventually It worked. So what I wanted to achieve was that the user was able to
drag 1 picture from an image gallery to another image gallery. This was very complicated. So
I searched on for a better solution than the jquery draggable and droppable plug-in. After a
short time of searching I found the jquery sortable class. This is basically a plug-in that
transforms a list into a list that can be sorted with drag and drop.

This plug-in also allows you to make 2 lists sortable and interact with each other really easy.
So I’ve started implementing this but it’s not done yet. So next week I’ll finish this drag and
drop functionality and then allow the user to save this list server side. I also intend to
implement the functionality that allows the user to search pictures with a keyword.

Chapter: Appendix C : Weekly Reports:


9
Olivier Janssens Sakai3 2009 - 2010

17.4 Report Week 4: Monday 29 March – Friday 1 April

17.4.1 Log

Day 1
- Solved bugs in the drag and drop functionality
- Solved bugs in the sorting functionality

Day2
- Solved bugs in the drag and drop functionality
- Solved bugs in the sorting functionality
- Implemented the second part of the flickr widget: Search for pictures by keyword

Day3
- Finished the second part of the flickr widget

Day 4
- Solved bugs in the flickr widget

Day 5
- Holiday

Chapter: Appendix C : Weekly Reports:


10
Olivier Janssens Sakai3 2009 - 2010

17.4.2 Summary

So this week started with trying to get the sortable plug-in working . This is a very neat plug-
in because it does all the drag and drop functionality and it also makes your lists sortable. So
at this moment I had an image gallery with the users’ pictures from flickr and the sidebar
where the user should drag and drop his/her pictures to.

So the problem here was that when the users is dragging the pictures, that the picture
stayed underneath some html components. This was fixed by changing parameters of the
sortable plug-in. Like the appendto, containement,z-index.

The next thing to do was implementing the jcarousel plugin on the sidebar (where the users
can drag and drop their pictures). This was fairly hard because the image gallery is normally
rendered on an existing UL. But in my case it had to adapt, so it had to expand when new
pictures were dragged into it. To make this work I tried several jQuery image gallery plug-ins

I couldn’t get this quite working so I started on the second part of the flickr widget. This was
the part where the user just could fill in a keyword and get pictures that were tagged with
that keyword. This was done rather fast. I only had a little problem with the Image gallery.

Then the last day I had to finish the flickr widget because next week Tuesday I would get a
new assignment. So Thursday I had to make my widget unbreakable. At this point there were
a few problems with my widget: the Image gallery on the sidebar didn’t work, the accordion
plug-in was a bit broken and then there was the strangest bug : the users wasn’t able to type
in a textbox. I went to Christian with this problem who fixed the textbox bug and he told me
I should drop the Image gallery plug-in for now.

So the rest of the day I fixed small bugs. Next week I’ll be starting with my new assignment.
This will be redeveloping the sakai dashboard pages.

Chapter: Appendix C : Weekly Reports:


11
Olivier Janssens Sakai3 2009 - 2010

17.5 Report Week 5: Monday 5 April – Friday 9 April

17.5.1 Log

Day 1
- Holiday

Day2
- Started with my new assignment, prototype development for sakai3.
- Analyze the sakai site_admin.js
- Implement the jQuery accordion plug-in

Day3
- Implemented drag and drop functionality in the prototype
- Implemented the context menu in the prototype

Day 4
- Implemented the rendering of textboxes when a user drops or selects a
component in the context menu.
- Implemented the inline editing for the text

Day 5
- Implemented the delete functionality for the text

Chapter: Appendix C : Weekly Reports:


12
Olivier Janssens Sakai3 2009 - 2010

17.5.2 Summary

This week I started with my new assignment. The assignment consisted of developing a
prototype for the sakai dashboard pages. The dashboard pages allow a user to create a site
within sakai in just a few minutes. I was given a wireframe by Christian that had been drawn
by another sakai developer (Oszkar nagy).

The prototype was designed to test if this was viable and to show it to the director. The
prototype was basically a new way of making a dashboard page. It was designed to be very
user-friendly for example lots of drag and drop was used and such.

So Monday I started with analyzing how the current dashboard pages worked in sakai and
implementing the jQuery Accordion plug-in. So that the user could choose between layouts,
text elements ( title, title with subtitle, etc) and widgets.

The next day I implemented the drag and drop functionality, so that the user could drag and
drop an element from the accordion into a layout and then the textboxes would be
rendered. This was fairly easy because I already had some experience with drag and drop
from my flickr widget.

Wednesday I wrote the code for the textbox rendering. I also implemented the jQuery
context menu, so that the user could right click and select the title element. The challenging
part was that I had to know what to render and where to render it with both plug-ins.

After this I started working on an update functionality. Because when the user drops a
textbox on the layout , he/she can fill in a title and then press submit and labels will be
rendered. And labels aren’t editable obviously. So here I tried to implement fluid infusion
again, but this didn’t work. I also looked into jEditable but this was a too advanced plug-in
for this. So I decided to write this inline editing code myself

When this was written I started working on a delete functionality. The delete functionality
works a follows : when a user hovers over a label an x button appeared in the upper right
corner of the label and he/she could just click it and the label would be deleted.

When this was done I had a chat with Oszkar. He told me how the concept of this prototype
would work if this would be implemented. He told me I should focus on the widget part. So
that a user could drag and drop any kind of widget into their layout. So that’s what I did
Friday. I tried to figure out how to make a widget appear in the layout. This was and still is
quite complex because all of the widgets are written or for the frontpage of sakai or the site
part of sakai and it’s not possible just to render a widget in the layout and expect it to work.

So Monday I’ll continue working on the widget part of the prototype and hope the prototype
will be finished Monday afternoon so it can be shown to the people of caret.

Chapter: Appendix C : Weekly Reports:


13
Olivier Janssens Sakai3 2009 - 2010

Chapter: Appendix C : Weekly Reports:


14
Olivier Janssens Sakai3 2009 - 2010

17.6 Report Monday Week 6: 12 April – Friday 17 April

17.6.1 Log

Day 1
- Converted the textboxes and title boxes to widgets
- Implemented the googlemaps widget

Day2
- Implemented the RSS widget
-

Day3
- Implemented the rendering functionality so that the user can switch from
preview to edit mode.

Day 4
- Implemented the jQuery Sortable plug-in so that the widgets can be dragged and
dropped within the chosen layout

Day 5
- Changed the jQuery Sortable plug-in to the fluid reorder plug-in

Chapter: Appendix C : Weekly Reports:


15
Olivier Janssens Sakai3 2009 - 2010

17.6.2 Summary

This week started with converting all the functionality I’ve written last week for the
textboxes to widgets. I had to do this because whole Sakai works with widgets and it would
be much easier to implement then. The big difference now is that there is an external css,
javascript and html file for a widget. So now it’s just possible to render a div in the layout of
the dashboard pages and call a function and the widget is rendered on the page.

This was fairly easy since I’ve developed widgets before. When this was done I was asked to
try to get some other Sakai widgets working in my dashboard pages. The first one I chose
was the googlemaps widget. A lot of css changes were required and a little bit of JavaScript
changes. For example a site widget has 2 modes. A settings mode, where the user can
change and insert data. And a render view, where the user can see the widget in action. This
sate is determent with a Boolean. I had to adapt this code so it would work in the dashboard
pages.

When this was done the user was able to construct a dashboard page by dragging and
dropping widgets in the chosen layout. So now it was time to implement the rendering
functionality. This basically means that the user can see a preview of the page how it would
look when it’s used. This took me about a day to implement.

At the end of the day I made a video of the functionality and I’ve send it to Christian , Simon,
Oskar ( the person who drew the prototype), John (the director) and Nicolaas. The next day I
got some feedback and I was asked to implement the drag and drop functionality so that the
user can swap widgets between columns and rows.

I chose to do this with the jQuery Sortable plug-in since I’ve used this in my flickr widget.
Though this was a bit more complex since there were more columns and rows than in my
flickr widget. Eventually it worked but I wasn’t that pleased with the result. At this point I
made another video to get some feedback.

Later on Simon told me I had to look into the Fluid Infusion Reorder plug-in. This is like on
the igoogle page or the sakai frontpage. This plug-in is amazing. It works very well when
there are just columns in the layout. But when a row is introduced everything goes wrong. It
always snaps to the row. So I had a chat with Christian and Oskar they told me that the Fluid
infusion reorder plug-in will not be used when this will be made for production.

Christian then told me I could stop working on the dashboard and continue on my flickr
widget. So I cleaned up my flickr code , since I was told to drop the authorization and
authentication part. This is because it’s not very user-friendly of yahoo. My JavaScript file
went from 756 lines of code to about 350. I also made my code jsLint valid.

Next week I’ll continue working on my flickr widget .I’ve decided to only get the public
pictures of a user.

Chapter: Appendix C : Weekly Reports:


16
Olivier Janssens Sakai3 2009 - 2010

17.7 Report Monday Week7 : 19 April – Friday 23 April

17.7.1 Log

Day 1
- Implemented the functionality so that the user can retrieve public photo’s from
twitter.

Day2
- Write the paging functionality for the image gallery
- Write the dynamic loading for the Image gallery

Day3
- Write The paging for the second image gallery and update the previous paging

Day 4
- Rewrite the paging functionality

Day 5
- Write the site preview page for the flickr widget

Chapter: Appendix C : Weekly Reports:


17
Olivier Janssens Sakai3 2009 - 2010

17.7.2 Summary

This week started with writing the part of the flickr widget that allows the user to retrieve
the public pictures from a person by filling in an e-mail or a username. This was
implemented rather fast since there was no difficulty. So the user can just fill in a username
or e-mail and will get 5 pictures at the time.

But every time a user clicks next or previous an ajax call was fired to retrieve images. This
wasn’t very efficient. So I was told to save all the images I’ve retrieved (in the html, and just
display a few). So that there would be less ajax calls. So I implemented this. This took me
quite a while since there was a lot of DOM manipulation involved.

The problem here was that this had to work with drag and drop too. So when the user
request images at the start I do an ajax call to get 10 pictures. 5 of these 10 are shown. If the
user clicks next, another 5 are requested and the previous image that are hidden. So there is
no loading that the user can see. But when the user is on page 1 and drag and drops an
image , there is a hole in the gallery. So this is filled by a hidden image. But then when the
user drags a lot of pictures there are no hidden images left. So at a certain point there has to
be another Ajax call.

The difficulty here was that when the user drags and drops a lot of pictures and then presses
next that he/she should get the next 5 images and won’t get duplicate image. This took me
about 2 days to write. When this was done I was told to implement a refresh functionality so
that the image gallery could be reloaded.

After this I implemented this paging functionality in another gallery. Luckily I had written my
code so that a lot of it was reusable. So this was done fairly quick. When this was done I
wrote the save functionality so the user could see how his image gallery would look like in
the site view. I chose to use a jQuery plug-in to display the pictures because it’s a static ul of
images.

When writing this code I also tested Christian’s new methods to retrieve or save data. The
only thing left to do now is to make the sidebar into a gallery. The sidebar is a container
where the user can drop images that will be saved. I’ll also tweak my paging a bit because at
the moment it’s not quite pretty.

Chapter: Appendix C : Weekly Reports:


18
Olivier Janssens Sakai3 2009 - 2010

17.8 Report Week 8 : Monday 26 April – Friday 30 April

17.8.1 Log

Day 1
- Change the sidebar to a gallery. (implementing paging)
- Fix bugs in the preview mode

Day2
- Make the sidebar interact correctly with drag and drop

Day3
- Add an external links button, so the user can go to the flickr website to get more
info
- try to write the functionality so that the user can enter a page number to get the
pictures from that page

Day 4
- Implement the delete functionality for the sidebar
- Fixing bugs in the paging functionality (failed)

Day 5
- Change the functionality of the external links
- Add functionality so the user can see his friends on flickr and get their pictures

Chapter: Appendix C : Weekly Reports:


19
Olivier Janssens Sakai3 2009 - 2010

17.8.2 Summary

This week started by transforming the sidebar into a gallery. It used to be just a div where
the user could drag and drop their pictures in. But now paging was added. The difficulty here
was that it had to interact with drag and drop. So when a user drags pictures into the
sidebar.The page number should increment. I’ve written this in about a day.

When this was done I added an external links button to the preview gallery. These external
links buttons are just underneath the pictures and when the user clicks on one them he gets
redirected to the flickr site so he can see more info about the picture. The difficulty here was
that the url is made of the username and the picture id. And the userid is something you
don’t have at that point.

Luckily there’s a site on the web that allows you to use the a url and put the picture id in a
querystring and then you get redirected to the right page. When this was done I wrote the
delete functionality for the sidebar. The idea of this was that when the user hovers over an
image a little x should appear in the right top corner. And when it’s clicked the picture
should be deleted from the server (jcr) and It should disappear from the sidebar. This was
quite difficult because when a user deletes a picture the paging should be updated too and 4
pictures should always be displayed.

So when 1 picture gets deleted another should be displayed. This took me another day.
When this was done I started writing the code so that when a user enters a page number in
the textbox of the paging. That page gets displayed. This was very difficult because the
previous and next page should always be cashed. So for example when the user is on page 1
and enters page 4. Page 3 4 5 should be requested and only page 4 should be displayed.

There are far more cases than this one. For example if the user is on page 2 , so page 1,2,3
are cashed and the user requests page 4. Only page 4 and 5 should be requested. This list
went on and on. I tried to do this with calculating how many pictures there were in the
gallery, Which page was shown, how many were dragged etc… I wrote most of the code in a
day. But then one morning in stumbled upon a case that just wasn’t fixable. So I had to give
up because lack of time. Though it would’ve been possible if I did it with arrays. For example
put the pictures that are loaded in an array and then those who are requested and then
compare them.

But if I wanted to do this , this would take me at least another day. So I deleted my code and
started writing the functionality so that when a user enters a name or e-mail from a person
that the user also will see the friends of that user. And then the user can click on 1 of those
friends and will see the pictures of that person. This was done fairly quickly because most of
the code was reusable.

After this I changed the external links buttons. Now when the user goes over a picture with
the mouse an icon gets appears. To get this working without any bugs was quite a challenge
because almost every method I tried was buggy. The icon started flickering etc. Eventually

Chapter: Appendix C : Weekly Reports:


20
Olivier Janssens Sakai3 2009 - 2010

with the help of posting my problem on stackoverflow I got it working. Next week I’ll finish
my flickr widget and probably start a new assignment.

Chapter: Appendix C : Weekly Reports:


21
Olivier Janssens Sakai3 2009 - 2010

17.9 Report Week9: Monday 3 May – Friday 7 May

17.9.1 Log

Day 1
- Bank holiday

Day2
- Test my flickr widget in chrome, safari, IE8
- Solve bugs in chrome and safari
- Start solving bugs in IE8

Day3
- Fix the gallery in IE8
- Fix the drag and drop in IE8
- Make the html and JavaScript valid

Day 4
- Make a skin in Sakai for the Cambridge integrated knowledge centre

Day 5
- Finish the skin for CIKC
- Fix Bugs in Sakai

Chapter: Appendix C : Weekly Reports:


22
Olivier Janssens Sakai3 2009 - 2010

17.9.2 Summary

This week I started by finishing my flickr widget. The only thing left to do was making the
widget work cross browser. I first tried to get it working in chrome and safari. There were a
few bugs there, for example: The drag and drop and sorting weren’t working like it should.
This was quite easily fixed. But then the misery started. I had to get the widget working in IE.

The first time I opened the widget in IE, it didn’t get loaded. This was because the html didn’t
get loaded properly. And this all was caused by bad nesting of html tags. This was a very silly
mistake. After this my widget got loaded properly. Now there were a few bugs left. The first
one was that the drag and drop didn’t work like it should. So when the user started dragging
an image, the image disappeared. I was very convinced this was because of the z-index.

IE is the only browser that doesn’t fully support the z-index, so it had to be because of this. I
tried every solution known to mankind to solve this but it didn’t work. Then I got some help
from Christian and we figured it had nothing to do with the z-index but it was because of the
opacity. Apparently IE doesn’t support it.

When this was done I only had to make sure my JavaScript and html were valid. The next day
I got a new assignment. I had to make a skin (template) in Sakai for the Cambridge
integrated knowledge centre (CIKC). The purpose of this was to show the people from the
CIKC how their website might look like and how it would work. This assignment took me 1.5
days to finish. This project wasn’t hard or challenging but it was nice to have a project that
didn’t require a lot of research. So it was sort of a small break for me.

Friday around noon I was done with my CIKC template. So I got a new assignment: fixing
bugs in Sakai. All the Sakai bugs are reported on Jira.sakaiproject.org. Then a developer can
assign a bug to a person and that person has to solve the bug. I was assigned 3 bugs by
Christian. The first bug was solved quite easily. It was just a CSS bug. Then the second bug,
the problem with this bug was that I wasn’t able to reproduce it .So I made a movie clip of
the steps that had to be taken to reproduce the error. And I posted this clip on jira. And it
turned out that the bug was already fixed.

Then the third bug. This bug is in the comment widget. When a user posts a comment, a post
is done to a messaging system. This messaging system drops the comment in the user’s
Chapter: Appendix C : Weekly Reports:
23
Olivier Janssens Sakai3 2009 - 2010

inbox and then posts it to jcr. This is done by an Ajax call and on the success of this Ajax call
another Ajax call is done to get all the comments. This is where it goes wrong. Because the
GET is done when the data isn’t saved yet, the data which is returned doesn’t contain the
new comment yet. So that’s what I’m currently fixing. Next week I’ll start with fixing this bug
and then probably get a new assignment.

Chapter: Appendix C : Weekly Reports:


24
Olivier Janssens Sakai3 2009 - 2010

17.10 Report Week 10: Monday 10 May – Friday 14 May

17.10.1 Log

Day 1
- Meeting with Christian and Simon about my performance
- Start my new assignment : Develop widgets for the Mac dashboard, vista sidebar,
iGoogle , Facebook
- Start developing the Mac widget (design)

Day2
- Mac widget: Write the login and find a way to debug.
- Mac widget: Figure out why the login isn’t working when the widget is deployed.

Day3
- Mac widget: Develop new login system that works with a token instead of a
cookie.
- Mac widget: Write a widget for the Sakai dashboard that generates the token.

Day 4
- Mac widget: Implement the animation so that the widget can flip.
- Mac widget: Write the functionality to get the recent messages and display them
on the front of the widget. (The token can be entered on the backside of the
widget)

Day 5
- Mac Widget: Redesign the widget.
- Mac Widget: Solve bugs in the widget

Chapter: Appendix C : Weekly Reports:


25
Olivier Janssens Sakai3 2009 - 2010

17.10.2 Summary

This week started with a meeting with Christian and Simon to give me feedback on the last 9
weeks. They also gave me a new assignment: Develop widgets for Sakai outside Sakai. This
meant I’ll have
ave to develop widgets for the Mac dashboard, Windows sidebar, iGoogle and
Facebook.

17.10.2.1 Mac Widget

17.10.2.2 Creation

Developing a widget for the Mac Dashboard is fairly easy because the widgets are made in
JavaScript, HTML and CSS. So it’s just like I’ve been doing the the past 9 weeks. Apart from these
3 files, a plist file is needed too. This is like an XML file and has quite a few properties. In this
file you have to specify if the widget is allowed to access remote content, the name of the
widget, the namespace etc...

2 Images are required too. An image that will be set as an icon and 1 image that’ll be the
background of the widget. So the layout of the folder:

My Sakai

mySakai.html

mySakai.css

mySakai.js

Default.png

icon.png

My Sakai.plist

To deploy the widget you just need to rename the folder to : My Sakai.wdgt and click it twice
and it’s installed.

17.10.2.3 Login
Chapter: Appendix C : Weekly Reports:
26
Olivier Janssens Sakai3 2009 - 2010

For the login I copied the login functionality from Sakai. The only problem here was that I
needed to include all the JavaScript files myself. Because if you are developing a widget for
in Sakai in Sakai these are already included. When developing the widget you can see the
results in the browser by just opening the html file. So there is some way of debugging.

The good thing here was that the debug worked if I surfed to
“http://localhost:8080/devwidgets/My Sakai/My Sakai.html. But it wouldn’t work when I
opened the file from my local file system (this is the way the widget works). There were a
few options why this didn’t worked. One of them was that cross domain calls weren’t
allowed. But after some researched I found out that cross domain calls were allowed in the
widget.

The second option was that it wasn’t possible to create cookies in the widget. After some
research this was confirmed. So I had to find a new way to allow the user to login. Luckily
Simon had a solution : The user would surf to the Sakai site and login, then generate a token.
A token is basically a string to verify which user is logged in. The user would then copy this
token and past it in the Mac widget. The reason for this token is to authenticate every call
that is done to the server. The token is added as a field in the header of a get or a post.

17.10.2.4 Recent Messages

A Mac widget has quite a few cool animations. One of these animations is the flip. So this
basically means that the widget has a front side and then you can press a button and the
widgets flips. So on the front I decided to display the recent messages and on the back of the
widget the user is able to fill in a token. The recent messages are the mails the user recently
received, these can also be found in the inbox in Sakai. I decided to display 7 of these. So the
user would see a list of subjects and if they click on the subject they see the entire message.

The only problem I encountered here was that some of mails are quite large and cannot be
displayed inside the Mac Widget so I had to implement a scrolling functionality. Luckily
Apple had provide a neat library for this. But unfortunately this wouldn’t work for me. This
was because I tried to do everything with animation. So the user would click on a subject and
then the message itself would appear underneath the subject. And because the scrolling
functionality has to be applied on that exact time it didn’t work because the div doesn’t have
a height at that moment.

Another solution here would be to use a fixed height but then it would look rather silly if
there was only 1 word. Then a solution was provide by Henry. It was super easy. Just hide
the list and display the message instead of all the fancy animation. Because of this solution I
had more space to display the message and the message always has a height so I could
implement the apple scrolling functionality.

17.10.2.5 Design

Because I wanted to make the deadline ( which was Friday) I didn’t put a lot of time in
designing the widget. Luckily most of the functionality was done by Friday morning so I was
able to redesign the widget with some help from Bert (specialization Multimedia).
Chapter: Appendix C : Weekly Reports:
27
Olivier Janssens Sakai3 2009 - 2010

When this was done, there were a few bugs left to fix: For example when a subject was
longer than 1 line it should be trimmed so that it would only display 1 line. Another problem
was to check if the token was valid. Because no matter what you enter as token you always
get a 200 back. But if the token is wrong you won’t see any messages. So I had to write more
input validation.

17.10.2.6 Vista Widget

The Mac Widget was done around Friday afternoon so in the time left I did some research on
the development of a Windows Vista widget. It appears it’s very similar to the Mac widget
expect for the fancy animations.

17.10.2.7 Next week

Next week I’ll develop the Windows Vista widget. The problems I expect to occur here are
too little room to display anything and again some login issues.

Chapter: Appendix C : Weekly Reports:


28
Olivier Janssens Sakai3 2009 - 2010

17.11 Report Week 11: Monday 17 May – Friday 21 May

17.11.1 Log

Day 1
- Windows 7 Widget : Figure out how to develop a windows 7 widget
- Windows 7 widget : Get a working version of Sakai on my windows
- Windows 7 widget : Creating the necessary files for the widget and write the
initial code.
- Mac Widget: Got feedback from Christian

Day2
- Mac widget: Apply changes to the Mac Widget
- Windows 7 widget: Write the log-in code
- Mac Widget: Got feedback from Christian

Day3
- Mac widget: Apply the changes to the Mac Widget.
- Windows 7 widget: Get the recent messages functionality working
- Windows 7 Widget : Write the log-out functionality.

Day 4
- Windows 7 Widget: Finish the widget
- Windows 7 Widget: Fix CSS & JavaScript bugs.
- Windows 7 Widget: Figure out how to deploy the widget.

Day 5
- Mac Widget: Implement the functionality to display the users’ profile
information.
- Mac Widget: Start implementing the chat functionality.

Chapter: Appendix C : Weekly Reports:


29
Olivier Janssens Sakai3 2009 - 2010

17.11.2 Summary

This week I started developing the Widget for windows 7. Initially I planned on making a
Windows Vista widget but then I was told a windows 7 widget would be better.

17.11.2.1 Getting Sakai working

To develop a Windows 7 widget I needed a machine that ran Windows 7. I was told I could
use one of the windows 7 computers in Caret. The only problem here was that I needed to
develop the widget on my Mac and then deploy it every time with remote desktop. And this
would cost me a lot of time.

So I chose to bring my laptop to Caret. The problem here was that my laptop wasn’t able to
connect to the wireless network because it’s some kind of apple network. So this meant I
wouldn’t be able to use the server that was running on my Mac. So I decided to get a
running version of Sakai on my windows machine.

This was easy because I just needed to take the compiled jar from my Mac and put it on my
windows machine. After this I cloned my master branch of the front-end from github on to
my windows machine. Then I was able to make a new branch for my Windows 7 machine.

17.11.2.2 Setting up the Gadget

While I was setting up Sakai on my laptop I did some research on the Windows 7 widget. It
turned out that it’s possible to use cookies inside the Widget. So this meant I was able to use
the normal Sakai log-in functionality instead of working with tokens like in the Mac Widget.

I also found out how to create a Windows 7 Widget (technically it’s called a Gadget). The file
structure is very similar to the Mac widget:

Chapter: Appendix C : Weekly Reports:


30
Olivier Janssens Sakai3 2009 - 2010

W7
w7i.html

w7.css

w7.js

Default.png

icon.png

gadget.xml

So the only difference here was that I needed an xml file instead of a plist.

17.11.2.3 Log in

When I was able to see my widget in the sidebar I started implementing the log-in
lo
functionality. I copied most of this code from the login page from Sakai itself. I just had to
make a few modifications.

I also found out that the cookies inside a gadget are kept during the time the widget is on
the desktop. So when the widget is closed to cookies get deleted.

17.11.2.4 Recent Messages

Since I ‘ve written this functionality before I was able to copy paste quite a lot here too. I just
had to modify some minor things and quite a lot of CSS. So the recent messages were
displayed in no time

17.11.2.5 Mac Widget

I also got some feedback on my Mac Widget, so I had to make a few changes in the widget.
These were just minor things like ids and classes that can’t have a capital letter or the prefix
of the ids and classes had to be changed (they all have to start
start with “mac_”. This is because
the Sakai developers strive for uniformity in their code. I also implemented a log-out
log
functionality.

17.11.2.6 Finishing up
Chapter: Appendix C : Weekly Reports:
31
Olivier Janssens Sakai3 2009 - 2010

After this I got back on the Windows 7Gadget. The only things left to do now were:
implement the log out functionality, change quite a lot of CSS and fix a few bugs in my
JavaScript code.

When this was done I did some research on how to deploy the Windows 7 Widget. This
seemed fairly straight forward since I just had to zip the gadget folder and then rename it to
“.gadget”. But this didn’t work for some reason. After a few hours of changing things in the
XML it finally worked. I still don’t know why it didn’t want to work the first time.

17.11.2.7 Profile information

At this point the Windows 7 Gadget was done so I got back on the Mac Widget. This time I
implemented the profile functionality. Because initially I wanted to start implementing the
chat but unfortunately the chat was broken that day. Displaying the users’ profile was rather
easy, so it was done fairly quickly.

17.11.2.8 Chat

Because eventually the chat would be fixed, I started writing the chat implementation. To do
this I had a look at the current chat. I started with getting the current online users.

17.11.2.9 Next Week

Next week I hope the chat functionality will be fixed in Sakai so I can continue on the chat.

Chapter: Appendix C : Weekly Reports:


32
Olivier Janssens Sakai3 2009 - 2010

17.12 Report Monday 24 May – Friday 28 May

17.12.1 Log

Day 1
- Mac Widget: Make a GUI for the chat.
- Mac Widget: Get the online users from the logged in person.

Day2
- Mac widget: Research how to send a message.
- Mac widget: Implement the first part to send a message.

Day3
- Mac widget: Research how to receive a message.
- Mac widget: Implement how to receive a message.

Day 4
- Mac widget: Allow the user to have multiple conversations at the same time.
- Mac widget: Deploy the widget to see if everything works on the dashboard.
- Mac widget: Fix a few bugs.

Day 5
- Mac Widget: Fix bugs (CSS &JavaScript).
- Mac Widget: Implement how to stop a conversation.

Chapter: Appendix C : Weekly Reports:


33
Olivier Janssens Sakai3 2009 - 2010

17.12.2 Summary

Now that the windows 7 widget was completed, I had chosen to implement the chat
functionality in the Mac widget. I chose to do this first in the Mac widget because Nakamura
(Sakai back-end server) is stable on a Mac and not so stable on a windows machine.

17.12.2.1 Mac Widget: GUI

The Mac widget is rather small so I had to keep this in mind when designing the chat. I’d
chosen to base my chat on the current Sakai chat , which looks like facebook’s.

17.12.2.2 Mac Widget: Getting the online contacts

The first thing to do was to get the online contacts. This was fairly easy as I had an example
of the Sakai chat. The only difference was that I had to pass an extra request header “x-
sakai-token” to make sure it was an authenticated call. The response of this Ajax call consists
of all the contacts ( offline and online). So I had to filter out the offline contacts. Those were
then displayed. This had to be done every 5 seconds.

17.12.2.3 Mac Widget : Starting a conversation

Just like in the Sakai chat I chose to allow the user to start a conversation when clicking on a
username. The things to keep in mind here were that when the users clicks on a username
and the conversation is already happening. This means that the chat box is already created,
another one shouldn’t be allowed to be created.

Another thing to keep in mind was that when 1 conversation was created and the user starts
another one , the 2nd should be created at the right side of the previous one and not on top
of it. Normally this isn’t a thing you would have to keep in mind but since everything in a
widget is “position absolute” , I had to keep it in mind.

To start an actual conversation I had bound a key press event to the input box and then I did
an Ajax call with the values gotten from the chat window.

17.12.2.4 Mac Widget : Getting the Chat messages

To get the chat message a certain node in JCR has to be polled every other second. The
response contains a value “update” which is false when there are no new chat messages.

If this update is true another request is be done to get the actual chat messages. When
getting these chat messages, 1 thing has to be kept in mind. Is the conversation already
occurring or does it still have to begin ? This is a check that I had to implement. Another
thing that I had to keep in mind was that when sending a message e.g. You are logged in as

Chapter: Appendix C : Weekly Reports:


34
Olivier Janssens Sakai3 2009 - 2010

admin and you send a message you’ll also get this message back when polling for chat
message.

This meant that it’s not very wise to just append every received chat message to the chat
box. These had to be filtered out. I did this by adding an id “mac_delete” to the chat
message when appending it to the chat box (when sending the message). And then when I
receive this message I check if this id exists if it does I don’t append it to the GUI.

The last thing to keep in mind is that it’s also possible for the same user to send a chat
message from different platforms . e.g. The user can be logged in Sakai (site) and via my
widget. This means that the user can chat from 2 places. I had to make sure that when
sending a message from 1 platform that it also was displayed on the other platform.

17.12.2.5 Mac Widget: Debugging

Because the engine of the widgets is safari I had to debug everything in Safari . Safari doesn’t
have firebug which makes debugging and developing in general very hard and very difficult.
Almost all code that I had to write had to be correct from the first time because, to find the
bugs I had to use alerts (the developer tools in Safari are rather bad). This is why developing
a widget for the Mac dashboard can take quite a lot of time.

When developing a Mac widget everything is tested within the browser. Which doesn’t
necessarily mean that it’ll work when deployed on the dashboard.

17.12.2.6 Next week

Next week I’ll make sure that the chat works without any bugs. This means that there should
be a solution for when the user wants to have 100 conversations at the same time. When
this is done I’ll probably implement the chat functionality in the Windows 7 widget.

Chapter: Appendix C : Weekly Reports:


35
Olivier Janssens Sakai3 2009 - 2010

17.13 Report Week 13: Tuesday 1 June – Friday 5 June

17.13.1 Log

Day 1
- Bank holiday.

Day2
- Mac Widget: Add the user icons to the chat windows
- Mac Widget: Find an efficient way to let the user access the current
conversations that he/she has closed.

Day3
- Mac Widget: Implement paging functionality so that the user can have multiple
conversations at the same time.
- Igoogle widget: Research how to develop an igoogle widget

Day 4
- Igoogle Widget: Research how to make a Igoogle widget.
- Igoogle Widget: Setup the basics of the Igoogle widget.
- Igoogle Widget: Get the recent message from a person via the Igoogle widget.

Day 5
- Igoogle Widget: Get the profile information of the user via the Igoogle Widget.
- Igoogle Widget: Finish the widget (Jslint, Comments,readme)
- JIRA: Fix a Sakai bug.
- Widgets: Try to let all the widgets communicate with eachother.

Chapter: Appendix C : Weekly Reports:


36
Olivier Janssens Sakai3 2009 - 2010

17.13.2 Summary

This week was a short week since we had a bank holiday on Monday. The rest of the week I
worked on my Mac Widget, Igoogle widget and fixed a bug in Sakai.

17.13.2.1 Mac Widget: Paging:

Because the Mac Widget is rather small I had to find a way to allow the user to have a lot of
conversations at the same time, without messing up the design. I chose to implement
paging, since facebook is using this too. The paging itself wasn’t hard to write since I’ve got
quite a lot of experience all kinds of paging because of my flickr widget. So this was done
rather fast.

17.13.2.2 Igoogle Widget:

Since the Mac widget was now done I chose to start developing an Igoogle Widget. I first had
to find out how to make one. It turned out it was pretty easy to make one. The Igoogle
Widget is basically an XML file with content in it. The only requirement is that this XML file is
hosted on an online domain so I couldn’t use localhost.

Xml file :

I chose to upload the xml file to www.ojtwist.be and set the content to an html file on my
localhost. This worked perfectly. The big advantage here is that I could use all the Sakai API
functionalities (This wasn’t the case in the Mac & W7 widget).

The Igoogle widget can be developed in almost every programming language. I chose to do it
in JavaScript & HTML, for the obvious reason that whole Sakai is built in it.

To actually see the widget on the Igoogle page you need to add a widget to the page called
“My Widget”. With this widget you can load the XML. And then the Widget is displayed.

Because of the lack of time I chose only to implement the Recent message and the profile
functionality. Because I’ve done this twice before this only took my an afternoon. After this
the widget was done.

17.13.2.3 JIRA

Because my Widget was done I was assigned a JIRA. This is a ticket of a bug in Sakai. I solved
this quite easily.

Chapter: Appendix C : Weekly Reports:


37
Olivier Janssens Sakai3 2009 - 2010

17.13.2.4 Widget Communication

Maxime Debosschere is currently working on an apple Iphone/Ipod touch app for Sakai. This
is near completion. Christian asked us to try if my widget could communicate with his app.
This took my quite a while to do because our Sakais were a different version. And there were
some minor problems because of ip configuration.

When this was done I wanted to add Bert Pareyn’s Sakai air application to this collaboration.
But unfortunately this didn’t want to work.

17.13.2.5 Next week

Next week I’ll make a movie of the collaboration between Maxime and me. And then I’ll be
solving JIRAs for the rest of the week.

Chapter: Appendix C : Weekly Reports:


38
Olivier Janssens Sakai3 2009 - 2010

18 Appendix D: Project fiche

Chapter: Appendix D: Project fiche


1

You might also like