[첫화면으로]UseModWiki소스수정/반영된사용자의견archive03

마지막으로 [b]

1. ||, |<, |> 에 대한 버그
2. 빈페이지 링크스타일을 사용자 설정에 따라 바꿔줌
3. 사용자목록 매크로
4. action=titleindex
5. EXTERN 에서 수정했으면 하는 부분
6. IncludeDay 매크로
7. 자동로그인 선택
8. 새로생긴 페이지에 NEW 마크 표시
9. RemoteWiki
10. 편집된 페이지의 처음이 빈 줄일 경우

1. ||, |<, |> 에 대한 버그

/ToDoOrBugReport 에 적어두신 내용을 보고 소스를 찾아봤습니다. 그러니까 그 페이지 위에 한번이라도 ||를 이용한 테이블이 나오면 그 이후 ||, |<, |> 가 td닫고 새로 열기로 바뀌어 버리는데요. 원인은 $TableMode라는 변수가 1로 설정된 상태로 남아있기 때문입니다.

WikiLinesToHtml 함수에서 다음 부분을 찾아서 바꿔주면 됩니다.

if ($tag eq "TABLE") {
        $TableMode = 0; # 원래 내용은 필요없음
};

테이블이 생성될 때 매 라인의 끝이 ||으로 끝나게 변경했고, 그 ||가 tr 닫기로 치환되므로 원래 저 부분에 있던 tr 닫기는 필요없습니다. tag가 TABLE이니 굳이 table로 바꿀 필요도 없구요. 단지 $TableMode만 0으로 만들어주면 됩니다.

-- 조프 2002-12-18 1:38 pm

조프님의 패치를 /버그또는문제점해결에 반영했습니다. 완료.

-- Raymundo 2002-12-18 2:23 pm

2. 빈페이지 링크스타일을 사용자 설정에 따라 바꿔줌

원래의 WikiX스타일 소스수정에서 다음과 같이 바꿔줍니다. 기본값은 $LinkFirstChar의 값을 따릅니다.


sub DoEditPrefs {
....
        print '<br>', &GetFormCheck('linkstyle', $LinkFirstChar,
                                                        T('Use WikiX link style for newpage')); # 추가한다.
        print '<br>', &GetFormCheck('linkrandom', 0,
                                                                                                T('Add "Random Page" link to link bar'));
        print '<br>', $q->submit(-name=>'Save', -value=>T('Save')), "\n";
....
}

sub DoUpdatePrefs {
....
        &UpdatePrefCheckbox("linkstyle"); #### 추가한다.
        &UpdatePrefCheckbox("linkrandom");
....
}

sub GetPageOrEditAnchoredLink {
....
#### 이것을
#       if (($LinkFirstChar) && ($name =~ /(\[)?([^\/]*\/)?([a-zA-Z0-9\/]|[\x80-\xff][\x80-\xff])([^\]]*)(\])?/)) {
#### 이것을

#### 이렇게 바꿔준다.
        if ((&GetParam('linkstyle', $LinkFirstChar)) && ($name =~ /(\[)?([^\/]*\/)?([a-zA-Z0-9\/]|[\x80-\xff][\x80-\xff])([^\]]*)(\])?/)) {
#### 이렇게 바꿔준다.
                return $2 . &GetEditLink($id,"<b>$3</b>") . $4;
        } else {
                return $name . &GetEditLink($id,"?");
        }
....
}

별다른 문제는 없을겁니다. 원격위키링크를 wikix스타일로 표시할 수 있게 누가 손좀 봐줬으면 좋겠는데..흑. ㅠㅠ

-- Bab2 2002-12-19 4:55 pm

이거 멋지군요. 반영했습니다.

-- Raymundo 2002-12-23 1:08 am

3. 사용자목록 매크로


적당한 위치에 다음 함수를 집어넣습니다.

