CGI::Application::Demo::Ajax - A search engine using CGI::Application, AJAX and JSON




        use CGI::Application::Demo::Ajax;

        CGI::Application::Demo::Ajax -> new() -> run();



        use strict;
        use warnings;

        use CGI::Application::Dispatch;
        use CGI::Fast;
        use FCGI::ProcManager;

        # ---------------------

        my($proc_manager) = FCGI::ProcManager -> new({processes => 2});

        $proc_manager -> pm_manage();


        while ($cgi = CGI::Fast -> new() )
                $proc_manager -> pm_pre_dispatch();
                CGI::Application::Dispatch -> dispatch
                args_to_new => {QUERY => $cgi},
                prefix      => 'CGI::Application::Demo',
                table       =>
                ''        => {app => 'Ajax', rm => 'initialize'},
                '/search' => {app => 'Ajax', rm => 'search'},
                $proc_manager -> pm_post_dispatch();


CGI::Application::Demo::Ajax demonstrates how to use CGI::Application together with AJAX and JSON.

It ships with:

Two CGI instance scripts: ajax.cgi and ajax

ajax.cgi is a trivial CGI script, while ajax is a fancy script using CGI::Application::Dispatch and FCGI::ProcManager.

A text configuration file: .htajax.conf

This will be installed into the same directory as And that's where looks for it.

By default, form_action is /cgi-bin/ajax.cgi, so you'll need to edit it to use form_action=/local/ajax.

Also, the default logging directory is /tmp, so this might call for another edit of .htajax.conf.

A set of HTML::Template templates: *.tmpl
This Perl module: CGI::Application::Demo::Ajax


This module is available as a Unix-style distro (*.tgz).

See for help on unpacking and installing distros.


All these assume your doc root is /var/www.

Install YUI

Browse to, download, and unzip into htdocs:

        shell>cd /var/www
        shell>sudo unzip ~/Desktop/

This creates /var/www/yui, and yui_url in .htajax.conf must match.

Install the module

Install this as you would for any Perl module:

Unpack the distro, and then either:

        perl Build.PL
        ./Build test
        sudo ./Build install


        perl Makefile.PL
        make (or dmake)
        make test
        make install

Install the HTML::Template files.

        shell>cd /var/www
        shell>sudo mkdir -p assets/templates/cgi/application/demo/ajax
        shell>cp distro's/htdocs/*.tmpl to assets/templates/cgi/application/demo/ajax

Alternately, edit the now installed .htajax.conf, to adjust tmpl_path.

Install the trivial instance script

        shell>cp distro's/htdocs/ajax.cgi to /usr/lib/cgi-bin
        shell>sudo chmod 755 /usr/lib/cgi-bin/ajax.cgi

Install the fancy instance script

        shell>cd /var/www
        shell>sudo mkdir local
        shell>cp distro's/htdocs/ajax to local
        shell>sudo chmod 755 local/ajax

Configure Apache to use local/ajax

If in fancy mode, add these to httpd.conf:

        LoadModule fcgid_module modules/


        <Location /local>
                SetHandler fcgid-script
                Options ExecCGI
                Order deny,allow
                Deny from all
                Allow from

And restart Apache.

Start searching

Point your broswer at (trivial script), or (fancy script, nice-and-clean URL).

The Flow of Control

Here's a step-by-step description of what's happening:

You initialize the process

Point your web client at or

This is equivalent to CGI::Application::Demo::Ajax -> new() -> run().

Since there is no run mode input, the code defaults to's sub initialize(). See sub setup() for details.

The code assembles the default web page

The work is done in's sub initialize().

This page is sent from the server to the client.

It contains the contents of, with both search.js and search.tmpl embedded therein.

Of course, it also contains a minimal set of YUI Javascript files.

The client accepts the response

The default web page is displayed.

You input a search term

The CGI form in search.tmpl is set to not submit, but rather to call the Javascript function search_onsubmit(), which lives in search.js.

It's actually the copy of this code, now inside, now inside your client, which gets executed.

The CGI form is submitted

Here, Javascript does the submit, in such a way as to also specify a call-back (Javascript) function, search_callback(), which will handle the response from the server.

This function also lives in search.js. runs again

This time a run mode was submitted, either as form data or as path info data.

And this means that when using the fancy script, you don't need the line in search.tmp referring to the hidden form variable 'rm', because of the path info '/search' in search_onsubmit().

sub search() carries out the search.

The run mode causes's sub search() to be the sub which gets executed this time.

It assembles the results, and uses JSON::XS to encode them.

The server replies

The results of the search are sent to the client.

The client accepts the response

When the client receives the message, these events occur, in this order:

Control passes to search_callback(), the call-back function
The data is decoded from JSON to text by a YAHOO.lang.JSON object
The data is moved into a YAHOO.util.LocalDataSource object
The data is formatted as it's moved into a YAHOO.widget.DataTable object

This object displays its data automatically. Actually, the object's constructor displays the data, which is why we call new by assigning the object to a Javascript variable, data_table.


It should be obvious that the code in's sub search() can be extended in any manner, to pass more complex hash refs to the Javascript function search_callback().

This data can then be ignored by the Javascript, or you can extend the responseSchema and column_defs to display it.

Given this framework, extending these data structures is basically effortless.


CGI::Application::Demo::Ajax was written by Ron Savage <> in 2009.

Home page:


Australian copyright (c) 2009, Ron Savage. All Programs of mine are 'OSI Certified Open Source Software'; you can redistribute them and/or modify them under the terms of The Artistic License, a copy of which is available at: