Advertisement

How to Add Auto Complete to Your Google Custom Search Engine

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

This tutorial will show you how to use the "Popular Queries" feed from your Google Custom Search Engine (CSE) as a data source for a jQuery autocomplete.

Preface

Google CSE Homepage

Google's Custom Search Engine (CSE) allows you to create a robust search feature for your Web site. They offer a free,
ad-supported version and a premium business version that starts at $100 per year. Additionally, CSE provides a wide range of metrics, ranging from integration with
Google Analytics to a feed of popular search queries.

This tutorial will show you how to use PHP and jQuery to add an auto complete feature to CSE's default search box using the popular search queries feed as the data source.

In order to successfully use this technique on your site, you'll need your own Google CSE and a decent amount of search traffic (to ensure we have a nice set of data for
our auto complete list).

Don't worry if you don't meet all of these requirements—you can still follow along. Google often cites MacWorld's CSE implementation
as an example, so I'll be using their search feed in this tutorial. Feel free to do the same if you'd like.

Let's get started.

Step 1: Create Your Search Page

The first thing we'll do is add the CSE's default search code to a new XHTML page. You can find this by logging into your control panel and clicking "code." It will
look something like this.

	<form action="http://www.google.com/cse" id="cse-search-box">
	  <div>
	    <input type="hidden" name="cx" value="003198751674731024891:ovffo1orlum" />
	    <input type="hidden" name="ie" value="UTF-8" />
	    <input type="text" name="q" size="31" />
	    <input type="submit" name="sa" value="Search" />
	  </div>
	</form>
	<script type="text/javascript" src="http://www.google.com/coop/cse/brand?form=cse-search-box&lang=en"></script>

Save this document in a new folder as search.html and open it in your browser. Search for something to make sure the search box works.

Google CSE Search Results

Step 2: Adding the jQuery Auto Complete Function

Although the jQuery UI has an auto complete function built in, you might find the
auto complete plugin
created by Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, and Jörn Zaefferer is a little easier to use. Download
jquery.autocomplete.zip and unzip it.

The plugin's archive contains a variety of different scripts for many implementations. While the best practice would be to move the scripts and stylesheets we're
going to use to appropriately named folders inside of our page's root, in the interest of simplicity, let's just drag the
"jquery-autocomplete" folder into the folder our search.html is in.

The plugin comes with a demo illustrating how the auto complete could be used with city names. Let's make sure jQuery and our plugin are working properly
by hooking our Google search box up to the list of cities. In search.html, add the following inside the <head> tag.

	<script type="text/javascript" src="jquery-autocomplete/lib/jquery.js"></script>
	<script type="text/javascript" src="jquery-autocomplete/jquery.autocomplete.js"></script>
	<script type="text/javascript" src="jquery-autocomplete/demo/localdata.js"></script>
	<link rel="stylesheet" type="text/css" href="jquery-autocomplete/jquery.autocomplete.css" /></p>
	
	<script type="text/javascript">
	$().ready(function() {
		$("#cse_search").autocomplete(cities);
	});
	</script>

We'll also need to slightly modify CSE's default search code by adding an id attribute to the search box. We'll call it "cse_search."

    <input type="text" id="cse_search" name="q" size="31" />

Save search.html and open it in your browser. In the search box, start typing the name of a city; you should see the autocomplete menu.

Starting to enter the name of a city will offer suggestions.

Step 3: Getting the Data Set

In the previous step, we included the "jquery-autocomplete/demo/localdata.js" script. If you open the file and look at it, you'll see a few different
JavaScript arrays. These are the arrays used to populate auto complete lists in the plugin's demo files. When we initialized jQuery and instructed the plugin
to auto complete our "cse_search" box, we also told it to get its data from the cities array:

	$().ready(function() {
		$("#cse_search").autocomplete(cities);
	});

Now we need to instruct jQuery to use our popular queries feed as its data source. But how?

We'll use a little PHP to pull in the popular queries feed, parse it, and echo out a valid JavaScript array. By including the PHP file as we would
a regular JavaScript file, it will be executed behind the scenes and the Web browser will think it's reading a static JS file.

Additionally, we're also going to supplement our popular queries feed with terms that we specify. The terms we specify here may not be searched often
enough to show up as a "popular query," but they still may be useful to have in our auto complete list. For instance, terms for which you've created
Google subscribed links or terms that monetize well with
AdSense for Search.