sub GetUserList {
        my (@userlist, $result);
        my $usernumber;
        opendir(USERLIST, $UserDir);
        @userlist = readdir(USERLIST);
        close(USERLIST);
        shift @userlist;
        shift @userlist;
        @userlist = sort @userlist;
        foreach $usernumber (0..(@userlist-1)) {
                @userlist[$usernumber] =~ s/(.*)\.db/($1)/gei;
                @userlist[$usernumber] = &StorePageOrEditLink("@userlist[$usernumber]", "@userlist[$usernumber]") . "<br>";
        }

        $result = "@userlist";

        return $result;

}

그리고나서 아래의 함수에 한줄 추가합니다.

sub MacroSubst {
        ....
        $txt =~ s/\&__LT__;userlist\&__GT__;/&GetUserList()/gei;  ####추가한다.
        ....
}

개인적으로 필요해서 추가했고, <userlist> 형식으로 사용하며, GenerateAllPagesList함수는 도저히 사용을 못하겠어서리, 그냥 보이는대로 만들었습니다.(허덥해서리..;; 최적화를 좀 부탁드리겠습니다.) 흐~ 사용자페이지가 없는데 그냥 링크를 넣고자 하면 &StorePageOrEditLink 대신에 &GetPageLink 를 넣음 될겁니다.

-- Bab2 2002-11-28 6:14 am

적용했습니다.

-- Raymundo 2002-12-30 3:34 pm

4. action=titleindex

RemoteWiki를 위한 부산물입니다.(정작 RemoteWiki부분은 시작도 안했는데 -_-a) http://no-smok.net/ns/moin.cgi/?action=titleindex 와 페이지 의 내용을 같은 형식의 Plain Text로 출력합니다.

#### 함수전체 추가.
sub DoTitleIndex {
        my (@list);
        my $index;
        print "Content-type: text/plain\n\n";
        @list = &AllPagesList();
        foreach $index (@list) {
                print $index."\r\n";
        }
}
#### 여기까지.

....

sub DoOtherRequest {
....
                } elsif ($action eq "index") {
                        &DoIndex();
                } elsif ($action eq "titleindex") {    #### 추가한다.
                        DoTitleIndex();               #### 추가한다.
                } elsif ($action eq "help") {                           # luke added
                        &DoHelp();
....
}

HTML을 문법을 몰라서 GetHttpHeader 함수를 그냥 복사해서 붙여넣기 했는데, DoTitleIndex에서 "print &GetPlainTextHeader();"를 그냥 html문으로 출력하게끔 누가 수정 해줬으면 하는 작은 소망이 있습니다. :)

-- Bab2 2002-12-9 8:53 pm

오오.. 상당히 규모가 큰 작업을 구상 중이신 것 같군요. 짝짝짝~ 말씀하신 '작은 소망'이란 것이, 저 GetPlainTextHeader 를 쓰지 않고 간단히 하길 원하시는 거라면...
    print "Content-type: text/plain\n\n";
이라고만 쓰셔도 똑같은 효과일 걸요. 이 경우 쿠키나 캐쉬에 대한 지정이 전혀 들어가지 않아서 문제가 될 수 있을지도 모르겠습니다만... CGI 는 저도 잘 몰라서요.
-- Raymundo 2002-12-9 10:46 pm

적용했습니다.

-- Raymundo 2002-12-30 4:05 pm

5. EXTERN 에서 수정했으면 하는 부분

아 별건 아니고요. 요즘 valid한 위키 페이지를 만드는 일을 해보고 있습니다.

에서 문서의 이름을 넣어주면 html이나 css가 문법적으로 에러가 없는지 확인할 수 있거든요.
한글로 된 주소를 넣으면 문서를 제대로 찾지 못한다는 치명적인 문제가 있습니다만, Opera에서 주소를 %12%34 형식으로 보여주기 때문에 그 주소를 넣어주면 테스트가 가능합니다. :-)

