The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Apache2::Autocomplete - Autocomplete service backend via mod_perl

SYNOPSIS

Given some form that using Google's autocomplete that receives suggestions from http://localhost/complete/search:

  ######################################################
  # in httpd.conf
  PerlModule Apache2::MyAutoComplete
  <Location /complete/search>
     SetHandler perl-script
     PerlResponseHandler Apache2::MyAutoComplete
  </Location>
  ######################################################
  
  ###################################################### 
  # module file Apache2/MyAutoComplete.pm
  package Apache2::MyAutoComplete;
  use base qw(Apache2::Autocomplete);
  # use whatever else
  
  my @NAMES = qw(bob carol ted alice);
  sub expand {
    my ($self, $query) = @_;
    my $re = qr/^\Q$query\E/i;
    my @names = grep /$re/, @NAMES;
    my @values = map {"some description"} @names;
    (lc $query, \@names, \@values, [""]);
  }
  
  sub handler {
    my $r = shift;
    my $ac = __PACKAGE__->new($r);
    $ac->run();
    return Apache2::Const::OK;
  }
  ######################################################

DESCRIPTION

This module is a mod_perl2 interface to JavaScript::Autocomplete::Backend, which is a base class for implementing an autocomplete service for a form using the Google Suggest protocol. See http://www.google.com/webhp?complete=1&hl=en for an illustration of Google Suggest in operation, as well as http://serversideguy.blogspot.com/2004/12/google-suggest-dissected.html for a description of how the JavaScript code works.

As well as mod_perl2, this package requires JavaScript::Autocomplete::Backend, as well as a CGI.pm-compatible CGI module for supplying the param() and header() methods. If available, CGI::Apache2::Wrapper will be used, which is a minimal module that uses methods of mod_perl2 and Apache2::Request to provide these methods; if this is not available, CGI (version 2.93 or greater) will be used.

Operation of this service requires inclusion of the Autocomplete JavaScript code; a copy of this is included in this distribution, the latest version of which is available at http://www.google.com/ac.js.

Example Form

An example form for which autocompletion is desired has the the following structure:

 <html><head>
 <title>Search</title>
 </head>
 <body onload="document.f.query.focus();">
 <form action="/search_handler" name=f>
 <br>
 <input autocomplete="off" maxlength=2048 
   name="query" size="25" title="Search" value="">&nbsp;
 <input name="btnG" type="submit" value="Search">
 </form>
 </body>
 <SCRIPT src="/js/ac.js"></SCRIPT>
 <SCRIPT>
 InstallAC(document.f,document.f.query,document.f.btnG,"search","en");
 </SCRIPT></html>

The Autocomplete JavaScript code is made available as /js/ac.js.

The basic operation of the autocompletion is controlled by the JavaScript function InstallAC (available in ac.js). This is called with 5 arguments:

  • document.f

    This specifies the name of the form

  • document.f.query

    This specifies the name of the form element where the autocompletion occurs

  • document.f.btnG

    This specified the name of the submit button of the form

  • search

    This specifies that http://localhost/complete/search will be used to get results for the autocompletion; if a value of, for example, my_handler was used instead of search, then http://localhost/complete/my_handler will be used.

  • en

    When the user types something into the form (after a specified timeout), a call to the specified handler is made in order to get the results to be displayed for the autocompletion. This will be of the form http://localhost/complete/search?hl=en&client=suggest&js=true&qu=a, where qu is the query typed so far and en is the value specified for the variable hl by this argument. If you need a value from the form to be sent to the autocompletion handler, you can do so in the following way: suppose we wanted to send the value of a form element with name extra:

     <input name="extra" type="hidden" value="secret">

    If we specify the last argument to InstallAC as document.f.extra.value (with no quotes), rather than "en", then the autocompletion handler will be called as http://localhost/complete/search?hl=secret&client=suggest&js=true&qu=a, so that the value of hl will be the value of the extra element of the originating form.

