Hi all, I am new to Perl, just learn this code in Essential Web Perl5
Please throw this book away. It is teaching you Bad Things™. Pick one of these Perl Books instead.
when i submit it it will write to 1.html, 2.html or number+.html. But i would like to have it write to title.html so i can look it easier. (ex. Title 020212 file will save as 020212.html.)
If you do this you will lose whatever is already in 020212.html. Is there some other name you would like to use instead?
Let's take a closer look at what you presented:
#!/usr/bin/perl5/perl
In modern perl a beginner would most likely start with:
#!/usr/bin/perl5/perl -T
use strict;
use warnings;
use diagnostics;
And if your using a perl version prior to 5.6.0:
#!/usr/bin/perl5/perl -wT
use strict;
use diagnostics;
Take a look at Use strict and warnings for some excellent reasons.
&get_form_data;
When you write your own subroutine for retreiving form data it is often referred to as rolling your own or re-inventing the wheel. Many much more experienced programmers have tweaked most of the errors out of common tasks. These programmers often place their experience into modules.
Modules are available for perl on CPAN. We can avoid the most common mistakes by re-using this code instead of rolling our own. For CGI applications, you'd do best with CGI.pm:
use CGI qw/:standard center/;
print "Content-type: text/html\n\n";
We'll skip this for how, but you should know that it's sending headers to the browser by printing them. The browser is waiting for us to print something.
opendir(DIR, "./Data");
while($name = readdir(DIR))
{
next if $name !~ /^\d*.html/;
push(@files, $name);
}
close(DIR);
Personally, I prefer indentation to create order and improve readability:
opendir(DIR, "./Data");
while( $name = readdir(DIR) ) {
next if $name !~ /^\d*.html/;
push(@files, $name);
}
close(DIR);
Unfornately this will not work because we enforced strict in the beginning of the program. There are also a few other glaring mistakes which is why I encouraged you to rid yourself of the book you were reading.
When we open a file or dir it is a Good Thing™ to check for success.
opendir (DIR, "./Data") || die "Couldn't open directory ./Data: $!";
OR:
opendir DIR, "./Data" or die "Couldn't open directory ./Data: $!";
I prefer the second one as I don't like the extra parenthesis. This is a question of style and you might have a look at perlsyn for style suggestions.
When we use strict we enforce certain rules about variable use. One rule is that we may have to use my the first time we use a variable. It also means we have to pay attention to what scope we first <tt class='inlinecode'>my</tt> it in.
while( $name = readdir(DIR) ) {
next if $name !~ /^\d*.html/;
push(@files, $name);
}
Might be re-written as:
my @files
while( my $name = readdir DIR ) {
next if $name !~ /^\d*.html/;
push(@files, $name);
}
When you become more experienced, you might shorten it to:
my @files
while( readdir DIR ) {
push @files, $_ if /^\d*.html/;
}
When we close a file or dir it is a Good Thing™ to check for success just as we did with opendir above. Here we use closedir
closedir(DIR) || die "Couldn't close directory './Data': $!";
OR:
closedir DIR or die "Couldn't close directory './Data': $!";
The following if-else block determines the value of $nextfile which is the name of the file to be written to. According to your message, you would like this to be named the same as the last file in the directory. That would write over whatever is already there, so let's just name it "testing.html". Look in the directory to make certain we're not overwriting some other file named "testing.html".
my $next_file = 'testing.html';
Because we accessed CGI.pm with Use CGI qw/:standard center/; we are prepared to use its function oriented mode and can re-write the next section. Note: I am not using flock, but you should read up on it when you can.
open OUT, ">Data/$nextfile" or die "Cannot open 'Data/$nextfile': $!";
print OUT
start_html( -title => param('title'),
-bgcolor => '#FFFFFF'),
center( h1( param('heading') ) ), br,
p( param('body') ),
end_html;
close OUT or die "Cannot close 'Data/$nextfile': $!";;
Actually, we should have put a check in there for the existence of param('title') , param('heading'), and param('body'). Our new code will fail if they don't all exist.
The rest of the script, properly indented, looks like:
push(@files, $nextfile);
print "<HTML>\n<BODY>\n";
foreach $file (@files) {
print "<A HREF=\"Data/$file\">$file</A>\n";
print "<BR>\n";
}
print "</BODY>\n</HTML>\n";
exit;
And might be re-written as:
push @files, $nextfile;
print headers, start_html( -title => 'File Listing');
print a({ -href => "Data/$_" }, $_ ), br for @files;
print end_html;
exit;
Let's look at it all together:
#!/usr/bin/perl5/perl -T
use strict;
use warnings;
use diagnostics;
use CGI qw/:standard center/;
opendir DIR, "./Data" or die "Couldn't open directory ./Data: $!";
my @files;
while ( my $name = readdir DIR ) {
next if $name !~ /^\d*.html/;
push(@files, $name);
}
closedir DIR or die "Couldn't close directory './Data': $!";
my $next_file = 'testing.html';
open OUT, ">Data/$next_file" or die "Cannot open 'Data/$next_file': $!
+";
print OUT
start_html( -title => param('title'),
-bgcolor => '#FFFFFF'),
center( h1( param('heading') ) ), br,
p( param('body') ),
end_html;
close OUT or die "Cannot close 'Data/$next_file': $!";
push @files, $next_file;
print header, start_html( -title => 'File Listing');
print a({ -href => "Data/$_" }, $_ ), br for @files;
print end_html;
HTH,
Charles K. Clarkson
Clarkson Energy Homes, Inc.
|