(You are Anonymous)

Site Configuration with CGI::Application

How to best use "PARAMS"* especially regarding the distinction between those that come from a config file, and those that are declared in the instance script

There are a couple of different common ways to declare configuration variables in the CGI::Application framework.

  1. use the PARAMS hash in the instance script
  2. use a separate, external configuration file

When to use the PARAMS hash in the instance script

An ideal use of PARAMS is for configuring a small stand-alone application. An example of this is CGI::Application::Search, which does just that.

In a larger project, you may put configuration variables there that change in each instance script. For example, you might have functionality that works slightly differently in Staff and Public zones of your website. So you might install two different instance scripts that talk to the same module, but use different params in the instance script:

# in public.cgi
zone => 'public',

# in staff.cgi
zone => 'staff', 

When to use an external configuration file

CGI::Application has several plugins for easy integration with configuration files. See the Plugins page for a complete list.

These are great to use when you configuration variables which are constant across projects that may span several modules and instance scripts. For example, you might declare:

HTML_ROOT_URL => '/home/carrot/www', 

This configuration value might be used by many instance scripts.

Making Configuration Values Read Only

The intent of configuration values is usually to have them be read-only. It may be sufficient to name them in all caps to denote their global-like nature and be disciplined to never modify them.

Two formal solutions for this are constant and Readonly. The documentation for the latter provides a comparision of two. I still use "discipline", after finding constants inflexible.

Managing multiple variations of configuration values

Quite likely you will need some of the configuration values to change for each location the application is installed in. At a minimum, you may have Development and Production installations, and often there are different values that need to be used for every developer working on a project.

The ideal solution is to have one copy of the configuration file that is managed through a source control system. Otherwise, changes will be made to the configuration file and the various copies will quickly become out of sync.

DEVMODE environment variable

For the source code to be identical in each location, a simple environment variable is used to declare which variation of the configuration value should be used. DEVMODE is used for this. It can be declared in an Apache configuration file or a file named Devmode.pl that looks simple like this:

$ENV{DEVMODE} = 'alpha';

In that case, you can do the file just before the configuration file is read. Don't put this file in the source control system, as it is different in each location.

I use a pure Perl file for configuration, so it's easy to make use of DEVMODE in there:

if ($ENV{DEVMODE} eq 'production') {
   $CFG{HTML_ROOT_DIR} = '/home/production/www';
}
else {
   $CFG{HTML_ROOT_DIR} = '/home/development/www';
}

The constant solution also allows some flexibility in this regard:

package Site::Configuration;
use constant SMTP_SERVER => "localhost";

Or:

package Site::Configuration;
sub SMTP_SERVER
{
   if ($ENV{DEVMODE})
   {
      return "localhost";
   } else {
      return "smtp.site.com";
   }
}

This document was originally compiled by Steve Comrie based on discussion between Mark Stosberg and Jesse Erlbaum on the Mailing List from May 31 to June 02, 2003. It was later significantly refactored by Mark Stosberg.