# ================================================================== # Gossamer Links - enhanced directory management system # # Website : http://gossamer-threads.com/ # Support : http://gossamer-threads.com/scripts/support/ # CVS Info : 087,071,086,086,085 # Revision : $Id: SiteHTML.pm,v 1.89 2008/04/29 04:02:34 brewt Exp $ # # Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved. # Redistribution in part or in whole strictly prohibited. Please # see LICENSE file for full details. # ================================================================== package Links::SiteHTML; # ================================================================== use strict; use Links qw/:objects :payment/; sub display { # ----------------------------------------------------------------- # Returns a specified template parsed. # my ($template, $vars, $opts) = @_; my $code = exists $Links::SiteHTML::{"site_html_$template"} ? $Links::SiteHTML::{"site_html_$template"} : _compile("site_html_$template"); defined $code or die "Invalid method: site_html_$template called."; $PLG->dispatch("site_html_$template", $code, $vars, $opts); } sub tags { # ----------------------------------------------------------------- # Returns the tags needed to properly include a template in another template, # instead of returning parsed HTML like display(). Currently only supports # 'link' for formatted link information. # my ($sub, $vars, $opts) = @_; my $code = exists $Links::SiteHTML::{"site_tags_$sub"} && $Links::SiteHTML::{"site_tags_$sub"}; defined $code or die "Invalid method: site_tags_$sub called."; $PLG->dispatch("site_tags_$sub", $code, $vars, $opts); } # All the templates are auto-loaded, except for the ones below which need # to do some special stuff. sub site_tags_link { # -------------------------------------------------------- # Format the tags for a single link. # my ($vars, $cat_id) = @_; my %block = $Links::GLOBALS ? map { $_ => 1 } keys %$Links::GLOBALS : (); my %rec = map { exists $block{$_} ? () : ($_ => $vars->{$_}) } keys %$vars; $rec{Add_Date_time} = GT::Date::timelocal(GT::Date::parse_format($rec{Add_Date}, GT::Date::FORMAT_DATE)); $rec{Mod_Date_time} = GT::Date::timelocal(GT::Date::parse_format($rec{Mod_Date}, GT::Date::FORMAT_DATE)); # Convert the date formats. if (GT::Date::FORMAT_DATE ne $CFG->{date_user_format}) { Links::init_date(); $rec{Add_Date} = GT::Date::date_transform($rec{Add_Date}, GT::Date::FORMAT_DATE, $CFG->{date_user_format}) || $rec{Add_Date}; $rec{Mod_Date} = GT::Date::date_transform($rec{Mod_Date}, GT::Date::FORMAT_DATE, $CFG->{date_user_format}) || $rec{Mod_Date}; } # Set new and pop to either 1 or undef for templates. $rec{isNew} = ($rec{isNew} and ($rec{isNew} eq 'Yes' or $rec{isNew} eq '1')) ? 1 : 0; $rec{isChanged} = ($rec{isChanged} and ($rec{isChanged} eq 'Yes' or $rec{isChanged} eq '1')) ? 1 : 0; $rec{isPopular} = ($rec{isPopular} and ($rec{isPopular} eq 'Yes' or $rec{isPopular} eq '1')) ? 1 : 0; $rec{isLinkOwner} = ($USER and defined $USER->{Username} and $rec{LinkOwner} eq $USER->{Username}) ? 1 : 0; $rec{paymentsEnabled} = 0; # The payment url is disabled by default if ($CFG->{payment}->{enabled}) { my $catp; # Fetch payment information for the category the link is in (used below to determine if the payment data should be shown) my @cid = $DB->table('CatLinks')->select('CategoryID', { LinkID => $rec{ID} })->fetchall_list; require Links::Payment; $catp = Links::Payment::load_cat_price(\@cid); # Add various extra tags regarding payment if the current user is the link owner: if ($rec{isLinkOwner} and $rec{ExpiryDate} != UNLIMITED and $catp->{payment_mode} != NOT_ACCEPTED) { my $expiry_date = $rec{ExpiryDate}; my $notify_date = time + $CFG->{payment}->{expiry_notify} * (24*60*60); $rec{paymentsEnabled} = 1; $rec{isUnpaid} = $expiry_date == UNPAID; $rec{isFree} = $expiry_date == FREE; $rec{isExpired} = ($expiry_date > UNPAID and $expiry_date < time or $rec{isFree} and $rec{LinkExpired}); $rec{wasPaid} = ($expiry_date > UNPAID and $expiry_date < FREE or $rec{isFree} and $rec{LinkExpired}); $rec{ExpiryDateFormatted} = ($expiry_date > UNPAID and $expiry_date < FREE) ? GT::Date::date_get($expiry_date, $CFG->{date_expiry_format}) : ($rec{isFree} and $rec{LinkExpired}) ? GT::Date::date_get($rec{LinkExpired}, $CFG->{date_expiry_format}) : ''; $rec{isNotify} = ($expiry_date >= time and $expiry_date <= $notify_date) ? 1 : 0; } $rec{isPaidLink} = 0; $rec{isFreeLink} = 0; if ($rec{ExpiryDate} >= time and $rec{ExpiryDate} < FREE) { $rec{isPaidLink} = 1; } elsif ($rec{ExpiryDate} == FREE) { $rec{isFreeLink} = 1; } } my $links = $DB->table('Links'); if ($CFG->{build_detailed}) { my $detailed; # Generate the detailed url for a specific the category that we're in (a link may be in multiple categories) if ($cat_id) { $detailed = $links->category_detailed_url($cat_id, $rec{ID}); } else { $detailed = $links->detailed_url($rec{ID}); } $rec{detailed_url} = "$CFG->{build_detail_url}/$detailed"; } # Load any reviews, if not already done $links->add_reviews(\%rec) unless exists $rec{Review_Loop}; \%rec; } sub site_html_link { # -------------------------------------------------------- # Format and return the HTML for a single link. # # Note that this method is deprecated in favour of generating all the html in # the templates. Instead, you should be doing: # <%Links::Utils::load_link_info%><%include link.html%> # my $rec = tags(link => @_); # Set the template set to use. my $opts = { dynamic => 0 }; if ($rec->{Category_Template} and $rec->{Category_Template} =~ /^[\w-]+(\.[\w-]+)?$/ and (not $1 or ($1 ne '.html' and $1 ne '.htm'))) { $opts->{template} = delete $rec->{Category_Template}; } # Parse the template. return Links::user_page('link.html', $rec, $opts); } sub site_html_detailed { # -------------------------------------------------------- # Return parsed detailed page (one link per html page). # my $rec = shift; $rec->{Add_Date_time} = GT::Date::timelocal(GT::Date::parse_format($rec->{Add_Date}, GT::Date::FORMAT_DATE)); $rec->{Mod_Date_time} = GT::Date::timelocal(GT::Date::parse_format($rec->{Mod_Date}, GT::Date::FORMAT_DATE)); # Convert the date formats. if (GT::Date::FORMAT_DATE ne $CFG->{date_user_format}) { Links::init_date(); $rec->{Add_Date_orig} = $rec->{Add_Date}; $rec->{Add_Date} = GT::Date::date_transform($rec->{Add_Date}, GT::Date::FORMAT_DATE, $CFG->{date_user_format}) || $rec->{Add_Date}; $rec->{Mod_Date_orig} = $rec->{Mod_Date}; $rec->{Mod_Date} = GT::Date::date_transform($rec->{Mod_Date}, GT::Date::FORMAT_DATE, $CFG->{date_user_format}) || $rec->{Mod_Date}; } # Set new and pop to either 1 or undef for templates. $rec->{isNew} = ($rec->{isNew} and ($rec->{isNew} eq 'Yes' or $rec->{isNew} eq '1')) ? 1 : 0; $rec->{isChanged} = ($rec->{isChanged} and ($rec->{isChanged} eq 'Yes' or $rec->{isChanged} eq '1')) ? 1 : 0; $rec->{isPopular} = ($rec->{isPopular} and ($rec->{isPopular} eq 'Yes' or $rec->{isPopular} eq '1')) ? 1 : 0; $rec->{isLinkOwner} = ($USER and defined $USER->{Username} and $rec->{LinkOwner} eq $USER->{Username}) ? 1 : 0; if ($CFG->{payment}->{enabled}) { $rec->{isPaidLink} = 0; $rec->{isFreeLink} = 0; if ($rec->{ExpiryDate} >= time and $rec->{ExpiryDate} < FREE) { $rec->{isPaidLink} = 1; } elsif ($rec->{ExpiryDate} == FREE) { $rec->{isFreeLink} = 1; } } # Set the template set to use. my $opts = { dynamic => 1 }; if ($rec->{Category_Template} and $rec->{Category_Template} =~ /^[\w-]+(\.[\w-]+)?$/ and (not $1 or ($1 ne '.html' and $1 ne '.htm'))) { $opts->{template} = delete $rec->{Category_Template}; } my $output = Links::user_page('detailed.html', $rec, $opts); return $output; } sub site_html_category { # -------------------------------------------------------- # Return parsed category page. # my $tags = shift; $tags->{build_links_per_page} = $CFG->{build_links_per_page}; ($tags->{category_first}) = $tags->{'category_name'} =~ m,/?([^/]+)$,; my $opts = { dynamic => 1 }; # Find the proper template. my $template = 'category.html'; # If the Category_Template ends with .htm or .html, then use that file as a template, otherwise, use it as a template set. if ($tags->{Category_Template} and $tags->{Category_Template} =~ /^[\w-]+(\.[\w-]+)?$/ and (not $1 or ($1 ne '.html' and $1 ne '.htm'))) { $opts->{template} = delete $tags->{Category_Template}; } elsif ($tags->{Category_Template}) { $template = $tags->{Category_Template}; } my $output = Links::user_page($template, $tags, $opts); return $output; } sub site_html_print_cat { # -------------------------------------------------------- # This routine prints out a list of categories. # # Note that this method has been deprecated in favour of using loops and # performing html generation in the templates. If you need to modify # the category data, use the build_category_loop plugin hook. # my @subcat = @{$_[0]}; my $parent_cat = shift @subcat; my $breakpoint = int(@subcat / $CFG->{build_category_columns}); $breakpoint++ if @subcat % $CFG->{build_category_columns}; my $table_head = $CFG->{build_category_table} || ''; my $width = int(100 / $CFG->{build_category_columns}); my $output = ''; my $i = 0; my $cat_db = $DB->table('Category'); my $opts = { dynamic => 0 }; # Print Header. if ($CFG->{build_category_columns}) { $output = qq|
\n
\n|; } # Figure out if we should use a different template. if ($parent_cat->{Category_Template} and $parent_cat->{Category_Template} =~ /^[\w-]+(\.[\w-]+)?$/ and (not $1 or ($1 ne '.html' and $1 ne '.htm'))) { $opts->{template} = delete $parent_cat->{Category_Template}; } # Go through each subcategory and print its template. for my $cat_r (@subcat) { $cat_r->{Short_Name} = $cat_r->{Name} =~ m,.*/([^/]+)$, ? $1 : $cat_r->{Name}; $cat_r->{URL} ||= $CFG->{build_root_url} . "/" . $cat_db->as_url($cat_r->{Full_Name}) . "/" . ($CFG->{build_index_include} ? $CFG->{build_index} : ''); # Set the short name. if ($cat_r->{Related}) { if ($cat_r->{RelationName}) { $cat_r->{Short_Name} = $cat_r->{RelationName}; } else { if (exists $parent_cat->{Name} and ($cat_r->{Short_Name} eq $parent_cat->{Name})) { my ($short) = $cat_r->{Full_Name} =~ m,([^/]+)/[^/]*$,; $short and ($cat_r->{Short_Name} = $short); } else { $cat_r->{Short_Name} = $cat_r->{Short_Name}; } } } # We check to see if we are half way through, if so we stop this table cell # and begin a new one (this lets us have category names in two columns). if ($CFG->{build_category_columns}) { $output .= qq|\n| if $i > 0 and not $i % $breakpoint; $i++; } $output .= Links::user_page('subcategory.html', $cat_r, $opts); } # Don't forget to end the table properly .. if ($CFG->{build_category_columns}) { $output .= "
\n"; } return $output; } sub site_html_error { # -------------------------------------------------------- # Print out the error page # my ($vars, $opts) = @_; $opts ||= { dynamic => 1 }; unless (exists $vars->{main_title_loop}) { require Links::Build; $vars->{main_title_loop} = Links::Build::build('title', Links::language('LINKS_ERROR'), $CFG->{build_root_url} . "/" . ($CFG->{build_home} || ($CFG->{build_index_include} ? $CFG->{build_index} : ''))); } return Links::user_page('error.html', $vars, $opts); } sub _compile { # ------------------------------------------------------------------- # Compile dynamically creates site_html routines if a template file # exists. # my $sub = shift; my ($file) = $sub =~ /^site_html_([\w-]+)$/; $file or return sub { display('error', { error => "Invalid SiteHTML method: '" . $IN->html_escape($sub) . "'." }) }; $file .= '.html'; my $template_set = Links::template_set(); unless (Links::template_exists($template_set, $file)) { return sub { display('error', { error => "Invalid SiteHTML method: $sub ($file). The template does not exist in '$template_set'." }) }; } my $code = sub { my ($vars, $opts) = @_; $opts ||= { dynamic => 1 }; return Links::user_page($file, $vars, $opts) }; $Links::SiteHTML::{$sub} = $code; $code; } 1;