The .pm file below is completely modular. You can add commands by just dropping in more packages. Or you can remove the existing ones if you don't want to support them. see MagicContent for documentation.
#MAGIC Commandname param1=value param2=value ...
use MagicContent;
$fullHtml .= &WikiToHTML($Text{'text'});
Block 1:
# magiccontent patch - tarquin my $magicline; if ( ($magicline) = $Text{'text'} =~ m[^\#MAGIC(.*)\n] ) { $Text{'text'} =~ s/^\#MAGIC.*\n//; # now kill the magic command line in source }
Block 2:
# magiccontent patch - tarquin if ( $magicline ){ my $magicmodule; # call: MakeSection( current page, magic module, line of parameters) $fullHtml .= (MagicContentMaker->MakeSection( $id, $magicline =~ m[^\W*(\w*)(.*)] ) || ''); #$fullHtml .= "<b>magic line is: '$magicline'</b><BR>"; # testing #( $magicmodule, $magicline ) = $magicline =~ m[^\W*(\w*)(.*)]; #$fullHtml .= "<b>magic package is: '$magicmodule'</b><BR>"; # testing #$fullHtml .= "<b>magic line is: '$magicline'</b><BR>"; # testing #$fullHtml .= (MagicContentMaker->MakeSection($magicmodule, $magicline) || ''); }
print PrintPageList?( blah);
The following enhancement adds the facility to place the generated content at the top of the page, as well as at the bottom. With this the #MAGIC line can optionally have @top or @bottom) between the #MAGIC token and the Commandname.
e.g. #MAGIC @top WantedPages threshold=2
Placing the Wiki text at the bottom make sense if it is intended to be used to allow people to comment on the auto-generated text. Placing the Wiki text at the top makes sense if it is an introduction to the auto-generated text.
Replace Block 1, Block 2 and the call to WikiToHTML as described in BrowsePage above with the code below to enable this functionality.
# magiccontent patch - tarquin # Refactored and added position functionality --DavidClaughton. my ($magiccommand, $magicpos, $magicparams); my ($magicHTML, $magicDiv, $wikiHTML) = ("", "", ""); if ( ($magicpos, $magiccommand, $magicparams) = $Text{'text'} =~ m[^\#MAGIC\s*(?:\@(top|bottom))?\s*(\w*)\s*(.*)\n] ) { $Text{'text'} =~ s/^\#MAGIC.*\n//; # kill the magic command line in source $wikiHTML = &WikiToHTML($Text{'text'}); $magicDiv = "<hr>\n"; # Remove if using CSS. # call: MakeSection( current page, magic module, line of parameters) $magicHTML .= (MagicContentMaker->MakeSection( $id, $magiccommand, $magicparams ) || ''); if (lc $magicpos eq "top"){ $fullHtml .= $magicHTML . $magicDiv . $wikiHTML; } else { $fullHtml .= $wikiHTML . $magicDiv . $magicHTML; } } else { $fullHtml .= &WikiToHTML($Text{'text'}); }
#!/usr/bin/perl ############################################################################### # # MagicContent.pm # # Generated content for Wiki pages, requested by the page text itself # Syntax in wiki pages: # #MAGIC ModuleName param1=value1 param2=value2 ... { package MagicContentMaker; our @registered; sub register { # borrowed from Mych's Wookee.pm - thanks Mych :-) # fills the @registered array with the names of the packages my $class = shift; $class = (ref $class or $class); push @registered, $class unless grep /^\Q$class\E$/, @registered; } sub GenerateContent { '' } sub CommandParameters { () } ############ sub ListParameters { my $class = shift; my $text; my @parameters = $class->CommandParameters; return '' if scalar @parameters == 0; $text .= '<h4>Parameters for this command</h4>'; $text .= '<UL>'; $text .= join '', map { "<LI>$_</LI>" } @parameters ; $text .= '</UL>'; return $text; } # call this from UseModWiki sub MakeSection { my $class = shift; my $page = shift; # the page being browsed my $magicmodule = shift; # the requested magicmodule my %params = map { s/^"|"$//g; $_ } (shift =~ m[(\w+)\s*=\s*("[^"]*"?|\S+)]g); #" $params{'thispage'} = $page; # add the page to the parameters hash foreach ( values %params ) { # escape HTML. keys are fine since grabbed as "\w+" s[&][&]g; s[<][<]g; } my $text; # ... make an opener $text .= qq[<div class="magic" id="$magicmodule">\n]; if( grep /^\Q$magicmodule\E$/ , @registered ){ # if one of our packages matches the name of the wiki page, run the script $text .= $magicmodule->GenerateContent(%params); $text .= $magicmodule->ListParameters; } else { # ...or complain $magicmodule =~ s[&][&]g; $magicmodule =~ s[<][<]g; $text .= qq[#MAGIC module "<b>$magicmodule</b>" cannot be found. Use "#MAGIC ListCommands" to see available modules.]; } # ... make a closer $text .= qq[</div>\n]; return $text; } } ############################################################# # # command: Foobar # this is just a template { package Foobar; @ISA = qw(MagicContentMaker); Foobar->register(); sub CommandParameters { () } # auto-documentation: list the params this module requires here. # safe to delete if no parameters ########################### sub GenerateContent { my ( $class, %params ) = @_; # put the script for the page here # access parameters thus: $params{'threshold'} # page being browsed is: $params{'thispage'} return "Generating... FooBar<BR>"; } } ############################################################# # # command: Params # this lists all the parameters the page has passed to the command, just for testing { package Params; @ISA = qw(MagicContentMaker); Params->register(); ########################### sub GenerateContent { my ( $class, %params ) = @_; my $text; $text .= '<h4>Parameters</h4><DL>'; while (($key, $value) = each %params) { $text .= qq[<DT>$key</DT> <DD>$value</DD>]; } $text .= '</DL>'; return $text; } } ############################################################# # # command: ListCommands # this returns all the available commands in this perl module { package ListCommands; @ISA = qw(MagicContentMaker); ListCommands->register(); ########################### sub GenerateContent { my ( $class, %params ) = @_; my $text; $text .= '<h4>Commands</h4><UL>'; $text .= join '', map { "<LI>$_</LI>" } @MagicContentMaker::registered; $text .= '</UL>'; return $text; } } ############################################################# # # command: AllPages # lists all the pages of the wiki { package AllPages; @ISA = qw(MagicContentMaker); AllPages->register(); sub CommandParameters {'list = ol|ul'} ########################### sub GenerateContent { my ( $class, %params ) = @_; my $text; my $listTag = $params{'list'}; $listTag = 'UL' unless defined $params{list}; if( $listTag !~ m/^(UL|OL)$/i ){ $listTag = 'UL'; $text .= qq[parameter "$params{'list'}" not recognized, defaulting to OL.]; } $text .= "<h4>List of all pages on this wiki:</h4><$listTag>"; $text .= join '', map { '<LI>' . UseModWiki::GetPageLink($_) . '</LI>' } UseModWiki::AllPagesList(); $text .= "</$listTag>"; return $text; } } ############################################################# # # command: Category # returns the search results for the browsed page title { package Category; @ISA = qw(MagicContentMaker); Category->register(); ########################### sub GenerateContent { my ( $class, %params ) = @_; my $text; $params{'thispage'} =~ s/_/ /g; $text = UseModWiki::PrintPageList(UseModWiki::SearchTitleAndBody(qq["[[$params{'thispage'}]]"])); $text =~ s[(\d+ pages? found)][Members of this category: $1]; #reset currently open page, so the referrer is correct in the edit links made below $UseModWiki::OpenPageName = $params{'thispage'}; return $text; } } ############################################################# # # command: WantedPages # lists wanted pages. refactored & better UseMod call { package WantedPages; @ISA = qw(MagicContentMaker); WantedPages->register(); sub CommandParameters { 'threshold = 0,1,2 ... : show only pages with more than this number of requests.' } ########################### sub SortItems { my ( $a , $b , $numA , $numB ) = @_; } sub GenerateContent { my ( $class, %params ) = @_; my ($text, @links); #my $testoutput; $params{threshold} = 0 unless defined $params{threshold}; if( $params{'threshold'} !~ /^\d+$/ ) { return q[Invalid value in parameter 'threshold'.]; } # grab the list of links from UseModWiki::GetFullLinkList which spits out an array # on the way, kill any items which are just one pagename: ie pages that make no requests @links = grep { !/^\w+\s*$/ } UseModWiki::GetFullLinkList(1,1,1,0,0,0,0,'',1); #reset currently open page, so the referrer is correct in the edit links made below $UseModWiki::OpenPageName = $params{'thispage'}; ################## # Data extraction # what we have so far: multiple lines like: # {Existing page} {list of wanted link plain text}\n my %requesters; # hash of arrays to store who wants the pages foreach (@links) { # we are chomping through each line at a time my $head; s[^(\S+)\s*]{ $head = $1; ''; }eg; # strip link tags and put the head name somewhere else # now $_ is the list of links wanted by page $head while( m[(\S+)\s*]g ) { #$testoutput .= "$1<BR>"; push @{ $requesters{$1} }, $head; } } # $testoutput .= join '<BR>', @links; # now we have a hash of arrays. Keys are wanted pages, value is array of requesters ################## # Data output my $wantedpage; # sort { SortList( $a, $b, @{$requesters{$a}}, @{$requesters{$b}} } ( grep ... ) foreach $wantedpage (sort { @{$requesters{$b}} <=> @{$requesters{$a}} || $a cmp $b } (grep { @{$requesters{$_}} > $params{'threshold'} } keys %requesters ) ) { # run through the hash keys # BUT sort them by size of the associated array, # AND only let through the arrays > threshold parameter $text .= '<dt>' # get an edit link for the wanted page . $wantedpage . &UseModWiki::GetEditLink($wantedpage,"?") #. &UseModWiki::GetEditLink($wantedpage,$wantedpage) # give number of requests . ' ('. @{$requesters{$wantedpage}} . ' requests)</dt><dd>Requested by: ' # list the requester, as page links . join(', ', map {UseModWiki::GetPageLink($_)} @{$requesters{$wantedpage}} ) . '</dd>'; } #return $testoutput . '<HR>'; my $thresholdmessage = ( $params{'threshold'} == 0 ) ? '' : 'May be further pages. '; return qq[<style type="text/css"> \#WantedPages dd {font-size:smaller; margin:1px 0px 1.5ex 4em;} \#WantedPages dl {margin:0px;} \#WantedPages dt {font-weight:normal;} </style> <DL>$text</DL> $thresholdmessage Threshold is $params{'threshold'}.]; } } ############################# 1;
This module is extremely useful, thank you. I noticed that the wantedpages command finds subpages which exist. Since we never notice any real wanted subpages this fix just skips over them:
next if $wantedpage =~ /^\//; # added # run through the hash keys