This is more of an FYI post than anything. I've had the website
http://www.gimblerus.com under the control of CGIP for about 6-8
months now and it is great. This note explains the things I do because
(a) I don't under CGIP::Hidden and (b) because I use HTML::Seamstress
instead of tt as my rendering engine.
First, let's look at a finished page:
http://www.gimblerus.com/cgi-bin/x?task=show_rules
Ok, the first thing is notice the query parameter "task" with value
"show_rules"? That allows the CGIP script named "x" to figure out what
page we are on via module called Gimble::Dispatch. Gimble::Dispatch is
just a hash from this query parameter to a Gimble::Page::* class.
package Gimble::Dispatch;
use strict;
use base qw(CGI::Prototype);
#use Class::Autouse;
our %task = (
home => 'Gimble::Page::Home::Base',
signup => 'Gimble::Page::Signup::Base',
signup_redo => 'Gimble::Page::Signup::Redo',
signup_confirm => 'Gimble::Page::Signup::Confirm',
signup_commit => 'Gimble::Page::Signup::Commit',
add_clan => 'Gimble::Page::AddClan::Base',
add_clan_confirm => 'Gimble::Page::AddClan::Confirm',
add_clan_commit => 'Gimble::Page::AddClan::Commit',
report_match => 'Gimble::Page::ReportMatch::Base',
report_match_confirm => 'Gimble::Page::ReportMatch::Confirm',
report_match_commit => 'Gimble::Page::ReportMatch::Commit',
show_rules => 'Gimble::Page::ShowRules::Base',
players => 'Gimble::Page::Players::Base',
login => 'Gimble::Page::Login::Base',
login_process => 'Gimble::Page::Login::Process',
player_stats => 'Gimble::Page::PlayerStats::Base',
viewsrc => 'Gimble::Page::ViewSrc::Base',
);
our %next = (
'Gimble::Page::Login::Base' => 'login_process',
'Gimble::Page::Login::Redo' => 'login_process',
'Gimble::Page::Login::Failed' => 'login_process',
'Gimble::Page::Signup::Base' => 'signup_confirm',
'Gimble::Page::Signup::Redo' => 'signup_confirm',
'Gimble::Page::Signup::Confirm' => 'signup_commit',
'Gimble::Page::AddClan::Base' => 'add_clan_confirm',
'Gimble::Page::AddClan::Redo' => 'add_clan_confirm',
'Gimble::Page::AddClan::Confirm' => 'add_clan_commit',
'Gimble::Page::ReportMatch::Base' => 'report_match_confirm',
'Gimble::Page::ReportMatch::Confirm' => 'report_match_commit',
);
sub view_player_url {
sprintf "/cgi-bin/x?task=player_stats&player_id=%d", shift() ;
}
sub dispatch {
my $self = shift;
my $taski = $self->param('task') || 'home' ;
my $dispatch = $task{$taski};
warn "$taski dispatched to => $dispatch";
eval "require $dispatch";
die $@ if $@;
return $dispatch;
}
1;
The full file is attached for reference.
Next, let's look at the page that was dispatch to. It is very simple
and clean, thanks to CGIP:
package Gimble::Page::ShowRules::Base;
use base qw(Gimble::Page::Base);
use Gimble::Model::player_t;
sub template { require html::rules; html::rules->new }
sub engine {
my ($self, $tree) = @_;
$tree->content_handler(
inactive_days => $Gimble::Model::player_t::inactive_days
);
$tree->content_handler(
provisional_days => $Gimble::Model::player_t::provisional_shelf
);
}
1;
Finally, we simply need look at my custom render_enter() method way up
in Gimble::Page::Base which all webpages in the site subclass from:
sub render_enter {
my $self = shift;
my $tree = $self->template;
# pass the HTML::Seamstress tree to engine()
$self->engine($tree);
# set the hidden parameter in the HTML file
$self->set_next_task($tree);
# pass manipulated tree to render() so it can send it to STDOUT
$self->reflect->addSlot(render_out => $tree);
}
And the HTML template for this page is here:
http://www.gimblerus.com/html/rules.html
It is pure HTML, just like the output page except it lacks css other
boilerplate that ->render() puts on it and you can see "blah blah"
where there should be actual numbers... the dynamic rendering
templates those out at runtime.
Regards,
Terrence Brannon