http://qs321.pair.com?node_id=184847

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

Fellow Monks,
I've written a CGI calendar which is the interface for an online schedule posting programme which I have yet to write. Before I get there, though, I'm stuck on a frustrating problem which I do not understand. Below is the code in its entirety, and yes, I know it's not the most streamlined code, but I'm new at this. My question is this: why won't the individual day numbers (which are links) display?

Note: Yes, I know it won't display them under the proper days...I just haven't written that portion yet. I figure I'd better get the them to just show up somewhere first!

A running version of this script as posted can be found here. Code is as follows:

#!/usr/bin/perl -w use CGI qw(:cgi); use CGI::Carp qw(fatalsToBrowser); print "Content-type: text/html\n\n"; ### Global Variables ### @month_abbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); @month_long = qw( January February March April May June July August Se +ptember October November December ); @days_abbr = qw( Sun Mon Tue Wed Thu Fri Sat ); #@days_long = qw( Sunday Monday Tuesday Wednesday Thursday Friday Satu +rday ); $jandays = $mardays = $maydays = $juldays = $augdays = $octdays = $dec +days = 31; $sepdays = $aprdays = $jundays = $novdays = 30; $febdays = 28; @thismonth = qw( $jandays $febdays $mardays $aprdays $maydays $jundays + $augdays $sepdays $octdays $novdays $decdays ); ################### ##### Main Routine ##### ################### &head; $thisyear = 2002; yeartable($thisyear); for ($x = 1; $x < 4; $x++) { &month_top($x); &meat($x, $thisyear); } print "</tr><tr><td>\n"; yeartable($thisyear + 1); for ($x = $x; $x < 7; $x++) { &month_top($x); &meat($x, $thisyear); } print "</tr><tr><td>\n"; for ($x = $x; $x < 10; $x++) { &month_top($x); &meat($x, $thisyear); } print "</tr><tr><td>\n"; for ($x = $x; $x < 13; $x++) { &month_top($x); &meat($x, $thisyear); } print "</tr><tr><td>\n"; ###################### ##### End Main Routine ##### ###################### sub head { # Opens the master table, too print "<html>\n"; print "<head>\n"; print "<title>Bettendorf Stanford Inc. [Employee Calendar]</title>\n"; print "<link rel=\"stylesheet\" href=\"../../format.css\" type=\"text/ +css\">\n"; print "</head><body>\n"; print "<!---------- BEGIN ALLWEBMENUS CODE ---------->\n"; print "<SCRIPT>var MenuCreatedBy='AllWebMenus 1.3.324'; awmMenuPath='. +./../menu'; awmAltUrl='';</SCRIPT>\n"; print "<SCRIPT SRC='../../menu/bsimenu.js' LANGUAGE='JavaScript1.2' TY +PE='text/javascript'></SCRIPT>\n"; print "<SCRIPT>awmBuildMenu();</SCRIPT>\n"; print "<!----------- END ALLWEBMENUS CODE ----------->\n"; print "</center>\n"; print "<!-- BEGIN THE MAIN TEXT -->\n"; print "<span id=\"logo\">\n"; print "<img src=\"../../images/logo.jpg\">\n"; print "</span>\n"; print "<span id=\"header\">\n"; print "<table><tr><td align=center valign=middle>\n"; print "Employee Calendar\n"; print "</td></tr></table>\n"; print "</span>\n"; print "<span id=\"main\">\n"; print "<table border=1>\n"; print "<tr><td valign=top>\n"; } sub yeartable { $year = $_[0]; print "<span id=\"collapse\">\n"; print "<table>\n"; print "<tr>\n"; print "<td width=32 valign=top align=center>", $year, "</td>\n"; print "</tr>\n"; print "<tr>\n"; print "<td>\n"; my $count = 0; foreach (@month_abbr) { $count++; print "<a href=\"mv"; print $year; print $count; print ".html\">"; print $_; print "</a><br>\n"; } print "</span>\n"; print "</td>\n"; print "</tr>\n"; print "</table>\n"; print "</td>\n"; } sub month_top { print "<td valign=top>\n"; print "<span id=\"collapse\">\n"; print "<table>\n"; print "<tr>\n"; print "<td valign=top colspan=7 align=center><b>",$month_long[$_[0]-1] +,"</b></td>\n"; print "</tr>\n"; print "<tr>\n"; for (0..6) { print "<td width=32 align=center>",$days_abbr[$_],"</td>\n"; } } sub meat { $days = $thismonth[$_[0]]; for (1..$days) { print "<td align=center><a href=\""; print $thisyear; print $thismonth; print $_[0]; print ".cgi\">"; print $_[0]; print "</a>"; print "</td>\n"; } print "</tr><tr>\n"; print "</table>\n"; print "</span>\n"; print "</td>\n"; } ##### Close off the file ##### print "</span>\n"; print "</td>\n"; print "</tr>\n"; print "</table>\n"; print "</span>\n"; print "</body>\n"; print "</html>\n";
Thanks! Foncé

