CGI-Application-Plugin-FillInForm-1.15/0040775000175200017520000000000011217770173016224 5ustar markmarkCGI-Application-Plugin-FillInForm-1.15/META.yml0100664000175200017520000000074211217770173017475 0ustar markmark--- #YAML:1.0 name: CGI-Application-Plugin-FillInForm version: 1.15 author: - Michael Graham - Mark Stosberg abstract: integrate with HTML::FillInForm license: perl requires: CGI::Application: 0 HTML::FillInForm: 1 Test::More: 0 recommends: HTML::FillInForm: 1.04 provides: CGI::Application::Plugin::FillInForm: file: lib/CGI/Application/Plugin/FillInForm.pm version: 1.15 generated_by: Module::Build version 0.2611 CGI-Application-Plugin-FillInForm-1.15/lib/0040775000175200017520000000000011217770173016772 5ustar markmarkCGI-Application-Plugin-FillInForm-1.15/lib/CGI/0040775000175200017520000000000011217770173017374 5ustar markmarkCGI-Application-Plugin-FillInForm-1.15/lib/CGI/Application/0040775000175200017520000000000011217770173021637 5ustar markmarkCGI-Application-Plugin-FillInForm-1.15/lib/CGI/Application/Plugin/0040775000175200017520000000000011217770173023075 5ustar markmarkCGI-Application-Plugin-FillInForm-1.15/lib/CGI/Application/Plugin/FillInForm.pm0100664000175200017520000001171611217770173025437 0ustar markmarkpackage CGI::Application::Plugin::FillInForm; use base 'Exporter'; use strict; use warnings; our $VERSION = '1.15'; our @EXPORT_OK = qw(fill_form); use Carp; =head1 NAME CGI::Application::Plugin::FillInForm - integrate with HTML::FillInForm =head1 SYNOPSIS use CGI::Application::Plugin::FillInForm (qw/fill_form/); my $t = $self->load_tmpl('farm.html'); $t->param( organic => 'less_pesticides' ); return $self->fill_form( \$t->output ); =head1 DESCRIPTION This plugin provides a mix-in method to make using HTML::FillInForm more convenient. =head2 fill_form() # fill an HTML form with data in a hashref or from an object with with a param() method my $filled_html = $self->fill_form($html, $data); # ...or fill from a list of data sources # (each item in the list can be either a hashref or an object) my $filled_html = $self->fill_form($html, [$user, $group, $query]); # ...or default to getting data from $self->query() my $filled_html = $self->fill_form($html); # extra fields will be passed on through: my $filled_html = $self->fill_form($html, undef, fill_password => 0 ); This method provides an easier syntax for calling HTML::FillInForm, and an intelligent default of using $self->query() as the default data source. By default, the mode param (usually 'rm') of every data source will be ignored. This prevents accidently clobbering your run mode for the next page, which may be stored in a hidden field. B<$html> must be a scalarref, or a reference to a scalarref. B<$filled_html> will be a reference to a string. Because this method only loads HTML::FillInForm if it's needed, it should be reasonable to load it in a base class and always have it available: use CGI::Application::Plugin::FillInForm (qw/fill_form/); =cut sub fill_form { my $self = shift; my $html = shift; my $data = shift; my %extra_params = @_; if (ref $html eq 'REF' and ref $$html eq 'SCALAR') { $html = $$html; } die "html must be a scalarref!" unless (ref $html eq 'SCALAR'); my %params = ( ignore_fields => [ $self->mode_param()], ); my (@fdat, @fobject); if ($data) { $data = [$data] unless ref $data eq 'ARRAY'; for my $source (@$data) { if (ref $source eq 'HASH') { push @fdat, $source; } elsif (ref $source) { if ($source->can('param')) { push @fobject, $source; } else { croak "data source $source does not supply a param method"; } } elsif (defined $source) { croak "data source $source is not a hash or object reference"; } } # The docs to HTML::FillInForm suggest that you can pass an arrayref # of %fdat hashes, but you can't. So if we receive more than one, # we merge them. (This is no big deal, since this is what # HTML::FillInForm would do anyway if it supported this feature.) if (@fdat) { if (@fdat > 1) { my %merged; for my $hash (@fdat) { for my $key (keys %$hash) { $merged{$key} = $hash->{$key}; } } $params{'fdat'} = \%merged; } else { # If there's only one fdat hash anyway, then it's the # first and only element in @fdat $params{'fdat'} = $fdat[0]; } } # Multiple objects, however, are supported natively by # HTML::FillInForm $params{'fobject'} = \@fobject if @fobject; } else { # If no data sources are specified, then use # $self->query $params{'fobject'} = $self->query; } require HTML::FillInForm; my $fif = new HTML::FillInForm; my $output = $fif->fill(scalarref => $html, %params, %extra_params); return \$output; } =head1 AUTHORS Cees Hek published the first draft on the CGI::App wiki Mark Stosberg, C<< >> polished it for release. Michael Graham, C<< >> added tests and some new features. The module is now co-maintained by Mark and Michael. =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 CONTRIBUTING Patches, questions and feedback are welcome. This project is managed using the darcs source control system ( http://www.darcs.net/ ). My darcs archive is here: http://mark.stosberg.com/darcs_hive/cap-fif/ =head1 Copyright & License Copyright 2005 Mark Stosberg, All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; # End of CGI::Application::Plugin::FillInForm CGI-Application-Plugin-FillInForm-1.15/t/0040775000175200017520000000000011217770173016467 5ustar markmarkCGI-Application-Plugin-FillInForm-1.15/t/02-fif.t0100664000175200017520000001630011217770173017634 0ustar markmark#!/usr/bin/perl use strict; use Test::More 'no_plan'; $ENV{'CGI_APP_RETURN_ONLY'} = 1; { package Dummy_Param; sub new { my $class = shift; my %data = @_; return bless \%data, $class; } sub param { my $self = shift; if (@_) { return unless exists $self->{$_[0]}; return $self->{$_[0]}; } else { return keys %$self; } } } { package WebApp; use vars qw(@ISA); use Test::More; use CGI::Application; use CGI::Application::Plugin::FillInForm qw/fill_form/; @ISA = ('CGI::Application'); sub setup { my $self = shift; $self->header_type('none'); $self->run_modes(['start']); } sub start { my $self = shift; $self->mode_param('rm_foo') ; $self->query->param('rm_foo' => 'bubba'); my $blank_form = qq{
}; my %blank_form_data = map { $_ => "" } qw( data_var1 data_var2 param_var1 param_var2 param_var3 data_varA1 data_varA2 data_varB1 data_varB2 param_varA1 param_varA2 param_varA3 param_varB1 param_varB2 param_varB3 param_varC1 param_varC2 param_varC3 ); $blank_form_data{'rm_foo'} = 'original_rm'; # Test filling with hashref (\%data) my %data = ( 'data_var1' => 'value1', 'data_var2' => 'value2', ); my $html = $blank_form; my $output = $self->fill_form(\$html, \%data); my %form_data = ( %blank_form_data, data_var1 => 'value1', data_var2 => 'value2', ); form_data_ok($output, %form_data, '[data] form data ok'); # Test filling with object ($param_obj) my $param_obj = Dummy_Param->new( 'param_var1' => 'value1', 'param_var2' => 'value2', 'param_var3' => 'value3', 'rm_foo' => 'bubbles', ); $html = $blank_form; $output = $self->fill_form(\$html, $param_obj); %form_data = ( %blank_form_data, param_var1 => 'value1', param_var2 => 'value2', param_var3 => 'value3', rm_foo => 'original_rm', ); form_data_ok($output, %form_data, '[obj] form data ok'); # Test filling with a list (mixed data and objects) my $param_obj1 = Dummy_Param->new( 'param_varA1' => 'pvalueA1', 'param_varA2' => 'pvalueA2', 'param_varA3' => 'pvalueA3', 'rm_foo' => 'bubbles', ); my $param_obj2 = Dummy_Param->new( 'param_varA1' => 'pvalueB1x', 'param_varB1' => 'pvalueB1', 'param_varB2' => 'pvalueB2', 'param_varB3' => 'pvalueB3', 'rm_foo' => 'bubbles2', ); my $param_obj3 = Dummy_Param->new( 'param_varC1' => 'pvalueC1', 'param_varC2' => 'pvalueC2', 'param_varC3' => 'pvalueCB3', 'rm_foo' => 'bubbles3', ); my %data1 = ( 'data_varB1' => 'dvalueA1x', 'data_varA1' => 'dvalueA1', 'data_varA2' => 'dvalueA2', 'rm_foo' => 'bubbles4', ); my %data2 = ( 'data_varB1' => 'dvalue1', 'data_varB2' => 'dvalue2', 'rm_foo' => 'bubbles5', ); $html = $blank_form; $output = $self->fill_form(\$html, [$param_obj3, \%data2, \%data2, $param_obj1, $param_obj2, \%data1]); %form_data = ( %blank_form_data, 'param_varC1' => 'pvalueC1', 'param_varC2' => 'pvalueC2', 'param_varC3' => 'pvalueCB3', 'param_varA1' => 'pvalueA1', 'param_varA2' => 'pvalueA2', 'param_varA3' => 'pvalueA3', 'param_varB1' => 'pvalueB1', 'param_varB2' => 'pvalueB2', 'param_varB3' => 'pvalueB3', 'param_varA1' => 'pvalueB1x', 'data_varB1' => 'dvalue1', 'data_varB2' => 'dvalue2', 'data_varA1' => 'dvalueA1', 'data_varA2' => 'dvalueA2', 'data_varB1' => 'dvalueA1x', rm_foo => 'original_rm', ); SKIP: { skip "Installed HTML::FillInForm does not support ignore fields with fdat - upgrade to version 1.04", 1 if $HTML::FillInForm::VERSION < 1.04; form_data_ok($output, %form_data, '[list] form data ok'); } # Test filling with no data sources - should default to query, but # not override the run mode param ('rm_foo') $self->mode_param('rm_foo') ; $self->query->param('rm_foo' => 'bubbles'); $self->query->param('param_var1' => 'query_value1'); $output = $self->fill_form(\$html); %form_data = ( %blank_form_data, 'rm_foo' => 'original_rm', 'param_var1' => 'query_value1', ); form_data_ok($output, %form_data, '[none] form data ok'); } sub form_data_ok { my $label = pop; my ($string_ref, %data) = @_; my @unmatched; my %matched; foreach my $name (keys %data) { if ($$string_ref =~ /name=("|')$name\1\s+value=("|')$data{$name}\2/ or $$string_ref =~ /value=("|')$data{$name}\1\s+name=("|')$name\2/) { $matched{$name} = $data{$name}; } else { push @unmatched, $name; } } if (eq_hash(\%data, \%matched)) { ok(1, $label); return 1; } else { ok(0, $label); # Print out some diagnostics print STDERR "form output:\n$$string_ref;\n"; if (@unmatched) { print STDERR "Unmatched keys: \n"; foreach my $key (@unmatched) { print STDERR "\t$key - expected: $data{$key}\n"; } print STDERR "\n"; } return; } } } WebApp->new->run; CGI-Application-Plugin-FillInForm-1.15/t/pod-coverage.t0100664000175200017520000000024111217770173021221 0ustar markmarkuse Test::More; eval "use Test::Pod::Coverage 0.08"; plan skip_all => "Test::Pod::Coverage 0.08 required for testing POD coverage" if $@; all_pod_coverage_ok(); CGI-Application-Plugin-FillInForm-1.15/t/pod.t0100664000175200017520000000020111217770173017424 0ustar markmarkuse Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); CGI-Application-Plugin-FillInForm-1.15/t/01-fif-args.t0100664000175200017520000001627211217770173020575 0ustar markmark#!/usr/bin/perl # This test tests that the arguments are correctly # passed from CAP::FiF to H::FiF # To do this we create a mock H::FiF object use strict; use Test::More 'no_plan'; $ENV{'CGI_APP_RETURN_ONLY'} = 1; my $FiF_Fill_Args; { # Create a dummy HTML::FillInForm object by # loading it and then clobbering its new and fill methods with # methods of our own use HTML::FillInForm; package HTML::FillInForm; no warnings; sub new { my $class = shift; return bless {}; } sub fill { my $self = shift; $FiF_Fill_Args = \@_; } } { package Dummy_Param; sub new { my $class = shift; my %data = @_; return bless \%data, $class; } sub param { my $self = shift; if (@_) { return unless exists $self->{$_[0]}; return $self->{$_[0]}; } else { return keys %$self; } } } { package WebApp; use vars qw(@ISA); use Test::More; use CGI::Application; use CGI::Application::Plugin::FillInForm qw/fill_form/; @ISA = ('CGI::Application'); sub setup { my $self = shift; $self->header_type('none'); $self->run_modes(['start']); } sub start { my $self = shift; my $html = 'test html'; my (%fif_params); $self->mode_param('rm_bar') ; $self->query->param('rm_bar' => 'bubba'); # Test filling with hashref (\%data) my %data = ( 'data_var1' => 'value1', 'data_var2' => 'value2', ); my %options = ( 'dopt1' => 'doptvalue1', 'dopt2' => 'doptvalue2', ); $self->fill_form(\$html, \%data, %options); %fif_params = @$FiF_Fill_Args; my $fdat = delete $fif_params{'fdat'}; my $ignore_fields = delete $fif_params{'ignore_fields'}; ok(eq_hash($fdat, \%data), '[data] fdat'); ok(eq_array($ignore_fields, ['rm_bar']), '[obj] ignore_fields '); is(delete $fif_params{'scalarref'}, \$html, '[data] scalarref'); is(delete $fif_params{'dopt1'}, 'doptvalue1', '[data] dopt1'); is(delete $fif_params{'dopt2'}, 'doptvalue2', '[data] dopt2'); ok(!keys %fif_params, '[data] no params unaccounted for'); # Same, but use a reference to the reference of the input $html %data = ( 'data_var1' => 'value1', 'data_var2' => 'value2', ); %options = ( 'dopt1' => 'doptvalue1', 'dopt2' => 'doptvalue2', ); my $html_ref = \$html; $self->fill_form(\$html_ref, \%data, %options); %fif_params = @$FiF_Fill_Args; $fdat = delete $fif_params{'fdat'}; $ignore_fields = delete $fif_params{'ignore_fields'}; ok(eq_hash($fdat, \%data), '[data (html ref)] fdat'); ok(eq_array($ignore_fields, ['rm_bar']), '[obj (html ref)] ignore_fields '); is(delete $fif_params{'scalarref'}, \$html, '[data (html ref)] scalarref'); is(delete $fif_params{'dopt1'}, 'doptvalue1', '[data (html ref)] dopt1'); is(delete $fif_params{'dopt2'}, 'doptvalue2', '[data (html ref)] dopt2'); ok(!keys %fif_params, '[data (html ref)] no params unaccounted for'); # Test filling with object ($param_obj) my $param_obj = Dummy_Param->new( 'param_var1' => 'value1', 'param_var2' => 'value2', 'param_var3' => 'value3', ); %options = ( 'popt1' => 'poptvalue1', 'popt2' => 'poptvalue2', ); $self->fill_form(\$html, $param_obj, %options); %fif_params = @$FiF_Fill_Args; my $fobject = delete $fif_params{'fobject'}; $ignore_fields = delete $fif_params{'ignore_fields'}; $fobject = $fobject->[0] if ref $fobject eq 'ARRAY'; is(delete $fif_params{'scalarref'}, \$html, '[obj] scalarref'); is($fobject, $param_obj, '[obj] fobj'); ok(eq_array($ignore_fields, ['rm_bar']), '[obj] ignore_fields '); is(delete $fif_params{'popt1'}, 'poptvalue1', '[obj] popt1'); is(delete $fif_params{'popt2'}, 'poptvalue2', '[obj] popt2'); ok(!keys %fif_params, '[obj] no params unaccounted for'); # Test filling with a list (mixed data and objects) my $param_obj1 = Dummy_Param->new( 'param_varA1' => 'valueA1', 'param_varA2' => 'valueA2', 'param_varA3' => 'valueA3', ); my $param_obj2 = Dummy_Param->new( 'param_varB1' => 'valueB1', 'param_varB2' => 'valueB2', 'param_varB3' => 'valueB3', ); my $param_obj3 = Dummy_Param->new( 'param_varA1' => 'valueC1x', 'param_varC1' => 'valueC1', 'param_varC2' => 'valueC2', 'param_varC3' => 'valueC3', ); my %data1 = ( 'data_varB1' => 'valueA1x', 'data_varA1' => 'valueA1', 'data_varA2' => 'valueA2', ); my %data2 = ( 'data_varB1' => 'valueB1', 'data_varB2' => 'valueB2', ); %options = ( 'lopt1' => 'loptvalue1', 'lopt2' => 'loptvalue2', ); $self->fill_form(\$html, [$param_obj3, \%data2, \%data2, $param_obj1, $param_obj2, \%data1], %options); %fif_params = @$FiF_Fill_Args; $fobject = delete $fif_params{'fobject'}; $fdat = delete $fif_params{'fdat'}; $ignore_fields = delete $fif_params{'ignore_fields'}; ok(eq_array($fobject, [$param_obj3, $param_obj1, $param_obj2]), '[list] fobject list'); ok(eq_hash($fdat, {%data2, %data1}), '[list] fdat merged hash'); ok(eq_array($ignore_fields, ['rm_bar']), '[obj] ignore_fields '); is(delete $fif_params{'scalarref'}, \$html, '[list] scalarref'); is(delete $fif_params{'lopt1'}, 'loptvalue1', '[list] lopt1'); is(delete $fif_params{'lopt2'}, 'loptvalue2', '[list] lopt2'); ok(!keys %fif_params, '[list] no params unaccounted for'); # Test filling with no data sources - should default to query, but # not override the run mode param ('rm_foo') $self->mode_param('rm_foo') ; $self->query->param('rm_foo' => 'bubbles'); $self->fill_form(\$html); %fif_params = @$FiF_Fill_Args; $fobject = delete $fif_params{'fobject'}; $fdat = delete $fif_params{'fdat'}; $ignore_fields = delete $fif_params{'ignore_fields'}; ok(eq_array($fobject, $self->query), '[none] fobject is query'); ok(eq_array($ignore_fields, ['rm_foo']), '[none] ignore_fields'); is(delete $fif_params{'scalarref'}, \$html, '[none] scalarref'); ok(!keys %fif_params, '[none] no params unaccounted for'); } } WebApp->new->run; CGI-Application-Plugin-FillInForm-1.15/t/00.load.t0100664000175200017520000000030011217770173017777 0ustar markmarkuse Test::More tests => 1; BEGIN { use_ok( 'CGI::Application::Plugin::FillInForm' ); } diag( "Testing CGI::Application::Plugin::FillInForm $CGI::Application::Plugin::FillInForm::VERSION" ); CGI-Application-Plugin-FillInForm-1.15/Changes0100664000175200017520000000403311217770173017514 0ustar markmarkRevision history for CGI-Application-Plugin-FillInForm 1.15 06/22/09 (No code changes) - Fix "fill_password" typo (Fred Steinberg) 1.14 09/13/05 - added Michael Graham to dist_author in Build.PL - lowered prereq of HTML::FillInForm to 1.00 - indicated that HTML::FillInForm version of 1.04 is recommended - changed fill_form() to accept $html being a reference to a scalarref. This is useful for use with templating plugins which return a reference to a string (CAP::AnyTemplate and CAP::TT both do this): my $html = $self->template->process; $self->fill_form(\$html, ...); # it does not matter if $html # was already a reference 1.13 09/01/05 - fixed a test failure when using an older version of HTML::FillInForm - added dist/prove_prereqs.pl for testing with older versions of prerequisite modules. See the source of that script file for info. 1.12 08/30/05 - added Michael Graham to list of maintainers in docs to reduce confusion over which is the official version 1.12_01 08/23/05 - To conserve memory, fill_form now returns a reference to the HTML output instead of a copy of it (Cees Hek). 1.11 08/15/05 - added CGI::Application to the prerequisites - now mode_param (e.g. 'rm') is always ignored by default (i.e. not just when the query is used as the source) 1.10 07/31/05 - clarified the docs about multiple data sources - upped the version number so this package cleanly supercedes all previous versions. 1.00_3 07/31/05 (unreleased) - now can accept list of data sources (Michael Graham) - added tests (Michael Graham) - fixed bug where $data was being ignored - attempt to re-flag this version as a developer release by changing version from 1.0_3 to 1.00_3 1.00_2 07/29/05 - Ignore 'rm' instead of deleting it. - require HTML::FillInForm 1.05 for good measure. 1.00_1 07/28/05 - First version, released on an unsuspecting world. CGI-Application-Plugin-FillInForm-1.15/MANIFEST0100664000175200017520000000030211217770173017345 0ustar markmarkBuild.PL Changes lib/CGI/Application/Plugin/FillInForm.pm Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.yml README t/00.load.t t/01-fif-args.t t/02-fif.t t/pod-coverage.t t/pod.t CGI-Application-Plugin-FillInForm-1.15/MANIFEST.SKIP0100664000175200017520000000061011217770173020114 0ustar markmark# This is a list of regular expressions of files to skip when rebuilding # the MANIFEST file. See the documention for the ExtUtils::Manifest module for more detail. -mls \bCVS\b ^MANIFEST\.bak$ ^Makefile$ ~$ \.old$ \.bak$ ^blib/ ^pm_to_blib$ ^MakeMaker-\d .tar.gz$ ^notes ^releases \.tgz$ \.tmp$ \.swp$ \.swm$ \.swn$ \.swo$ \.patch$ \.orig$ \.diff$ _darcs _build ^Build$ t/prereq_scenarios CGI-Application-Plugin-FillInForm-1.15/Build.PL0100664000175200017520000000133611217770173017520 0ustar markmark#!/usr/bin/perl use strict; use Module::Build; my $builder = Module::Build->new( module_name => 'CGI::Application::Plugin::FillInForm', license => 'perl', dist_author => [ 'Michael Graham ', 'Mark Stosberg ' ], dist_version_from => 'lib/CGI/Application/Plugin/FillInForm.pm', create_makefile_pl => 'traditional', create_readme => 1, requires => { 'Test::More' => 0, 'HTML::FillInForm' => 1.00, 'CGI::Application' => 0, }, recommends => { 'HTML::FillInForm' => 1.04, }, add_to_cleanup => [ 'CGI-Application-Plugin-FillInForm-*' ], ); $builder->create_build_script(); CGI-Application-Plugin-FillInForm-1.15/Makefile.PL0100664000175200017520000000102411217770173020170 0ustar markmark# Note: this file was auto-generated by Module::Build::Compat version 0.03 use ExtUtils::MakeMaker; WriteMakefile ( 'NAME' => 'CGI::Application::Plugin::FillInForm', 'VERSION_FROM' => 'lib/CGI/Application/Plugin/FillInForm.pm', 'PREREQ_PM' => { 'CGI::Application' => '0', 'HTML::FillInForm' => '1', 'Test::More' => '0' }, 'INSTALLDIRS' => 'site', 'PL_FILES' => {} ) ; CGI-Application-Plugin-FillInForm-1.15/README0100664000175200017520000000520411217770173017102 0ustar markmarkNAME CGI::Application::Plugin::FillInForm - integrate with HTML::FillInForm SYNOPSIS use CGI::Application::Plugin::FillInForm (qw/fill_form/); my $t = $self->load_tmpl('farm.html'); $t->param( organic => 'less_pesticides' ); return $self->fill_form( \$t->output ); DESCRIPTION This plugin provides a mix-in method to make using HTML::FillInForm more convenient. fill_form() # fill an HTML form with data in a hashref or from an object with with a param() method my $filled_html = $self->fill_form($html, $data); # ...or fill from a list of data sources # (each item in the list can be either a hashref or an object) my $filled_html = $self->fill_form($html, [$user, $group, $query]); # ...or default to getting data from $self->query() my $filled_html = $self->fill_form($html); # extra fields will be passed on through: my $filled_html = $self->fill_form($html, undef, fill_password => 0 ); This method provides an easier syntax for calling HTML::FillInForm, and an intelligent default of using $self->query() as the default data source. By default, the mode param (usually 'rm') of every data source will be ignored. This prevents accidently clobbering your run mode for the next page, which may be stored in a hidden field. $html must be a scalarref, or a reference to a scalarref. $filled_html will be a reference to a string. Because this method only loads HTML::FillInForm if it's needed, it should be reasonable to load it in a base class and always have it available: use CGI::Application::Plugin::FillInForm (qw/fill_form/); AUTHORS Cees Hek published the first draft on the CGI::App wiki Mark Stosberg, C<< >> polished it for release. Michael Graham, C<< >> added tests and some new features. The module is now co-maintained by Mark and Michael. BUGS Please report any bugs or feature requests to "bug-cgi-application-plugin-fillinform@rt.cpan.org", or through the web interface at . I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. CONTRIBUTING Patches, questions and feedback are welcome. This project is managed using the darcs source control system ( http://www.darcs.net/ ). My darcs archive is here: http://mark.stosberg.com/darcs_hive/cap-fif/ Copyright & License Copyright 2005 Mark Stosberg, All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.