Yahoo! Mobile - Blueprint Blog
Get Yahoo! Go 3.0

Trapster shows location-chooser and map control in action

Thursday July 24th 2008

Trapster, a service that alerts you about police speed traps, has recently updated their Blueprint Widget to use the location-chooser and map controls. With the new version, users can easily find their location by typing it in and getting Yahoo! geo-location results, or by pressing one button to retrieve GPS or Cell ID information (on supported devices).

Once the location has been set or automatically retrieved, the map control displays speed traps around the users location as POIs. By selecting different POIs, the user can get details about the trap, such as the presence of red-light cameras or the number of reports about a particular trap.

Location chooser in Trapster widget Trapster Widget uses <map> component

The map control provides a full-featured map service including zoom, pan, traffic information, and satellite or hybrid view.

Trapster shows a very good use of two new controls introduced with Blueprint 1.0. The coding required a change in the blueprint.php library that has been published with todays SDK update. Please use the new SDK version if you want to implement the location-chooser using the blueprint.php helper classes. An additional documentation in the SDK provides you with more detailed information on how to use the location chooser control.

Especially if you are using Yahoo! Go 3.0 on a GPS-enabled devices you definitely should try this service. The widget is live in the Widget Gallery.

Thanks to Trapster for building such a great Blueprint Widget!

Filed under: Mobile Widgets
No Comments
Posted by Markus

SDK Update

Wednesday July 23rd 2008

We just launched an update of the Blueprint SDK. The new sdk.zip contains:

• an updated Blueprint Developers Guide
• an updated blueprint.php helper class with a bug fix related to the location-chooser
• a Quick Start guide for developers who are new to Blueprint
• a guide to the location-chooser control
• an article (adapted from this blog) that provides *guidelines for designing Widget icons

The new documentation will help you to understand the complex location-chooser control. The Quick Start will give you an overview of Blueprint and help you with the Twitter example that comes with the SDK.

Especially if you are working on projects that use location-based services, we encourage you to download the updated SDK from: http://mobile.yahoo.com/developers/download

Filed under: Mobile Widgets
1 Comment
Posted by Markus

A Blueprint example in PHP/XSLT

Friday July 11th 2008

Our friends from the Yahoo! Developer Network (YDN) published a great article that guides you through the first steps of Blueprint development. The example that is described in the article is a widget that displays RSS content from the YDN blog. It is a great example of how to code a Blueprint widget using PHP/XSLT and pulling data from an existing RSS feed.

You can find the article here: A quick Blueprint how-to - your first widget.

Filed under: Mobile Widgets
No Comments
Posted by Markus

Introducing: Blueprint 1.0

Wednesday June 25th 2008

We are happy to announce our first official version of Blueprint. It’s now out of beta and available in version 1.0. We have streamlined the language as well as extended it by adding exciting new features. Here’s a quick rundown on four of the most exciting new features that will help you to write compelling mobile widgets:

Location awareness
With Blueprint 1.0 you can use the location chooser to prompt the user to enter their location. If your widget runs in the Yahoo! Go 3.0 client environment on a phone that supports either GPS or cell ID location, the user can send their location to you without entering it manually in the phone. As a developer you have only to specify the in your widget and the Blueprint platform will pass the location to you.

Maps
The new map feature makes it easy for you to display one or more POIs on a mobile map without building the whole map infrastructure from scratch. On some devices, an interactive map is inlined where the control occurs. On other devices, the control appears as a static image that links to a full-screen interactive map. Each POI is represented by a clickable icon that opens a pop-up containing descriptive text and an image. Want to specify a certain zoom level on your map? No problem. Show traffic information? Absolutely! Show your map in satellite or hybrid map view containing street information? Go for it! We wanna see cool mobile widgets with maps-a-go-go.

Driving Directions
Help mobile users find their way. The show-driving-directions feature provides an interactive map for specified origin and destination.

Table support
Organizing and displaying structured data on a small screen is a challenge. For example, if you want to display sports scores, time tables, or financial overviews such as stock quotes, you will need to work with tables. The new Blueprint 1.0 table support gives you flexibility to display content in a table on a mobile in a smart way.

If you wanna hear more, don’t worry. Each of these new features will be discussed more in detail in the next few days in separate blog posts.

For now please go ahead and download the new SDK, read the documentation and look through the new sample widgets.

