Roll your own search engine plugins

13 Aug Tagged code, firefox, Google, seearch

In response to Willscrlt's comment here's a short guide to creating search plugins for Firefox.

 

The XML file (the plugin)

The plugin itself is an OpenSearch XML file. You can find details of the OpenSearch spec here. While I'd recommend reading the whole spec it's much easier to hack an existing plugin.

Start with the code from my Google Caffeine search plugin.

<?xml version="1.0" encoding="UTF-8" ?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
    <ShortName>Google Caffeine</ShortName>
    <Description>Google Caffeine Dev Preview Search</Description>
        <Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA</Image>
    <InputEncoding>UTF-8</InputEncoding>
    <Url type="application/x-suggestions+json" rel="suggestions" method="GET" template="http://suggestqueries.google.com/complete/search?output=firefox&amp;client=firefox&amp;hl={moz:locale}&amp;q={searchTerms}" />
    <Url type="text/html" method="GET" template="http://www2.sandbox.google.com/search?q={searchTerms}"/>
</OpenSearchDescription>

Change the "ShortName" and "Description" to describe your search.

<ShortName>Twitter</ShortName>
    <Description>Twitter realtime search</Description>

The next line, "Image" can be either an image URI or base64 encoded image as text. Encoding the image as text is faster and more reliable but static. You can find base64 encoders online should you choose to encode as text. For this example I'll use a URL.

<Image height="16" width="16" type="image/x-icon">http://twitter.com/favicon.ico</Image>

The "application/x-suggestions" URL line is optional. This line enables the suggest feature by sending the partial search string to a suggest API each time a new character is typed. Items in the curly braces {} are variables. The search provider must provide a suggest API in order to use this. If you are unsure whether the search provider has a suggest API delete this line.

<Url type="application/x-suggestions+json" rel="suggestions" method="GET" template="http://suggestqueries.example.com/complete/search?output=firefox&amp;client=firefox&amp;hl={moz:locale}&amp;q={searchTerms}" />

The next URL line is the one that runs the actual search. It tells the browser to use the "GET" HTTP method at the specified URL and insert the search terms in place of the variable {searchTerms}.

<Url type="text/html" method="GET" template="http://search.twitter.com/search?q={searchTerms}"/>

This is what the new search plugin XML would look like:

<?xml version="1.0" encoding="UTF-8" ?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
    <ShortName>Twitter</ShortName>
    <Description>Twitter realtime search</Description>
        <Image height="16" width="16" type="image/x-icon">http://twitter.com/favicon.ico</Image>
    <InputEncoding>UTF-8</InputEncoding>
   <Url type="text/html" method="GET" template="http://search.twitter.com/search?q={searchTerms}"/>
</OpenSearchDescription>

The installer

The installer is also part of the OpenSearch spec. It's a Javascript method 'window.external.AddSearchProvider()' on an HTML page which tells the browser that the linked XML file is a search engine plugin to be installed instead of rendered.

<a onclick="window.external.AddSearchProvider('http://blog.kylehasegawa.com/sites/blog.kylehasegawa.com/files/twitter.xml');return false;" href="#">Add Twitter search</a>

Add Twitter search

That's it.

All code on this site is free for use at your own risk and provided as-is under the WTFPL license unless otherwise stated. Attribution is appreciated but not required.
Blog content, with the exception of externally quoted material, is licensed under the Creative Commons Attribution 3.0 license