Add Google AJAX Search to your DNN skin (Part 2 of 3)

Location: BlogsAll BlogsDNN Development    
Posted by: mamlin 7/27/2008 6:33 PM

Following up on Part 1 of this series on adding Google Custom Search to your DotNetNuke skin:  Here in Part 2 we'll examine a few of the many options for customizing Google searches as well as ways to influence the ranking of results.  As part of the customization we'll learn how to initiate multiple searches at once (and see why you'd want to do that).  And just as in Part 1, all of this functionality is delivered for -free- from the Google Search AJAX library...


Parts 1, 2 and 3
In Part 1, we saw how to remove DNN Search out of your skin and replace it with the (free) Google AJAX search.  Here, in Part 2, we will examine a few of the many options for customizing Google searches as well as ways to influence the ranking of results.  Finally, in Part 3, we'll see how to tie it all in with a Google web account (totally free) so you can define and manage custom engine criteria online and get user search info reported to you via Google Analytics (also totally free).


Recall the Nitty-Gritty
In the final step (2D) outlined in Part 1, we added a JavaScript function "OnLoad()" that instantiated several objects (defined in the Google library file), set options on those objects and then added a page OnLoad event to call the "OnLoad()" function.  This step comprised the bulk of the changes made in Part 1 and I told you to just add it all and ignore the "nitty-gritty" details until Part 2.  Well, here we are in Part 2 and it's time to get nitty about the gritty.

Recall the function that we added:

   function OnLoad()
   { 
      var searchControl = new google.search.SearchControl();
      var drawOptions = new google.search.DrawOptions();
      drawOptions.setInput(document.getElementById("gss_input"));
      var options = new google.search.SearcherOptions();
      options.setExpandMode(google.search.SearchControl.EXPAND_MODE_OPEN);
      options.setRoot(document.getElementById("
ContentPane"));
      // options.setNoResultsString("No results found.");  <-- This option is broken as of 11/10/2008
      searchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
      searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET); 
      var siteSearch = new google.search.WebSearch();
      siteSearch.setSiteRestriction("YOUR WEBSITE URL GOES HERE");
      searchControl.addSearcher(siteSearch, options); 
      searchControl.draw(null, drawOptions);
   }

In the spirit of keeping this closer to a blog entry rather than a textbook, I'll cover only the most interesting points and gloss over the rest.

First up, we create a "Search Control".  You have to have it and you only need one.  We'll cover a couple of this object's options in a bit.

Next is "DrawOptions".  You should know that you can use DrawOptions to have Google auto-insert its own text input field and labels.  If you do you'll have little or no control over input field sizing, colors, etc.  I prefer to use my own input box so that's what our example does.  For our example, then, the only thing we need from "DrawOptions" is to define a link to our input box.  We do this via "DrawOptions.setInput()".

Moving on we come to "SearcherOptions".  This object tells Google where to deliver our results and how to display them.  The next few lines define some of these options:

  • setExpandMode:  display search results in a collapsed DIV or an expanded DIV (default)
  • setRoot:  defines what page element/container to insert search results into
  • setNoResultsString:  sets what message is displayed when there are no search results 
    NOTE:  As of 11/10/2008, the 'setNoResultsString' option causes an error when no search results are returned.  I have commented it out of our example, above, until Google fixes the issue in their AJAX library.

Now we jump back to the "Search Control" object.  Our example is setting two options:

  • setLinktarget:  defines whether search links open in the same window or a new window
  • setResultSetSize:  defines how many results are returned per result page;  Currently you may define result sizes of 1, 4 or 8 though you cannot specify the size directly by an integer value.  Instead you must use Google's predefined labels.  For our example we used "LARGE_RESULTSET" in order to view 8 results per result page.

Finally we get to "WebSearch".  This is where things get interesting.  Google provides different types of searches including web, blog, book, image, video and more.  WebSearch references the standard Google search and is probably what you'll use the most.  Even more interesting, though, is the fact that one "Search Control" object can have multiple searches defined for it.  That means that your single search input box could generate results for multiple categories at the same time:  Web, Images, Blogs, etc.  We're going to do exactly this in our next example.

In our Part 1 example, the only "WebSearch" option we used was "setSiterestriction".  As you've probably guessed, this option directs Google to restrain its search to the domain specified.  This is the option that transforms a standard Google web search to a Google site search.

The last two lines of our function linked our SearcherOptions with our WebSearch and then initiated the "Draw" method to link it all up to our text input.  If we had wanted Google to insert it's own input box we would have specified (as the first parameter) a page container element to insert the control into instead of passing a value of "null".


Search Example #2:  Multiple Searches at Once
Now that we have an idea of what the core Google search objects do, let's expand our Part 1 example to perform two searches at once.  Why two searches?  Because we're going to search for different things.  Physically different things, that is:  one search will return matching web pages from our site and the other search will return matching files stored in our DNN instance's "portals" directory.  This is exactly what the example Google AJAX Search does on this page (see the Custom Site Search box in the upper-right corner of the page).

The code below is our same example as before with added functionality.  (Unchanged code is in gray to make it easy to see where we're adding new code.)

   function OnLoad()
   { 
      var searchControl = new google.search.SearchControl();
      var drawOptions = new google.search.DrawOptions();
      drawOptions.setInput(document.getElementById("gss_input"));
      var options = new google.search.SearcherOptions();
      options.setExpandMode(google.search.SearchControl.EXPAND_MODE_OPEN);
      options.setRoot(document.getElementById("ContentPane"));
      options.setNoResultsString("No results found."); 
      searchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
      searchControl.setResultSetSize(google.search.Search.SMALL_RESULTSET);

      // Set up a site web page search.  We're only including "aspx" pages from our site.
      //    We're specifically excluding "LinkClick" page links (links with "fileticket").
      var siteSearch = new google.search.WebSearch();
      siteSearch.setSiteRestriction("YOUR WEBSITE URL GOES HERE");
      siteSearch.setQueryAddition("+filetype:aspx -fileticket");
      siteSearch.setUserDefinedLabel("WEB PAGE search results from YOURSITE");
      searchControl.addSearcher(siteSearch, options);

      // Set up a site file search.  To keep things simple we're only including files
      //   directly linked from our site's PORTALS directory, not files linked via DNN
      //    "LinkClick" links.
      var fileSearch = new google.search.WebSearch();
      fileSearch.setSiteRestriction("YOUR WEBSITE URL GOES HERE");
      fileSearch.setSiteRestriction("YOUR WEBSITE URL/portals/YOUR PORTAL ID");
      fileSearch.setQueryAddition("-filetype:aspx");
      fileSearch.setUserDefinedLabel("FILE search results from YOURSITE
");
      searchControl.addSearcher(fileSearch, options);

      searchControl.draw(null, drawOptions);
   }

Our updated code now provides two sets of search results, one following the other.  Each search is carried out independantly of the other so you'll often notice one set of results appearing before or after the other set.  To make sure we're not returning too many results to comfortably present on our webpage we're also limiting the number of results to 4 per search.  We do this via the "setResultSetSize" with a value of "SMALL_RESULTSET".  Both sets of searches have independant AJAX-driven pagination so you can advance each set of results independantly of the other without a page referesh.

The first set of results is the site web page results.  Note the "setUserDefinedLabel" option we've added.  This lets us give the user an indication of the type of result -- very handy when returning mutiple result sets.  For our web page results, we've employed the "setQueryAddition" option in order to sneakily add our own search input text to the user's search term(s).  You can use this feature to influence user searches.  For example, if you want users' search results to skew towards things having to do with bananas, you could use "setQueryAddition" to add "bananas" to their search terms without the users knowing it.  This can be extremely useful if you want to give weight to search results featuring a particular topic ("+DNN", "+DOTNETNUKE") or locale ("+EUROPE", "+ITALY").

For our example, we're adding two "setQueryAddition" search directives within the same string:

  • "+filetype:aspx":  This directs Google to only include results with a filetype of "aspx".
  • "-fileticket":  This directs Google to exclude any results that include "fileticket".  This is optional but for DNN sites it helps to exclude certain page links from our results (we only want actual pages, not links).

The second set of results is the site file results.   Although Google provides specialized search objects for Blogs, Books, etc., Google does not (yet) have a search object specifically geared for files.  To overcome this, we use the standard Web search object as before and once again turn to the "setQueryAddition" option combined with the "setSiteRestriction" option to restrict our search results.  This time around we're ignoring "aspx" files (web pages) and are also restricting our results to files directly linked to our site's PORTALS subdirectory.  That is, files stored locally on our DNN server in our portal's file area.

Note that by configuring the fileSearch's "setSiteRestriction" to include the "PORTALS" directory in the path we are excluding results that include DNN's "FlieClick" method -- that's the method used by DNN to allow the counting of user clicks on individual file links.  Of course, you could allow the DNN "FileClick" links but keep in mind that a "FileClick" link can link to anything:  a local file, remote file, local page, remote page, etc.  "FileClick" links are not guaranteed to link only to files.  To insure that our File Search results only contain links to acutal files, our example restricts results to files directly linked from the "PORTALS" directory.


Other Display Options
Our two sets of results were shown together in order because we only specified a single page container as the target.  We could have specified separate page container targets for the two searches.  This would allow us to display the two sets of results side-by-side or even within different tabs of a tabstrip object.  See one of Google's examples (including Local, Blog and Web search results):   http://www.google.com/uds/samples/apidocs/somewhere-else.html


Going Beyond Our Example
You should find the Goolge AJAX Search documentation to be quite useful in moving beyond the examples we've looked at so far:  http://code.google.com/apis/ajaxsearch/index.html

Coming Part 3
In "Part 3" we'll tie our examples in with a (free) Google web account so we can employ online management of our custom search engines as well as access reports on what our users are searching for.  Our Google account will also let us define custom search criteria that is hosted at Google (instead of defined inline as we've been doing) so end users will not be able to pick apart our search settings by viewing the page source code.

Permalink |  Trackback

Comments (6)   Add Comment
Re: Add Google AJAX Search to your DNN skin (Part 2 of 3)    By Lara on 12/5/2008 4:21 PM
When can we expect part 3? Great series, thank you!

Re: Add Google AJAX Search to your DNN skin (Part 2 of 3)    By mamlin on 12/5/2008 4:40 PM
Thanks, Lara. I've got a number of new blog entries in the works plus several recent postings that temporarily diverted my attention from the Google AJAX Search series. I started working up "Part 3" and had intended to have it completed well before now but I simply haven't given it the attention it needs to be a worthy post. Thanks for reading and for the nice comment -- I'll try to wrap-up and publish "Part 3" within the next few weeks.

Re: Add Google AJAX Search to your DNN skin (Part 2 of 3)    By Turoc on 1/9/2009 9:55 AM
Is there a way to localise the search results ? I am using this in a site based in south Africa, and would like the results to be SA oriented. When I tried using the site restriction set to google.co.za, the results are different to those that I get when doing a normal Google search from google.co.za ...Otherwise thanks for an awesome bit of info - I will be using this on a lot of our client sites from now on :)

Re: Add Google AJAX Search to your DNN skin (Part 2 of 3)    By mamlin on 1/9/2009 10:08 AM
Turoc- Thanks for the feedback and nice comments. It's great to hear where our blog contirbutions are getting some good use. Regarding your search results, "setSiteRestriction" is intended to show results from a specific target content site (not to filter to search results of a regional Google instance). To have your custom search use a regional Google engine rather than the default "Google.com" engine, append the region code to the end of the search terms. For instance, to use the United Kingdom-based Google search engine you'd append "UK" to the end of results. In your case you want to add "za" to the end of your search term(s). To do that automatically with the AJAX search, use the "setQueryAddition" option to specify "za". If you are already including setQueryAddition as shown in the Part 2 example on this page, simply add " za" to the end of the existing string to get "+filetype:aspx -fileticket za" for the siteSearch. Do the same for fileSearch if you're including that search. Try it and let me know if that does what you need.

Re: Add Google AJAX Search to your DNN skin (Part 2 of 3)    By Site Tool on 9/5/2009 7:03 AM
That's great, I never thought about Add Google AJAX Search to your DNN skin like that before.

Re: Add Google AJAX Search to your DNN skin (Part 2 of 3)    By Dubravko on 1/15/2010 6:12 PM
Sorry but just StummpledUpon. Where is part 3 ?!


Your name:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment   Cancel 
You are here:  
 
>> Back to the top of the blog list...

 
        account   advanced   blog   click   cloud   code   content   create   data   different   events   example   feature   file   files   free   function   good   google   just   line   list   module   modules   need   option   page   pages   query   results   role   roles   script   search   select   settings   simple   site   skin   solution   step   tags   terms   time   user   users   value   version   want  
Minimize Google AJAX Search
 
Search ES:  
This is an example of a Google AJAX Search with asynchronous search execution for two searches.  See our blog series, 'Add Google AJAX Search to your DNN skin' for info and sample code.
 
     
Minimize Get the T-Shirt
 
Shirts by Eguana Solutions
(Be cool like us!)
 
     
Minimize Most-Commented Blogs
 
 
     

Minimize Looking for more info?
 

There are tons of helpful
posts from Eguana Solutions 
on the DotNetNuke.com forums.
  
 
Click HERE to see our posts.

 
     
Minimize Modules for Sale
 

Looking for Eguana's modules? 
We're still working on them!
  

Until ours are ready to dazzle and
amaze, you'll have to make do with
the thousands of modules already
available on SnowCovered.

 
     
Minimize Favorite Modules
 

There are many great DNN modules.
A few we highly recommend are:
 
Dynamic Registration
Total control over the user signup process.  Create custom forms, execute your own SQL, use the integrated payment processing features to assign user roles, validate USERNAMEs via AJAX and much more.  Very cool.
 
URL Master
Change to friendly URLs that really ARE friendly.  Add keywords into your page URLs for better SEO.  Create 301 redirects for individual pages.  Force visitors (and search bots) to a single domain (i.e., make everyone use the "www" version of your site's URL or vice versa).  One of the single best upgrades for any DNN site.
 
Document Exchange 5 (DMX5)
Drag-and-drop from Windows Explorer directly into the DMX file manager!  File versioning, file and folder moderation, extend user permissions down to the file level (for user groups and even for individual users).  Infinite file and file info presentation options via custom display templates.  Store files locally or remotely via UNC (i.e., can securely store files somewhere besides your web server).  Much more.
 
XMOD by DNNDev
Rock-solid form module for data collection.  From simple feedback / email forms to complex, multi-part tabbed forms.  XMOD is different from other form modules because XMOD does not create a new database table for every new form definition -- an important feature if you plan to create dozens or hundreds of forms over the life of your DNN instance!  Excellent support from the developer and an active community around this module.
 
If you desire your form module to create a new DB table for each new form definition, a great alternative to XMOD is the Dynamic Forms module from DataSprings.  Dynamic Forms offers direct DB access beyond that found in XMOD as well as an easy drag-and-drop form builder option to help you get up and running very quickly.

 
     

Login