​Triggers are coarse filters; they may send you queries you cannot handle. By defining a handle function you can tell your Instant Answer on which triggered search queries to run - or not.
A simple handle function, below, checks if the query remainder has anything in it. If not, it returns undef
.
handle remainder => sub {return if $_ eq ''; # Explicitly check for the empty stringreturn $_;};
In a Spice, the handle function returns a value that will be inserted as the parameter to the API call.
In a Goodie, the handle function returns the actual answer.
To stop the Instant Answer from proceeding, a handle function simply returns nothing, e.g. return;
A handle function takes a handler - a pre-packaged part of the query - that it can use to determine whether the Instant Answer should run or not.
When you choose a handler, you're choosing which input to pass to your handle function. For example, passing query_lc
means that query_lc
is passed as the input to the function so the value of query_lc
(a string) is available in $_
:
handle query_lc => sub {my $lowercased_query = $_;}
However, words
and matches
return an array - these values will be available in the default array variable, @_
:
handle words => sub {my @words_array = @_;my $first_word = shift;};
The available handlers are:
remainder
- The query without the trigger words, spacing and case are preserved
remainder_lc
- Like remainder but in lowercase
query_raw
- Like remainder but with trigger words intact
query
- Full query normalized with a single space between terms
query_lc
- Like query but in lowercase
query_clean
- Like query_lc but with non-alphanumeric characters removed
query_nowhitespace
- All whitespace removed
query_nowhitespace_nodash
- All whitespace and hyphens removed
matches
- Returns an array of captured expression from a regular expression trigger
words
- Like query_clean but returns an array of the terms split on whitespace
query_parts
- Like query but returns an array of the terms split on whitespace
query_raw_parts
- Like query_parts but array contains original whitespace elements
Inside the handle function you have access to the various attributes of the original query (the DDG::Request
instance) in a variable called $req
. For example, $req->query
, $req->query_lc
, $req->query_raw
, $req->remainder
, and so on.
This can be useful in determining whether your Instant Answer should run. For example, in GoWatchIt.pm
, the handle function aborts if the query contains words in a "stop words" array (defined at the top of the file):
return if grep {$req->query_lc eq $_} @stopwords;
Inside the handle function you also have access to $loc
for location data, and $lang
for language related attributes. Learn more about these two useful: Language and Location Reference.
We much prefer you use trigger words when possible because they are faster on the back end. In some cases however, regular expressions are necessary, e.g., you need to determine whether a query is suitable beyond the trigger words.
In this case we suggest you consider using triggers as much as you can, supplemented with a regex guard in your handle function. A regex guard is a conditional return statement at the very beginning of your handle function.
A good example of this is the Base64 Goodie. In this case we want to trigger on queries with the form "base64 encode/decode \". Here's an excerpt from Base64.pm which shows how this case is handled using a word trigger, with a regex guard:
triggers startend => "base64";​handle remainder => sub {return unless $_ =~ /^(encode|decode|)\s*(.*)$/i;
Another example, the Base Goodie's has a return
statement paired with an unless
right on the first line of its handle
function:
handle remainder => sub {return unless /^([0-9]+)\s*(?:(?:in|as)\s+)?(hex|hexadecimal|octal|oct|binary|base\s*([0-9]+))$/;...}