CAF Examples - Guide to the CAF Example scripts
First, make sure that you've read and followed the instructions in the INSTAL.txt file.
A typical CGI::Application::Framework project has the following layout:
CGI::Application::Framework
cgi-bin/ app.cgi # The CGI script framework/ framework.conf # Global CAF config file projects/ MyProj/ framework.conf # MyProj config file common-templates/ # login templates go here common-modules/ CDBI/ MyProj.pm # The Class::DBI project module MyProj/ app.pm # The Class::DBI application module MyProj.pm # The project module applications/ myapp1/ framework.conf # myapp1 config file myapp1.pm # An application module templates/ runmode_one.html # templates for myapp1 runmode_two.html myapp2/ framework.conf # myapp2 config file myapp2.pm # An application module templates/ runmode_one.html # templates for myapp2 runmode_two.html
The Example applications follow this layout closely:
(*) cgi-bin/ app.cgi # The CGI script (**) framework/ framework.conf # Global CAF config file (+) projects/ Example/ framework.conf # Exmample config file common-templates/ # login templates go here common-modules/ CDBI/ Example.pm # The Class::DBI project module Example/ example.pm # The Class::DBI application module Example.pm # The project module applications/ example_1/ framework.conf # example_1 config file example_1.pm # The 'example_1' application templates/ main_display.html # template for myapp1 example_2a/ framework.conf # example_2a config file example_2a.pm # The 'example_2a' application templates/ main_display_mutt.html # templates for example_2a main_display_jeff.html
When we refer to the [cgi-bin] directory, we are referring to the directory that contains app.cgi (the [cgi-bin] directory is indicated above with (*)). When we refer to the [framework] directory, we mean the directory marked with (**), above. When we refer to the [projects] directory, we are referring to the projects directory within the top level framework directory (as indicated with (+), above).
[cgi-bin]
app.cgi
(*)
[framework]
(**)
[projects]
projects
framework
(+)
Inspect the following files on disk via the command line:
[cgi-bin]/app.cgi
and
[projects]/Example/example_1/example_1.pm
Run the example_1 application through the web, for instance at:
http://localhost/cgi-bin/app.cgi/Example/example_1
Does it give you anything more than a server error? If so, then odds are you set up your installation correctly. If you get an error, happy hunting!
This is the the only CGI script in the whole entire CGI::Application::Framework! Through this single script, all your applications are run.
It works by analyzing the PATH_INFO portion of the URL. In the following example:
PATH_INFO
http://localhost/cgi-bin/app.cgi/Example/example_1?rm=main_display
The PATH_INFO is "/Example/example_1".
This is broken up into two parts: project (Example) and application example_1.
Example
example_1
CGI::Application::Framework searches for example_1.pm in the project tree:
example_1.pm
[projects]/Example/applications/example_1/example_1.pm
Once it has found your application module, it runs it. Exactly *how* it runs it is controlled by your configuration file.
The programs in the CGI::Application::Framework follow the general structure of a CGI::Application program. That means that at any given time, they have a run mode which is their current state. Each run mode has a subroutine.
CGI::Application
run mode
In the case of example_1 the only run mode is called main_display.
main_display
When you leave out the run mode, CGI::Application::Framework's run_app mechanism knows to call the main_display run mode, because this is set in the configuration file.
Look at the project level framework.conf in
framework.conf
[projects]/Example/framework.conf
In this file there is a paramter called post_login_rm:
post_login_rm
post_login_rm = main_display
This means that after login, CGI::Application::Framework will dispatch to the main_display run mode.
Other applications can have different start run modes. For instance, example_2's first run mode is main_display_mutt:
example_2
main_display_mutt
<LocationMatch example_2> post_login_rm = main_display_mutt </LocationMatch>
More information on configuration system is available in the CGI::Application::Framework docs.
For more information on CGI::Application, see its documentation at:
http://search.cpan.org/dist/CGI-Application/lib/CGI/Application.pm
Note that the CAF uses templates for its its presentation (aka "view") layer.
Currently, you have a choice between HTML::Template, HTML::Template::Expr, Template::Toolkit and Petal.
HTML::Template::Expr
Petal
See the documentation for these modules at:
http://search.cpan.org/dist/HTML-Template/Template.pm http://search.cpan.org/dist/Template-Toolkit/lib/Template.pm http://search.cpan.org/dist/Petal/lib/Petal.pm
This file has the heck commented out of it. Read it extensively to start to get an idea of what is possible, and what the efficient idioms are, in the CGI::Application::Framework.
Regarding the line
use base qw ( Example );
When you start developing applications that relate to a different base class, you can change this to
use base qw ( YourProject );
Make sure you create a
[projects]/YourProject/common-modules/YourProject.pm
file and a
[projects]/YourProject/common-templates
directory with the templates that you need to put in there, per what is named in your YourProject.pm file.
YourProject.pm
You get to decide what template you need and what their names are, within reasonable limits. For instance, by default, the Framework expects different types of templates to use different extensions:
HTML::Template .html Template::Toolkit .tmpl Petal .xhtml
But this is a convention, and configurable in your top-level framework.conf.
For examples on how to create a project and a set of templates, refer to
[projects]/Example/common-modules/Example.pm [projects]/Example/common-templates
These are fairly heavily documented internally as well.
Note that, in the setup subroutine, mode_param and start_mode are NOT defined. They normally would be here in a CGI::Application program, but these are managed by the CGI::Application::Framework module here.
setup
mode_param
start_mode
In the main_display subroutine, the first CAF-oriented thing that you encounter is:
my $config = $self->conf->context;
This is a quick way of getting the current application configuration. $config is a hash ref. You use it like this:
$config
my $start_mode = $config->{'post_login_rm'};
You can store values in framework.conf and they will be visible to your application in this hashref.
# in [projects]/Example/applications/example_1/framework.conf favourite_colour = blue # in [projects]/Example/applications/example_1/example_1.pm my $config = $self->conf->context; my $background = $config->{'favourite_colour'};
The configuration system is very powerful and flexible. To make a configuration value available to all apps in a project, declare it the project level framework.conf:
To make a configuration value available to all apps on the system, declare it the top-level framework.conf:
[framework]/framework.conf
Additionally, configuration files allow matching based on the current module, the current URL and other runtime data. So for instance, you could put the following in the top level framework.conf:
<LocationMatch example> favourite_colour = red </LocationMatch>
And this would set the favourite_colour configuration parameter to 'red' any time an application's URL matched the string 'example'.
favourite_colour
'red'
'example'
See the CGI::Application::Framework docs for details.
The next thing unique to CGI::Application::Framework is the first-class session, $self->session. This is a "scratchpad" area that persists across all loadings of the application via the web and across all subroutines. The programmer doesn't have to create the session object, as the framework does this for the programmer. The session will come with a few pre-populated fields, e.g. _session_id, _timeout and _cgi_query, as well as whatever is defined by the programmer in the .pm file that defines the project class (e.g. Example.pm). See that file to get some ideas of what you can do here.
$self->session
Example.pm
$self->make_link is meant to create all <a href=...> style links that are displayed throughout the application. If you don't use this to link to another run mode within the application and you instead just create the <a href> yourself then the application will die with a rather strongly-worded error message. More documentation regarding make_link and all its options can be found inside the docs of CGI::Application::Framework.
$self->make_link
<a href=...>
<a href>
Finally there is the templating code:
return $self->template->fill(\%tmplvars);
In one step, this creates a template, fills it with the paramters in the hash %tmplvars and then returns the output.
%tmplvars
Since we haven't specified a filename, the system will load a template with a filename matching the current runmode (in this case main_display.html).
main_display.html
As for the type of template used (and other The template options) the template is created according to the rules set out in your application's configuration. In the case of the examples, the template type is set to HTML::Template by default.
HTML::Template
If you want to override this for a particular run mode, you can:
my $template = $self->template('named_config')->load( file => 'yummy' type => 'TemplateToolkit' add_include_path => '.', ); $template->param('foo' => 'bar'); return $template->output;
This would create a template named yummy.tmpl in the Template::Toolit format, set some parameters and then return the result.
yummy.tmpl
This is the same as app.cgi but with one small difference -- its beginning is:
#!/usr/bin/perl -d:ptkdb sub BEGIN { $ENV{DISPLAY} = ":0.0" ; }
This is meant to activate the Perl TK Debugger. You probably need to specify the hostname or IP of the display that ptkdb will target, and "xhost +" the display as well. ptkdb doesn't work on Apache::Registry scripts, which is a bit of a drag, so you have to make sure that you run this through CGI. This is an excellent way of finding out what's wrong in your CGI::Application::Framework applications.
Apache::Registry
This isn't runable, but it is meant to show how small and compact these applications can be without all of the comment verbage in example_1.pm It is entirely equivalent to example_1.pm in how it would run, though.
This demonstrates how to link between two applications while maintaining the user's session.
This demonstrates how to create a navigation bar of links to multiple applications without having to log in each time.
This demonstrates the component embedding system. It shows you how to embed runmodes within runmodes by using the navigation bar as an example.
This is meant to illustrate a standard CRUD application (Create, Read, Update, Delete) as done in the CAF. All database interaction is mediated via the Class::DBI-based parallel framework that I've created for CGI::Application::Framework called CDBI. The file
Class::DBI
CDBI
[projects]/Example/common-modules/CDBI/Example/example.pm
mirrors the database "example", and highlights some of the relationships within it via its has_many and has_a statements. See documentation for this at:
has_many
has_a
http://search.cpan.org/dist/Class-DBI/lib/Class/DBI.pm http://search.cpan.org/dist/Class-DBI-mysql/lib/Class/DBI/mysql.pm http://search.cpan.org/dist/Class-DBI-Pg/Pg.pm http://search.cpan.org/dist/Class-DBI-SQLite/lib/Class/DBI/SQLite.pm
Note the use of the check_rm in process_add_user comes from CGI::Application::Plugin::ValidateRM. See its documentation, and the documentation for the modules that support it, at:
check_rm
process_add_user
CGI::Application::Plugin::ValidateRM
http://search.cpan.org/dist/CGI-Application-Plugin-ValidateRM/lib/CGI/Application/Plugin/ValidateRM.pm http://search.cpan.org/dist/Data-FormValidator/lib/Data/FormValidator.pm
The _add_user_profile subroutine shows a Data::FormValidator profile that includes some programmatic elements.
_add_user_profile
Data::FormValidator
Richard Dice, <rdice-at-pobox.com>
<rdice-at-pobox.com>
Copyright 2005 Richard Dice, All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install CGI::Application::Framework, copy and paste the appropriate command in to your terminal.
cpanm
cpanm CGI::Application::Framework
CPAN shell
perl -MCPAN -e shell install CGI::Application::Framework
For more information on module installation, please visit the detailed CPAN module installation guide.