If you already have developed a widget on Blueprint we encourage you to read the release notes that cover that changes that have been made during the beta phase till this official first release now.

Please make sure that if you already have developed a widget and you like to update it with one of the features mentioned above to re-submit it using the “Submit Upgrade” link in your Manage Widgets page.

We can’t wait to see all your new widgets showcasing the new features of Blueprint 1.0!

Your Yahoo! Blueprint Team

Filed under: Mobile Widgets
No Comments
Posted by Markus

Write a Widget in 15 Minutes with Ruby on Rails

Monday June 2nd 2008

In this article, I’ll show you how easy it is to get a widget up and running with Ruby on Rails. For the purpose of this article, a familiarity with Rails 2.0 or higher is assumed. If you would like to follow along with the actual code, feel free to download it first.

The first thing we need is an idea for our widget. For the sake of simplicity, let’s say we wanted to display a list of the most popular searches on Yahoo!. If you head on over to the Yahoo! Buzz Index, you’ll see that we can pull from several RSS feeds to get the information we’re after. For this widget, we’ll be displaying the top searches in the following categories: overall, actors, movies, music, sports, tv and video games.

Creating the Rails Application

The first thing we need to do is generate our application code and databases:

$ rails ybuzz
$ rake db:create:all

Generating the Model

Next, we will generate a Category model to represent each of our 7 search categories. Each category will have a name and a feed url:

$ ./script/generate model Category name:string feed_url:string


Now we need to create a new model for each category. Since this is a fairly static list of categories, there is no need to create an interface for category creation. Instead, we can just set up each of our categories in the migration file, in the self.up method:

overall = Category.new(
  :name       => "Overall", 
  :feed_url   => "http://buzz.yahoo.com/feeds/buzzoverl.xml")
actors = Category.new(
  :name       => "Actors", 
  :feed_url   => "http://buzz.yahoo.com/feeds/buzzactl.xml")
movies = Category.new(
  :name       => "Movies", 
  :feed_url   => "http://buzz.yahoo.com/feeds/buzzmovl.xml")
music = Category.new(
  :name       => "Music", 
  :feed_url   => "http://buzz.yahoo.com/feeds/buzzmusl.xml")
sports = Category.new(
  :name       => "Sports", 
  :feed_url   => "http://buzz.yahoo.com/feeds/buzzsportl.xml")
tv = Category.new(
  :name       => "Television", 
  :feed_url   => "http://buzz.yahoo.com/feeds/buzztvl.xml")
videogames = Category.new(
  :name       => "Videogames", 
  :feed_url   => "http://buzz.yahoo.com/feeds/buzzgamesl.xml")
overall.save
actors.save
movies.save
music.save
sports.save
tv.save
videogames.save


Now we need create the database table for categories and populate it:

$ rake db:migrate


In order to get RESTful routes for categories, we can add the following line to routes.rb, which will give us the method, category_path, that we can use in our views to link to specific category pages.

map.resources :categories


The Category model is where the meat of our application code will go. We want to be able to take a particular category, and have it give us all of the top searches from the Yahoo! Buzz Index in that category. To do this, we will create an instance method, named searches, in our Category class, which fetches an XML feed, and returns a list of top searches in its category. To make things interesting, let’s also see if we can find a photo on Flickr which corresponds to the search term, for a little more visual appeal. In order to use the Flickr API, you will need to sign up for an API key. We can create a variable in our environments.rb file to store our key, so that it will be available to us throughout the application.

FLICKR_KEY = "insert_flickr_key_here"


Now that we have a key for the Flickr API, we can start fetching and parsing the XML for our Buzz feed. To do this, we will be using the Hpricot gem. If you haven’t used this before, I recommend reading through the documentation on the website. It’s a very easy to use XML parser, which allows us to use XPath to target nodes in a document. We will also be using open-uri to fetch the actual XML document, so you may need to require that library in your Category model. Opening an XML document with Hpricot and open-uri is very easy. First, let’s take a glance at what our feed actually looks like:

<?xml version="1.0" encoding="iso-8859-1" ?>
<rss version="0.91">
  <channel>
    <title>Yahoo! Buzz Index Leaders Overall</title>
    <link>http://buzz.yahoo.com/overall/</link>
    <description>Yahoo!'s most popular search terms.</description>
    <language>en-us</language>
    <copyright>Copyright 2008 Yahoo! Inc. All rights reserved</copyright>
    <managingEditor>buzz-help@yahoo-inc.com</managingEditor>
    <item>
      <title>1. American Idol</title>
      <link>http://search.yahoo.com/search?p=american+idol&cs=bz</link>
    </item>
    <item>
      <title>2. Jessica Alba</title>
      <link>http://search.yahoo.com/search?p=jessica+alba&cs=bz</link>
    </item>
    ...
  </channel>
