*UPDATE 9/28/10: We have added an updated link to the “support files”. You can get the updated support files directly here. Thanks Jeremy!
Hello and welcome to the inaugural post of the Connected TV team blog. My name is Jeremy Johnstone and I’m a lead on the Connected TV team. Through posts on this blog, we will share tips and best practices which we hope will make it easier to develop TV widgets as well as share insight into why some of the things are architected the way they are.
In this first post, we are going to dive right into getting on board with the platform and give you a quick start guide to developing your first TV widget. The screenshots and instructions here will be using a Mac, but if you own a Linux or Windows based PC, have no fear, you are supported as well. This tutorial illustrates using Virtual Box as the virtual machine environment which is fully supported across all three platforms. Once you have Virtual Box and Vagrant installed, the process should be very similar from that point on.
To get started, what we need to do is to download the needed software. This list includes the following:
- Virtual Box – http://www.virtualbox.org
- VagrantVersion – http://www.vagrantup.com
- Yahoo! Connected TV Widget Development Kit (WDK) – http://connectedtv.yahoo.com/developer/
Please install Virtual Box and Vagrant following the instructions on their respective sites. Here are screenshots of Virtual Box being installed and running on OS X. After downloading the WDK from our website, save it somewhere handy as we will be needing it again here very soon.
The next step we need to do is to install the custom Ubuntu Vagrant “box” (their name for a VM image) we have created to make it easy to get up and running quickly. This box has all dependencies pre-installed and has been customized and stripped down to provide an ideal widget development environment. To install the box, we run the following commands at a shell prompt.
> wget http://h.yimg.com/us.yimg.com/lib/ctv/wdk/wdk.box.zip > unzip wdk.box.zip > vagrant box add wdk ./wdk.box
Depending on the speed of your internet connection, this may take a while (the file is about 1gb in size), so feel free to familiarize yourself with the documentation while we wait. After the box is downloaded and installed, you should see something like this. If you don’t and instead see an error, then please refer to the Vagrant documentation or visit the forums for additional assistance.
Ok, now that we have the box installed, we need to fire it up and take it for a spin. First we need to decide where on our local machine we want to store our widget code. In this example, our project directory is named “wdk” and it’s off of my home directory (aka ~/wdk). Feel free to put this anywhere you desire based on your preferred workflow. Inside this project directory, we are going to extract the zip file of the WDK we downloaded along with the support files zip from here. Inside the WDK zip we will find documentation and a Debian installer package (the .deb file). Inside the support files zip we will find a file named “Vagrantfile” used by Vagrant along with some sample code. The Vagrantfile is what contains the information needed to fire up the Ubuntu box we downloaded earlier. The nice thing about Vagrant is that if you ever completely hose your install and just want to start over, it’s as simple as running two commands and you have a new clean environment retaining all the widgets you developed previously.
To actually start up the VM, we need to run the following command from inside our project directory:
This simple command provisions a new virtual machine and starts it up. Don’t worry if you see a log line saying “Trying to connect” a few times as in this screenshot here, it will connect successfully as soon as the machine is started. Once it’s up and running, you should see something like this:
The next thing we need to do is fire up a terminal inside the VM and install the WDK. First click on Applications→Accessories→Terminal. When it opens, cd into the /devwidgets directory and after doing an
inside there to list the directory contents, you will see that the directory is actually mapped over to the same directory on your local machine in which you ran “vagrant up” from. This way you can use the development environments you are used to on your local machine and then simply use the VM environment to run the code and test your widget. To actually install the WDK, we need to run the installer which you can do by typing the following command:
At this point, we now have our environment fully setup and we are ready to begin developing our first widget. This widget will be a rather anemic “Hello World!” style widget following programming tutorial convention, but we promise future tutorials will include much meatier content. To create our HelloWorld.widget, we will simply make a copy of the BaseTemplate.widget which is provided in the support files zip file you downloaded (and should already be extracted in your project directory). Copy the directory similarly to the following:
cp -r BaseTemplate.widget HelloWorld.widget
After making the copy, fire up your favorite editor of choice and point it at that directory. In this tutorial, I am using TextMate which is a commonly used text editor on OS X, but feel free to use whatever works best for you. For development, I use a mixture of TextMate, vim, and Eclipse on a daily basis depending on the task I am working on, so pretty much every style app normally used for coding should be well-supported. You can see a screenshot here of TextMate running along with Terminal.app in the foreground on OS X with the Ubuntu VM running in the background.
The first thing we need to change in the HelloWorld widget is to edit the widget.xml file. This file contains identifier information which is used by our widget engine. The relevant piece we need to change at the moment is the identifier and give it something that is unique to you. Later, you can revisit this and customize the other portions but the identifier is the important part for now.
Next we need to add in the language strings we will use in our widget. Technically we could hard code English strings throughout the code, but as widgets are available in many languages, it’s a good practice to get used to unless you want to block a large portion of the globe from using your widget. These are stored inside a file called Localizable.strings inside the Resources directory. Inside the Resources directory you will see a number of directories, one for each language. For now, let’s just open up the Resources/en/Localizable.strings file and add the following strings:
"Snippet.Text" = "Hello World"; "Main.ButtonLabel" = "Press Me!"; "Main.DialogTitle" = "A button was pressed"; "Main.DialogMessage" = "You pressed the button!"; "Main.DialogOkButton" = "Ok";
You would do the same thing for the other language’s strings files in a real widget, but for simplicity we will just do English right now.
Now that we have our strings in place, we will now create our “snippet”. The snippet is a small view of the widget (think an app icon on steroids) which is shown along side other widgets in the widget dock. In our example we are going to simply have a stylized text element with the highly original string “Hello World!” in it. The code is as follows:
A sample of what the code should look like at this point is available here. Also take a look at that screenshot for additional background information on what’s going on in the code.
The next view type we need to create is a “sidebar” view. Sidebar views are one of the three available view types, the other two being snippet previously mentioned and also fullscreen views which will be covered in a future tutorial. They consume the left hand side of the TV screen. In our sidebar view, we are going to just have a single button which when pressed by the user shows a dialog box on screen. The code for this view is as follows:
Now that we have added that as seen here, we are ready to test out our widget for the first time.
Flipping back to the virtual machine which should still be running from when we started it before, we will start up the simulator and see our widget in action. We do this by clicking on Applications→TV Widgets→540 Latest Production→540 Latest Production Simulator from the start menu in the VM. Once the simulator starts up and does it’s initial bootstrap install, you should see something similar to this:
You might have to arrow over to the left to bring your widget into view. If you don’t see it, it might mean you jumped ahead and started the simulator before. If so, simply close the simulator and click on the “reset” option inside the same menu just below the simulator you picked previously. Once it finishes, close that window and restart the simulator as before.
With our widget now up and running, you should see the snippet saying “Hello World” like we previously coded. Hitting enter with that snippet focused (in blue) will instruct the dock to open the widget and show it’s sidebar. Inside the sidebar as seen here, we should see our button we added “Press Me”. Selecting it should also show the dialog box we added to the code.
Pretty neat and really simple, eh? The last thing I want to go over in this tutorial is to give a very brief introduction to the console and show how powerful it can be for debugging your widgets. You might have noticed when you started up the simulator that a terminal window opened and spewed lots of logs. Not only are these logs useful (albeit a bit verbose sometimes) in debugging your widget, that window is also a live console into the widget engine allowing you to do virtually anything you can do in your code, live in the widget. If you have ever done web development and used Firebug, this is somewhat similar.
The first thing we need to do in the console is switch to the “context” of our widget. Each widget is segregated into it’s own “context” space so they can’t interfere with each other. To find out which widget context is for your widget, type the following into the console window:
You can also use the shorthand version which is $$(); to print out the same thing. Looking at the output, you will see there is a window tag which contains a single text element node with the text “Hello World”. This window is our snippet view. The actual structure isn’t super important as the KONtx framework abstracts this away from you, but it can be helpful especially for debugging purposes.
var view = $('snippet-main');
$() is a shortcut function which makes it easier to get a reference to an element which was added into the DOM (in this case a view). Next what we will do is to change the text which is shown inside the snippet. If you remember back to when we created the SnippetView class (feel free to look back if not), you will see that we assigned the created Text element to “this.controls.text”. In the scope of a view like that, ‘this’ is the view class itself and using the above code we made a reference to the class object with the variable named ‘view’. So in the console now, if we access view.controls.text we will be directly accessing the Text element we had created in our widget. Text elements have a helper method on them named setText() which allows you to change the text shown to the user at a later time after creating it. If you type the following into the console:
you should see the snippet update instantly from saying “Hello World” to “Hi Mom!” similar to what’s shown in this screenshot:
This example barely scrapes the surface of what’s possible in the console and future tutorials here will go into much more depth.
I hope you have enjoyed this tutorial and that it’s been informative. If you have any questions or concerns, please do not hesitate to post in the forums or contact us at email@example.com. Additional documentation beyond what is included in the WDK download can be found on YDN at http://developer.yahoo.com/connectedtv/