#!/usr/bin/perl # TmNetWiki version 0.4 (September 11, 2002) # Copyright (C) 2002 Adam Brate # # Based on the GPLed UseModWiki 0.92 # Copyright (C) 2000-2001 Clifford A. Adams # or # Based on the GPLed AtisWiki 0.3 (C) 1998 Markus Denker # # ...which was based on # the LGPLed CVWiki CVS-patches (C) 1997 Peter Merel # and The Original WikiWikiWeb (C) Ward Cunningham # (code reused with permission) # Email and ThinLine options by Jim Mahoney # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the # Free Software Foundation, Inc. # 59 Temple Place, Suite 330 # Boston, MA 02111-1307 USA package Wiki::template; use strict; # needs subs Wiki::utility: FreeToNormal, GetParam # Wiki::index: AllPagesList # Wiki::page: GetPageFile, PageIsLocked (used by GetPageOrEditLink) # Wiki::translate: T, Ts # Wiki::user: UserCanEdit # Wiki::calc: TimeToText # Wiki::area: GetArea # needs consts $ScriptName, $FreeLinks, $MainPage, $UseIndex, $RedirType # needs vars $IndexInit, %IndexHash use base 'Exporter'; use Template; use Wiki::consts; use Wiki::utility; use Wiki::index; use Wiki::page; use Wiki::translate; use Wiki::user; use Wiki::calc; use Wiki::area; use Wiki::quotes; #if ($^V and $^V gt v5.6.0) { # our @EXPORT; #else { use vars qw(@EXPORT); #} @EXPORT = qw( ScriptLink GetPageLink GetPageLinkText GetEditLink GetOldPageLink GetPageOrEditLink GetSearchLink GetPrefsLink GetRandomLink ScriptLinkDiff ScriptLinkDiffRevision ScriptLinkTitle GetAuthorLink GetHistoryLink GetHeader GetHttpHeader GetHtmlHeader GetFooterText GetCommonFooter GetMinimumFooter GetHiddenValue GetFormStart GetFormText GetFormCheck GetTemplate GetTextArea GetGotoBar GetSearchForm GetRedirectPage ); sub GetTemplate { my ($type,$vars,$tName) = @_; my $output; my $templateFile = $tName || "_default"; $templateFile = "$type/$templateFile.tt"; $Template->process($templateFile,$vars,\$output); return $output; } # ==== HTML and page-oriented functions ==== # I think the template version is pretty slow now... sub ScriptLink { my ($action, $text) = @_; return "{ScriptName}?$action\">$text"; return &GetTemplate('links',{ Consts => $Consts, action => $action, text => $text, },'scriptLink'); } sub GetPageLink { my ($id) = @_; my $name = $id; $id =~ s|^/|$MainPage/|; if ($Consts->{FreeLinks}) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink($id, $name); } sub GetPageLinkText { my ($id, $name) = @_; $id =~ s|^/|$MainPage/|; if ($Consts->{FreeLinks}) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink($id, $name); } sub GetEditLink { my ($id, $name) = @_; if ($Consts->{FreeLinks}) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink("action=edit&id=$id", $name); } sub GetOldPageLink { my ($kind, $id, $revision, $name) = @_; if ($Consts->{FreeLinks}) { $id = &FreeToNormal($id); $name =~ s/_/ /g; } return &ScriptLink("action=$kind&id=$id&revision=$revision", $name); } sub GetPageOrEditLink { my ($id, $name) = @_; my (@temp, $exists); if ($name eq "") { $name = $id; if ($Consts->{FreeLinks}) { $name =~ s/_/ /g; $name =~ s|^/||; # hide leading slash of subpages } } $id =~ s|^/|$MainPage/|; if ($Consts->{FreeLinks}) { $id = &FreeToNormal($id); } $exists = 0; if ($Consts->{UseIndex}) { if (!$IndexInit) { @temp = &AllPagesList(); # Also initializes hash } $exists = 1 if ($IndexHash{$id}); } elsif (-f &Wiki::page::GetPageFile($id)) { # Page file exists $exists = 1; } if ($exists) { return &GetPageLinkText($id, $name); } if ($Consts->{ShowLinks} || &UserCanEdit()) { if ($Consts->{FreeLinks}) { if ($name =~ m| |) { # Not a single word $name = "[$name]"; # Add brackets so boundaries are obvious } } $name .= &GetEditLink($id,"?"); } return $name; } sub GetSearchLink { my ($id) = @_; my $name = $id; $id =~ s|.+/|/|; # Subpage match: search for just /SubName $name =~ s|^.+/||; # name doesn't have parent page if ($Consts->{FreeLinks}) { $name =~ s/_/ /g; # Display with spaces $id =~ s/_/+/g; # Search for url-escaped spaces } return &ScriptLink("search=$id", $name); } sub GetPrefsLink { my ($linkname) = @_; $linkname ||= &GetParam("username",'unknown user'); return &ScriptLink("action=editprefs", T($linkname)); } sub GetRandomLink { return &ScriptLink("action=random", T('Random Page')); } sub ScriptLinkDiff { my ($diff, $id, $text, $rev) = @_; $rev = "&revision=$rev" if ($rev ne ""); $diff = &GetParam("defaultdiff", 1) if ($diff == 4); return &ScriptLink("action=browse&diff=$diff&id=$id$rev", $text); } sub ScriptLinkDiffRevision { my ($diff, $id, $rev, $text) = @_; $rev = "&diffrevision=$rev" if ($rev ne ""); $diff = &GetParam("defaultdiff", 1) if ($diff == 4); return &ScriptLink("action=browse&diff=$diff&id=$id$rev", $text); } sub ScriptLinkTitle { my ($action, $text, $title) = @_; if ($FreeLinks) { $action =~ s/ /_/g; } return "{ScriptName}?$action\" title=\"$title\">$text"; } sub GetTalkLink { my ($id) = @_; my ($title); $title = $Consts->{TalkName}; if ($Consts->{FreeLinks}) { $title =~ s/_/ /; } $title = T($title); return $title if $id =~ m|^Talk/|; $id =~ s/\//_>_/g; # convert subpages since only have one level return &GetPageOrEditLink("$Consts->{TalkName}/".$id,$title); } sub GetAuthorLink { my ($host, $userName, $uid) = @_; my ($html, $title, $userNameShow); $userNameShow = $userName; if ($Consts->{FreeLinks}) { $userName =~ s/ /_/g; $userNameShow =~ s/_/ /g; } if (&ValidId($userName) ne "") { # Invalid under current rules $userName = ""; # Just pretend it isn't there. } # Later have user preference for link titles and/or host text? if ($uid > 0) { if ($userName ne "") { my $title = Ts('ID %s',$uid); $title .= ' '.Ts('from %s',$host) if $host ne ''; $html = &ScriptLinkTitle("$Consts->{UsersName}/".$userName, $userNameShow, $title); } else { $html = Ts('ID %s', $uid); } } else { $html = $host; } return $html; } sub GetHistoryLink { my ($id, $text) = @_; if ($FreeLinks) { $id =~ s/ /_/g; } return &ScriptLink("action=history&id=$id", $text); } sub GetHeader { my ($id, $title, $oldId, $rev,$action) = @_; my ($header,$logoImage,$result,$embed,$altText,$parent); my ($httpHeader,$htmlHeader,$logoLink,$redirectMessage); my ($titleF,$topLinkBar); $embed = &GetParam('embed', $EmbedWiki); $altText = T('[Home]'); $httpHeader = &GetHttpHeader(); if ($Consts->{FreeLinks}) { $title =~ s/_/ /g; # Display as spaces } $htmlHeader = &GetHtmlHeader("$SiteName: $title",$id); if ((!$embed) && ($Consts->{LogoUrl} ne "")) { $logoImage = "img src=\"$Consts->{LogoUrl}\" alt=\"$altText\" border=0"; if (!$Consts->{LogoLeft}) { $logoImage .= " align=\"right\""; } $logoLink = &ScriptLink($Consts->{HomePage},"<$logoImage>"); } # Don't want the "redirected message" (unless logged in & can edit) if ($oldId ne '' && &UserCanEdit()) { $redirectMessage = &GetTemplate('messages',{page => &GetEditLink($oldId,$oldId) },'redirect'); } if (&GetParam("toplinkbar", 1)) { # default is 1 # Later consider smaller size? $topLinkBar = &GetGotoBar($id, $rev,$action); } ($parent) = ($id =~ m!([^/]+)/!); if ($parent) { # remove parent page from title $title =~ s!^[^/]+!!; if ($Consts->{UseTalk}) { if ($parent eq $Consts->{TalkName}) { $id =~ s!^[^/]+/!!; } } } return &GetTemplate('header',{ Consts => $Consts, id => $id, embed => $embed, httpHeader => &GetHttpHeader(), htmlHeader => $htmlHeader, logoLink => $logoLink, getSearchLink => \&GetSearchLink, getScriptLink => \&ScriptLink, getPageLink => \&GetPageLink, getQuote => \&GetQuote, title => $title, parent => $parent, message => $redirectMessage, toplinkbar => $topLinkBar, }); } sub GetHttpHeader { my $cookie; if (defined($SetCookie{'uid'})) { $cookie = "$CookieName=" . "rev&" . $SetCookie{'rev'} . "&uid&" . $SetCookie{'uid'} . "&randkey&" . $SetCookie{'randkey'}; $cookie .= ";expires=Fri, 08-Sep-2010 19:48:23 GMT"; if ($HttpCharset ne '') { return $q->header(-cookie=>$cookie, -type=>"text/html; charset=$HttpCharset"); } return $q->header(-cookie=>$cookie); } if ($HttpCharset ne '') { return $q->header(-type=>"text/html; charset=$HttpCharset"); } return $q->header(); } sub GetHtmlHeader { my ($title,$id) = @_; my ($dtd, $bgcolor, $html, $bodyExtra); $html = ''; $dtd = '-//IETF//DTD HTML//EN'; $bgcolor = 'white'; # Later make an option $html = &GetTemplate('htmlHeader',{ Consts => $Consts, id => $id, dtd => $dtd, bgcolor => $bgcolor, html => $html, title => $title, styleSheet => $StyleSheet, }); return $html; } sub GetFooterText { my ($id, $rev) = @_; my $result = ''; my ($gotobar,$editbar,$searchform,$minfooter,$lastedited); if (&GetParam('embed', $EmbedWiki)) { return $q->end_html; } $result = ""; my $minfooter = &GetMinimumFooter(); $result .= $minfooter; $result .= $q->end_html(); $result = &GetTemplate('footer',{ gotobar => $gotobar, searchform => $searchform, lastedited => $lastedited, editbar => $editbar, minfooter => $minfooter }); return $result; } sub GetCommonFooter { return "
" . &GetFormStart() . &GetGotoBar("") . &GetSearchForm() . $q->endform . &GetMinimumFooter(); } sub GetMinimumFooter { if ($FooterNote ne '') { return T($FooterNote); # Allow local translations } } # form elements sub GetHiddenValue { my ($name, $value) = @_; $q->param($name, $value); return $q->hidden($name); } sub GetFormStart { return $q->startform("POST", "$Consts->{ScriptName}", "application/x-www-form-urlencoded"); } sub GetFormText { my ($name, $default, $size, $max) = @_; my $text = &GetParam($name, $default); return $q->textfield(-name=>"p_$name", -default=>$text, -override=>1, -size=>$size, -maxlength=>$max); } sub GetFormCheck { my ($name, $default, $label) = @_; my $checked = (&GetParam($name, $default) > 0); return $q->checkbox(-name=>"p_$name", -override=>1, -checked=>$checked, -label=>$label); } sub GetTextArea { my ($name, $text, $rows, $cols) = @_; if (&GetParam("editwide", 1)) { return $q->textarea(-name=>$name, -default=>$text, -rows=>$rows, -columns=>$cols, -override=>1, -style=>'width:100%', -wrap=>'virtual'); } return $q->textarea(-name=>$name, -default=>$text, -rows=>$rows, -columns=>$cols, -override=>1, -wrap=>'virtual'); } sub GetGotoBar { my ($id,$rev) = @_; my ($main, $bartext); if ($id =~ m|/| && # Show top page for subpages !($Consts->{UseTalk} && $id =~ m|^$Consts->{TalkName}/|)) { $main = $id; $main =~ s|/.*||; # Only the main page name (remove subpage) $bartext .= " | " . &GetPageLink($main); } $bartext = &GetTemplate('page',{ Consts => $Consts, id => $id, parent => $main, areaId => &GetArea($id), linkrandom => &GetParam('linkrandom',0), rev => $rev, T => \&T, Ts => \&Ts, getPageLink => \&GetPageLink, getRandomLink => \&GetRandomLink, getEditLink => \&GetEditLink, getOldPageLink => \&GetOldPageLink, userCanEdit => \&UserCanEdit, getTalkLink => \&GetTalkLink, getPrefsLink => \&GetPrefsLink, getHistoryLink => \&GetHistoryLink, },'gotobar'); return $bartext; } sub GetSearchForm { my ($options) = @_; my ($result); my $size = $options->{size} || 20; $result = T('Search:') . ' ' . $q->textfield(-name=>'search', -size=>$size) . &GetHiddenValue("dosearch", 1); return $result; } sub GetRedirectPage { my ($newid, $name, $isEdit) = @_; my ($url, $html); my ($nameLink); # Normally get URL from script, but allow override. $FullUrl = $q->url(-full=>1) if ($FullUrl eq ""); $url = $FullUrl . "?" . $newid; $nameLink = "$name"; if ($RedirType < 3) { if ($RedirType == 1) { # Use CGI.pm # NOTE: do NOT use -method (does not work with old CGI.pm versions) # Thanks to Daniel Neri for fixing this problem. $html = $q->redirect(-uri=>$url); } else { # Minimal header $html = "Status: 302 Moved\n"; $html .= "Location: $url\n"; $html .= "Content-Type: text/html\n"; # Needed for browser failure $html .= "\n"; } $html .= "\n" . Ts('Your browser should go to the %s page.', $newid); $html .= ' ' . Ts('If it does not, click %s to continue.', $nameLink); } else { if ($isEdit) { $html = &GetHeader('', T('Thanks for editing...'), ''); $html .= Ts('Thank you for editing %s.', $nameLink); } else { $html = &GetHeader('', T('Link to another page...'), ''); } $html .= "\n

"; $html .= Ts('Follow the %s link to continue.', $nameLink); $html .= &GetMinimumFooter(); } return $html; }