Create a file inside the "jquery-autocomplete" folder called searchdata.php and paste in the following:

	<?php
		/* This script parses the Popular Queries feed from Google's CSE product and outputs
		   the recent queries in a JavaScript array for use with the jQuery Autocomplete plugin. */

		// There may be some search queries you want to include in the autocomplete box
		// that aren't necessarily popular searches and therefore don't show up in your 
		// Google CSE feed.  You can add those terms to this array to ensure they show up.
		// You will want to make sure you enter the terms in lowercase. 
		$data = array(
			"steve jobs",
			"macbook pro",
			"macbook air",
			"itunes",
			"ipod"
		);

		// Load the Popular Queries RSS Feed from Google's CSE using SimpleXML
		// The URL is available by clicking "Statistics" from inside your CSE control panel.
		if (!$s = simplexml_load_file("http://www.google.com/coop/api/003198751674731024891/cse/ovffo1orlum/queries?sig=__GaZojo71AtdDbVHqJ9KDPhwXAhk=")) {
			exit();											// cheap error handling.
		}

		// Create an array of all the popular queries. 
		foreach($s->item as $item) {
			$search_term = strtolower(trim($item->title)); 	// trim() is used to remove whitespaces.
			if (!in_array($search_term, $data)) {           // ensure there are no duplicates. 
				$data[] = $search_term;					    // add $search_term to data array.
			}
		}	
		sort($data); //alphabetize the array

		// Format the data for JavaScript output.
		foreach($data as $search_term) {
			$js_data[] = "\"" . $search_term . "\"";	
		}	
		
		// Let's inform the browser that we're sending JavaScript.
		header("Content-type: text/javascript\n\n");
		
		// Next we'll escape from PHP and create a JavaScript array. Inside the array, we'll return to
		// PHP and use implode() to return a comma-separated string of all the data inside $js_data.
	?>
	var searchdata = [<?php echo implode($js_data, ", "); ?>];
Output of searchdata.php

If you're using your own CSE feed, you'll want to replace the URL on line 7. In this example, I used the overall popular queries feed for MacWorld.com.
You can use your own overall popular queries feed by going to your CSE Manage Page > Statistics >
Overall. Other available options are popular query feeds by day, week, and month.

Next, we'll need to remove the demo's localdata.js script from search.html and replace it with our searchdata.php file:

	Replace:
	<script type="text/javascript" src="jquery-autocomplete/demo/localdata.js"></script>
	
	With:
	<script type="text/javascript" src="jquery-autocomplete/searchdata.php"></script>

We'll also need to slightly modify our initialization code:

	Replace:
	$("#cse_search").autocomplete(cities);
	
	With:
	$("#cse_search").autocomplete(searchdata);

Now let's upload everything to the server and give search.html a shot. If everything is working like it's supposed to, your auto complete
should be working perfectly.

A working examples of the CSE RSS-powered autocomplete.

A Word on Caching

Sites that receive a significant amount of traffic may want to consider caching the search array. Having the server parse the feed
each time someone types into the search box will use a significant amount of resources. You can cache the results by replacing your
searchdata.php file with the following:

Note: The script will create the cache for the first time, but it must have write access to the directory you're
going to store it in.

	<?php
		/* This script parses the Popular Queries feed from Google's CSE product and outputs
		   the recent queries in a JavaScript array for use with the jQuery Autocomplete plugin. */

		// Set information about the cache
		$cache_path	= "cache/searchdata-cache.txt";   // the directory must be writeable by the server
		$cache_time = 3600;							  // seconds to keep the cache for

		// Determine if the cache is there
		$cache_exists = @file_exists($cache_path);	  // returns true or false

		// Let's inform the browser that we're sending JavaScript.
		header("Content-type: text/javascript\n\n");

		// If there is a cache and it's old, delete it. If it's current, use it.
		if ($cache_exists) {
			$cache_age = filectime($cache_path);
			if ($cache_age < (time() - $cache_time)) {
				unlink($cache_path);				  // delete the cache
			} else {
				include($cache_path);				  // load the cache
				exit();								  // no need to continue processing
			}
		}

		// There may be some search queries you want to include in the autocomplete box
		// that aren't necessarily popular searches and therefore don't show up in your 
		// Google CSE feed.  You can add those terms to this array to ensure they show up.
		// You will want to make sure you enter the terms in lowercase. 

		$data = array(
			"steve jobs",
			"macbook pro",
			"macbook air",
			"itunes",
			"ipod"
		);

		// Load the Popular Queries RSS Feed from Google's CSE using SimpleXML
		// The URL is available by clicking "Statistics" from inside your CSE control panel.
		if (!$s = simplexml_load_file("http://www.google.com/coop/api/003198751674731024891/cse/ovffo1orlum/queries?sig=__GaZojo71AtdDbVHqJ9KDPhwXAhk=")) {
			exit();											// cheap error handling.
		}

		// Create an array of all the popular queries. 
		foreach($s->item as $item) {
			$search_term = strtolower(trim($item->title)); 	// trim() is used to remove whitespaces.
			if (!in_array($search_term, $data)) {           // ensure there are no duplicates. 
				$data[] = $search_term;					    // add $search_term to data array.
			}
		}	
		sort($data); //alphabetize the array

		// Format the data for JavaScript output.
		foreach($data as $search_term) {
			$js_data[] = "\"" . $search_term . "\"";	
		}	

		// Setup the cache
		$fp = fopen($cache_path, "w");

		// Create the JavaScript array
		$js_array = "var searchdata = [" . implode($js_data, ", ") . "];";

		// Write the array to the cache
		fwrite($fp, $js_array);

		// Close the cache
		fclose($fp);

		// Include the cache file.
		include($cache_path);
	?>
  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.