Resumen en español al final del artículo
(Editor's Note: This is the second - and last - part of a 1600 word saga on how to develop Sugar Activities using HTML5 and in particular the Enyo framework. You can find the first part here.)
How to start?
Let's start with a very simple HTML page with images and sounds coming from the Art4Apps library. Run the sample.
When you click on an image, you could hear the pronunciation of the word.
Here is the Enyo source code for this page:
enyo.kind({
name: "TestArt4Apps",
kind: enyo.Control,
components: [
{ components: [
{ content: "Click image or use control bar to hear the word.", classes: "title" },
{ kind: "Item.Element", text: "Alligator", image: "images/alligator.png", sound: ["audio/alligator.ogg", "audio/alligator.mp3"], classes: "item" },
{ kind: "Item.Element", text: "Girl", image: "images/girl.png", sound: ["audio/girl.ogg", "audio/girl.mp3"], classes: "item" },
{ kind: "Item.Element", text: "Sandwich", image: "images/sandwich.png", sound: ["audio/sandwich.ogg", "audio/sandwich.mp3"], classes: "item" },
{ classes: "footer", components: [
{ content: "Images and sounds CC BY-SA from", classes: "licence" },
{ tag: "a", attributes: {"href":"http://art4apps.org/"}, content: "Art4Apps", classes: "licence" }
]}
]}
],
// Constructor
create: function() {
this.inherited(arguments);
}
});
new TestArt4Apps().renderInto(document.body);
This source code creates a new JavaScript Enyo component "TestArt4Apps" with three "Item.Element" and some simple text contents. The last line (normally embedded in the HTML page) will create the object and will ask to Enyo framework to render it as the body of the HTML document.
"Item.Element" is another Enyo component that consolidates image, sound and text. Here is the source code:
enyo.kind({
name: "Item.Element",
kind: enyo.Control,
published: { image: "", sound: "", text: "" },
ontap: "taped",
components: [
{ name: "itemImage", classes: "itemImage", kind: "Image", ontap: "taped" },
{ name: "itemText", classes: "itemText", ontap: "taped" },
{ name: "itemSound", classes: "itemSound", kind: "HTML5.Audio", preload: "auto", autobuffer: true, controlsbar: true }
],
// Constructor
create: function() {
this.inherited(arguments);
this.imageChanged();
this.soundChanged();
this.textChanged();
},
...
});
I'm sure you could appreciate here the simplicity of the Enyo framework. You just need to compound components of the page and leave styles and formatting stuff in the CSS file.
Let's transform this HTML page into a Sugar Activity. As you probably know a Sugar Activity is a ".XO" file. A "XO file" is just a zipped file with Python code and initialization (setup and a manifest). To avoid complexity related to this file, I've prepared a template here. The template is a standard Activity with a Web Browser that fills the main part of the screen. Here is the Python code to do that:
vbox = Gtk.VBox(True)
self.webview = webview = WebKit.WebView()
webview.show()
vbox.pack_start(webview, True, True, 0)
vbox.show()
The template also includes the latest version of the Enyo Framework. So you just copy all your HTML content in a the "html" subdirectory and that's all. At startup the Python code will launch your "index.html" page in the Web Browser. Here how:
web_app_page = os.path.join(Activity.get_bundle_path(), "html/index.html")
self.webview.load_uri('file://' + web_app_page)
I've copied my sample page into this template, the resulting XO Activity is downloadable here. It's a standard Sugar Activity like any other. Here is the result:
The complete source code can be found on git.sugarlabs.org.
How to integrate HTML5 content with Sugar?
Writing Activity using HTML5 and JavaScript is nice but there is some time where you probably need to call Sugar API. It's the case for example when you would interact with the Activity toolbar or when you need to store contents in the Sugar datastore (i.e. Journal).
To avoid integration of an HTTP Server in the Activity, I choose to develop a small framework that allows bi-directional exchange between the Activity and the embedded HTML content. The framework is available both in Python and in JavaScript. So you could call Python code from your HTML5 content and conversely.
On the Python side, you just need to create a new instance of a class named "Enyo" with the WebView object as parameter:
self.enyo = Enyo(webview)
Then you could subscribe to JavaScript events using the "connect" method. Here the "init_context" Python method will be called when the JavaScript will raise a "ready" event.
self.enyo.connect("ready", self.init_context)
Conversely you could send a message to the JavaScript code using the "send_message" method. Here the "forward_clicked" event is sent to JavaScript when the toolbar forward button is clicked. The event will receive a parameter (here the number 1) that could be a base type or a complex object (conversion from Python data types to JavaScript data types are handle by the framework).
self.enyo.send_message("forward_clicked", 1)
The JavaScript side is no more complex. You just need to instantiate a "Sugar" class object in your HTML5 content.
this.sugar = new Sugar();
You could subscribe to Python events using the "connect" method that you bind to a JavaScript method. Here the code to react to the toolbar event explained before.
this.sugar.connect("forward_clicked", enyo.bind(this, "upgradePageCount"));
You could also send a message to the Python code using the "sendMessage" method. Once again the framework will manage the optional parameter to convert it to a Python object.
this.sugar.sendMessage("ready");
Note that my template integrates this framework so both the Sugar object and the Enyo object are already instantiated in the template.
I've wrote a more complete sample to show how exchanges between Python and JavaScript works. You could download the Activity and see source code here.
This other Activity use basic and complex message exchanges between Python and JavaScript and use events to synchronize Python widgets with HTML controls. More, it include a small HTML5 Logo Turtle that you could pilot from Python :-)
Conclusion
With the Art4apps content and the Enyo to Sugar framework, we hope that more developers will be interested by Sugar development and will expand the existing library of Sugar Activity. If you're an HTML5 developer: you've got the key so please give your talent to children!
Lionel Laské is the president and co-founder of OLPC France.
Resumen en español: En esta segunda - y ultima - parte mitad de una saga con 1600 palabras se explica lo que hay que hacer para adaptar y integrar una aplicación de HTML5 con Sugar. La primera parte está allí