Paul Pival noticed a problem with the browser widget I made the other day to search Google and Live side-by-side. The service invoked by that widget, at dualsearch.atsites.net, fails when your query contains double-quoted phrases.
It’s an easy fix as I’ll demonstrate here. There are three ingredients:
- A itty-bitty web application
- A simple XML file
- An even simpler HTML/JavaScript file
Let’s examine them.
1. The web application just receives a query, URL-encodes it, and interpolates it into the template for a web page that invokes the two search engines in side-by-side frames.
There are a million ways to do that. Here’s a Python/Django implementation:
def doublesearch(request):
import urllib
q = request.GET['q']
q = urllib.quote(q)
template = """<html>
<frameset cols="*,*" frameborder="no">
<frame src="http://www.google.com/search?q=__QUERY__" />
<frame src="http://search.msn.com/results.aspx?q=__QUERY__" />
</frameset>
</html>"""
html = template.replace('__QUERY__',q)
return HttpResponse(html)
2. The XML file contains an OpenSearch description that invokes that little web application, passing it the query that you type into your browser’s search box. Here’s an example that uses a sample service I’ve located at my elmcity.info site:
<?xml version="1.0" encoding="UTF-8" ?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>DoubleSearch</ShortName>
<Description>DoubleSearch provider</Description>
<Image height="16" width="16" type="image/x-icon">
http://jonudell.net/img/doublesearch.ico"</Image>
<InputEncoding>UTF-8</InputEncoding>
<Url type="text/html"
template="http://elmcity.info/doublesearch/?q={searchTerms}" />
</OpenSearchDescription>
3. Finally, here’s the HTML file that encapsulates the snippet of JavaScript that installs the OpenSearch widget into your browser:
<a href="javascript:window.external.AddSearchProvider
('http://jonudell.net/doublesearch.xml')">Add</a> the
DoubleSearch provider.
You can Add the DoubleSearch widget and try it for yourself. Unlike other variants I’ve found, this one doesn’t wrap any cruft around the side-by-side results. It simply presents them.
As I mentioned the other day, I’m finding that combining the top 10 results from both engines makes for a more useful set of 20 results than taking the top 20 from either.
With today’s wider screens, placing the two result frames side-by-side works out pretty well. In this mode, however, you’ll want to avoid clicking through directly on a result. Instead, right-click on the result and open it in a new tab.
October 16, 2008 at 7:41 pm
You’ve got to remember to escape < too, otherwise you’ll have XSS vulernabilities like this in the <title>.
October 16, 2008 at 8:14 pm
Thanks for the fix, Jon!
October 16, 2008 at 11:11 pm
> You’ve got to remember to escape < too
Great point, thanks Philip. I switched to Python’s urllib.quote which now escapes the whole query string.
October 16, 2008 at 11:21 pm
This is VERY nice, Jon…both as a service, and (perhaps even better IMO) a great example of how to whip this sort of mashup together quickly and easily.
Obviously, it requires a background in Django for this to be immediately usable, but regardless: a) this is case for any toolkit/framework, and b) Python is so close to pseudo-code that anyone “skilled in the art” can basically just read the script and translate it on the fly.
Now I see how to wire up OpenSearch widgets as well…nifty! Thanks again.
October 17, 2008 at 7:26 am
> Obviously, it requires a background in
> Django for this to be immediately usable
The web “application” piece of this is just one step up from Hello World, you can do it trivially in any CGI-like environment on any platform in any language.
October 17, 2008 at 7:50 pm
[...] and Track over realtime IM or an embeddable surrogate will quickly grab at least a strategic corner of this new information router console. CrunchBase Information FriendFeed Twitter [...]
October 18, 2008 at 11:51 am
[...] Udell has written a Javascript gizmo to search using two engines side-by-side that’s rather [...]
October 18, 2008 at 4:34 pm
[...] and Track over realtime IM or an embeddable surrogate will quickly grab at least a strategic corner of this new information router [...]
October 29, 2008 at 10:53 pm
[...] and Track over realtime IM or an embeddable surrogate will quickly grab at least a strategic corner of this new information router console. CrunchBase Information FriendFeed Twitter [...]