</rss>


And the code to fetch that feed and turn it into something we can use:

doc = Hpricot.XML(open("http://buzz.yahoo.com/feeds/buzzoverl.xml"))


This will return an Hpricot::Doc object which we can traverse to find the nodes we are interested in. Since this is an RSS feed, the nodes we care about are all the item elements in the document. The expression to return all these elements is:

items = doc.search("//item")


Once we have all the elements in our feed, we can iterate over them and attempt to find a photo from Flickr that relates to the search term.

items.each do |item|
  title = item.at("title").innerHTML.gsub(/[0-9]*.s?/,'')
  photos_url = "http://api.flickr.com/services/rest/?method=flickr.photos.search
&api_key=#{FLICKR_KEY}&text=#{CGI::escape(query)}
&per_page=5&license=1,2,3,4,5,6"
  photos_doc = Hpricot.XML(open(photos_url))
  photos = photos_doc.search("//photo")
  if !photos.empty?
    photo = photos[rand(photos.length)]
    user_id = photo["owner"]
    user_url = "http://api.flickr.com/services/rest/?method=flickr.people.getInfo
&api_key=#{FLICKR_KEY}&user_id=#{user_id}"
    user_doc = Hpricot.XML(open(user_url))
    user_name = user_doc.at("person").at("username").inner_html
    image = {
      :url => "http://farm#{photo["farm"]}.static.flickr.com/#{photo["server"]}/
#{photo["id"]}_#{photo["secret"]}.jpg",
      :owner => user_name
    }
  else
    image = false
  end
  searches << { :title => title, :image => image }
end


This code first finds the title element within the item element and does a regular expression replacement of the leading numeral (1., 2., etc.) returned by the Yahoo! Buzz feed. Next, it constructs a Flickr API photos.search url using our Flickr API key and a url-escaped version of the search query from the feed. This url returns 5 Creative Commons licensed photos whose title or description match the search query. It then uses Hpricot to fetch an XML document from Flickr and parses out all 5 of the photo elements from it. Since we don’t want to see the same photo every time, we select a random element from this array of photos. The last step is to find the username of the owner of each photo so that we can attribute the source of the photo in our widget. This requires making a call to the people.getInfo API method.

Some minor refactoring of our model code, and this is our final category.rb:

require 'hpricot'
require 'open-uri'

class Category < ActiveRecord::Base

  def searches
    doc = Hpricot.XML(open(self.feed_url))
    return parse_searches(doc)
  end
  
  protected
  
  def parse_searches(doc)
    searches = Array.new
    items = doc.search("//item")
    items.each do |item|
      title = item.at("title").innerHTML.gsub(/[0-9]*.s?/,'')
      image = get_flickr_image(title)
      searches << { :title => title, :image => image }
    end
    searches
  end
  
  def get_flickr_image(query)
    begin
      timeout(2) do 
        url = "http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=#{FLICKR_KEY}
&text=#{CGI::escape(query)}&per_page=5&license=1,2,3,4,5,6"
        doc = Hpricot.XML(open(url))
        photos = doc.search("//photo")
        return false if photos.empty?
        photo = photos[rand(photos.length)]
        user_id = photo["owner"]
        user_url = "http://api.flickr.com/services/rest/?method=flickr.people.getInfo
&api_key=#{FLICKR_KEY}&user_id=#{user_id}"
        user_doc = Hpricot.XML(open(user_url))
        user_name = user_doc.at("person").at("username").inner_html
        image = {
          :url => "http://farm#{photo["farm"]}.static.flickr.com/#{photo["server"]}/
#{photo["id"]}_#{photo["secret"]}.jpg",
          :owner => user_name
        }
        image
      end
    rescue Timeout::Error
      return false
    end
  end

end

Generating The Controllers and Views

The next step is to create our controllers. We will need two controllers - one for the main “splash” page which gives the user the option of choosing which category they want to view and one for displaying the top searches for each category.

$ ./script/generate controller buzz
$ ./script/generate controller categories


