This project has two distinct parts: the framework and the sample apps. These are developed and distributed separately. The framework and each sample app is a regular Perl distibution like you would find on CPAN (though they may be bundled together). They use Module::Build instead of ExtUtils::MakeMaker. This means that the procedure for installation (after you untar the distribution) is:

perl Build.pl
./Build
./Build test
./Build install

You need to do this for the framework itself and again for each sample app you want to deploy.

Once you have installed the framework and a sample app, you need to configure the app. This amounts to including a few directives in your httpd.conf. You can just add this to you system httpd.conf or to a virtual host within it:

Include /path/to/Billing/docs/httpd.conf

See that file for clues about configuration, details follow later in this doc.

To run the billing sample app, you must also set up a database for it. To create the database, use billing.sql in the docs directory of the distibution. Choose any name you like for the database, but change the PerlSetVars in your httpd.conf appropriately (look for the ones that start with db).

In order for the apps to serve images and style sheets, you need to copy the css and images directories into your document root and set the PerlSetVars for css_root and img_root to point to the Apache serveable directory where you put them.

A private contractor billing system. It keeps track of who you work for, what you did for them, and the invoices you sent to them. The invoices can be viewed as PDFs for printing, but are also stored in the database.

The Apps::Billing::Companies inherits from Apps::Billing, which in turn inherits from Gantry. The only handler you should ever need is in the Gantry. (Though you could override it, we never have).

The handler is a template method, meaning that it performs a standard outline of steps calling particular methods of your subclass as it needs specific help or information. Typically this sequence is

init
do_something
clean_up

In init, you typically do two things: fish PerlSetVars out of the request object through its dir_config method and setup your database access. We usually have two inits for the entire app, see init in Billing.pm and Gantry.pm for example. Grouping all of an apps configuration parameters makes them easier to find, since they all live in the same Location directive in the conf file. Further, for those reading the code, they are all in only one or two places, again making them easier to find.

In cleanup, you release any resources you need to. But, note that Class::DBI based modules handle the database connection pools for you, so you don't usually need to put database disconnects in cleanup. We usually have a single cleanup for the entire app, see Billing.pm for example.

All of the action methods begin with do_. What comes after that is taken directly from the URL.

In the do_ method, you perform whatever action you need to for the page the user requested. This includes populating the view data portion of the site object ($site). That view data goes to the template.

In reality, the handler is a bit more complex. But you can think of it like it is shown above until you care to adjust its behavior.

The main mystery is, "How does it make output?" The short answer is, it calls do_process (after the steps shown above). That method is supplied by the template engine of your choice (ours is TT). When you use Gantry, you do it like so (this is taken from Billing.pm):

use Gantry qw/-Engine=MP20 -TemplateEngine=TT/;

The Engine here is mod_perl 2.0. The TemplateEngine is Template Toolkit.

The framework handles Engine and TemplateEngine options specially. See below for how it handles TemplateEngine options. Engines must be in the Gantry::Engine namespace. The engine is responsible for exporting the following methods (yes, I said exporting and methods):

Template engines handle the view part of MVC processing. Typically, you don't have to write any code for them, you can just use one included in the distribution. But, should you want to use Mason or some other templating system, you will have to write a template engine. These must live in the Mutant::KrKit::Template namespace.

This is the actual dispatcher which calls the do_* methods of the modules you write. While most do_methods merely store their data in the site object for later retrieval in the template, some return their output instead. This method is responsible for storin such returned data in the site object stash.

In addition to loading an engine and a template engine, use Gantry can also load any other plugins you request. All plugins must live in the Gantry::Plugins namespace.

Plugins are very simple. They are a lot like mixins from Ruby. Each one is a package which exports methods. These are then available throughout the app as methods of the site object. A plugin could be as simple as: