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}

); } if ($rss->{textinput}{link}) { $code .= qq(

$rss->{textinput}{description}: type in a term and hit 'Enter."

); } $code .= qq(

$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}

); } } else { $code .= qq( ); } if ($rss->{textinput}{link}) { $code .= qq(

$rss->{textinput}{description}: type in a term and hit 'Enter."

); } $code .= qq(

$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", ); close FOOT or warn "$!"; } $code .= p('© 2005 SRF Consulting Group, Inc.'); $self->{ 'page_footer' } = $code; return $code; } sub get_qlinks { my ( $self, $dbh, $ruser ) = @_; my $ruser = $dbh->quote( $ruser ); my $sql = qq( Select page_title, url, selected, id From quick_links Where remote_user = $ruser And (selected > 0 OR page_title = 'google') Order By selected ); my $links = $dbh->selectall_hashref( $sql, 'id' ); # printError( "Error fetching links:" . DBI::errstr()) unless $links; $self->{ 'get_qlinks' } = $links; return $links; } sub set_page_sidebar { my ( $self, $dbh ) = @_; my $sidebar; $sidebar .= $self->quick_links( $dbh ); $sidebar .= $self->whats_new(); $self->{ 'page_sidebar' } = $sidebar; return $sidebar; } sub set_page_content { my ( $self, $code ) = @_; $self->{ 'page_content' } = $code; return $code; } sub set_page_banner { my ( $self, $code ) = @_; $self->{ 'page_banner' } = $code; return $code; } sub html_out { my ( $self, $args ) = @_; # set defaults for missing information print header(-charset =>'utf-8'), start_html( -title => $args->{ title }, -lang => 'en-US', -encoding => 'utf-8', -style => $args->{ css }, -script => $args->{ js }, -head => $args->{ head } ), a({-name=>"top"}, ' '), div({-id=>'header'}, $self->{ 'page_header' } ), div({-id=>'page'}, div({-id=>'navigation'}, $self->{ 'left_navigation' } ), div({-id=>'banner'}, $self->{'page_banner'} ), div({-id=>'content'}, $self->{'page_content'}, div({-class=>'spacer', -style=>'float: left; width: 100%; height: 1px; clear: both;'}, ' ' ) ), div({-id=>'footer'}, $self->{'page_footer'} ) , div({-id=>'sidebar'}, $self->{'page_sidebar'} ) ), end_html(); } 1;