Fall Housekeeping

November 1, 2010

When we introduced this blog over four years ago, the term AJAX was only a year old, and Google had exactly one relevant API . Ajax has since become a mainstream part of the Web, and our family of APIs has grown. Like many growing families, we’ve accumulated a lot of cruft over the years, and have outgrown our first home. Time for some housekeeping.

API Documentation - Now easier to find and use
We’ve reorganized our documentation to make it easier to find what you’re looking for, based on what you want to do. We used to group our APIs based on technology - for instance, there were Google Data APIs and AJAX APIs. Now, you’ll see that each API has been given its own place, including its own documentation pages. This new documentation has been created from the ground up to provide a better experience for people coding against the APIs. We’ve also organized these more logically by product, such as moving the Book Search API into the Books family of APIs, and added many more samples to help you get started.

A fond farewell
In the spirit of consolidation, we’ll be retiring this blog in favor of the Google Code Blog. By concentrating on fewer blogs, we’ll be able to keep the blog fresher and help make sure that as wide an audience as possible is able to benefit from our posts. We’ll continue using tags, so that you can subscribe to your favorite APIs and focus on the content that most interests you (though we hope you’ll check in occasionally to see what new stuff you might be missing).

Show your support for the Code blog by hopping over to read about the new Google APIs console and Custom Search API, and also say good-bye to the Web and Local Search APIs, which are being deprecated. Full post here.

Posted by: Adam Feldman, Product Manager

Increase site efficiency by retrieving just your preferred number of results

June 29, 2010

When using any of the searchers available in the Search API, four results are returned by default. Historically, it has been possible to request a large set of eight results (or ten for filter Custom Search Engines), but that’s it. We understand that there are many use cases for this API, and some of them require a finer grain of control over the number of results displayed.

For instance, with the JavaScript API, you can use .setResultSetSize(1) or .setResultSetSize(6) in addition to using the enum to request a SMALL_RESULTSET or LARGE_RESULTSET. When using the RESTful interface, you can also use any integer from 1 to 8 with the rsz parameter.

With this addition, you can now request an arbitrary number of results, based on the exact number you need. By requesting only the results you’re going to show to the end-user, you can make your site or app more efficient. Also, this will control the cursor values that can be used to retrieve subsequent pages of results (and impact paging in the Custom Search element).

For more details, check out the documentation, and if you have any questions, stop by our IRC channel and support forum.

Diacritization added to the Google Language API

June 24, 2010

Earlier this year, we launched the Tashkeel (Diacritization) service on Google Labs. I'm pleased to announce that we've added an experimental Diacritization component to the Google Language API. This is a simple JSON API which you can use to add diacritic symbols to strings of Arabic text.

To test it out, try clicking this link:
https://www.googleapis.com/language/diacritize/v1?lang=ar&message=مرحبا%20العالم&last_letter=false&callback=result

A URL-encoded string is supplied as the message parameter, and it's returned by the API with diacritics included. These symbols are useful to people just learning the language and as an important pre-step for several text processing applications.

Right now, the API only supports Arabic, but we're working on adding more languages, as well as a JavaScript API, so be sure to watch this blog for details. For more information, see the documentation and our post on the Google Arabia blog (you may want to click "view post in English").


Posted by: Adam Feldman, Product Manager and Jeff Scudder, Software Engineer

Google Feed API — Now with instant gratification

May 19, 2010

One of Google's most popular APIs is our Feed API. This API is found all over the web, making any feed content available for developers to embed on their sites.

A problem with embedding content in this manner is that there's no good way to make sure that your visitors see the freshest data, regardless of how long they stay on your page. Of course, you could try polling (also known as the "are we there yet?" method), repeatedly reloading the feed to see if the content has changed. This technique is generally a waste of bandwidth and doesn't always result in very low latency.

Instead, we've got something better. I'm pleased to announce a preview of a brand new version of the Feed API, which includes push updates. With this new version, you'll be able to make the latest feed data available to your visitors - when it's available - without polling or requiring a page refresh. The best part is that this will work with any PubSubHubbub enabled feed.