Edit by tye

Replies are listed 'Best First'.
Re: Calendar
by giulienk (Curate) on Jul 24, 2002 at 14:24 UTC
    • Take a look at CPAN: a simple search for HTML::Calendar return 4 results: don't reinvent wheels!
    • Again if you got to manipulate dates a search on the friendly CPAN return lots of results: take a look at Date::Calc, Date::Manip and Time::Piece to start.
    • If you use CGI use it indeed! It's really comfortable to build tables and lots of other stuff (from writing headers to process query string, etc.)


    $|=$_="1g2i1u1l2i4e2n0k",map{print"\7",chop;select$,,$,,$,,$_/7}m{..}g

(jeffa) Re: Calendar
by jeffa (Bishop) on Jul 24, 2002 at 14:39 UTC
    giulienk and giant are correct - use a CPAN module for this. But, i am sure that you are still itching to get this code work - the first glarring error i see (besides no strict!!) is this:
    @thismonth = qw( $jandays $febdays $mardays $aprdays ... # you obviously meant: @thismonth = ($jandays,$febdays,$mardays,$aprdays, ...
    But even with that fix, you will still get erroneous results. My advice? Start over, use strict, use the HTML methods from CGI - at least use CGI.pm's header(). Learn a templating module such as Template-Toolkit or (my favorite) HTML::Template. That or use one of the aforementioned CPAN modules that generats calenders (which is what i would really do).

    Oh, by the way, hashes are great for storing the number of days in a given month:

    my %days_in_month = ( jan => 31, feb => 28, # maybe? mar => 31, apr => 30, may => 31, etc ... );
    But you have to account for leap years too ...

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    
    
    (the triplet paradiddle with high-hat)
    
      Man, would I love to utilize those modules, to simplify my life...but...I don't have access to install modules on our webserver (@#$% bad hosting!) and it costs $20 for them to install a module. A module, as in, singular. So...for the time being, I have to write this without the help of those modules.

      I'm not too worried about leap years, as this is not going to be a permanant script. It's a fix until the boss forks out some cash.

      I'll keep working with this...hopefully it will work well enough.


      Foncé
        Well, when you're in Rome, the Romans don't need to know everything you do. :)

        FTP the module to your cgi-bin directory. (Make sure you follow the directory paths for the leading bits of the module name though.)

        So for HTML::CalendarMonthSimple, you'd make the directory /path/to/your/cgi-bin/HTML and FTP the file CalendarMonthSimple.pm to that directory. Then put this line in your code:

        use lib '/path/to/your/cgi-bin';

        That will tell your script to look for modules in this directory first. (Technically, it prepends the @INC array with this path.)
Re: Calendar
by kodo (Hermit) on Jul 24, 2002 at 14:25 UTC
    You should consider using HTML::CalendarMonthSimple, which I've used before for Calendar-WWW-Stuff and which works really create and is VERY_simple to use. There are even other modules for that if you need something more specific. Why should you want to rewrite all that stuff that is already there? And if you want to for some reason, have a look at Date::Calc to get your days_per_months etc.
    When you use such modules you probably will also have less problems in your code ;)

    giant