일단 BrowseExternUrl에서

        } else {
                print &GetHttpHeader();
                print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\">\n"; # 추가
를 해줘야 하고요. (일반 위키 페이지의 경우는 DOCTYPE이 제대로 출력됩니다)

좀 애매한 부분이긴 한데, 원래 frameset에는 border라는 속성이 없습니다.
frame에 frameborder라는 속성이 있어서 이 속성을 0을 주면 되지요. [참고]
문제는 Opera가 이 속성을 제대로 지원하지 않는 것 같다는... 이건 지금 테스트 중입니다.

그럼.

-- 조프 2002-12-10 1:15 pm

오... frameset 에 border 가 사실은 없는 거라니.. 처음 알았네요. 반영하겠습니다.
-- Raymundo 2002-12-10 2:04 pm

6. IncludeDay 매크로

지금 [조프위키] 대문을 보면 날짜와 그날 일정이 나옵니다.

오늘은 '''<date>''' 입니다.\\
<IncludeToday()>
이런 식으로 해놨지요. IncludeToday의 내용은 오늘 날짜에 맞는 페이지를 Include 해주는 단순한 함수입니다.

제가 추가한 함수는 대강 다음과 같습니다.

sub MacroToday {
        my ($cal_name) = @_;
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Now);

        if ($cal_name ne "") {
                $cal_name .= "/";
        }

        my $cal_page = $cal_name . ($year + 1900) . "-";
        if ($mon + 1 < 10) {
                $cal_page .= '0';
        }
        $cal_page .= ($mon+1);
        if ($mday < 10) {
                $cal_page .= "-0$mday";
        } else {
                $cal_page .= "-$mday";
        }

        return &MacroInclude($cal_page);
}

구찮아서 날짜 처리를 안했죠. -_-; 달력을 사용하는 김에 추가하면 대문이나 개인 페이지에 사용하기 괜찮지 않나 싶네요.

-- 조프 2003-2-6 7:12 pm
달력처럼 날짜를 정할수 있게 하는 것이 가능할까요?
<IncludeToday(0,-1)> <IncludeToday(0,0)> <IncludeToday(0,1)>
이런식으로요. '_'a
-- Bab2 2003-2-6 8:12 pm
예, 저는 필요를 느끼지 못해서 그냥 오늘만 되게했지만, MacroCalendar 함수의 날짜 처리루틴을 응용하면 그리 어렵지 않게 구현할 수 있을 것 같네요.
-- 조프 2003-2-6 10:59 pm

Bab2님도 그렇고 조프님도 그렇고... 이런 맛에 UseModWiki 를 떠날 수 없네요. 멋집니다. 잘 지내시죠? ^_^

-- Raymundo 2003-2-6 8:55 pm
예 :-)
-- 조프 2003-2-6 10:59 pm
저두요! 그리고 유즈모드의 심플함도 매력이죠.
-- Nyxity 2003-2-6 11:07 pm
저도요. 'v'
-- Bab2 2003-2-6 11:45 pm

조프님 홈에서 잠깐 테스트 해 보았는데, 인자로 페이지 이름이 들어갈 경우 페이지 이름이 위키네임이면 동작을 안 하는 것 같네요. 매크로 검사하기 전에 먼저 a href 링크로 바뀌어 버리니까 그러는 것 같습니다. 현재 작업 중입니다. 간만에 하려니까 문법도 가물가물하군요. ^^;

-- Raymundo 2003-2-11 1:27 am

날짜 offset 을 인자로 받을 수 있도록 개선하여 반영했습니다. 완료.

-- Raymundo 2003-2-11 2:36 am

7. 자동로그인 선택