Here's a short demonstration of what I'm talking about:
video

As the video shows, this new version works much like the older Feed API. But instead of loading the existing feed data, you actually subscribe to the feed, and your callback is executed any time new feed data comes in.

Let's see how this works. First, you must load the API (just like before, except now v2):

google.load("feeds",  "2");
Now, subscribe to the feed you're interested in and give the callback to be executed:
var feed = new google.feed.push.Feed("example.com/atom.xml");
feed.subscribe(myCallback);
And, finally, you need to write the callback method that is run every time there's an update. In this example, we just display each new entry title as it comes in:
function myCallback() {
var container = document.getElementById("feed");
for (var i = 0; i < result.feed.entries.length; i++) {
var div = document.createElement("div");
div.appendChild(document.createTextNode(result.feed.entries[i].title));
container.appendChild(div);
}
}
For a running example you can try out, check out the Code Playground.

We want to encourage you to experiment and build innovative applications with this new API - but since we don't know how it will be used, we can't quite open the floodgates yet. Therefore, we're initially making it available on a sign-up basis. Please fill out this form, telling us a little about how you'd like to use this API, and we'll try to give you access as soon as possible. Also, please remember that this is a Code Labs version, and therefore it may change or be removed at any time.

After we get some data from this experimental period we'll be able to open it up to everyone. Once you've begun experimenting, be sure to stop by our support forum or IRC channel to share your creations with everyone. If you'd like to learn more about how this API works, our Google I/O session will be posted to YouTube soon.


Posted by: Brett Bavar, Software Engineer and Adam Feldman, Product Manager

Transliteration API adds 6 more languages

April 25, 2010

We're excited to announce the addition of 6 new languages (Greek, Russian, Serbian, Sanskrit, Amharic, Tigrinya) to the Transliteration API. Using Google Transliteration you can convert Roman characters to their phonetic equivalent in your language. Note that this is not the same as translation — it's the sound of the words that are converted from one alphabet to the other.

Transliteration API allows this functionality to be available to all websites, which will make it easier for you to add transliteration capabilities to textfields on your webpages. Using this customizable API, you can enable users of your website to type 19 languages. For more information, please take a look at the documentation and samples at our code playground. If you're looking for a finer level of control on your web pages, also check out the low-level interface to transliteration, and the font rendering support APIs.

Google Transliteration is integrated into several Google properties and we have bookmarklets in addition to API to extend this capability to other websites. Please try these out and let us know what you think and how you're using it.

Posted by: Kuntal Loya and Ajay Somani, Software Engineers

Rendering custom data in the Custom Search element

April 13, 2010

Last year we introduced Rich Snippets in Custom Search, allowing you to define your own custom attributes that we'll index and return with your custom search results. A few months later we showed you how to render some of these rich snippets in your Custom Search element. Sure, this was a powerful way to let your visitors see thumbnails or interact with the results via actions. But we felt it was still too constrained. It is with great pleasure that today we're announcing that you now have full rendering control of all your metadata in the Custom Search element.

What do I mean? If a picture is worth a thousand words, an example is worth a thousand pictures. Here's a fully customized element, showcasing results and metadata from Scribd.com:

By  -  pages -  views  - last modified 


The results really jump out at you, huh? The thumbnails really help users see what they're looking at, but we've shown you those before. Same with the Download action links by each result. But never before could you include arbitrary, per-result metadata with your Google Custom Search results so easily. Notice the author, length, views and date information in each result. There's even an icon representing each result's document type.

So how can you add this to your page? Let's take a look.

First, you need to include custom attributes within your webpages, either via microformats, RDFa, or a special markup called PageMaps. A PageMap identifies specific attributes that Google recognizes and indexes, and then returns along with search results. Our prior blog post on Structured Custom Search tells you how to add PageMaps to your site. Please keep in mind that your site needs to be re-indexed, which can take some time. Therefore, your PageMaps might not show up immediately.