At this point, it is worth mentioning that a Yahoo! widget must send a Content-Type: application/x-ywidget+xml header. It is also strongly recommended to send a Cache-Control: no-cache header in order to avoid your widget’s dynamic content from being cached, particularly for the Java Go client. So, let’s create a before_filter in our application controller which sets the necessary headers for each response:

class ApplicationController < ActionController::Base
  before_filter :set_content_type
  
  protected
  
  def set_content_type
    response.headers["Content-Type"] = "application/x-ywidget+xml"
    response.headers["Cache-Control"] = "no-cache"
  end
end


In order for us to have a blueprint template we can use for our views, we need to create a new layout in app/views/layouts named application.html.erb:

<page>
  <content>
    <header layout="simple">
      <layout-items> 
        <block class="title">Most Popular Y! Searches</block> 
      </layout-items>
    </header>
    <%= yield %>
  </content>
</page>


This is a blueprint layout with one simple header element. The layout yields to our action views, where the main content for each page will go.

Now we can create the view for our main controller, which just lists the available categories. It will only have one index method. Here, we will find all categories and store them in an instance variable so that they will be available to the view.

def index
  @categories = Category.find(:all)
end


The view for this action is where we will create the blueprint to show a list of all the categories. So, create a file named index.html.erb in app/views/buzz:

<module>
  <header layout="simple">
    <layout-items> 
      <block class="title">Select a Category</block> 
    </layout-items>
  </header>
  <% @categories.each do |category| -%>
  <placard layout="simple" class="link">
    <layout-items>
      <block class="title"><%= category.name -%></block>
    </layout-items>
    <load event="activate" 
          resource="<%= category_path(category).sub('/','') -%>" />
  </placard>  
  <% end -%>
</module>


Rendered Blueprint for Splash Page
Rendered Blueprint for Splash Page

We create one module element where our list of categories goes. Inside of that, we have a simple header element and a series of placard elements, one for each category. Each placard lists the category’s name (Overall, Actors, Movies, etc.) and links to its corresponding page. It’s worth noting here that we are using our RESTful routes for categories with the category_path method. However, we need to remove the first slash from the path, i.e. /categories/1, to turn it into categories/1. If we don’t do that, the widget platform will create the link //categories/1.

Now we can create the actions and views for displaying each category’s top searches in the categories controller. Since we are using RESTful routes, the categories/1 path will map to the show method of the categories controller. This will be the only action we create in this controller.

def show
  # get category from params array
  @category = Category.find(params[:id])
  # get the top searches from buzz feed
  @searches = @category.searches
  # load all categories for navigation
  @categories = Category.find(:all)
end


This code finds the category with the given id extracted from the GET parameters and loads its top searches. We also need to load all the categories so that we can display links to those category pages in our view. So now we need to create a view file called show.html.erb in app/views/categories:

<options>
  <% @categories.each do |category| -%>
  <option>
    <label><%= category.name -%></label>
    <load event="activate" 
          resource="<%= category_path(category).sub('/','') -%>" />
  </option>  
  <% end -%>
</options>
<module>
  <header layout="simple">
    <layout-items>
      <block class="title"><%= @category.name -%></block>
    </layout-items>
  </header>
  <% @searches.each do |search| -%>
  <placard layout="card" class="link">
    <layout-items>
      <% if search[:image] -%>
      <image resource="<%= search[:image][:url] -%>" />
      <% end %>
      <block class="title"><%= search[:title] -%></block>
      <% if search[:image] -%>
      <block class="subtext">*photo credit: <%= search[:image][:owner] -%></block>
      <% end -%>
    </layout-items>
    <load event="activate"
          resource="http://beta.m.yahoo.com/m/search?q=<%= CGI::escape(search[:title]) -%>" />
  </placard>
  <% end -%>
  <block class="small gray">*All photo credits are cited as Flickr usernames.</block>
</module>


Rendered Blueprint for Actors Category Page
Rendered Blueprint for Sports Cateogory Page

First, we create an options element to link to all of our category pages. Next, we open a module element, and display a simple header with the name of the category being shown. Finally, we iterate over the category’s top searches, displaying a placard element for each one. The placard contains the Flickr photo and attribution, if available, and the search query. Each placard links to a oneSearch for that particular search query.

And that’s it! The last thing left to do is package our application for deployment.

Packaging Your Widget

As with all widgets you wish to deploy, you must create a directory structure like the following:

