Displaying Your Goodie Instant Answer
Making a Cheat Sheet? Skip to the Cheat Sheet Reference.
The final step in every Instant Answer is displaying it to the user. All Instant Answers display in the "AnswerBar", which is the area above the organic search results. The way each Instant Answer is displayed and behaves is determined by a set of display options and events. This document shows you how to set these options for a Goodie.
Easy Structured Responses
If your answer requires html templates and special interactions, consider setting display properties.
Many Goodies are simple operations that return a string response. For example, the Flip Text Goodie:
Displaying such Goodies is easy. Instead of setting display properties, simply return three properties:
- Input (what the user typed in, perhaps highlighting how it was parsed)
- Operation (the term for what happened)
- Result (the final answer)
For example, for the Flip Text Goodie:
Passing Structured Responses
Here is the return statement of the Flip Text Goodie:
my $result = upside_down($input);
return $result, # text-only Goodie result, for the API
structured_answer => {
input => [html_enc($input)],
operation => 'Flip text',
result => html_enc($result),
};
The following properties are returned in the structured_answer
hash:
input
[required, but can be empty] array
- Make sure to
html_enc()
any user input to prevent XSS - To avoid displaying an input, pass an empty array:
[]
(see the GUID Goodie)
operation
[required] string
- Stated as a command, e.g. "Calculate", "Flip text", "URL decode", etc.
result
[required] string
- Make sure to
html_enc()
input to display characters properly - Do not pass custom HTML in this string; instead specify a template.
Further Examples
Here are some more Goodies that make use of simple, structured responses:
Setting Display Properties in a Goodie
If your Goodie is very simple, consider passing a structured response instead.
When developing a Goodie, display options can be set either in your backend (Perl) or frontend (JavaScript) code. Most display properties can be set in either. Some Display properties, by their nature, can only be set in the frontend.
Here is a quick summary of the break down of display options:
Display Property | Can Set in Perl (Backend) | Can Set in JavaScript (Frontend) |
---|---|---|
id | ✓ | ✓ |
name | ✓ | ✓ |
data | ✓ | ✓ |
meta | ✓ | ✓ |
templates | ✓ | ✓ |
view | ✓ | ✓ |
model | ✓ | ✓ |
normalize | ✓ | |
relevancy | ✓ | |
sort_fields | ✓ | |
Events | ✓ |
Setting Display Options on the Backend
If your Goodie is very simple, consider passing a structured response instead.
Most options can be defined in the Goodie's backend, the Perl file. These options are set by returning as a hash called structured_answer
when the Perl file finishes running. This hash is returned alongside the $plaintext
string version of your Goodie result, used for the API):
return $plaintext,
structured_answer => {
...
};
For an example of how this works, take a look at the final return statement of the BPM to ms Goodie Perl file.
Specifying options in Perl is the most straightforward method, but there are several optional properties that cannot be specified on the server-side. These must be specified in the Goodie's frontend, in a JavaScript file.
The following is a code summary of how display options are set in your Goodie Perl file:
return $plaintext,
structured_answer => {
id => String,
name => String,
data => Array or Hash (in the case of a single item),
meta => {
searchTerm => String,
itemType => String,
primaryText => String,
secondaryText => String,
sourceName => String,
sourceLogo => String,
sourceUrl => String (url),
sourceIcon => Boolean,
sourceIconUrl => String (url),
snippetChars => Integer
},
templates => {
group => String,
options => Hash,
# Note that while the following may reference JavaScript variables,
# they are still specified as strings in Perl
item => String,
item_custom => String,
item_mobile => String,
detail => String,
detail_custom => String,
detail_mobile => String,
item_detail => String,
variants => Hash,
elClass => Hash,
}
view => String,
model => String,
};
For more information on each property and its usage, visit the display options reference.
Setting Goodie Display Options on the Frontend
While most display properties can be set in a Goodie's Perl file, others by their nature must be specified in the frontend part of the code. These are:
To specify any of these, simply create a javascript file in share/goodie/INSTANT_ANSWER_ID/INSTANT_ANSWER_ID.js
. For example, using the "BP to ms" Instant Answer as an example (where the id
is set to 'bpmto_ms'
):
Create a file at share/goodie/bpmto_ms/bpmto_ms.js
, which creates a namespace and a build function.
DDH.bpmto_ms = DDH.bpmto_ms || {}; // create the namespace in case it doesn't exist
DDH.bpmto_ms.build = function(ops) {
return {
// Specify any frontend display properties here
};
};
The build function takes ops
as an argument; this represents the structured_answer
hash from the Perl as a JavaScript object.
Your build function returns an object with any frontend display properties you want to set. For example, you could set an event:
return {
onShow: function() {
console.log("onShow for bpmto_ms");
},
}
Or you could set a normalize
function - and so on:
return {
...
normalize: function(item){
return {
title: item.heading
};
}
}
Additionally, it is worth noting that all of the display options specified in Perl could instead be specified in your JavaScript - if you so desired.
For example:
return {
...
templates: {
group: 'base',
detail: false,
options: {
// Note that because this is JavaScript, sub-templates are specified
// as function references rather than strings.
content: DDH.bpmto_ms.content
}
}
}
Fun with Goodie JavaScript
Goodie's frontend components allow you to do much more than set display properties and events. You may also execute any JavaScript you'd like to do interesting and delightful things.
Continuing from the example above from the BP to ms Instant Answer, we created a JavaScript file at share/goodie/bpmto_ms/bpmto_ms.js
. Inside this file, we declare a build
function.
Everything returned by your build
function is used to extend your structured_answer
Perl hash (from your Goodie's .pm file). However, you can use the function to run other JavaScript, making use of JQuery.
DDH.bpmto_ms.build = function(ops) {
// Execute delightful JavaScript here
// with access to JQuery
return {
// Specify any frontend display properties here
onShow: function(){
// Consider using an event, such as onShow, to run your code at the right time
}
};
};
Consider using events as the starting points for your code. You can also create a css file to reference, for example share/goodie/bpmto_ms/bpmto_ms.css
.
You might use Goodie JavaScript to create an in-browser game related to certain search results. Or an easter egg, for fun. The community is excited to review pull requests for fun and delightful additions to DuckDuckGo's Instant Answers.