Once your custom attributes have been indexed, you're ready to tell the element how to render them. If you don't already have the element on your page, you can add it with a few lines:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// Load the Search API
google.load('search', '1');

// Set a callback to load the Custom Search Control when you page loads
google.setOnLoadCallback(
function(){
new google.search.CustomSearchControl('INSERT-YOUR-ID').draw('cse');
},
true);
</script>
<div id="cse"></div>
Here's the Scribd.com sample, with only the default rich snippet inclusion:

It looks okay, but let's make it better.

We have to override the default rendering, by adding this line to the onLoadCallback:
google.search.Csedr.addOverride("mysite_");
Now, create a div to hold all of the rendering information - put it right above the div that the element uses:
<div style="display:none">
</div>
Okay, now that everything's set up, it's time for the good part. First off, let's try shrinking the thumbnails a bit. Inside the div that was just added above, and tell the element to render the images at 48x48 pixels:
<div id="mysite_thumbnail">
<div data-if="Vars.thumbnail" class="gs-image-box gs-web-image-box">
<a class="gs-image" data-attr="{href:url, target:target}">
<img class="gs-image" data-attr="{src:thumbnail.src, width:48, height: 48}"/>
</a>
</div>
</div>
This replaces the default thumbnail rendering code with a similar version that sets the image dimensions directly.

Here's the same sample with the above code added:
Now it's time to add the new content and tweak the rendering of the basic content, too:
<div id="mysite_webResult">
<div class="gs-webResult gs-result"
data-vars="{longUrl:function() {
var i = unescapedUrl.indexOf(visibleUrl);
return i < 1 ? visibleUrl : unescapedUrl.substring(i);}}">

<table>
<tr>
<td valign="top">
<div data-if="Vars.richSnippet" data-attr="0"
data-body="render('thumbnail',richSnippet,{url:unescapedUrl,target:target})"></div>
</td>

<td valign="top">
<div class="gs-title">
<a class="gs-title" data-attr="{href:unescapedUrl,target:target}"
data-body="html(title)"></a>
</div>
<div class="gs-snippet" data-body="html(content)"></div>
<div class="gs-visibleUrl gs-visibleUrl-short" data-body="longUrl()"></div>
<div style="& Vars.richSnippet.document">
<img data-attr="{src:Vars.richSnippet.document.filetypeImage}">
By <span data-body="Vars.richSnippet.document.author"></span> -
<span data-body="Vars.richSnippet.document.pageCount"></span> pages -
<span data-body="Vars.richSnippet.document.viewCount"></span> views
- last modified <span data-body="Vars.richSnippet.document.timeAgo"></span>
</div>

<div data-if="Vars.richSnippet && Vars.richSnippet.action" class="gs-actions"
data-body="render('action',richSnippet,{url:unescapedUrl,target:target})"></div>
</td>
</tr>
</table>
</div>
</div>
Voila! The sample is now complete, and here's how it looks:

This example is a bit more complex. It shows how to use the render() function to call other code, and also how you can include any JavaScript logic. You can even define internal functions, such as longUrl().

Didn't quite catch all of that or want to do even more? Check out the documentation.

The best part of announcing new features like this is seeing what innovative implementations people come up with. Don't keep us waiting - come show off your handiwork in our support forum or IRC channel!
Posted by: David Gibson, Software Engineer and Adam Feldman, Product Manager

Restricting by licenses now available in the Image Search API

April 12, 2010

I'm always amazed at the creative ways developers use Google's APIs. I'm always pleased when we are able to add a new feature to the API, as I know that someone, somewhere will do something cool and unexpected with it. The latest addition is to the Image Search API. You can now restrict results by various licenses applied to each image.

There are two different ways to use this feature. In the JavaScript API, you can restrict your results to one of four common licenses (just like on Google Image Search). This is done using the setRestriction method, after creating your Image Search searcher. Here's how to restrict to images which have been labeled for reuse with modification:

var searcher = new google.search.ImageSearch();
searcher.setRestriction(google.search.ImageSearch.RESTRICT_RIGHTS,
google.search.ImageSearch.RIGHTS_MODIFICATION);
You can experiment with a live example of this in our Code Playground.

