- Timestamp:
- 11/03/04 15:18:24 (20 years ago)
- Location:
- trunk/lib/Text
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Text/FormBuilder.pm
r15 r16 4 4 use warnings; 5 5 6 our $VERSION = '0.03'; 7 6 our $VERSION = '0.04'; 7 8 use Carp; 8 9 use Text::FormBuilder::Parser; 9 10 use CGI::FormBuilder; … … 34 35 sub parse_text { 35 36 my ($self, $src) = @_; 37 36 38 # so it can be called as a class method 37 39 $self = $self->new unless ref $self; 40 38 41 $self->{form_spec} = $self->{parser}->form_spec($src); 42 43 # mark structures as not built (newly parsed text) 44 $self->{built} = 0; 45 39 46 return $self; 40 47 } … … 42 49 sub build { 43 50 my ($self, %options) = @_; 44 51 52 # save the build options so they can be used from write_module 45 53 $self->{build_options} = { %options }; 46 54 … … 87 95 } 88 96 97 # TODO: configurable threshold for this 89 98 foreach (@{ $self->{form_spec}{fields} }) { 90 99 $$_{ulist} = 1 if defined $$_{options} and @{ $$_{options} } >= 3; … … 114 123 $self->{form}->field(%{ $_ }) foreach @{ $self->{form_spec}{fields} }; 115 124 125 # mark structures as built 126 $self->{built} = 1; 127 116 128 return $self; 117 129 } … … 119 131 sub write { 120 132 my ($self, $outfile) = @_; 133 134 # automatically call build if needed to 135 # allow the new->parse->write shortcut 136 $self->build unless $self->{built}; 137 121 138 if ($outfile) { 122 139 open FORM, "> $outfile"; … … 129 146 130 147 sub write_module { 131 my ($self, $package) = @_; 132 133 use Data::Dumper; 148 my ($self, $package, $use_tidy) = @_; 149 150 croak 'Expecting a package name' unless $package; 151 152 # automatically call build if needed to 153 # allow the new->parse->write shortcut 154 $self->build unless $self->{built}; 155 156 # conditionally use Data::Dumper 157 eval 'use Data::Dumper;'; 158 die "Can't write module; need Data::Dumper. $@" if $@; 159 134 160 # don't dump $VARn names 135 161 $Data::Dumper::Terse = 1; 136 162 137 my $title = $self->{form_spec}{title} || '';138 my $author = $self->{form_spec}{author} || '';163 my $title = $self->{form_spec}{title} || ''; 164 my $author = $self->{form_spec}{author} || ''; 139 165 my $description = $self->{form_spec}{description} || ''; 140 my $headings = Data::Dumper->Dump([$self->{form_spec}{headings}],['headings']); 141 my $fields = Data::Dumper->Dump([ [ map { $$_{name} } @{ $self->{form_spec}{fields} } ] ],['fields']); 142 143 my $source = $self->{build_options}{form_only} ? $self->_form_template : $self->_template; 144 145 my $options = keys %{ $self->{build_options} } > 0 ? Data::Dumper->Dump([$self->{build_options}],['*options']) : ''; 166 167 my $headings = Data::Dumper->Dump([$self->{form_spec}{headings}],['headings']); 168 my $fields = Data::Dumper->Dump([ [ map { $$_{name} } @{ $self->{form_spec}{fields} } ] ],['fields']); 169 170 my %options = %{ $self->{build_options} }; 171 my $source = $options{form_only} ? $self->_form_template : $self->_template; 172 173 delete $options{fomr_only}; 174 175 my $form_options = keys %options > 0 ? Data::Dumper->Dump([$self->{build_options}],['*options']) : ''; 146 176 147 177 my $field_setup = join( … … 179 209 }, 180 210 }, 181 $ options211 $form_options 182 212 ); 183 213 … … 190 220 1; 191 221 END 222 192 223 my $outfile = (split(/::/, $package))[-1] . '.pm'; 193 224 194 if ($outfile) { 225 if ($use_tidy) { 226 # clean up the generated code, if asked 227 eval 'use Perl::Tidy'; 228 die "Can't tidy the code: $@" if $@; 229 Perl::Tidy::perltidy(source => \$module, destination => $outfile); 230 } else { 231 # otherwise, just print as is 195 232 open FORM, "> $outfile"; 196 233 print FORM $module; 197 234 close FORM; 198 } else { 199 print $module; 200 } 201 } 202 203 sub form { shift->{form} } 235 } 236 } 237 238 sub form { 239 my $self = shift; 240 241 # automatically call build if needed to 242 # allow the new->parse->write shortcut 243 $self->build unless $self->{built}; 244 245 return $self->{form}; 246 } 204 247 205 248 sub _form_template { … … 245 288 <hr /> 246 289 <div id="footer"> 247 <p id="creator">Made with <a href="http://formbuilder.org/">CGI::FormBuilder</a> version <% $CGI::FormBuilder::VERSION %>.</p>290 <p id="creator">Made with <a href="http://formbuilder.org/">CGI::FormBuilder</a> version <% CGI::FormBuilder->VERSION %>.</p> 248 291 </div> 249 292 </body> … … 267 310 =head1 NAME 268 311 269 Text::FormBuilder - Parser for a minilanguage describing web forms312 Text::FormBuilder - Parser for a minilanguage for generating web forms 270 313 271 314 =head1 SYNOPSIS 272 315 316 use Text::FormBuilder; 317 273 318 my $parser = Text::FormBuilder->new; 274 319 $parser->parse($src_file); 275 320 276 # returns a new CGI::FormBuilder object with the fields277 # from the input form spec321 # returns a new CGI::FormBuilder object with 322 # the fields from the input form spec 278 323 my $form = $parser->form; 279 324 … … 287 332 288 333 # or as a class method 289 my $parser = T xt::FormBuilder->parse($src_file);334 my $parser = Text::FormBuilder->parse($src_file); 290 335 291 336 =head2 parse_text 337 338 $parser->parse_text($src); 339 340 Parse the given C<$src> text. Returns the parse object. 292 341 293 342 =head2 build … … 310 359 defaults that this module uses. 311 360 361 The C<form>, C<write>, and C<write_module> methods will all call 362 C<build> with no options for you if you do not do so explicitly. 363 This allows you to say things like this: 364 365 my $form = Text::FormBuilder->new->parse('formspec.txt')->form; 366 367 However, if you need to specify options to C<build>, you must call it 368 explictly after C<parse>. 369 312 370 =head2 form 313 371 314 372 my $form = $parser->form; 315 373 316 Returns the L<CGI::FormBuilder> object. 374 Returns the L<CGI::FormBuilder> object. Remember that you can modify 375 this object directly, in order to (for example) dynamically populate 376 dropdown lists or change input types at runtime. 317 377 318 378 =head2 write … … 327 387 =head2 write_module 328 388 329 $parser->write_module($package );389 $parser->write_module($package, $use_tidy); 330 390 331 391 Takes a package name, and writes out a new module that can be used by your 332 392 CGI script to render the form. This way, you only need CGI::FormBuilder on 333 393 your server, and you don't have to parse the form spec each time you want 334 to display your form. 394 to display your form. The generated module has one function (not exported) 395 called C<get_form>, that takes a CGI object as its only argument, and returns 396 a CGI::FormBuilder object. 397 398 First, you parse the formspec and write the module, which you can do as a one-liner: 399 400 $ perl -MText::FormBuilder -e"Text::FormBuilder->parse('formspec.txt')->write_module('MyForm')" 401 402 And then, in your CGI script, use the new module: 335 403 336 404 #!/usr/bin/perl -w 337 405 use strict; 338 406 339 # your CGI script340 341 407 use CGI; 342 408 use MyForm; 343 409 344 410 my $q = CGI->new; 345 my $form = MyForm:: form($q);411 my $form = MyForm::get_form($q); 346 412 347 413 # do the standard CGI::FormBuilder stuff … … 352 418 print $form->render; 353 419 } 354 420 421 If you pass a true value as the second argument to C<write_module>, the parser 422 will run L<Perl::Tidy> on the generated code before writing the module file. 355 423 356 424 =head2 dump 357 425 358 Uses L<YAML> to print out a human-readable representa iton of the parsed426 Uses L<YAML> to print out a human-readable representation of the parsed 359 427 form spec. 360 428 … … 367 435 !author ... 368 436 437 !description { 438 ... 439 } 440 369 441 !pattern name /regular expression/ 442 370 443 !list name { 371 444 option1[display string], … … 394 467 =item C<!author> 395 468 469 =item C<!description> 470 396 471 =item C<!head> 397 472 … … 417 492 =head1 TODO 418 493 419 =head2 Langauge 420 421 Directive for a descriptive or explanatory paragraph about the form 494 C<!include> directive to include external formspec files 495 496 Field groups all on one line in the generated form 497 498 Tests! 422 499 423 500 =head1 SEE ALSO … … 425 502 L<CGI::FormBuilder> 426 503 504 =head1 AUTHOR 505 506 Peter Eichman <peichman@cpan.org> 507 508 =head1 COPYRIGHT AND LICENSE 509 510 Copyright E<copy>2004 by Peter Eichman. 511 512 This program is free software; you can redistribute it and/or 513 modify it under the same terms as Perl itself. 514 427 515 =cut -
trunk/lib/Text/FormBuilder/grammar
r14 r16 14 14 } 15 15 16 list_def: '!list' list_name (static_list | dynamic_list)17 { $lists{$item{ list_name}} = [ @options ]; @options = () }16 list_def: '!list' var_name (static_list | dynamic_list) 17 { $lists{$item{var_name}} = [ @options ]; @options = () } 18 18 19 19 static_list: '{' option(s /,\s*/) /,?/ '}' … … 29 29 } 30 30 31 list_name: /[A-Z_]+/32 33 31 description_def: '!description' <perl_codeblock> 34 32 { warn "[Text::FormBuilder] Description redefined at input text line $thisline\n" if defined $description; … … 38 36 } 39 37 40 line: <skip:'[ \t]*'> ( title | author | pattern_def | heading | field | comment | blank ) "\n"38 line: <skip:'[ \t]*'> ( title | author | pattern_def | heading | unknown_directive | field | comment | blank ) "\n" 41 39 42 40 title: '!title' /.*/ … … 47 45 { $author = $item[2] } 48 46 49 pattern_def: '!pattern' pattern_name pattern50 { $patterns{$item{ pattern_name}} = $item{pattern} }47 pattern_def: '!pattern' var_name pattern 48 { $patterns{$item{var_name}} = $item{pattern} } 51 49 52 pattern_name: /[A-Z_]+/53 50 pattern: /.*/ 54 51 … … 88 85 name: identifier 89 86 87 var_name: /[A-Z_]+/ 88 90 89 field_size: '[' ( row_col | size ) ']' 91 90 … … 123 122 124 123 identifier: /\w+/ 124 125 # skip unknown directives with a warning 126 unknown_directive: /\!\S*/ /.*/ 127 { warn "[Text::Formbuilder] Skipping unknown directive '$item[1]' at input text line $thisline\n"; }
Note: See TracChangeset
for help on using the changeset viewer.