페이지에 들어 있는 링크 목록을 별도로 보관하게 함
- 역링크 나 상단의 "링크" 메뉴, 그 외 여러 매크로들은 데이타 디렉토리에 있는 모든 페이지들을 읽어서 페이지 내의 링크들을 뽑아내어야 한다. 따라서 페이지 수가 늘어나면 속도가 현저하게 느려진다.
- 링크들을 별도의 디렉토리 (데이타 디렉토리 아래의 "link" 디렉토리) 를 만들어서 그 안에 "페이지이름.lnk" 의 화일에 보관한다.
- 필수 요구 사항: 없음
- 선택 요구 사항: 없음
- 사용법: 그냥 평소대로 살면 된다. :-) 다만 내부적으로는 다음과 같이 동작이 달라진다.
- 이 패치를 적용하고 제일 처음으로 링크 목록을 뽑아내는 시점에서 (역링크를 출력한다던가, 링크 메뉴를 클릭한다던가, 매크로를 사용한다던가 등) 필요한 페이지의 링크가 link 디렉토리 아래에 "페이지.lnk" 의 형식으로 저장된다.
- 일단 저장된 후에는 그 화일로부터 링크들을 읽어온다.
- 한꺼번에 모든 페이지의 링크 목록을 만들어주고 싶다면 wiki.pl?action=maintain 을 하면 된다.
- 모든 유저 인터페이스는 그대로 유지된다.
-
wiki.pl?action=links&page=1 # 1 - 내부링크 출력, 0 - 출력하지 않음 (기본값 1)
wiki.pl?action=links&inter=1 # 1 - 인터링크 출력, 0 - 출력하지 않음 (기본값 0)
wiki.pl?action=links&url=1 # 1 - 외부URL 출력, 0 - 출력하지 않음 (기본값 0)
wiki.pl?action=links&unique=1 # 1 - 중복되는 링크를 한 번만 출력, 0 - 중복 횟수만큼 출력 (기본값 1)
wiki.pl?action=links&sort=1 # 1 - 링크들을 정렬하여 출력, 0 - 정렬하지 않음 (기본값 1)
wiki.pl?action=links&exists=2 # 0 - 내용이 없는 링크만 출력, 1 - 내용이 있는 링크만 출력, 2 - 모두 출력 (기본값 2)
wiki.pl?action=links&empty=1 # 1 - 링크가 하나도 없는 페이지도 출력, 0 - 출력하지 않음 (기본값 0)
wiki.pl?action=links&search=string # 링크 목록 중에 "string" 이라는 문자열이 포함되어 있는 경우만 출력
wiki.pl?action=links&reverse=string # 링크 목록 중에 "string" 이라는 링크가 있는 경우만 출력 (즉, 역링크)
wiki.pl?action=links&page=1&inter=1&exists=1 # 이런 식으로 여러 파라메터를 조합할 수 있다
- 함수 인터페이스는 - 계속 고민하다가 결국 - 기존의 함수는 그대로 두고 대신 별도의 함수를 추가했다. 다른 매크로를 추가로 제작할 경우, GetPageLinks 함수를 써야 되는 경우에 GetPageLinksFromFile 이라는 함수를 쓰면 lnk 화일로부터 링크 목록을 읽는다.
- 관리 메뉴에서 페이지 이름바꾸기나 링크 변경을 할 경우 자동으로 링크 목록 화일들도 갱신된다.
- 부작용: 모름
- 이런 저런 테스트를 하긴 했는데, 별 문제가 발견되지는 않았다. 적어도 아직까지는. :-)
- 이 패치와 별도로, 역링크속도개선논의에 있는 패치를 사용할 수도 있다. 구현에 따라 각각 장단점이 있으니 참조할 것.
- config.pl 화일에 다음을 추가한다
-
...
$RcOldFile = "$DataDir/rclog.old";
$IndexFile = "$DataDir/pageidx";
$LinkDir = "$DataDir/link";
...
- 이하는 wiki.pl 의 수정
-
...
use vars qw(
$UserGotoBar $UserGotoBar2 $UserGotoBar3 $UserGotoBar4
$ConfigFile $SOURCEHIGHLIGHT %SRCHIGHLANG $LinkFirstChar
$EditGuideInExtern $SizeTopFrame $SizeBottomFrame
$LogoPage $CheckTime $LinkDir
);
...
-
...
$IndexFile = "$DataDir/pageidx";
$LinkDir = "$DataDir/link";
$UseEmoticon = 1;
...
-
sub GetFullLinkList {
...
%seen = ();
}
@links = &GetPageLinksFromFile($name, $pagelink, $interlink, $urllink);
foreach $link (@links) {
$seen{$link}++;
...
}
-
sub DoPost {
...
&SaveDefaultText();
&SavePage();
&SaveLinkFile($id);
&WriteRcLog($id, $summary, $isEdit, $editTime, $user, $Section{'host'});
...
}
-
sub DoMaintain {
...
foreach $name (&AllPagesList()) {
&OpenPage($name);
&OpenDefaultText();
&ExpireKeepFile();
&SaveLinkFile($name);
print ".... " if ($name =~ m|/|);
print &GetPageLink($name), "<br>\n";
}
...
}
-
sub BuildLinkIndexPage {
...
my ($page) = @_;
my (@links, $link, %seen);
@links = &GetPageLinksFromFile($page, 1, 0, 0);
%seen = ();
...
}
-
sub RenameTextLinks {
...
if ($changed) {
$file = &GetPageFile($page);
&WriteStringToFile($file, join($FS1, %Page));
&SaveLinkFile($page);
}
...
}
-
sub RenamePage {
...
my ($oldlink, $newlink);
$oldlink = &GetLinkFile($old);
if (-f $oldlink) {
$newlink = &GetLinkFile($new);
&CreatePageDir($LinkDir, $new);
rename($oldlink, $newlink) || die "error while renaming link file";
}
&EditRecentChanges(2, $old, $new) if ($doRC);
if ($doText) {
&BuildLinkIndexPage($new);
&RenameTextLinks($old, $new);
}
}
-
sub GetLinkFile {
my ($id) = @_;
return $LinkDir . "/" . &GetPageDirectory($id) . "/$id.lnk";
}
sub SaveLinkFile {
my ($page) = @_;
my (%links, @pagelinks, @interlinks, @urllinks, @alllinks, $link);
@alllinks = &GetPageLinks($page, 1, 1, 1);
foreach $link (@alllinks) {
if ($link =~ /^$InterLinkPattern$/) {
push(@interlinks, $link);
} elsif ($link =~ /^$UrlPattern$/) {
push(@urllinks, $link);
} else {
push(@pagelinks, $link);
}
}
$links{'pagelinks'} = join($FS2, @pagelinks);
$links{'interlinks'} = join($FS2, @interlinks);
$links{'urllinks'} = join($FS2, @urllinks);
&CreatePageDir($LinkDir, $page);
&WriteStringToFile(&GetLinkFile($page), join($FS1, %links));
}
sub GetPageLinksFromFile {
my ($name, $pagelink, $interlink, $urllink) = @_;
my ($status, $data, %links, @result, $fname);
@result = ();
$fname = &GetLinkFile($name);
if (!(-f $fname)) {
&SaveLinkFile($name);
}
($status, $data) = &ReadFile($fname);
if (!($status)) {
return &GetPageLinks($name, $pagelink, $interlink, $urllink);
}
%links = split($FS1, $data, -1);
push (@result, split($FS2, $links{'pagelinks'}, -1)) if ($pagelink);
push (@result, split($FS2, $links{'interlinks'}, -1)) if ($interlink);
push (@result, split($FS2, $links{'urllinks'}, -1)) if ($urllink);
return @result;
}
&DoWikiRequest() if ($RunCGI && ($_ ne 'nocgi'));
1;
-
sub DeletePage {
...
$fname = &GetLockedPageFile($page);
unlink($fname) if (-f $fname);
&UnlinkHtmlCache($page);
$fname = &GetLinkFile($page);
unlink($fname) if (-f $fname);
unlink($IndexFile) if ($UseIndex);
...
}
Notes
페이지 삭제 시에 링크 화일도 삭제하는 루틴을 추가했습니다. 위의 마지막 박스를 별도로 적용하면 됩니다.
위키위키분류
Tweak in order to not create file .lnk if file doesn't exist.
sub GetPageLinksFromFile {
...
- if (!(-f $fname)) {
+ if (!(-f $fname) && (-f &GetPageFile($name))) {
&SaveLinkFile($name);
}
- --JuanmaMP
Tweak in order to not create file .lnk if links doesn't exist.
sub SaveLinkFile {
my ($page) = @_;
my (%links, @pagelinks, @interlinks, @urllinks, @alllinks);
@alllinks = &GetPageLinks($page, 1, 1, 1);
+ if (@alllinks) {
foreach my $link (@alllinks) {
if ($link =~ /^$InterLinkPattern$/) {
push(@interlinks, $link);
} elsif ($link =~ /^$UrlPattern$/) {
push(@urllinks, $link);
} else {
push(@pagelinks, $link);
}
}
$links{'pagelinks'} = join($FS2, @pagelinks);
$links{'interlinks'} = join($FS2, @interlinks);
$links{'urllinks'} = join($FS2, @urllinks);
&CreatePageDir($LinkDir, $page);
&WriteStringToFile(&GetLinkFile($page), join($FS1, %links));
}
}
- --JuanmaMP
- How are you? :-) That's very reasonable idea. Thanks!
I'm fine, thanks; but don't ask me a time ago :)
I hope that you're fine too.