#### 쿠키에 expire항목 추가.
sub GetHttpHeader {
...
        if (defined($SetCookie{'id'})) {
################## 바꿔준다.
                $cookie = "$CookieName=" . "expire&" . $SetCookie{'expire'} . "&rev&" . $SetCookie{'rev'} . "&id&" . $SetCookie{'id'} . "&randkey&" . $SetCookie{'randkey'};
                if ($SetCookie{'expire'} eq "1") {
                        $cookie .= ";expires=Fri, 08-Sep-2010 19:48:23 GMT";
                } else {
                        $cookie .= ";";
                }
################## 끝.
                if ($HttpCharset ne '') {
...
}


#### DoEnterLogin으로부터 받은 값을 해쉬에 추가. (약간 삐리리한.. -_-;)
sub DoLogin {
        my $expire_mode; # 추가
....
        $expire_mode = &UpdatePrefCheckbox("p_expire"); # 추가

                        ################# 밑에서부터 여기까지.
                        if ($expire_mode eq "") {
                                $SetCookie{'expire'} = 1;
                        } else {
                                $SetCookie{'expire'} = $expire_mode if ($expire_mode ne "");
                        }
                        #### ↓이것들의 바로위에 ↑ 이것들 추가.(crypt함수 수정으로 인해 원문을 모름.)
                        $SetCookie{'id'} = $uid;
                        $SetCookie{'randkey'} = $UserData{'randkey'};
                        $SetCookie{'rev'} = 1;
....
}

#### 로긴창에 체크박스 폼 집어넣음.
sub DoEnterLogin {
....
        print "<br>", &GetFormCheck('p_expire', 0, T('Keep login information')); ## 추가한다.

        print '<br>', $q->submit(-name=>'Login', -value=>T('Login')), "\n";
        print "<hr>\n";
....
}
겜방에서 컴터를 많이 쓴다는 누군가의 협박(?)으로 대충 만들어 봤는데, 어떨지 모르겠네요. 여전히 펄이나 웹이나 그런건 암것도 몰라서 ㅜㅡ; 좋은 하루 되세요.. ^^
-- Bab2 2003-1-4 4:11 am

반영했습니다. 완료.

-- Raymundo 2003-2-11 5:35 pm

8. 새로생긴 페이지에 NEW 마크 표시

....
sub GetRcHtml {
                if ($UseDiff && &GetParam("diffrclink", 1)) {
                        $link .= &ScriptLinkDiff(4, $pagename, $tDiff, "") . "  ";
                }
#### 수정한다.
                if ($pagecount{$pagename} eq 1) {
                        $link .= &GetPageLink($pagename)." <small>(<font color=red>" . &T('NEW') . "</font>)</small>";
                } else {
                        $link .= &GetPageLink($pagename);
                }
#### 끝.
                $html .= "<tr><td style=\"border:0\">&nbsp;&nbsp;</td><td style=\"border:0\"><li>$link $sum</td>"
....
}
굳이 필요할까라는 의문이 듭니다만..;;
-- Bab2 2002-12-22 4:55 am

적어주신 것이.. new 마크가 제목 뒤에 붙더군요. 다른 페이지들의 "~번 변경됨" 자리에 있는 게 더 나아보여서 조금 다르게 적용했습니다만... 정말 필요가 없어 보이는데요. :-) 어쨌거나 완료.

-- Raymundo 2003-2-11 6:40 pm

9. RemoteWiki

특정위키사이트의 인덱스목록을 받아와서 지정한 값과 일치하는 제목이 있으면 그 사이트의 해당페이지로 링크를 만들어줍니다.
* 페이지 목록을 받아오는 액션은 wiki.pl?action=remotepage 이며 현재 plain/text만 가능

NoSmok http://no-smok.net /ns/moin.cgi?action=titleindex

이런, 제가 그것 때문에 몇 번이나 삽질을 했으면서도 알아채질 못했군요. ^^ 그래서 RemoveLink 라는 함수를 만들어놨습니다. RemoveLink($string) 하면 a href 태그 등을 떼어내고 원래 문자열을 반환해 줄 겁니다. - raymundo
우헐헐헐~ 고맙습니다. 이제 대충 쓸만해졌네요.
-- Bab2 2002-12-10 11:47 pm

#config.pl 에 추가해야할 내용
$RemoteDir   = "$DataDir/remotewiki"; # 원격위키의 타이틀인덱스가 저장될 장소.
$UseRemoteWiki = 1; #1 원격 활성 2 비활성
$RemoteFile = "remotemap"; # 원격위키 타이틀인덱스 경로
#### 끝.

# wiki.pl에 추가할 내용.
#### 변수추가.
use vars qw(@RcDays @HtmlPairs @HtmlSingle
....
$RemoteFile $UseRemoteWiki $RemoteDir ### 추가
....
#### 해당페이지의 쌍둥이페이지가 있고, $UseRemoteWiki=1일때 페이지하단에 쌍둥이페이지 링크를 무조건 출력한다. KLE의 RemoteWiki 설명 참고.
sub BrowsePage {
....
        #### 추가
        if ($UseRemoteWiki eq 1) {
                $oldId = $id if($oldId eq "");
                $fullHtml .= &WikiToHTML("<br><br><hr>\nSee Also: <metasearch($oldId)>");
                ## REDIRECT매크로 사용시 리다이렉트된 페이지가 아닌 원래페이지의 목록을 보여줌.
        }
        #### 끝.
        $fullHtml .= &GetFooterText($id, $goodRevision);
        print $fullHtml;
        return  if ($showDiff || ($revision ne ''));  # Don't cache special version
....
}
....
#### <metasearch()> 매크로
sub MacroSubst {
....
        $txt =~ s/\&__LT__;metasearch\(([^\n]+)\)\&__GT__;/&MacroMetaSearch($1)/gei; #### 추가.
....
}

#### 전체추가
#### 원격사이트 페이지목록을 소켓으로 긁어온다.
sub GetUrlSocket {
        use IO::Socket;
        my($url, $addr) = @_;
        my (@data, $result);
        my $sock;

        $sock = IO::Socket::INET->new(PeerAddr=>$url, Proto=>'tcp', PeerPort=>'80');
        print $sock "GET ". $addr . "\n\n";

        @data = <$sock>;

        $result = join ($FS,@data);
        $result =~ s/(\n|\r)//g;

        close($sock);

        return $result;
}

#### 긁어온 목록을 정리해서 화일로 저장한다.
sub GetRemotePage{
        my (@all, $data, $status, $count, $result);

        ($status, $data) = &ReadFile($RemoteFile);
        return ""  if (!$status);
        @all = split(/\s+/, $data);

        &CreateDir($RemoteDir);

        for ($count=1;$count<1+(@all/3);$count++) {
                open (remotewiki, ">"."$RemoteDir"."/"."$all[3*$count-3]".".db");

                @all[3*$count-2] =~ s/http\:\/\/(.*)/$1/g;
                ##### 0은 이름 1(3count-2)은 주소 2(3count-1)는 실행경로 #####
                $result = &GetUrlSocket(@all[3*$count-2], @all[3*$count-1]);

                print remotewiki $FS.$result;

                close (remotewiki);
        }

        print &GetHeader('', T('Get RemotePages'), "");
        print "<br>Getting RemoteWiki pages done.<br>";
        print &ScriptLink("처음", T('<br>첫화면으로..<br>'));
        print "<hr>\n";
        print $q->endform;
        print &GetMinimumFooter();

        return "";
}

#### 페이지 이름과 일치하는 원격사이트 목록을 출력한다.
sub MacroMetaSearch {
        my ($name) = @_;
        my (@remotename, @all, $data, $status, $count, $remotedata);
        my $page;
        my $result = "";

        $name = &RemoveLink($name);
        ($status, $data) = &ReadFile($RemoteFile);
        return ""  if (!$status);
        @all = split(/\s+/, $data);

        for ($count=1;$count<1+(@all/3);$count++) {
                @all[3*$count-2] =~ s/http\:\/\/(.*)/$1/g;
                ##### 0은 이름 1(3count-2)은 주소 2(3count-1)는 실행경로 #####
                open (getdb, ($RemoteDir."/".@all[3*$count-3].".db"));
                $remotedata = <getdb>;
                if ($remotedata =~ /$FS($name)$FS/i) {
                        $result .= &StoreInterPage("@all[3*$count-3]\:$1")." ";
                }
                close (getdb);
        }
        return $result;
}
#### 끝.
....
#### 원격사이트로부터 타이틀인덱스를 받는 action 추가
sub DoOtherRequest {
....
                } elsif ($action eq "titleindex") {
                        DoTitleIndex();
                #### 추가.
                } elsif ($action eq "remotepage") {
                        &GetRemotePage();
                #### 끝.
                } elsif ($action eq "help") {                           # luke added
                        &DoHelp();
....
}
....
sub GetPageOrEditAnchoredLink {
        my ($id, $anchor, $name) = @_;
        my (@temp, $exists);
        my $intername;  #### 추가.
        ....
        if ($exists) {
                $id = "$id#$anchor" if $anchor;
                $name = "$name#$anchor" if $anchor && $NamedAnchors != 2;
                return &GetPageLinkText($id, $name);
        #### 추가한다.
        } elsif (($UseRemoteWiki) && (!$LinkFirstChar) && ($Section{'revision'} > 0)) {
                $intername = &MacroMetaSearch($id);
                $intername =~ s/\s+(.*)//g;
                return $intername." ".&GetPageLinkText($id,"?") if ($intername ne "Nothing.");
        }
        #### 끝.
        if ($FreeLinks) {
....
}

어딜 찾아봐도 구체적으로 어떻게 구현했다는 말이 없으니...원..
그럭저럭 돌아갈겁니다. 노스모크의 "-_-" <- 이 링크가 안되는 문제가 있는데 이것은 StoreInterPage 함수의 문제이기 때문에 어쩔 수 없습니다.
(라기 보단 손대기 귀찮죠 -_-;;)
본문의 리모트 페이지는 우선순위가 제일 높은 한페이지만 표시하게 했습니다.
cron 대몬을 써서 자동으로 갱신시키고자 한다면. GetUrlSocket함수와 GetRemotePage를 별도의 화일로 만들어서 하루에 한 번 정도 갱신시켜주면 될 것입니다.
그 외에는 메뉴에 링크를 걸어서 직접 고쳐주는 수밖에 없죠. --;
WikiX스타일 링크는 적용이 안되는데 그건 wikix스타일을 쓰는 다른분이 해결좀 해주셨음 좋겠군요..
다른 문제는 모두 해결했습니다. (꽁수로 --;)
진짜로 끝냈다 만세~

각 페이지의 이름배열을 foreach문으로 변수하나하나에 나누어 검사하는 것을 화일(사이트) 한개마다 양쪽에 둘러쳐진 $FS변수 단위로 짤라서 한번에 검사하도록 수정했습니다. 이제 적용해도 괜찮을겁니다. WikiX는 스타일은 도저히 수가 안나서 포기했습니다. ^^;;

-- Bab2 2002-12-12 3:53 am


내일은 시험치는 과목이 없어서 그나마 다행입니다. 좋은 하루 되세요. :)
-- Bab2 2002-12-10 5:04 am

그럴 리가요? 문자열은 eq 로 비교하면 정확히 잡아내던데요. "abc" eq "abcd" 로 했을 때 true 가 되더라는 말씀인가요? 제 홈페이지가 있는 서버에서는 잘 되던데요. 혹시 perl 버전에 따른 버그일지도.. 설마...
-- Raymundo 2002-12-10 8:33 am
펄 버전 5.6.1(근영님 쓰시는 버전이 몇이신지..?)에서 테스트 해봤습니다. 결과는 마찬가지..-_-;;
-- Bab2 2002-12-10 3:00 pm
5.6.0 입니다. 문제가 되는 코드가 어떤 것인지 모르겠습니다만,
#!/usr/bin/perl
$string1 = "abc";
$string2 = "abcd";

if ($string1 eq $string2) {
    print "yes!\n";
} else {
    print "no!\n";
}
의 결과가 어떻게 되나요?
흐미~ No요. 이건 잘되네 -_-;
-- Bab2 2002-12-10 4:22 pm

UseModWiki소스수정/RemoteWiki 에 이동했습니다. 완료.

-- Raymundo 2003-2-20 9:51 am

10. 편집된 페이지의 처음이 빈 줄일 경우

저장할때마다 한 줄씩 사라져 버립니다. 물론 제일 위쪽의 빈 줄들에 한해서만 그렇습니다. 또 봐바야될듯..ㅜㅡ
-- Bab2 2002-11-25 8:41 pm

사는 데 지장없는 문제로 판단함. 완료. :-)

-- Raymundo 2003-2-26 10:55 am


위키위키분류

마지막 편집일: 2007-1-8 12:19 pm (변경사항 [d])
605 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기