Jump to content

Use opensearch to build search (and include autocomplete)


Recommended Posts

There is a standard for defining search engines.


It started in 1997 as a sherlock plugin but has gone by many names: mycroft plugins, search engines, search plugins, and more recently opensearch.


All browsers can read this format and let the user choose it to search the web.

Since Alfred is all about searching the web, it would be nice if it could use this capability.


A web page has an html header that tells the browser where the search engines are defined:

<link rel="search" type="application/opensearchdescription+xml" title="Stack Overflow" href="/opensearch.xml">

And the actual document is relatively straight forward: 

<?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>Stack Overflow</ShortName>
  <Description>Search Stack Overflow: Q&A for professional and enthusiast programmers</Description>
  <Image width="16" height="16" type="image/x-icon">//sstatic.net/stackoverflow/img/favicon.ico</Image>
  <Url type="text/html" method="get" template="http://stackoverflow.com/search?q={searchTerms}"></Url>
They can even support auto complete templates:
<Url type="application/x-suggestions+json" template="http://example.com/suggest?q={searchTerms}"/>

Usecase comes in 2 forms:


1. add a web search (and type in a website's url e.g.: google.com)

2. click "add a web search from the current chrome window"


Then, Alfred reads the icon, url, and name from the header and creates the search definition.



Also, alfred uses the auto complete suggestions extension to give super awesome feedback.




Link to comment
Share on other sites

Seems a much better fit for a workflow, imo.
Asking other applications about their state, and especially fetching live results from the web are slow. And if Alfred is all about one thing, it's speed.
As a result, I don't think the features are a good fit for the core Alfred application. Especially as this is trivially done with a workflow (or rather, 95% of the work has already been done).
It's simple enough to query browsers for their current URLs (Vítor has a list of the requisite AppleScript for common browsers), fetch and parse the page, and generate an Alfred custom search URL.
Searchio! already covers the search-engine auto-suggestion (and includes support for an opensearch site or two, IIRC).

Link to comment
Share on other sites

  • 1 month later...
  • 2 months later...

Ok, so I've moved search engine discovery into a workflow. But I can not find how to "add" a search engine to Alfred itself.

var queryString = "{"+"query"+"}";
var jsGetUrl = "searches = document.querySelectorAll(\"link[rel='search']\")[0]; searches && searches.href";

function log(msg) { if(console) console.log(msg); }
function uw(x) { return ObjC.unwrap(x); }

function detect(nodes, attr, ref) {
  var nl = nodes.length;
  for(var i = 0; i < nl ; i++) {
    var n = nodes[i];
    if(n[attr]() == true) {
      return ref ? n[ref]() : n;

function detectFrontApp() {
  if(false) { // hardcode for testing
    return "Google Chrome";
  } else if(false) { // hardcode for testing
    return "Safari";
  } else {
    var Events = Application("System Events")
    return detect(Events.processes, "frontmost", "name");

// convert search to alfred friendly search string
function searchFromUrl(str) {
  str = str.replace("%7Bquery%7D", queryString);
  if(str.indexOf(queryString) > 0)
    return str;

// download open search document and return the query string
function urlFromDoc(openSearchUrl) {
  log("curl -s -o "+ openSearchUrl)
  var app2 = Application.currentApplication()
  app2.includeStandardAdditions = true

  var strXML = app2.doShellScript("curl -s "+ openSearchUrl);
  var doc = $.NSXMLDocument.alloc.initWithXMLStringOptionsError(strXML, 0, null)
  var root = doc.rootElement // <OpenSearchDescription>
  var title = uw(uw(root.elementsForName('ShortName'))[0].stringValue);
  var icon = uw(uw(root.elementsForName('Image'))[0].stringValue);
  var searchUrl = uw(uw(root.elementsForName('Url'))[0].attributeForName('template').stringValue).replace("{searchTerms}", queryString);

  return {
    title: title,
    icon: icon,
    searchUrl: searchUrl

var frontApp = detectFrontApp();
var app = Application(frontApp);

var openSearchUrl, searchUrl;
switch(frontApp) {
  case "Safari":
  case "Webkit":
    log("==> " + frontApp);
    searchUrl = searchFromUrl(app.documents[0].url());
    if(!searchUrl) {
      openSearchUrl = app.doJavaScript(jsGetUrl, { in: app.windows[0].currentTab })
  case "Google Chrome":
  case "Google Chrome Canary":
  case "Chromium":
    log("==> " + frontApp);
    var tab = app.windows[0].activeTab();
    searchUrl = searchFromUrl(tab.url());
    if(!searchUrl) {
      openSearchUrl = tab.execute({javascript: jsGetUrl});

if(searchUrl) {
  log("searchUrl=" + searchUrl + " <<< YAY");
} else if(openSearchUrl) {
  log("openSearchUrl=" + openSearchUrl);
  searchUrl = urlFromDoc(openSearchUrl)['searchUrl'];
  log("searchUrl=" + searchUrl + " <<< YAY");
} else {
  searchUrl = "unable to contact " + frontApp + " and get search term";
  log("nuttin via" + frontApp);

searchUrl; // want to add THIS to Alfred's search engine

Edited by kbrock
Link to comment
Share on other sites

What do you mean by "add a search engine to Alfred"?
If you want to add a custom search, you need to create a custom search URL. It will look something like this: 


Paste that into Alfred to add the search.
If you want autosuggest, that has to go in a workflow, like Searchio! mentioned above.

Edited by deanishe
Link to comment
Share on other sites

  • 5 years later...
On 7/14/2021 at 5:42 PM, JCHH said:

@deanishe ...don't suppose you have an updated vision of the link for thetvdb do you?


Here's the one I currently use:



Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...