use strict; use FindBin; use lib "$FindBin::Bin"; # push curdir onto @INC use App; use CGI qw(:cgi); use CGI::Carp; use Matrix::HTML; my $app = App->new(tmpl_path=> '/templates'); $app->run( start => { TEMPLATE => 'start.tt', TEMPLATE_VARS => sub { #CODEREF OR HASH REF return {name=>'foo bar', size=>'big'} }, PERSIST => [qw(fred wilma betty)], #ARRAYREF VALIDATE => sub { if (param('Color') eq 'Green') { croak "I hate green" } }, POSTSUBMIT => sub{ print "HELLO!!!!!!"}, NEXTPAGE => sub {return 'two'}, #CODEREF or STRING } , two => { TEMPLATE => 'two.tt', TEMPLATE_VARS => { x => Matrix::HTML->new([[431,442,3],[334,5,6],[7,8,4449]]), what_you_picked => param('Color'), size=>rand(10) } } ); #### package App; use strict; use CGI::Carp; use CGI qw(:cgi); use Template; use FindBin; sub new { my $class = shift; my $self = { tmpl_path => '', mode_param => 'rm', default_mode => 'start' }; bless($self, $class); # set default values my %parms = @_; foreach my $p (keys %parms) {$self->set($p, $parms{$p});} return $self; } sub set { my ($self, $p, $v) = @_; croak "unknown parm: $p" unless exists($self->{$p}); $self->{$p} = $v; } sub get { my ($self, $p) = @_; croak "unknown parm: $p" unless exists($self->{$p}); return $self->{$p}; } sub run { my ($self, %logic) = @_; my $nextmode; # figure out which page was just submitted my $mode = ¶m($self->get('mode_param')); if (defined($mode)) { # is this mode valid? croak "unknown mode: $mode" unless defined($logic{$mode}); # determine next mode (coderef or string) if (ref($logic{$mode}{NEXTPAGE}) eq 'CODE') { $nextmode = &{$logic{$mode}{NEXTPAGE}}; } else { $nextmode = $logic{$mode}{NEXTPAGE}; } # run validator, if one exists (coderef) &{$logic{$mode}{VALIDATE}} if $logic{$mode}{VALIDATE}; # run postsubmit, if one exists (coderef) &{$logic{$mode}{POSTSUBMIT}} if $logic{$mode}{POSTSUBMIT}; } else { # if no mode specified, use default $nextmode = $self->get('default_mode'); } # now work on next page $mode = $nextmode; # load template vars, if any (coderef or hashref) my $tmpl_vars; if (ref($logic{$mode}{TEMPLATE_VARS}) eq 'CODE') { $tmpl_vars = &{$logic{$mode}{TEMPLATE_VARS}}; } if (ref($logic{$mode}{TEMPLATE_VARS}) eq 'HASH') { $tmpl_vars = $logic{$mode}{TEMPLATE_VARS}; } # get the persistant variables (arrayref) my %hidden; foreach my $h (@{$logic{$nextmode}{PERSIST}}) { $hidden{$h}=param($h); } # and add in the runmode variable $hidden{$self->get('mode_param')} = $nextmode; # chunk into template vars $tmpl_vars->{hidden} = \%hidden; # set up the template object my $T = Template->new({ INCLUDE_PATH =>$FindBin::Bin . $self->get('tmpl_path') }); # get the name of the template file my $template = $logic{$nextmode}{TEMPLATE}; # and spit out page $T->process($template, $tmpl_vars) || croak $T->error(); } 1;