If you're using the JSON API, you can use the as_rights optional parameter to tell the API to include or exclude certain attributions. To perform the same restriction as above, try adding this to your requests:
&as_rights=
(cc_publicdomain|cc_attribute|cc_sharealike|cc_noncommercial).-(cc_nonderived)
For a full list of the attribute combinations for each type of license, perform an appropriately restricted search on Google Image Search's advanced search and take a look at the as_rights parameter in the URL on the results page.

Note: Images returned with this filter may still have conditions on the license for use. Please remember that violating copyright is strictly prohibited by the API Terms of Use. For more details, see this article.

Please come visit our IRC channel and support forum and let us know how you've used this feature in your site or app!

Media RSS support added to the Feed API

April 8, 2010

More and more sites are adding support for MediaRSS to include images, videos and other types of multimedia files. Today, we're announcing that the Google Feed API now includes this metadata in the response. This content is now included in the JSON and XML results returned by the API. For more details on the result format, check out the documentation.

Please note that complete MediaRSS content is generally only available in feed entries newer than February 1, 2010.

Questions? Comments? If you're attending Google I/O, come meet the team and learn more about the Feed API at our Office Hours. If you can't wait that long, there's always our IRC channel and support forum.

Helping you help us help you

March 31, 2010

As I mentioned in a previous post, we've taken several measures to help differentiate legitimate API traffic from bad requests. To help us serve you better, I'm pleased to announce a new way for you to identify your request as harmful. Beginning today, please include the &evil=true parameter in your API requests if you're one of the bad guys.

How does this work in practice? Here's an example query which lets Google know that you're intending to use the API for nefarious purposes. This way, we can respond to your request in the appropriate manner as efficiently as possible.

Note: In order to encourage adoption as quickly as possible, we are requiring all bad requests to include the evil bit by the end of today, April 1.

Search Form and Results on Two Different Pages

March 16, 2010

One of the major advantages of an Ajax style search box is that users can perform their queries and get their results without leaving the page. However, some webmasters prefer that their users go to a separate results page after they enter a search. The Ajax search library supports this "two-page" use case as well, and since this is a question that we see from time to time we've set up a simple demo site.

To create this page we wrote a simple form in HTML and added JavaScript to add the "Google Custom Search" branding in the search box. View source to see all the details.

When the user submits the form, they are taken to a results page which has the following HTML structure:

    <div id="results">Loading...</div>

We then tell the search library to draw its search box and results in the div we just created:

        // Draw the control in content div
customSearchControl.draw('results');

Since the user came to this page from our search form, their query terms are now part of the page URL, so all we need to do now is extract them and execute their query:

      function getQuery() {
var url = '' + window.location;
var queryStart = url.indexOf('?') + 1;
if (queryStart > 0) {
var parts = url.substr(queryStart).split('&');
for (var i = 0; i < parts.length; i++) {
if (parts[i].substr(0, 1) == 'q') {
return unescape(parts[i].split('=')[1].replace(/\+/g, ' '));
}
}
}
return '';
}

// See the source code of the results page for full details.

...


// Run a query
customSearchControl.execute(getQuery());

There is one more optional setting that you might be interested in. The second page which we've just created contains a search box that will allow the user to perform searches on this same page. If you would prefer for the search box not to appear on this results page we can add the following HTML to the page:

    <input style="display:none" id="hidden-input" />

We hide the input box because we don't want the Ajax search library to render the usual query input box, just to show the results. We then tell the search library to draw its search box in the hidden input, making it invisible:

        // Set drawing options to use our hidden input box.
var drawOptions = new google.search.DrawOptions();
drawOptions.setInput(document.getElementById('hidden-input'));

// Change the draw call to include our new options.
customSearchControl.draw('results', drawOptions);

To see an example of a two-page search setup with a hidden query input, visit this page.

To learn more about the Google Custom Search API, read our documentation. If you run into any problems while setting this up, post your question in our discussion group or hop on our IRC channel.