func has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I've been working on a script that will print out the tags and meta tags I would usually write in a xhtml page before I begin to write out the page's content.

I would appreciate your comments/criticism on the script.

Thanks for your time

The script:

#!/usr/bin/perl -w # Program: ~/bin/newxhtmlpage # Syntax: newxhtmlpage [> yourpagename.html] # Modules: use strict; page_specs (); page_head (); page_body (); sub page_specs { # The document's specifications # Variables: my $xml_version; # xml version my $encoding; # encoding to use $encoding="iso-8859-1"; $xml_version="1.0"; print <<XHTMLSPECS; <?xml version="$xml_version" encoding="$encoding"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> XHTMLSPECS } sub page_head { # The head area of the web page # Variables: my $pagetitle; # page's title my $author; # author's name my $copyright_holder; # the copyright holder my $chartset; # character set # Does $chartset have to be the same as # $encoding in page_specs? my $default_keywords; my $default_description; # Variable defaults: $pagetitle="PUT-YOUR-TITLE-HERE"; $author="mynamehere"; $copyright_holder=$author; $chartset="iso-8859-1"; $default_keywords=""; $default_description=""; print <<XHTMLHEAD; <head> <meta http-equiv="Content-Type" content="text/html; chartset=$chartset" /> <meta name="author" content="$author" /> <meta name="copyright" content="$copyright_holder" /> <meta name="keywords" content="$default_keywords" /> <meta name="description" content="$default_description" /> <title>$pagetitle</title> </head> XHTMLHEAD } sub page_body { # The body area and closing tag print <<XHTMLBODY; <body> </body> </html> } # End
Edit kudra, 2002-04-16 Added readmore

Replies are listed 'Best First'.
the finest hand rolled XHTML known to man vs. evil factory produced XHTML (boo)
by boo_radley (Parson) on Apr 14, 2002 at 02:40 UTC
    func sez :
    I would appreciate your comments/criticism on the script.
    sub page_body { # The body area and closing tag print <<XHTMLBODY; <body> </body> </html> }
    this doesn't even compile, but that's probably a bad copy & paste problem -- you forgot the end XHTMLBODY.
    Once that's fixed, we get the following output :
    <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; chartset=iso-8859-1" /> <meta name="author" content="mynamehere" /> <meta name="copyright" content="mynamehere" /> <meta name="keywords" content="" /> <meta name="description" content="" /> <title>PUT-YOUR-TITLE-HERE</title> </head> <body> </body> </html>
    Not bad. It's valid XHTML, and it doesn't look too bad. You've accomplished what you set out to do.

    However, through the use of CGI, this code can be compacted :
    use CGI::Fast qw(start_html endhtml); print start_html(-title=>'PUT-YOUR-TITLE-HERE', -enctype=>'iso-8859-1', -meta=>{ 'author'=>'my name here', 'copyright'=>'my name here', 'keywords' => '', 'description' =>'' }, ), end_html ;
    which outputs
    <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head><title>P +UT-YOUR-TI TLE-HERE</title> <meta name="description" content="" /> <meta name="author" content="my name here" /> <meta name="keywords" content="" /> <meta name="copyright" content="my name here" /> </head><body http-equiv="text/html" enctype="iso-8859-1"></body></html +>
    Pretty similar (the encoding in the xml header differs and the DTD is XHTML Basic, not Strict, and CGI adds the http-equiv and enctype to the body tag.). If this isn't too big a difference, you could cut down your code to far fewer lines. If you're concerned about readability, substitue CGI::Pretty for CGI::Fast. (Wouldn't a CGI::Fast::Pretty be nice?)
      this doesn't even compile, but that's probably a bad copy & paste problem -- you forgot the end XHTMLBODY.

      *cough* yes. Sometimes, me, my browser and editor don't get on. :) :)

      Your code with CGI::Fast certainly is smaller, and I like the fact you only have to write out the variable information.

      I'll be trying out CGI::Pretty as I like all that indented stuff and I can pretend to everyone I'm still a html hand-roller. :)

      Thanks.

Re: Making a 'blank' xhtml page - request for comments
by Kanji (Parson) on Apr 14, 2002 at 03:12 UTC

    Personally, I find your commenting style to be extremely redundant.

    I could see more sense in them if you use abbreviated or otherwise possibly confusing variable names, but as they are now your comments just restate the obvious.

    The script also feels unecessarily bulky because of the way you declare now and assign later, something many do only if the variable is set in a less-simple fashion (ie, iteratively built, passed through eval).

    Taking both of those into consideration, here's how I'd rewrite your script (untested ;)), taking the liberty to roll in some flexibility via Getopt::Long...

    #!/usr/bin/perl -w use strict; use Getopt::Long qw/ GetOptions /; # Default variables my %config = ( 'author' => 'me', # Does 'char_set' have to be the same as # 'encoding' in 'page_specs'? 'char_set' => 'iso-8859-1', 'pagetitle' => 'put-your-title-here', # ... ); # Allow user to override any of the %config # defaults by invoking the script with switches # in the form of --variable='new value' GetOptions( \%config, map { "$_=s" } keys %config, ); # Spit out the page print <<XHTML; <?xml version="$config{'xml_version'}" encoding="$config{'encoding'}"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; chartset=$config{'char_set'}" /> <meta name="author" content="$config{'author'}" /> ... XHTML

        --k.


      In regards to the comments and 'declare now, use later' I'm still working out what makes code have clarity and what is unneeded. (I've also just understood what my is used for, apart from being able to stop strict from complaining, so I might do less of that 'declare now, use later' stuff from now on. :) )

      I'm glad you used Getopt::Long as that is something I've wanted to use in this script. You've given me a good head-start. :)

      Thanks

Re: Making a 'blank' xhtml page - request for comments
by Zaxo (Archbishop) on Apr 14, 2002 at 02:36 UTC

    Bug, you've omitted the XHTMLBODY tag in sub page_body.

    There's nothing wrong with doing this as heredocs, but you might try it with use CGI qw( :standard ); or with one of the template module sets. Each approach has strengths, the choice depends mostly on how your application is organized.

    After Compline,
    Zaxo

      Thanks for your suggestions. I never thought about using a CGI module.

      I've noted what you've said about templates in your reply and in the chatterbox and am currently looking at CGI::FastTemplate.

      I've also been searching PM and google to find out what heredocs are, but have had no success. I'd appreciate a definition or link if possible. :)

        See perldata for the Perl definition of heredocs ... but I'm a little baffled since you used them in your original post.

        print <<HEREDOC; ... HEREDOC

            --k.


oops.
by func (Acolyte) on Apr 14, 2002 at 02:36 UTC
    That last sub should read:
    sub page_body { # The body area and closing tag print <<XHTMLBODY; <body> </body> </html> XHTMLBODY # this is the line I left out from above }

    Bad copy & paste on my part. :)

    It seems Zaxo beat me to my mistake. :)

Re: Making a 'blank' xhtml page - request for comments
by Juerd (Abbot) on Apr 14, 2002 at 10:16 UTC

    Just a style suggestion. Using whitespace doesn't slow Perl down, but speeds up reading a script, because it makes things more clear.

    You now have:

    # Variables: my $pagetitle; # page's title my $author; # author's name my $copyright_holder; # the copyright holder my $chartset; # character set # Does $chartset have to be the same as # $encoding in page_specs? my $default_keywords; my $default_description; # Variable defaults: $pagetitle="PUT-YOUR-TITLE-HERE"; $author="mynamehere"; $copyright_holder=$author; $chartset="iso-8859-1"; $default_keywords=""; $default_description="";
    While I think the following is clearer:
    # Variables: my $pagetitle; # page's title my $author; # author's name my $copyright_holder; # the copyright holder my $chartset; # character set # Does $chartset have to be the # same as $encoding in page_spec +s? my $default_keywords; my $default_description; # Variable defaults: $pagetitle = "PUT-YOUR-TITLE-HERE"; $author = "mynamehere"; $copyright_holder = $author; $chartset = "iso-8859-1"; $default_keywords = ""; $default_description = "";
    You first use my, and then assign. You can have an assignment directly after my:
    my $pagetitle = "PUT-YOUR-TITLE-HERE";
    Making the names shorter and using a hash can also help a lot:
    my %hash = ( title => 'PUT-YOUR-TITLE-HERE', author => 'mynamehere', copyright => 'mynamehere', charset => 'iso-8859-1', keywords => '', description => '' ) # hash values can be accessed as $hash{title} etc.

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

      I think I'll start using the 'lined up comments' style you've displayed. I also think it's clearer.

      Thanks :)