Two important points:
That being said, it works for me. I much prefer the title to do backlinking. Maybe because I grew up on C2's wiki. I added another patch /DefaultSearch to partially compensate for replacing the title full-search. /DefaultSearch puts the title into the search text so all you have to do is click in it and hit enter, like in Wiki:FindPage (when clicked from an existing page, such as Wiki:FindPage&value=FrontPage).
This patch does two things.
Going from top to bottom...
We need a new configuration variable. Instead of adding to the huge list, I just added a new line right after the list.
# Configuration/constant variables: use vars qw(@RcDays? @HtmlPairs @HtmlSingle? $TempDir? $LockDir? $DataDir $HtmlDir? $UserDir $KeepDir? $PageDir ... $UserGotoBar); # PATCH: Backlinks use vars qw($BackLinks?); # /PATCH: Backlinks
$FreeUpper = 1; # 1 = force upper case, 0 = do not force case $FastGlob? = 1; # 1 = new faster code, 0 = old compatible code # PATCH: Backlinks $BackLinks? = 1; # 1 = back-links only, 0 = full search for title # /PATCH: Backlinks
Possible suggestion: Set the default value in wiki.pl to 0 and override that with the configuration file. Since full-search is traditional, this might make more sense, even though backlinks are better ;-)
Old version:
sub GetSearchLink { my ($id) = @_; my $name = $id; $id =~ s|.+/|/|; # Subpage match: search for just /SubName? if ($FreeLinks) { $name =~ s/_/ /g; # Display with spaces $id =~ s/_/+/g; # Search for url-escaped spaces } return &ScriptLink("search=$id", $name); }
Becomes:
# PATCH: Backlinks sub GetTitleLink? { my ($id) = @_; my $name = $id; $id =~ s|.+/|/|; # Subpage match: search for just /SubName? if ($FreeLinks) { $name =~ s/_/ /g; # Display with spaces $id =~ s/_/+/g; # Search for url-escaped spaces } if ($BackLinks?) { return &GetBackLink?($id, $name); }else{ return &GetSearchLink($id, $name); } }
sub GetSearchLink { my ($id, $name) = @_; return &ScriptLink("search=$id", $name); }
sub GetBackLink? { my ($id, $name) = @_; return &ScriptLink("search=$id&back=1", $name); } # /PATCH: Backlinks
if ($id ne '') { $result .= $q->h1($header . &GetSearchLink ($id)); } else { $result .= $q->h1($header . $title); }Becomes:
if ($id ne '') { # PATCH: Backlinks $result .= $q->h1($header . &GetTitleLink?($id)); # /PATCH: Backlinks } else { $result .= $q->h1($header . $title); }
if (($search ne "") || (&GetParam("dosearch", "") ne "")) { &DoSearch?($search); return; }Becomes:
if (($search ne "") || (&GetParam("dosearch", "") ne "")) { # PATCH: Backlinks if (&GetParam("back", 0)) { &DoBackLinks($search) }else{ &DoSearch?($search); } # /PATCH: Backlinks return; }
# PATCH: Backlinks sub DoBackLinks { my ($string) = @_;
if ($string eq '') { &DoIndex?(); return; } print &GetHeader(, &QuoteHtml?(Ts('BackLinks? for: %s', $string)), ); print '
'; &PrintPageList?(&GetBackLinkList?($string)); print &GetCommonFooter(); }
sub GetBackLinkList? { my ($name, $link, $search); my (@found, @links, @pglist);
$search = &GetParam("search", ""); $search =~ s/ /_/g;
@pglist = &AllPagesList(); PAGE: foreach $name (@pglist) { @links = &GetPageLinks($name, 1, 0, 0); foreach $link (@links) { $link =~ s/\.//; if ($link eq $search) { push(@found, $name); next PAGE; } } } @found = sort(@found); return @found; } # /PATCH: Backlinks
Consider UseMod:search=ModWiki vs. UseMod:search=\bModWiki\b vs. UseMod:search=\b(?-i)ModWiki\b. This gives us a smaller patch that will be as fast as searching.
sub GetBackLinksSearchLink { my ($id) = @_; my $name = $id; $id =~ s|.+/|/|; # Subpage match: search for just /SubName if ($FreeLinks) { $name =~ s/_/ /g; # Display with spaces $id =~ s/_/+/g; # Search for url-escaped spaces } return &ScriptLink("back=$id", $name); }
sub GetHeader { ... if ($id ne '') { $result .= $q->h1($header . &GetBackLinksSearchLink($id)); } else { $result .= $q->h1($header . $title); } ... }
sub DoOtherRequest { ... $search = &GetParam("search", ""); if (($search ne "") || (&GetParam("dosearch", "") ne "")) { &DoSearch($search); return; } else { $search = &GetParam("back",""); if( $search ne "" ) { &DoBackLinks($search); return; } } ... }
Place directly after sub DoSearch?...
sub DoBackLinks { my ($string) = @_; if (&ValidId($string) ne '') { &DoIndex(); return; } print &GetHeader('', &QuoteHtml(Ts('Backlinks for: %s', $string)), ''); print '<br>'; &PrintPageList(&SearchTitleAndBody("\\b(?-i)$string\\b")); print &GetCommonFooter(); }
-- SunirShah
Moving discussion to MeatBall:BackLink...
For 1.0, I'm going to go with the easier patch for now simply due to computation overhead concerns. Note that false positives for links like [[the]]
are resolvable by just upgrading the easy patch to be sensitive to the FreeLinkPattern?. e.g. /\[\[the\]\]/gs However, I encourage people to apply the better patch to their own scripts. If we can optimize this search without consuming a very large amount of disk space, we should definitely do it. -- SunirShah
## modify it. sub DoOtherRequest { .... $search = &GetParam("reverse", ""); if ($search ne "") { # &DoReverse($search); &DoGetBackSearchLink($search); return; } } ## add new codes. sub DoGetBackSearchLink { my ($id) = @_; my @x; my @split_text; my ($name, $mainid, $subid); my $result; $name = $id; if ($FreeLinks) { $name =~ s/_/ /g; # Display with spaces $id =~ s/_/+/g; # Search for url-escaped spaces } ($mainid, $subid) = split(/\//,$name); if ($id eq '') { &DoIndex(); return; } print &GetHeader('', &QuoteHtml(Ts('Search for: %s', $name)), ''); print '<br>'; @x = &SearchBack($mainid, $subid); @x = sort @x; &PrintPageList(@x); print &GetCommonFooter(); } sub SearchBack { my ($mainid, $subid) = @_; my ($name, $temp_name, $temp_sub, @found); foreach $name (&AllPagesList()) { ($temp_name, $temp_sub) = split (/\//, $name); if (($name ne $mainid) && ($mainid ne $temp_name)) { &OpenPage($name); &OpenDefaultText(); $Text{'text'} =~ s/((.|\n)*?\<\/nowiki>)|($UrlPattern)|(<html>(.|\n)*?\<\/html>)|(<pre>(.|\n)*?\<\/pre>)//gi; if ($subid ne "") { if ($mainid =~ /$LinkPattern/) { if (($subid =~ /$LinkPattern/) && ($Text{'text'} =~ /$mainid\/$subid[^\/]/)) { push(@found, $name); } elsif ($Text{'text'} =~ /\[\[$mainid\/$subid\]\]/) { push(@found, $name); } } else { if ($Text{'text'} =~ /\[\[$mainid\/$subid\]\]/) { push(@found, $name); } } } else { if ($mainid =~ /$LinkPattern/) { if ($Text{'text'} =~ /$mainid[^\/]/) { push(@found, $name); } } else { if ($Text{'text'} =~ /\[\[$mainid\]\]/) { push(@found, $name); } } } } elsif (($name eq $mainid) || ($mainid eq $temp_name)) { &OpenPage($name); &OpenDefaultText(); if ($subid ne "") { if ($temp_name =~ /$LinkPattern/) { if (($subid =~ /$LinkPattern/) && (($Text{'text'} =~ /$mainid\/$subid[^\/]/) || ($Text{'text'} =~ /\/$subid[^\/]/))) { push(@found, $name); } else { if (($Text{'text'} =~ /\[\[$mainid\/$subid\]\]/) || ($Text{'text'} =~ /\[\[\/$subid\]\]/)) { push(@found, $name); } } } else { if ($subid =~ /$LinkPattern/) { if ($Text{'text'} =~ /\/$subid[^\/]/) { push (@found, $name); } } else { if (($Text{'text'} =~ /\[\[$mainid\/$subid\]\]/) || ($Text{'text'} =~ /\[\[\/$subid\]\]/)) { push(@found, $name); } } } } else { if ($mainid =~ /$LinkPattern/) { if ($Text{'text'} =~ /$mainid/) { push(@found, $name); } } else { if ($Text{'text'} =~ /\[\[$mainid\]\]/) { push(@found, $name); } } } } } return @found; } </pre> Im not a Perl programmer, I cannot resolve like <nowiki>[http://bla.bla "anywikilink"]. and, maybe "regular backlink patch" has same problem too. please modify it. - anonymous ---- I remodified. If you decide to use below regular-expression routine, you can get more correct result but too slow nor you can get very fast but correctless result.(maybe include that such as WikiLinks) <pre> sub SearchBack { .... ## rate vs quality $Text{'text'} =~ s/(<nowiki>(.|\n)*?\<\/nowiki>)|($UrlPattern)|(<html>(.|\n)*?\<\/html>)|(<pre>(.|\n)*?\<\/pre>)//gi; } ....- same anonymous