CGI::Ex::Fill(3)
β¨ NAME β¨
CGI::Ex::Fill β a fast but compliant regex based form filler π
(also hi bestie, this is CGI::Ex::Fill(3) from the User Contributed Perl Documentation corner of the internet π¦ pull up a chair)
πΈ VERSION πΈ
version 2.55
π SYNOPSIS π
use CGI::Ex::Fill qw(form_fill fill);
my $text = my_own_template_from_somewhere();
my $form = CGI->new;
# OR
# my $form = {key => 'value'}
# OR
# my $form = [CGI->new, CGI->new, {key1 => 'val1'}, CGI->new];
form_fill(\$text, $form); # modifies $text
# OR
# my $copy = form_fill($text, $form); # copies $text
# OR
fill({
text => \$text,
form => $form,
});
# ALSO
my $formname = 'formname'; # form to parse (undef = anytable)
my $fp = 0; # fill_passwords ? default is true
my $ignore = ['key1', 'key2']; # OR {key1 => 1, key2 => 1};
form_fill(\$text, $form, $formname, $fp, $ignore);
# OR
fill({
text => \$text,
form => $form,
target => 'my_formname',
fill_password => $fp,
ignore_fields => $ignore,
});
# ALSO
### delay getting the value until we find an element that needs it
my $form = {key => sub {my $key = shift; # get and return value}};
π DESCRIPTION π
So form_fill is literally the sibling of HTML::FillInForm. Same energy, same test suite β it passes all of them. Actually bestie, it's a lil bit kinder on the parse: it won't change case, it won't reorder your attributes, it won't mess with miscellaneous spaces, and it won't require the HTML to be well formed. Iconic behavior, no notes. π
Here's the tea β β HTML::FillInForm is built on HTML::Parser, while CGI::Ex::Fill is purely regex driven. The performance of CGI::Ex::Fill will be better on HTML with many markup tags, because HTML::Parser will parse each tag while CGI::Ex::Fill will search only for those tags it knows how to handle. And CGI::Ex::Fill generally won't break on malformed html. Slay. β¨
On tiny forms (< 1 k) form_fill was ~ 13% slower than FillInForm. BUT β if the html document incorporated very many entities at all, the performance of FillInForm goes down (adding 360 <br> tags pushed form_fill to ~ 350% faster). So like, it scales, periodt. π
That said, if you are only filling in one form every so often, then it shouldn't matter which you use β but form_fill will be nicer on the tags and won't balk at ugly html and will decrease performance only at a slow rate as the size of the html increases. See the benchmarks in the t/samples/bench_cgix_hfif.pl file for more information (ALL BENCHMARKS SHOULD BE TAKEN WITH A GRAIN OF SALT). π§
There are two functions, fill and form_fill. The function fill takes a hashref of named arguments. The function form_fill takes a list of positional parameters. Two sisters, two vibes. π«Ά
π¦ ARGUMENTS TO form_fill π¦
The following are the arguments to the main function fill.
textβ A reference to an html string that includes one or more forms. πformβ A form hash,CGIobject, or an array of hashrefs and objects. Mix and match, main character energy. πtargetβ The name of the form to swap. Default isundefwhich means to swap all form entities in all forms.fill_passwordβ Defaulttrue. If set tofalse, fields of typepasswordwill not be refilled. πignore_fieldsβ Hashref of fields to be ignored from swapping. Not me ignoring your exes.remove_scriptβ Defaults to the package global$REMOVE_SCRIPTwhich defaults totrue. Removes anything in<script></script>tags which often cause problems for parsers.remove_commentβ Defaults to the package global$REMOVE_COMMENTwhich defaults totrue. Removes anything in<!-- -->tags which can sometimes cause problems for parsers.object_methodβ The method to call on objects passed to theformargument. Default value is the package global$OBJECT_METHODwhich defaults to'param'. If aCGIobject is passed, it would callparamon that object passing the desired keyname as an argument. Lowkey elegant.
π ARGUMENTS TO form_fill π
The following are the arguments to the legacy function form_fill. (yes bestie, this one is the old-school positional one, iykyk π)
"\$html"β A reference to an html string that includes one or more forms or form entities."\%FORM"β A form hash, orCGIquery object, or an arrayref of multiple hash refs and/orCGIquery objects that will supply values for the form.$form_nameβ The name of the form to fill in values for. The default isundefwhich indicates that all forms are to be filled in.$swap_passβ Defaulttrue. Indicates that"<lt"input type="password"<gt>>fields are to be swapped as well. Set tofalseto disable this behavior."\%IGNORE_FIELDS"OR"\@IGNORE_FIELDS"β A hash ref of key names or an array ref of key names that will be ignored during the fill in of the form.
π¦ BEHAVIOR π¦
okay bestie, this is the part where fill and form_fill are out here trying to DWYM β like, do what you mean β when they're filling in values. and the vibes they bring depend on what kind of form element they're dealing with. here's the whole rundown π
<input type="text">
when it clocks a text input, it plays by these rules, in order:
- grab the value from the form that matches the input's
"name". - if that value is defined β it adds it or replaces whatever was already sitting there.
- if the value is not defined and the existing value is also not defined, a value of
""gets added. empty bestie, but present β¨
for example:
my $form = {foo => "FOO", bar => "BAR", baz => "BAZ"};
my $html = '
<input type=text name=foo>
<input type=text name=foo>
<input type=text name=bar value="">
<input type=text name=baz value="Something else">
<input type=text name=hem value="Another thing">
<input type=text name=haw>
';
form_fill(\$html, $form);
$html eq '
<input type=text name=foo value="FOO">
<input type=text name=foo value="FOO">
<input type=text name=bar value="BAR">
<input type=text name=baz value="BAZ">
<input type=text name=hem value="Another thing">
<input type=text name=haw value="">
';
and listen β if the value coming back from the form is an array ref, the values in that array ref get used sequentially for each input found by that name, until the values run out. if it's not an array ref, that one value fills in every value by that name. like a little rotation, no cap π
$form = {foo => ['aaaa', 'bbbb', 'cccc']};
$html = '
<input type=text name=foo>
<input type=text name=foo>
<input type=text name=foo>
<input type=text name=foo>
<input type=text name=foo>
';
form_fill(\$html, $form);
$html eq '
<input type=text name=foo value="aaaa">
<input type=text name=foo value="bbbb">
<input type=text name=foo value="cccc">
<input type=text name=foo value="">
<input type=text name=foo value="">
';
<input type="hidden">
same as <input type="text">. sneaky but identical π
<input type="password">
same as <input type="text">. it's giving secure but it's giving identical, fr fr π
<input type="file">
same as <input type="text">. (note β this one is subject to browser support for pre-population, so like, don't be shocked if the browser says no)
<input type="checkbox">
every time a checkbox gets found, these rules roll out:
- grab the values from the form (and do nothing if no values are found).
- strip out any existing
"checked=checked"or"checked"markup from the tag. bye π - compare the
"value"field to the values, and mark it withchecked="checked"if there's a match.
and if there's no "value" field in the html at all? a default value of "on" gets used β which is literally what most browsers send as the default value for checked boxes that don't have "value" fields. iconic default behavior honestly π
$form = {foo => 'FOO', bar => ['aaaa', 'bbbb', 'cccc'], baz => 'on'};
$html = '
<input type=checkbox name=foo value="123">
<input type=checkbox name=foo value="FOO">
<input type=checkbox name=bar value="aaaa">
<input type=checkbox name=bar value="cccc">
<input type=checkbox name=bar value="dddd" checked="checked">
<input type=checkbox name=baz>
';
form_fill(\$html, $form);
$html eq '
<input type=checkbox name=foo value="123">
<input type=checkbox name=foo value="FOO" checked="checked">
<input type=checkbox name=bar value="aaaa" checked="checked">
<input type=checkbox name=bar value="cccc" checked="checked">
<input type=checkbox name=bar value="dddd">
<input type=checkbox name=baz checked="checked">
';
<input type="radio">
same as <input type="checkbox">. twins π
<select>
every select box found gets these rules applied β and note, these apply regardless of whether the box is a select-one or a select-multi. and if multiple values end up selected on a select-one? that's on the browser to pick which one to highlight, not us π€·ββοΈ
- grab the values from the form (do nothing if no values are found).
- remove any existing
"selected=selected"or"selected"markup from the tag. - compare the
"value"field to the values, and mark it withselected="selected"if there's a match. - if there's no
"value"field β use the text sitting in between the"option"tags.
(Note: there does not need to be a closing "select" tag or closing "option" tag)
$form = {foo => 'FOO', bar => ['aaaa', 'bbbb', 'cccc']};
$html = '
<select name=foo><option>FOO<option>123<br>
<select name=bar>
<option>aaaa</option>
<option value="cccc">cccc</option>
<option value="dddd" selected="selected">dddd</option>
</select>
';
form_fill(\$html, $form);
ok(
$html eq '
<select name=foo><option selected="selected">FOO<option>123<br>
<select name=bar>
<option selected="selected">aaaa</option>
<option value="cccc" selected="selected">cccc</option>
<option value="dddd">dddd</option>
</select>
', "Perldoc example 4 passed");
<textarea>
the rules for swapping textarea content go like this:
- grab the value from the form that matches the textarea's
"name". - if the value is defined β it adds or replaces the existing value.
- if the value is not defined, the text area is left alone. respecting its peace βοΈ
(Note β there does not need to be a closing textarea tag. In the case of a missing close textarea tag, the contents of the text area will be assumed to be the start of the next textarea of the end of the document β which ever comes sooner)
if the form handed back an array ref of values, those values get used sequentially each time a textarea by that name is found. if it's a single value (not an array ref), that value gets used for each textarea by that name. same energy as the text inputs bestie πΈ
for example.
$form = {foo => 'FOO', bar => ['aaaa', 'bbbb']};
$html = '
<textarea name=foo></textarea>
<textarea name=foo></textarea>
<textarea name=bar>
<textarea name=bar></textarea><br>
<textarea name=bar>dddd</textarea><br>
<textarea name=bar><br><br>
';
form_fill(\$html, $form);
$html eq '
<textarea name=foo>FOO</textarea>
<textarea name=foo>FOO</textarea>
<textarea name=bar>aaaa<textarea name=bar>bbbb</textarea><br>
<textarea name=bar></textarea><br>
<textarea name=bar>';
<input type="submit">
does nothing. literally nothing. the value for submit should typically be set by the templating system or application system β that's their job, not this module's π
<input type="button">
same as submit. also just vibing in the corner doing nothing β¨
π HTML COMMENT / JAVASCRIPT π
okay so there are just too many problems that could pop off with html comments and javascript, so form_fill temporarily removes them during the fill. clean slate energy.
you can turn that behavior off by setting $REMOVE_COMMENT and $REMOVE_SCRIPT to 0 before calling form_fill. and why would you ever do that? mainly if you wanted to have form elements inside the javascript and comments get filled. like, living inside the chaos.
and honestly? disabling the removal only gets you a speed increase of 5%. that's it. that's the whole bag π
the function uses \0COMMENT\0 and \0SCRIPT\0 as placeholders, so it would be good to avoid these in your text. (Actually they may be reset to whatever you'd like via $MARKER_COMMENT and $MARKER_SCRIPT.)
β¨ UTILITY FUNCTIONS β¨
html_escape
a very minimal entity escaper, for filled-in values.
my $escaped = html_escape($unescaped);
html_escape(\$text_to_escape);
get_tagval_by_key
get a named value for from an html tag (key="value" pairs).
my $val = get_tagval_by_key(\$tag, $key);
my $valsref = get_tagval_by_key(\$tag, $key, 'all'); # get all values
swap_tagval_by_key
swap out values in an html tag (key="value" pairs).
my $count = swap_tagval_by_key(\$tag, $key, $val); # modify ref
my $newtag = swap_tagval_by_key($tag, $key, $val); # copies tag
π LICENSE π
this module may distributed under the same terms as Perl itself. periodt.
π«Ά AUTHOR π«Ά
Paul Seamons <perl at seamons dot com>
and that's the whole page bestie, you ate it π
this was perl v5.42.0, dated 2025-07-25, and it's CGI::Ex::Fill(3) β go forth and fill those forms, mwah ππβ¨
π¦ where this page comes from
- fedora 43: perl-CGI-Ex 2.55-6.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms