CGI::AppToolkit - An object-oriented application development framework


This module is the single access point for data and interface abstraction modules. These abstraction layers have a similar interface, and are called using the same techniques.

This framework has been developed for web-based applications, but there is no reason for it not to work in other perl applications.

The data abstraction portion's primary use is to provide a simple and easy to use interface to retrieve and store data. This allows varying types of data to be accessed using the same API. The varying types of data are handled in self-contained sub-objects that inherit from CGI::AppToolkit::Data::Object. There are subclasses of CGI::AppToolkit::Data::Object that are specialized to use DBI.

The interface abstraction part is a text templating module, CGI::AppToolkit::Template. Please read the CGI::AppToolkit::Template documentnation for more information about the templating syntax and calling methods.


  use strict;
  use CGI;
  use CGI::AppToolkit;
  my $kit = new CGI::AppToolkit;
  my $cgi = new CGI;
  if ($cgi->param('do') eq 'search') {
    my $keywords = $cgi->param('keywords') || '';
    #fetch a arrayref of hashrefs
    my $articles = $kit->data('Articles')->fetch(keywords => $keywords);
    #print the header and the 'search' template with our results
    print $cgi->header;    
    print $kit->template('search')->make(articles => $articles, keywords => $keywords);
  } elsif ($cgi->param('do') eq 'show-one') {
    my $article = $kit->data('Articles')->fetch(id => $cgi->param('id') || 1);
    #print the header and the 'form' template filled in with our data
    print $cgi->header;
    print $kit->template('form')->make($article);
  } elsif ($cgi->param('do') eq 'save-one') {
    my $article = $kit->data('Articles')->fetch(id => $cgi->param('id') || 1);
    foreach my $key (qw/content byline headline/) {
      $article->{$key} = $cgi->param($key);
    my $result = $kit->data('Articles')->store($article);
    if (ref $result =~ /::Error/) {
      #there's an error
      my ($errors_a, $missing_a, $wrong_a) = $ret->get();
      #put the error text into the data structure
      $article->{'errors'} = $errors_a;
      #and flag the parameters that were wrong or missing
      #the template can somehow display the form fields that need changed
      foreach $erroneous (@$missing_a, @$wrong_a) {
        $article->{$erroneous . '-wrongflag'} = 1;
      #show the form again
      print $cgi->header;
      print $kit->template('form')->make($article);
    } else {
      # all is well, go back to the display
      print $cgi->redirect('./index.cgi?do=show-one&id=' . $result->{'id'});


  $kit = CGI::AppToolkit->new();

Returns a new CGI::AppToolkit object. OPTIONS is an options list of key-value pairs that are made available to all of the objects that use or are used by CGI::AppToolkit. These values can be accessed later with get_* and set_* to retrieve or set the values, respectively. The keys and accessors are NOT case-sensitive.

  $kit = CGI::AppToolkit->new(DBI => DBI->connect(...)); # See connect()
  $db = $kit->get_dbi();
  #... in another module that was passed $kit
  if ($kit->get_projectSpecific()) {
  $t = $kit->template('template name');
  print $t->make(\%data);

Returns a CGI::AppToolkit::Template object with the NAMEd template loaded.

If NAME is actually a multiline string, then it will be assumed that it is the actual template itself and parsed for tokens.

If NAME is a file name, then the template will be loaded and (by default) cached. This cache will persist across severel uses of CGI::AppToolkit::Template under mod_perl or similar environments.

CGI::AppToolkit::Template employs a shell-style PATH mechanism for convenience. Call CGI::AppToolkit::Template->set_path(LIST) to set the path to list. It is set to qw/. templates/ by default. If the template name requested contains a '/', then the PATH will not be used and it will attempt to load the file exactly as it is named.

  $kit->data('data source name')->fetch( ... );

Returns a data object that you can use to access and manipulate the data in some sort of database (or flat file). See CGI::AppToolkit::Data::Object for instructions on creating data objects. Data objects are loaded from other modules and cached. Please see DATA SOURCE NAMING for what to provide as the NAME, and DATA SOURCE METHODS for how to call the data sources.


Using the built-in AUTOLOAD mechanism, you can retrieve and set object variables with named method calls. These method names are not case sensitive.

  # setting
  # retrieving
  my $value = $kit->get_wierd_variable();


The data source is an object in CGI::AppToolkit::Data:: that inherits from CGI::AppToolkit::Data::Object or one that inherits from it such as CGI::AppToolkit::Data::SQLObject or CGI::AppToolkit::Data::Automorph.

Data source names that begin with automorph:, and end with a SQL table name will use an instance of CGI::AppToolkit::Data::Automorph directly, instead of a subclass. In this case, CGI::AppToolkit::Data::Automorph will make certain assumptions (as well as do some investigation) about the structure of the table. This is good for simply structured tables that don't requre any special or complex SQL.

All other data source names are normalized into package names like this:

  1. The first character and all characters following underscores and space runs are uppercased.

  2. All underscores and space runs are removed.

  3. The results will be appended to CGI::AppToolkit::Data:: and used as a package name.

So, 'the real_THING' will become 'CGI::AppToolkit::Data::TheRealTHING'. That package must be requireable. This will be done automatically by data():

  require CGI::AppToolkit::Data::TheRealTHING;

If the require fails, Data will throw a fatal error with a little bit of diagnostic information.

You should not use or require the object in your code.


These methods can be made on the data sources returned from CGI::AppToolkit-data()>.

fetch([OPTIONS]) or fetch_one([OPTIONS])
  # return the first match as a hashref
  $data_hash_ref = $kit->data('people')->fetch_one({'id' => 12});
  # or return every match in a arrayref of hashrefs
  $data_array_ref = $kit->data('people')->fetch({'name' => 'Rob'});

Returns a data structure retrieved from the data source. The format of the data structure returned depends on whether you called fetch() or fetch_one().

  # %person holds the data needed to create or store a person
  $ret = $kit->data('people')->store(\%person);
  if (ref $ret =~ /Error/) {
        # error handling

Stores a data structure provided in OPTIONS to the data source. store() returns a CGI::AppToolkit::Data::Object::Error upon failure, otherwise it conventionally returns the data that was passed to it, possibly altered (e.g.: an unique ID was assigned, etc.).

  $kit->data('people')->update({'id' => $id, 'position' => 'Management'});

Updates the data source based upon the OPTIONS sent. Returns like store().

  $kit->data('people')->delete({'id' => $id});

Delete data from the data source based upon data provided in OPTIONS.

  $dbi = $kit->connect($data_source, $username, $auth, \%attr);

This method loads DBI (if need be), opens a DBI connection with the given parameters, stores it, and returns it. Please see DBI for what parameters to pass.

  $dbi = $kit->get_dbi();

This method returns the DBI handle object that was stored in connect().

This is mostly for use within the CGI::AppToolkit::Data::Object descendant modules.


  • These docs need cleaned up.

  • SQLObject still doesn't have the range and data checking that Automorph provides vars for.

  • SQLObject needs to have specific support for reformatting dates, both incoming and outgoing.

  • Template needs rewritten for several reason. It should support objects as values (such as a Data::Object::Error object), as well as data delegates. It should have a pure-perl fallback for when in a C++-free environment. It should have support for shared memory caching. The parser should be seperated into another method, for overriding.

  • CGI::AppToolkit::Data::XMLObject needs to be written. I haven't even started it yet.


Copyright 2002 Robert Giseburt ( All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Please visit for complete documentation.