package My::HTML::Common; use strict; use CGI qw(-autoload -no_xhtml); our (@ISA, @EXPORT); use Exporter; @ISA = qw(Exporter); @EXPORT = qw(); # we don't need no stinkin' exports sub new { my ( $class, $args ) = @_; my $self = {}; bless $self, $class; # Set some items from the constructor $self->{ rdf } = $args->{ rdf } || { url => '/usr/local/apache/htdocs/rdf/whatsNew.rdf', full_descriptions => 1 }; $self->{ maxhits } = $args->{ maxhits } || 5; return $self; } # each method will store the HTML generated in the object as a hash reference with the name of the # method as the key and also returns the HTML generated # page_header gathers up all of the HTML code fragments (i.e, not a full HTML Docuemnt) # in the file specified by $path, stores it in a hash reference and returns it. sub page_header { my ( $self, $path ) = @_; my $header; my $err = qq(
Unable to retrive page: $path
); open $header, $path or do { warn $err; return $err; }; my $code; while( <$header>) { $code .= $_; } close $header or return $err; $self->{ 'page_header' } = $code; return $code; } # provides some filler body copy sub body_text { my $self = shift; my $code = qq( ); $self->{ 'body_text' } = $code; return $code; } sub left_navigation { my $self = shift; my $dbh = shift; my $path = $_[0]; my $ruser = $_[1] || ''; #if $ruser is set, we are also making quicklinks my $width = $_[2] || '100%'; my $class = $_[3] || 'bordered'; my ($nav, $code); # open the navigation library specified in path if ( $path && -e $path) { open $nav, $path or return ' '; while ( <$nav> ) { $code .= $_; } close $nav or warn "$!"; } else { warn "Path to Navigaion Library not specified or file does not exist: $path"; return ' '; } if ( $ruser && $dbh ) { $code .= quick_links( $dbh, $ruser, undef, $width, $class ); } $self->{ 'left_navigation' } = $code || ' '; return $code; } # Sub Quicklinks - Takes a database handle, a user name and # three optional arguments for displaying an HTML table. # Calls get_qlinks # return Code for an HTML table. Needs the following css styles defined: # .qLinkHeader, .white, .bordered (or whichever class is sent in) sub quick_links { my $self = shift; my $dbh = shift; my $ruser = $_[0] || remote_user(); my $align = $_[1] || 'right'; my $width = $_[2] || '100%'; my $class = $_[3] || 'bordered'; $ruser ||= 'default'; my $links = $self->get_qlinks( $dbh, $ruser ); if ( ! keys %$links ) { # if there are no keys, the user has not set their own quicklinks, we should fetch the defaults $links = $self->get_qlinks( $dbh, "default" ); } my $google = ''; my $link_title = ( $ruser eq 'default' ? 'Default Links' : 'My QuickLinks' ); my $link_option = ( $ruser eq 'default' ? qq([ My QuickLinks ]) : qq([ edit ] ) ); my ( $code, $li ); foreach ( sort { $links->{$a}{selected} <=> $links->{$b}{selected} } keys %$links ) { next unless ( $links->{$_}{selected} > 1 || $links->{$_}{page_title} eq 'google'); if ( $links->{$_}{page_title} =~ /google/ ) { # If google is fetched, the user has requested the google search box on every page $google = 1; } else { $li .= li( a({-href=>"$links->{$_}{url}"}, $links->{$_}{page_title}) ); } } $code = div({-id=>'quicklinks', -class=>'palatte'}, div({-class=>'linkhider', -style=>'width: 30%; text-align: right; float: right; clear: right;'}, img({-src=>'/images/icons/down.gif'}) ), div({-class=>'linkheader', -style=>'width: 70%; text-align: left; float:left'}, strong( $link_title ) ) ). ul({-style=>'clear: left;'}, $li ); $code .= q( ) unless $ruser eq 'default'; if ( $google ) { $code .= start_form(-action=>"http://www.google.com/search", -name=>"f") . hidden(-name=>"hl", -value=>"en") . p({-class=>"small", -style=>'padding-bottom: 3px; margin-bottom: 12px; border-bottom: 1px solid silver'}, 'Search Google:', hidden(-name=>"ie", -value=>"ISO-8859-1") , textfield(-maxlength=>"256", -size=>"18", -name=>"as_q", -value=>"") ), end_form(); } $self->{ 'quick_links' } = $code; return $code; } sub news_feeds { require XML::RSS; my ( $self, $dbh, $position, $width ) = @_; # takes a layout attribute used to select items from the database. # called once for each value in the main array @columns. # To make things easy, our database handle and rdf directory are exported # with the use var pragram. $self->{ 'rdf_dir' } ||= '/usr/local/apache/htdocs/rdf'; bail([ "No Database"]) unless $dbh; $position ||= 'right'; $width ||= "100%"; my $sql = qq( Select url, linkID, name, position, selected, id From rdf Where selected > 0 and position = "$position" ); my $links = $dbh->selectall_hashref( $sql, 'selected' ) ; printError( "Can't Fetch news feeds: $dbh->errstr()") if $dbh->errstr(); my $div; my $palette = 1; foreach my $row ( sort{ $b<=>$a } keys %$links ) { # Check to see if we have a local copy of that rdf file next unless -e "$self->{'rdf_dir'}/$links->{$row}{linkID}" ; my $rss = new XML::RSS; print p("Unable to Initialize Newsfeed $links->{$row}{linkID}") unless $rss; # trap errors and skip the rss file if it's bad. eval { $rss->parsefile("$self->{'rdf_dir'}/$links->{$row}{linkID}") }; warn "$links->{$row}{linkID} will not parse $@" and next if $@; my $last_mod = scalar localtime( (stat("$self->P{'rdf_dir'}/$links->{$row}{linkID}"))[9] ); # We only want x number of headlines per feed my $count = 0; my $code; for (@{$rss->{items}}) { $count ++; last if $count > $self->{ maxhits }; $code .= qq(
$_->{title}
$_->{description}
$rss->{textinput}{description}: type in a term and hit 'Enter."
$last_mod
); $div .= div({-id=>'newsfeeds' . $palette, -class=>'palatte'}, div({-class=>'linkhider', -style=>'width: 30%; text-align: right'}, img({-src=>'/image/icons/down.gif'}) ), div({-class=>'linkheader', -style=>'width: 70%; text-align: left'}, $links->{$row}{name} ), p( $rss->{channel}{title} ), $code ); $palette ++; } # we're done here $self->{ 'news_feeds' } = $div; return $div; } sub whats_new { require XML::RSS; my $self = shift; my $rdf = $self->{ rdf }; return "No News File specified
" unless $rdf->{url}; my $align = $_[0] || 'left'; my $width = $_[1] || '100%'; my $class = $_[2] || 'bordered'; my $rss = new XML::RSS; return p("Unable to Fetch Newsfeeds") unless $rss; # trap errors and skip the rss file if it's bad. eval { $rss->parsefile( $rdf->{url} ) }; if ( $@ ) { #warn "$rdf->{url} will not parse $@"; return undef; } my $code; my $last_mod = scalar localtime((stat( $rdf->{url} ))[9]); # return the results in a table $code .= div({-id=>'quicklinks', -class=>'palatte'}, div({-class=>'linkhider', -style=>'width: 30%; text-align: right; float: right; clear: right;'}, img({-src=>'/images/icons/down.gif'}) ), div({-class=>'linkheader', -style=>'width: 70%; text-align: left; float:left'}, strong( $rss->{channel}{title} ) ) ) . p({-class=>"body", -style=>'clear: both;'}, $rss->{channel}{description} ); # We only want x number of headlines per feed my $count = 0; if ( $rdf->{full_descriptions} > 0 ) { for (@{$rss->{items}}) { $count ++; last if $count > $self->{ maxhits }; $code.= qq($_->{title}
$_->{description}
$rss->{textinput}{description}: type in a term and hit 'Enter."
$last_mod
); # we're done here $self->{ 'whats_new' } = $code; return $code; } sub printError { my $self = shift; my $msg = shift; print header(), start_html('page_error'), p({-class=>'error'}, $msg ), end_html(); exit(0); } sub bail { my ( $self, $msg ) = @_; print header(), start_html('page_error'), p({-class=>'error'}, $msg ), end_html(); exit(0); } sub page_footer { my ( $self, $path ) = @_; my $code; if ( $path && -e $path ) { open FOOT, $path or do{ warn "$!"; return; } ; $code = join( "\n",