Apache Handler

The autocompletion handler is specified through an Apache configuration directive such as

  PerlModule Apache2::MyAutoComplete
  <Location /complete/search>
     SetHandler perl-script
     PerlResponseHandler Apache2::MyAutoComplete
  </Location>

Here, search is the value specified by the fourth argument to InstallAC, as discussed above - the complete part of the location is hard-coded in ac.js. The Perl module which handles requests for this location has the form

  # module file Apache2/MyAutoComplete.pm
  package Apache2::MyAutoComplete;
  use base qw(Apache2::Autocomplete);
  # use whatever else
  
  sub expand {
    my ($self, $query) = @_;
    # decide what completions to return, based on the $query
    (lc $query, $names, $values, [""]);
  }
  
  sub handler {
    my $r = shift;
    my $ac = __PACKAGE__->new($r);
    $ac->run();
    return Apache2::Const::OK;
  }

This must inherit from Apache2::Autocomplete. Within this handler must be an expand method:

  sub expand {
    my ($self, $query) = @_;
    # decide what completions to return, based on the $query
    (lc $query, $names, $values, [""]);
  }

which is to return a list of 4 elements to be used for autocompletion of the I$query> argument passed in from the form. This list has the following elements:

  • $query

    This is the query as returned to the frontend script (typically converted to lowercase)

  • $names

    This is an array reference of results to be used as the list of suggested completions.

  • $values

    This is an array reference of values that are usually shown on the right-hand side of the drop-down box in the front end; Google uses it for the estimated result count.

  • $prefix

    As discussed in JavaScript::Autocomplete::Backend, the purpose of $prefix is not certain at this time. It appears that if the array is empty, the drop-down menu appears but the word in the input box itself is not completed, while if the array is not empty (for example, contains an empty string as its only element), the word in the input box is completed as well.

The Apache handler itself:

  sub handler {
    my $r = shift;
    my $ac = __PACKAGE__->new($r);
    $ac->run();
    return Apache2::Const::OK;
  }

creates the object and calls the run method on it, which returns the autocomplete results in the form of JavaScript code that the original form then uses to fill in the suggestions.

Methods

The following methods are available.

  • my $ac = __PACKAGE__->new($r);

    This creates the object, and takes a mandatory argument of the Apache2::RequestRec object $r.

  • $ac->run();

    This is the main method which calls the expand method to find and format the results to be returned for the autocompletion.

    By default, the only header Apache::Autocomplete sets is the Content-Type, for which text/html is used. If additional headers are required, they may be passed as an optional argument into run()in the form of a hash reference, as in

      my $header = {'Content-Type' => 'text/html; charset=utf-8',
                    'X-err_header_out' => 'err_headers_out',
                   };
      $ac->run($header);
  • my $r = $ac->r;

    This returns the Apache2::RequestRec object passed into the new method.

  • my $cgi = $ac->cgi;

    This returns the CGI.pm-compatible object used to supply the param() and header() methods needed by JavaScript::Autocomplete::Backend.

SEE ALSO

For a description of the JavaScript backend, see JavaScript::Autocomplete::Backend and http://serversideguy.blogspot.com/2004/12/google-suggest-dissected.html.

If using CGI is a concern due to the memory footprint, see CGI::Apache2::Wrapper for a minimal CGI.pm-compatible module that uses methods of mod_perl2 and Apache2::Request.

Development of this package takes place at http://cpan-search.svn.sourceforge.net/viewvc/cpan-search/Apache2-Autocomplete/.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Apache2::Autocomplete

You can also look for information at:

COPYRIGHT

The Perl software is copyright 2007 by Randy Kobes <r.kobes@uwinnipeg.ca>. Use and redistribution are under the same terms as Perl itself; see http://www.perl.com/pub/a/language/misc/Artistic.html. The JavaScript autocomplete code contained in ac.js of this distribution is Copyright 2004 and onwards by Google Inc.