Widget Packaging Structure
Widget Packaging File Structure

The important file here is config.xml. Here’s an example:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://mobile.yahoo.com/widgets/schema/1.0/config/"
  xmlns="http://mobile.yahoo.com/widgets/schema/1.0/config/">
  <title>Yahoo! Search Buzz</title>
  <version>0.1</version>
  <identifier>ysearchbuzz</identifier>
  <description>See the most popular searches on Yahoo!</description>
  <icon>buzz</icon>
  <author organization="Yahoo!" href="http://michael.vc" 
          email="mj@yahoo-inc.com">Michael Johnston</author>
  <widget base="http://michael.vc:21000">
    <preview>
      <icon>buzz</icon>
      <label>Y! Search Buzz</label>
    </preview>
    <shortcuts>
      <item default="true">
        <label>Main</label>
        <href>buzz/index</href>
      </item>
    </shortcuts>
  </widget>
</config>


In this case, we are serving our rails application on port 21000, although it is up to you to serve your widget however you like. And don’t forget that the email attribute in the author element is now required for all widgets.

Besides the config.xml, you also need to create a gallery.xml which is used when users are browsing your widget in the Widget Gallery. Lastly, you’ll need to create icons for your widget. For an in-depth overview of how to make excellent icons that look well across all devices, take a look at this article.

The final step is zipping up this directory and submitting it for testing. Once you test it out in your Yahoo! account, and make sure everything works as expected, you can submit it for real to the Widget Gallery, and watch as users subscribe to your widget.

So, that’s a quick overview of how you can take a widget from concept to completion in 15 minutes with Ruby on Rails. There are certainly other considerations to keep in mind when creating a full-featured widget you intend to deploy to users, such as internationalization. But I hope this gives you Rails developers out there a jump start into the Mobile Widget Platform. So get out there and start developing!

You can pick up the source code here.

Filed under: Mobile Widgets
No Comments
Posted by Michael

Empty nodes for controls required

Thursday May 29th 2008

Hi, please read this post carefully if you already have developed a widget or you are just in the process of developing one.

We are not doing the right thing in our current release. We are supposed to hide controls that are bound to nodes that do not exist. Unfortunately, we documented (and implemented) it such that you just get an empty control. This is not proper xForms behavior and we must change it.

What you need to do is basically to add empty nodes for the controls you want to show up:

<instance>
<data>
<name/>
</data>
</instance>

Previously, you did not have to have the name node to get an empty control. Now you do and we like you to check your widget code if you have to implement these changes and add empty nodes.

Our next release is coming up in the next few days and it will require to have empty nodes for controls. If you already have submitted a widget, please change it and upload your server-side code again.

Let us know if you have any questions by posting them to the Mobile Developers Group.

Markus

Filed under: Mobile Widgets
No Comments
Posted by Markus

Update to config.xml schema

Thursday May 22nd 2008

We launched a small but important update to the test and gallery submission pages. The author element in the config.xml file needs now to contain an email attribute. The email attribute is required (so that Yahoo! can contact you even you are not using Yahoo! as your standard mail provider), but is not available to the public and will not be published in the Widget Gallery.

A sample author element looks now like this:

<author organization=”MyCompany” href=”http://www.mycompany.com” email=”john@mycompany.com”>John Doe</author>

The organization and the href attributes are optional; email is now a requirement.

Please make sure to include this new attribute from now on in your config.xml for testing your widget and the final submission to the widget gallery.

You can also download a new version of the SDK package that contains updated documentation and updated samples, templates as well an updated schema.

Filed under: Mobile Widgets
1 Comment
Posted by Markus

How to Make Great Widget Icons

Friday May 9th 2008

PNG vs. GIF

In order to render the best quality icons for your widget, you’ll need to upload your icons in PNG 24 format with alpha-transparency blending. If you know what this means, you can skim through this article, read the section on sizing, and get back to work on your widget. If you don’t, please read through this tutorial and complain to the management if you haven’t figured it out by the end.

Below are four images that show the difference between what you can do with the alpha channel capabilities of the PNG format, and what you can (or can’t) do with the anti-aliasing capabilities of the GIF format. Note that the two examples on the left blend seamlessly with the background, while the images on the right break abruptly.

 

PNG 24: Alpha channel against a transparent background.

 

GIF: Anti-aliasing with one color (white) removed against a transparent background.

 
 

