CGI::A...rmState(3pm)
π CGI::Application::Plugin::FormState π
okay bestie, welcome to CGI::A...rmState(3pm) β the User Contributed Perl Documentation corner of the universe, and this page is long, so buckle up, we're doing it in parts. This one? Part 1. More is coming. π
β¨ NAME β¨
CGI::Application::Plugin::FormState β store form state without hidden fields. Yes, for real. No cap. π
πΈ VERSION πΈ
Version 0.12
π¦ SYNOPSIS π¦
FormState is literally just a lil temporary stash π«Ά that you can use for storing and retrieving private parameters in your multi-page form. That's it. That's the whole vibe.
use CGI::Application::Plugin::FormState;
my $form = <<EOF;
<form action="app.cgi">
<input type="hidden" name="run_mode" value="form_process_runmode">
<input type="hidden" name="cap_form_state" value="<tmpl_var cap_form_state>">
...
</form>
EOF
sub form_display_runmode {
my $self = shift;
# Store some parameters
$self->form_state->param('name' => 'Road Runner');
$self->form_state->param('occupation' => 'Having Fun');
my $t = $self->load_tmpl(scalarref => \$form);
return $t->output;
}
sub form_process_runmode {
my $self = shift;
# Retrieve some parameters
print $self->form_state->param('name'); # 'Road Runner'
print $self->form_state->param('occupation'); # 'Having Fun'
}
π EXAMPLE π
okay so this one is a more complete example, and it's using CGI::Application::Plugin::ValidateRM. iconic collab honestly β¨
use CGI::Application::Plugin::Session;
use CGI::Application::Plugin::FormState;
use CGI::Application::Plugin::ValidateRM;
my $form = <<EOF;
<form action="app.cgi">
<input type="hidden" name="run_mode" value="my_form_process">
<input type="hidden" name="cap_form_state" value="<tmpl_var cap_form_state>">
...
</form>
EOF
sub my_form_display {
my $self = shift;
my $errs = shift;
my $t = $self->load_tmpl(scalarref => \$form);
# Stash some data into it
$self->form_state->param('name' => 'Wile E. Coyote');
$self->form_state->param('occupation' => 'Mining Engineer');
# Normal ValidateRM error handling
$t->param($errs) if $errs;
return $t->output;
}
sub my_form_process {
my $self;
# Normal ValidateRM validation
my ($results, $err_page) = $self->check_rm('my_form_display','_my_form_profile');
return $err_page if $err_page;
# The data from the submitted form
my $params = $self->dfv_results;
$params->{'name'} = $self->form_state->param('name'); # 'Wile E. Coyote'
$params->{'occupation'} = $self->form_state->param('occupation'); # 'Mining Engineer'
# Now do something interesting with $params
# ...
my $t = $self->load_tmpl('success.html');
return $t->output;
}
# Standard ValiateRM profile
sub _my_form_profile {
return {
required => 'email',
msgs => {
any_errors => 'some_errors',
prefix => 'err_',
},
};
}
π DESCRIPTION π
CGI::Application::Plugin::FormState provides a temporary storage area within the user's session for storing form-related data. It's giving little locker, but for your form. π
The main use of this is for multi-page forms. Instead of using hidden fields to store data related to the form, you store and retrieve values from the form state. Revolutionary behaviour honestly.
In the first instance of your app:
$self->form_state->param('some_name' => 'some_value');
$self->form_state->param('some_other_name' => 'some_other_value');
And later, in a different instance of your app:
$val1 = $self->form_state->param('some_name');
$val2 = $self->form_state->param('some_other_name');
To connect the first instance and the second, you put a single hidden field in your template:
<input type="hidden" name="cap_form_state" value="<tmpl_var my_storage_name>">
And you do not have to worry about creating the template param cap_form_state β it is added automatically to your template parameters via the load_tmpl hook. It just shows up. Like magic but it's Perl. π§
If you want to use a parameter other than cap_form_state you can do so via the name parameter to form_state->config.
If you're skeptical about whether all this abstraction is a good idea, see MOTIVATION, below. We got you. π«Ά
π PRESERVING FORM STATE ACROSS REDIRECTS π
You can include the form_state hash in a link:
my $link = '/app.cgi?rm=list&cap_form_state=' . $self->form_state->id;
If you use CGI::Application::Plugin::Redirect, you can easily create redirect this way:
$self->redirect('/app.cgi?rm=list&cap_form_state=' . $self->form_state->id);
If you also use CGI::Application::Plugin::LinkIntegrity it is as simple as:
$self->redirect($self->link('/app.cgi', 'rm' => 'list', 'cap_form_state' => $self->form_state->id));
Or, in the case of a link to the currently running app:
$self->redirect($self->self_link('rm' => 'list', 'cap_form_state' => $self->form_state->id));
π IMPLEMENTATION π
When you call $self->form_state for the first time, a top-level key is created in the user's session. This key contains a random, hard-to-guess element. It might look something like:
form_state_cap_form_state_84eb13cfed01764d9c401219faa56d53
All data you place in the form state with param is stored in the user's session under this key.
You pass the name of this key on to the next instance of your application by means of a hidden field in your form:
<input type="hidden" name="cap_form_state" value="<tmpl_var cap_form_state>">
You manually put this hidden field in your template. The template parameter cap_form_state is automatically added to your template parameters via the load_tmpl hook. It contains the random, hard-to-guess portion (e.g. 84eb13cfed01764d9c401219faa56d53). When the template is filled, the hidden field will look something like this:
<input type="hidden" name="cap_form_state" value="84eb13cfed01764d9c401219faa56d53">
Since all values are stored on the server in the user's session, the user can't tamper with any of them. bestie-proof. π
To keep old form_data from cluttering up the user's session, the system uses CGI::Session's expire feature to expire old form state keys after a reasonable amount of time has passed (2 days by default).
You can manually delete a form state storage by calling:
$self->form_state->delete;
π«Ά ACKNOWLEDGEMENTS π«Ά
Okay so massive shoutout moment, because this module literally would not exist in its current form without these two legends:
- Richard Dice and Cees Hek β for helping me sort out all the issues with this whole approach. Like, genuinely helped me figure it out, no cap. Besties fr fr. π
And a very specific little credit moment, because we love transparency:
- The informative error message text that shows up when this module gets loaded before your app is actually an
@ISA"CGI::Application"object β yeah, that text? Stolen. Borrowed. Repurposed with love. It came straight from Cees'sCGI::Application::Plugin::TTmodule. π
π COPYRIGHT & LICENSE π
Copyright 2005 Michael Graham, All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Periodt. β¨
And that's a wrap on the whole page, bestie! π Everything you just read lives in the docs forperlversionv5.34.0, dated2022-06-09, underCGI::A...rmState(3pm)β the user-contributed Perl documentation corner of the internet. Go forth and preserve that form state. Slay. π π¦
π¦ where this page comes from
- debian bookworm: libcgi-application-plugin-formstate-perl 0.12-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libcgi-application-plugin-formstate-perl 0.12-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libcgi-application-plugin-formstate-perl 0.12-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libcgi-application-plugin-formstate-perl 0.12-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libcgi-application-plugin-formstate-perl 0.12-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms