NAME

Text::FormBuilder - Create CGI::FormBuilder objects from simple text descriptions

SYNOPSIS

use Text::FormBuilder;

my $parser = Text::FormBuilder->new;
$parser->parse($src_file);

# returns a new CGI::FormBuilder object with
# the fields from the input form spec
my $form = $parser->form;

# write a My::Form module to Form.pm
$parser->write_module('My::Form');

REQUIRES

Parse::RecDescent, CGI::FormBuilder, Text::Template

DESCRIPTION

new

parse

# parse a file
$parser->parse($filename);

# or pass a scalar ref for parse a literal string
$parser->parse(\$string);

Parse the file or string. Returns the parser object.

parse_file

$parser->parse_file($src_file);

# or as a class method
my $parser = Text::FormBuilder->parse($src_file);

parse_text

$parser->parse_text($src);

Parse the given $src text. Returns the parser object.

build

$parser->build(%options);

Builds the CGI::FormBuilder object. Options directly used by build are:

form_only

Only uses the form portion of the template, and omits the surrounding html, title, author, and the standard footer. This does, however, include the description as specified with the !description directive.

css, extra_css

These options allow you to tell Text::FormBuilder to use different CSS styles for the built in template. A value given a css will replace the existing CSS, and a value given as extra_css will be appended to the CSS. If both options are given, then the CSS that is used will be css concatenated with extra_css.

messages

This works the same way as the messages parameter to CGI::FormBuilder->new; you can provide either a hashref of messages or a filename.

The default messages used by Text::FormBuilder are:

text_author       Created by %s
text_madewith     Made with %s version %s
text_required     (Required fields are marked in <strong>bold</strong>.)
text_invalid      Missing or invalid value.

Any messages you set here get passed on to CGI::FormBuilder, which means that you should be able to put all of your customization messages in one big file.

charset

Sets the character encoding for the generated page. The default is ISO-8859-1.

All other options given to build are passed on verbatim to the CGI::FormBuilder constructor. Any options given here override the defaults that this module uses.

The form, write, and write_module methods will all call build with no options for you if you do not do so explicitly. This allows you to say things like this:

my $form = Text::FormBuilder->new->parse('formspec.txt')->form;

However, if you need to specify options to build, you must call it explictly after parse.

form

my $form = $parser->form;

Returns the CGI::FormBuilder object. Remember that you can modify this object directly, in order to (for example) dynamically populate dropdown lists or change input types at runtime.

write

$parser->write($out_file);
# or just print to STDOUT
$parser->write;

Calls render on the FormBuilder form, and either writes the resulting HTML to a file, or to STDOUT if no filename is given.

write_module

$parser->write_module($package, $use_tidy);

Takes a package name, and writes out a new module that can be used by your CGI script to render the form. This way, you only need CGI::FormBuilder on your server, and you don't have to parse the form spec each time you want to display your form. The generated module has one function (not exported) called get_form, that takes a CGI object as its only argument, and returns a CGI::FormBuilder object.

First, you parse the formspec and write the module, which you can do as a one-liner:

$ perl -MText::FormBuilder -e"Text::FormBuilder->parse('formspec.txt')->write_module('My::Form')"

And then, in your CGI script, use the new module:

#!/usr/bin/perl -w
use strict;

use CGI;
use My::Form;

my $q = CGI->new;
my $form = My::Form::get_form($q);

# do the standard CGI::FormBuilder stuff
if ($form->submitted && $form->validate) {
    # process results
} else {
    print $q->header;
    print $form->render;
}

If you pass a true value as the second argument to write_module, the parser will run Perl::Tidy on the generated code before writing the module file.

# write tidier code
$parser->write_module('My::Form', 1);

dump

Uses YAML to print out a human-readable representation of the parsed form spec.

DEFAULTS

These are the default settings that are passed to CGI::FormBuilder->new:

method => 'GET'
javascript => 0
keepextras => 1

Any of these can be overriden by the build method:

# use POST instead
$parser->build(method => 'POST')->write;

LANGUAGE

field_name[size]|descriptive label[hint]:type=default{option1[display string],...}//validate

!title ...

!author ...

!description {
    ...
}

!pattern name /regular expression/

!list name {
    option1[display string],
    option2[display string],
    ...
}

!list name &{ CODE }

!section id heading

!head ...

Directives

!pattern

Defines a validation pattern.

!list

Defines a list for use in a radio, checkbox, or select field.

!title
!author
!description

A brief description of the form. Suitable for special instructions on how to fill out the form.

!section

Starts a new section. Each section has its own heading and id, which are written by default into spearate tables.

!head

Inserts a heading between two fields. There can only be one heading between any two fields; the parser will warn you if you try to put two headings right next to each other.

Fields

First, a note about multiword strings in the fields. Anywhere where it says that you may use a multiword string, this means that you can do one of two things. For strings that consist solely of alphanumeric characters (i.e. \w+) and spaces, the string will be recognized as is:

field_1|A longer label

If you want to include non-alphanumerics (e.g. punctuation), you must single-quote the string:

field_2|'Dept./Org.'

To include a literal single-quote in a single-quoted string, escape it with a backslash:

field_3|'\'Official\' title'

Now, back to the beginning. Form fields are each described on a single line. The simplest field is just a name (which cannot contain any whitespace):

color

This yields a form with one text input field of the default size named `color'. The generated label for this field would be ``Color''. To add a longer or more\ descriptive label, use:

color|Favorite color

The descriptive label can be a multiword string, as described above. So if you want punctuation in the label, you should single quote it:

color|'Fav. color'

To use a different input type:

color|Favorite color:select{red,blue,green}

Recognized input types are the same as those used by CGI::FormBuilder:

text        # the default
textarea
password
file
checkbox
radio
select
hidden
static

To change the size of the input field, add a bracketed subscript after the field name (but before the descriptive label):

# for a single line field, sets size="40"
title[40]:text

# for a multiline field, sets rows="4" and cols="30"
description[4,30]:textarea

For the input types that can have options (select, radio, and checkbox), here's how you do it:

color|Favorite color:select{red,blue,green}

Values are in a comma-separated list of single words or multiword strings inside curly braces. Whitespace between values is irrelevant.

To add more descriptive display text to a value in a list, add a square-bracketed ``subscript,'' as in:

...:select{red[Scarlet],blue[Azure],green[Olive Drab]}

If you have a list of options that is too long to fit comfortably on one line, you should use the !list directive:

!list MONTHS {
    1[January],
    2[February],
    3[March],
    # and so on...
}

month:select@MONTHS

There is another form of the !list directive: the dynamic list:

!list RANDOM &{ map { rand } (0..5) }

The code inside the &{ ... } is evaled by build, and the results are stuffed into the list. The evaled code can either return a simple list, as the example does, or the fancier ( { value1 => 'Description 1'}, { value2 => 'Description 2}, ... ) form.

NOTE: This feature of the language may go away unless I find a compelling reason for it in the next few versions. What I really wanted was lists that were filled in at run-time (e.g. from a database), and that can be done easily enough with the CGI::FormBuilder object directly.

If you want to have a single checkbox (e.g. for a field that says ``I want to recieve more information''), you can just specify the type as checkbox without supplying any options:

moreinfo|I want to recieve more information:checkbox

In this case, the label ``I want to recieve more information'' will be printed to the right of the checkbox.

You can also supply a default value to the field. To get a default value of green for the color field:

color|Favorite color:select=green{red,blue,green}

Default values can also be either single words or multiword strings.

To validate a field, include a validation type at the end of the field line:

email|Email address//EMAIL

Valid validation types include any of the builtin defaults from CGI::FormBuilder, or the name of a pattern that you define with the !pattern directive elsewhere in your form spec:

!pattern DAY /^([1-3][0-9])|[1-9]$/

last_day//DAY

If you just want a required value, use the builtin validation type VALUE:

title//VALUE

By default, adding a validation type to a field makes that field required. To change this, add a ? to the end of the validation type:

contact//EMAIL?

In this case, you would get a contact field that was optional, but if it were filled in, would have to validate as an EMAIL.

Comments

# comment ...

Any line beginning with a # is considered a comment.

TODO

Allow for custom wrappers around the form_template

Maybe use HTML::Template instead of Text::Template for the built in template (since CGI::FormBuilder users may be more likely to already have HTML::Template)

Better examples in the docs (maybe a standalone or two as well)

!include directive to include external formspec files

Better tests!

BUGS

I'm sure they're in there, I just haven't tripped over any new ones lately. :-)

SEE ALSO

CGI::FormBuilder

THANKS

Thanks to eszpee for pointing out some bugs in the default value parsing, as well as some suggestions for i18n/l10n and splitting up long forms into sections.

AUTHOR

Peter Eichman <peichman@cpan.org>

COPYRIGHT AND LICENSE

Copyright ©2004 by Peter Eichman.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.