PNG 24: Image with an alpha channel against a colored background.

 

GIF: Image anti-aliased against a white background on top of an unintended background color.

Now that you see the distinction between the two image formats, you’re probably wondering why anyone would use the GIF format when PNGs are so much sexier. The answer’s easy: Not all devices support the PNG format, so the fallback is GIF.

Problem? Nah! Fortunately for you, the exceptionally talented and hard-working Blueprint rendering team here at Yahoo! Mobile has solved this problem for you. They’ve built an engine that renders your icons as PNGs on devices that support them, and as GIFs on the devices that don’t. It even anti-aliases the GIFs against the various background colors on page headers, section headers and placards.

So, the bottom line is: Figure out this PNG stuff, upload them with your widget, and you’re square. Upload GIFs and you’re… wait, bad analogy –you know what I mean.

*If you want to know more about alpha channels and anti-aliasing, please read the addendum at the bottom of this article.

Working with Branded Assets

Are you building a widget for an established company? If so, then you can often find a logo in PNG, EPS or PDF format on the Press section of the company’s website or from a designer within the company. If nobody gives you one, keep asking. They’re bound to have it somewhere. Once you have a good source file in one of these formats, it’s pretty easy, using an imaging program such as Adobe Photoshop, to convert them while retaining the alpha information and resize them to the correct sizes needed for your widget.

Logo Creation from Scratch

I’ll go over the process of logo creation using tools many people are familiar with, Adobe Flash and Adobe PhotoShop. If you’re not familiar with these programs, you should probably just give-up now and hire a designer. If you’re stubborn, however, you can download trial versions from their website at Adobe.com and labor through the following instructions.

First, I’ll create a piece of vector art in Flash, then render it into a high-resolution PNG file for further manipulation in Photoshop. Working with vectors is an excellent way to get a high-quality image that scales without losing quality. You can draw your icons at a high resolution, then scale them down to get a good idea of how they will look at various sizes.

Step 1: Draw your logo

Open a new Adobe Flash file and start drawing your logo. It’s important to remember that your logo will eventually be contained in a small square, so you’ll want to leave out extremely detailed features or text that will be unreadable at small sizes. A good technique is to draw a square box on a layer of it’s own, lock the layer, and then draw your logo inside it on a new layer above. Then, when you’re finished, you can simply remove the underlying layer before exporting your image.

Here is an example of a logo I created in Adobe Flash for my moBar widget that can be scaled down to look good at any size.

Step 2: Export your image

Once you’ve created your logo and are happy with the way it looks at various sizes, you’ll want to remove the background box and any other artwork (such as the scaled-down copies you just created) and export the image. You do this by selecting File > Export > Export Image from the menu.

Once you name your file and select Save, you’ll be presented with a dialog box that looks something like this:

Don’t worry too much about the Dimensions of the image at this point, but you’ll need to make sure that you select Minimum Image Area from the Include dropdown and select the Smooth checkbox.

There you have it! You’re PNGing, baby! Almost there!

Step 3: Sizing Appropriately

Now that you have your PNG source file, you can start resizing your icon to the various sizes needed by the Blueprint rendering engine. It’s important to note that although you only need to upload one 90×90 icon for your widget, it’s good practice to create as many sizes as possible so that you have some control over what gets rendered at each size. Those smart and conscientious Blueprint engineers I told you about earlier, have identified 19 different sizes of icon that various devices will display, so if you want to ensure that your icon is going to look how you intended, you can create each of these sizes and upload them with your widget.

In some cases, if you have a logo that looks good at say, 52×52 pixels, but terrible at 12×12, you may want to consider using entirely different artwork at the smaller sizes. If you don’t have the time or patience to create all 19 sizes of logo, don’t worry, the Blueprint renderer will take the closest size match that is bigger than the size the device will display and scale it down to the appropriate size for that specific device.

It’s always a good idea to include at least these four sizes:

90×90, 52×52, 34×34 & 16×16.

If you’re paranoid, however, you can include them all (believe me, it’s fun):

90×90, 70×70, 68×68, 56×56, 52×52, 46×46, 44×44, 40×40, 38×38, 34×34, 30×30, 28×28, 26×26, 22×22, 20×20, 18×18, 16×16, 14×14 & 12×12.

Step 4: Resizing in Adobe PhotoShop

Now that you have your source file and know the image sizes you want, you can start working in PhotoShop. I recommend taking the following steps.

  1. Resize your source file to a perfect square. You do this by selecting Image > Canvas Size in the menu, then adjusting the height or width in the dialog to match the larger of the two sizes. In the example below, I’ve changed the width to the same size as the height and left the anchor at center.

  2. Now you can start resizing. My tactic is to create the same number of duplicates of the image in Adobe PhotoShop as I’ll be making icons. You can do this by going to Image > Duplicate in the menu. It’s a good idea at this point to give the same name to the duplicates as the names of the final images you’ll be saving.

  3. Once you have all your duplicates on the stage you can start resizing them. It’s important to remember that the final icons will need to have at least one pixel of transparent space around all edges of the image. What I found works best is to resize each duplicate to exactly two pixels smaller than the final target size, then go back and resize the canvas to the actual export size. So, you would resize your 90×90 image to 88×88, your 34×34 to 32×32, etc., then go back into the Canvas Size dialog and resize the canvas to the same size that you named the image while setting the Anchor in the middle of the box. This will ensure that you always have one pixel of transparency around the final icon.

  4. So, the steps are as follows:

    1. Go to Image > Image size in the menu, and resize the icon. (e.g. 88×88)

    2. Go to Image > Canvas Size and resize the canvas. (e.g. 90×90)

    3. Go to File > Save for Web and Devices and save as a PNG 24 with the Transparency checkbox checked in the controls on the right of the dialog.

    4. Save your file, making sure to name it with the underscore and size convention. (e.g. olive_90×90.png).

Follow the same steps for all your icon sizes and you’re almost there. Remember, you need the one pixel of transparency around the edges of the image, so that the Blueprint renderer can do a better job of resizing your icons for various devices.

Below is an example of what a 90×90 icon will look like when finished. I’ve blown it up to immense proportions, so you can see the detail.

90×90 olive icon at 300%. Note the 1 pixel of transparency around the edges.

Step 5: Using separate artwork for smaller logos

Again, using separate artwork at different sizes can be critical. Let’s say your icon is a hippopotamus. That’s a cool icon, and it may look great at 52×52, but anything under 34×34 looks like something that came out the back of a hippopotamus. One idea would be to use just one part of the larger image, such as the head of the hippo for your smaller sized icons.

This is a common problem with icons that contain logotype. An icon containing text is always unreadable at small sizes, so it’s important to have an alternate strategy.

Step 6: Submitting your icons

Now that you have all your icons and are ready to upload your widget, you’ll need to make sure you put them in the resources/images folder of your widget and name them appropriately. You can name your icon whatever you like, but it must contain the size information in the name. The format is this: olive_52×52.png, olive_34×34.png, olive_16×16.png, etc. Just make sure you also add the correct name to the nodes of your config.xml file before uploading. The default is “icon”, but in this case, it would be: olive.

Step 7: Brag

That’s it! You’re finished. Once your widget is active in the gallery, you can show all your friends what a great icon maker you are. Congratulations! Now go have drink, and don’t forget to tip one up for the Blueprint team!

Cheers, -T

More on Alpha-Channels

Alpha channels contain transparency information on a per-pixel basis, which is important for blending images into underlying backgrounds. Think of each pixel containing four channels; red, green, blue and alpha. By blending the first three channels you obtain color, while the fourth channel determines the transparency of the pixel. Transparency is especially important for the edges of your icons, which will be rendered against various color backgrounds. The only image format containing an alpha channel rendered by modern browsers is PNG (Portable Network Graphics), but unfortunately, not all browsers, especially mobile web browsers, support the PNG format, so in Blueprint, your PNGs will be converted to anti-aliased GIFs on the devices that can only render GIFs.

More on Anti-Aliasing

Anti-aliasing is a process of blending foreground pixels into background pixels without retaining the alpha information, thus creating a gradient of colors between the two layers. For example, anti-aliasing a black image against a white background, or visa versa, would result in a gradient of gray pixels between the two colors. This works great if your image is going to appear on the intended background color, but terribly if it ends-up on a different color. It’s still common to see GIF images on web pages with a halo around them, due to being displayed on a background unintended by the original designer. The GIF format does not support alpha channels, but instead supports full pixel transparency. This means that you can’t have color and transparency in the same pixel. Anti-aliasing against the correct color will yield great results, but if the image appears over the wrong color, you’ll have a choppy halo around the image.

Filed under: Mobile Widgets
No Comments
Posted by Travis

