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