This is more of an FYI post than anything. I've had the website 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:

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;


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) = @_;

    inactive_days => $Gimble::Model::player_t::inactive_days

    provisional_days => $Gimble::Model::player_t::provisional_shelf



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()

  # set the hidden parameter in the HTML file         

  # 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:

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. 

Terrence Brannon

Reply via email to