Go Global: Make your Widget available in other countries

Thursday April 24th 2008

Delivering on Yahoo! Mobile’s promise of globally accessible products, a few weeks ago we released Yahoo! Go 3.0 in 6 new countries. Germany, UK, France, Spain, Italy and Canada can now get a fully localized Yahoo! Go 3.0 experience in their native language. Yahoo! Go asks the mobile user to select their country when they use Yahoo! Go for the first time. This country information means that developers can build widgets with local awareness. The country and language information is included in a page request sent by Yahoo’s mobile application server.

  • Accept-Language
    This HTTP header contains the RFC 4646/4647 language code. For a US user this language code is mainly “Accept-Language: en-US”. For a German user the header would contain “Accept-Language: de-DE”. Yahoo! Go also supports multiple languages in the one country. For instance, in Canada, the user has the choice to choose between Canada/English (en-CA) and Canada/French (fr-CA).

  • Geo-Country
    This header contains only the country setting as an ISO 3166 country or UN M.49 region code. A sample header would look like this for Canada: “Geo-Country: CA”.

This language and country information can be very useful to you when deciding which language, or what type of content your widget should offer. Especially if you offer default values in your widget (like default currencies, cities or formats) you can now provide a better user experience by showing country and language specific content.

For our friends in other countries, we have not forgotten about you! We continue to work hard to roll out Yahoo! Go 3.0 to new countries and new devices, so stay tuned to this blog for the latest updates.

Au revoir, Auf Wiedersehen, Adios, Ciao, until next time!

Filed under: Mobile Widgets
No Comments
Posted by Markus

CTIA 08 Re-cap and the Widget approval process

Monday April 14th 2008

A few days ago saw the Mobile Widgets team at the CTIA Wireless show in Las Vegas where we spoke to mobile developers, operators and publishers about the Yahoo! Mobile Developer Platform. Apart from Yahoo’s announcements regarding the revolutionary new Yahoo! oneSearch 2.0(tm) featuring Yahoo! oneSearch with Voice, the Mobile Developer Platform area also attracted a lot of attention at the Yahoo! booth. We heard many questions from developers and publishers about our Mobile Widget approval process and thought many of you might have the same questions. We thought we’d answer one of the most frequently asked questions here:

Q: Does Yahoo! have a Mobile Widget approval process before the Widget goes live in the gallery?

A: Yes, there is an approval process. Here it how it works:

  • You start developing a Widget using the Blueprint SDK. Once you are ready to test it, you simply put together a zip package and submit it on the Test Widget page. Immediately after uploading, your widget will appear on the carousel in our Java client, or on your “My Widgets” page on the mobile home page (you must be signed in to view it). It is only visible to your Yahoo! account - no one else can see it during this phase. You can submit your Widget for testing as often as you like, but generally you don’t need to submit again unless you need to change your images or aspects of your configuration file.

  • Once you are done coding and testing, you submit the zip package via the Submit Widget page. Once uploaded, the Yahoo! Mobile Widgets team can see and test your Widget. Our goal is to ensure that your Widget works, is not broken, does not contain offensive content and complies with our Yahoo! Mobile Widget Developer Terms of Use. These terms can be viewed and need to be accepted before you upload your Widget. The approval process is very straight forward and should not take longer than a couple of days. If we have any questions regarding your submission we will get in touch with you via email. Once your Widget is approved you and the rest of the world will be able to see it in our Mobile Widget Gallery, both in Yahoo! Go 3.0 and through Yahoo’s new mobile home page.

As always, if you have any questions regarding Mobile Widgets, Blueprint or the Yahoo! Mobile Developer Platform, please feel free to ask at the Yahoo! Mobile Developer Group.

Happy coding!

Filed under: Mobile Widgets
No Comments
Posted by Markus
« Previous Entries
Next Entries »
  • Categories

    • Mobile Widgets
    • Uncategorized
  • Archives

    • October 2008
    • September 2008
    • August 2008
    • July 2008
    • June 2008
    • May 2008
    • April 2008
    • March 2008
    • February 2008
    • January 2008
  • Links

    • Yahoo!
    • Yahoo! Blueprint Developer Site
    • Yahoo! Developer Network
    • Yahoo! Mobile

Copyright © 2007 Yahoo! Inc. All rights reserved. Copyright Policy | Terms of Service | Send Feedback | Help | Privacy Policy.