근본적인 문제는 UseMod 위키가 각 페이지의 처음을 대문자만 사용하도록 지정해놨다는 것이더군요.
FreeToNormal 이라는 함수에서 ucfirst라는 함수를 돌리는데, 이 함수가 단어의 첫번째 글자를 대문자로 바꿔주는 함수입니다.
그리고 DoUpdatePrefs 함수에서 FreeToNormal 함수를 호출하면서 아이디의 첫 글자가 대문자로 바뀌는 것이죠.
실제로는 아이디를 가지고 페이지를 만들 수도 있고, RecentChanges에서 아이디에 링크도 걸리기 때문에,
그 부분을 함부로 수정했다가는 어떤 부작용이 생길지 짐작하기가 힘드네요.
지양 - 환경 설정에서만이라면..
어찌어찌 했더니 소문자로 시작하는 아이디라도 소문자 화일명으로 제대로 생성됩니다. 로그인도 소문자로 시작하는 아이디로 당연히 되지요. 다만 최근변경내역이나 환경설정에서는 여전히 대문자로 시작하는 아이디가 나와버리긴 합니다. 사용자가 좀 헷갈릴 수는 있어도 저는 그냥 이러고 쓰고 있습니다.
DoUpdatePref 에서
$UserID = &GetParam("p_username", "");이것을
$UserID = &GetParam('id', ""); if ( $UserID eq '' ) { $UserID = &GetParam("p_username", ""); }이것으로 고치면 화일을 만들 때 username 이 아니라 id 대로 만들겠지요.
예제 부분을 각각
<pre> || first || second || third || |||| span four || five || </pre>
<pre> TABLE: bgcolor=yellow cellspacing=5 border=1 width=90% align=center || first || second || third || |||| span four || five || </pre>
이렇게 고쳐주는게 좋을 것 같습니다. (원래는 pre가 아니라 nowiki 로 되어있습니다)
sub DoPreview { my $textPreview; $ClickEdit = 0; print &GetHttpHeader(); print &GetHtmlHeader("$SiteName: Preview", "Preview"); $textPreview = &GetParam("text", undef); print &WikiToHTML(&ProcessPostMacro($textPreview)); } sub ProcessPostMacro { my ($string) = @_; my $authorAddr = $ENV{REMOTE_ADDR}; my ($timestamp) = CalcDay($Now) . " " . CalcTime($Now); ... return $string; } sub DoPost { ... # Remove "\r"-s (0x0d) from the string $string =~ s/\r//g; # Post Macro $string = &ProcessPostMacro($string); # Lock before getting old page to prevent races &RequestLock() or die(T('Could not get editing lock')); ... }이런 식으로 수정해봤더니 일단 되는 것 같네요.
그리고... 쓸 때 <mysign> 이라고 쓰면 저장할 때는 바로 저장하는게 아니라 <mysign(네임,시간)> 이런 식으로 저장한 다음에, 화면 출력할 때 실제 html로 바꿀 수는 없을까요? 중간에 mysign에 대한 포맷을 전부 변경하고 싶어질 때를 대비할 수 있는 방법이 아닐까 생각합니다.
(모인모인은 잘 모르겠고 phpwiki에서는 테이블 내부정렬을 |> |< 이것을 사용합니다.)
-- Bab2 2002-11-19 6:34 pm
sub WikiLinesToHtml { ..(중간생략).. while (@htmlStack < $depth) { push(@htmlStack, $code); if ($code eq "TABLE") { # added luke $pageHtml .= "<TABLE $TableTag>\n"; <- 요걸 $pageHtml .= "<TABLE $TableTag border='1'>\n"; <- 요렇게 } else { $pageHtml .= "<$code>\n"; }; ..(이하생략)..
sub GetMinimumFooter { my $result = ''; ##추가 if ($FooterNote ne '') { # return T($FooterNote) . $q->end_html; # Allow local translations $result .= T($FooterNote) . $q->end_html; # Allow local translations ##변경 } #################################################### ### replaced by gypark ### page 마지막에 top 으로 가는 링크를 추가 # return $q->end_html; # return "\n<div align=\"right\"><a accesskey=\"x\" name=\"#PAGE_BOTTOM\" href=\"#PAGE_TOP\">" . T('Top') . "</a></div>\n" . $q->end_html; $result .= "\n<div align=\"right\"><a accesskey=\"x\" name=\"#PAGE_BOTTOM\" href=\"#PAGE_TOP\">" . T('Top') . "</a></div><br>\n" . $q->end_html; ##변경 -> <br> 안붙여주면 FooterNote내용과 섞여버림. return $result; ### #################################################### }
$FooterNote="<p align='right'><img src='이미지경로'></p>";
뭔가 특별한 이유가 없으면 고쳐볼까 생각중입니다. -Gravi
## 사용자암호 수정 sub DoUpdatePrefs { my ($username, $password); my $hashpass = ""; #### 추가한다. .... $password = &GetParam("p_password", ""); $hashpass = crypt($password, "salt"); #### 추가한다. if ($password eq "") { print T('Password removed.'), '<br>'; undef $UserData{'password'}; } elsif ($password ne "*") { print T('Password changed.'), '<br>'; # $UserData{'password'} = $password; #### 이것을 ↓ $UserData{'password'} = $hashpass; #### 이것으로 바꾼다. .... } .... } elsif ($password ne "*") { print T('Administrator password changed.'), '<br>'; # $UserData{'adminpw'} = $password; #### 이것을 ↓ $UserData{'adminpw'} = $hashpass; #### 이것으로 바꾼다. .... } sub DoLogin { my ($uid, $password, $success); my $hashpass = ""; $password = &GetParam("p_password", ""); $hashpass = crypt($password, "salt"); #### 추가한다. if (($password ne "") && ($password ne "*")) { $UserID = $uid; &LoadUserData(); # if (defined($UserData{'password'}) && ($UserData{'password'} eq $password)) { #이것을 if (defined($UserData{'password'}) && ($UserData{'password'} eq $hashpass)) { #이것으로 바꾼다 ....
## 관리자암호 수정 sub UserIsAdmin { my (@pwlist, $userPassword); my $hashadmin = crypt($AdminPass,"salt"); #### 추가한다. ..... ########## #이것을 ---> # foreach (split(/\s+/, $AdminPass)) { #이것으로 바꾼다. ---> foreach (split(/\s+/, $hashadmin)) { ########## ..... } sub UserIsEditor { my (@pwlist, $userPassword); my $hashadmin = crypt($EditPass,"salt"); #### 추가한다. ..... ########## #이것을 ---> # foreach (split(/\s+/, $EditPass)) { #이것으로 바꾼다. ---> foreach (split(/\s+/, $hashadmin)) { ########## ..... }
그럭저럭 달력 매크로를 만들었습니다. Perl 의 날짜처리 함수의 한계 때문에 1902년 정도에서 2037 년까지만 안전하게 출력할 수 있습니다. 그 이상의 범위에서는 에러가 나던가, 엉뚱한 달력이 출력됩니다. 사실 1902년의 달력도 정확한지 확인해본건 아니지만... /TestCalendar 에서 페이지소스와 출력결과를 볼 수 있습니다.
로그아웃할때 화면상에 로그아웃했다는 메세지가 뜨면서 메뉴항목은 로그인으로 다시 바껴야 하는데 로그아웃으로 그대로 남아있습니다. 아래와 같이 하면 일단 로그아웃할때 메뉴이름도 "로그인"으로 바로 바뀝니다. 꽁수이긴 합니다만은...
sub GetGotoBar { ....(중간생략) # if (($UserID eq "113") || ($UserID eq "112")) { if (($UserID eq "113") || ($UserID eq "112") || ($UserID eq "")) { # "",그니깐 NULL 추가 $bartext .= ' </td><td bgcolor=white> ' . &ScriptLink("action=login", T('Login')); } else { $bartext .= ' </td><td bgcolor=white> ' . &ScriptLink("action=logout", T('Logout')); } ....(이하생략) } sub DoLogout { ## 이하 주석(#)처리된 구문은 원래코드이며, 통째로 갈아치운다. <--- 함수내용을 통째로 바꾼다. ---> # my ($uid); ## 사실은 저도 몰라여-_-;; 판단 기준을 $UserID = NULL (or) not NULL 로 뒀음. # $SetCookie{'id'} = ""; # $SetCookie{'randkey'} = $UserData{'randkey'}; # $SetCookie{'rev'} = 1; # print &GetHeader('', T('Logout Results'), ''); # if (($UserID ne "113") && ($UserID ne "112")) { # print Ts('Logout for user ID %s complete.', $UserID); # print &ScriptLink("처음", T('<br>첫화면으로..<br>')); # print "<hr>\n"; # %UserCookie = %SetCookie; # $UserID = ""; # #print &GetGotoBar(''); # print $q->endform; # print &GetMinimumFooter(); my ($uid); $uid = ""; $UserID = $uid; &LoadUserData(); $SetCookie{'id'} = ""; print &GetHeader('', T('로그아웃'), ''); print Ts('로그아웃 하였습니다.<br>'); print &ScriptLink("처음", T('첫화면으로..<br>')); %UserCookie = ""; print "<hr>\n"; print $q->endform; print &GetMinimumFooter(); <--- 여기까지 함수내용을 통째로 바꾼다. ---> }
어차피 3글자 이하는 잘 쓰지 않는다는 생각에 저는 영문 4글자 이상으로 아이디 제한을 둬서 쓰고 있습니다. sub DoUpdatePrefs { .... # if ($username eq "") { ## 위와 같은 이유로 이 부분은 일단 주석처리 해버린다. db화일이 지워지지도 않았던 것 같다. # print T('UserName removed.'), '<br>'; # undef $UserData{'username'}; # } elsif ((!$FreeLinks) && (!($username =~ /^$LinkPattern$/))) { <--- 추가 ---> if (length($username) < 4) { # Too long print T('사용자명은 영문 3글자 이상, 한글 2글자 이상이어야 함. 저장하지 않음.'), "<br>\n"; $UserID = 0; print "<br><br>".&ScriptLink("action=editprefs", T('다시신청')); return; <--- 추가 ---> } elsif ((!$FreeLinks) && (!($username =~ /^$LinkPattern$/))) { print Ts('Invalid UserName %s: not saved.', $username), "<br>\n"; .... } 근데 sub DoUpdatePrefs()를 보시면 아이디를 50자이하로 제한하게끔 한 IF 구문을 볼 수 있을 것입니다. 위의 것을 추가하지 않고 # } elsif (length($username) > 50) { # Too long <-- 이것을 } elsif (length($username) > 50 || length($username) <4) { # Too long <-- 이렇게 해도 됩니다.
sub dologin { (중간생략)... $success = 1; } else { $SetCookie{'id'} = ""; $UserID = ""; ### 추가한다. &LoadUserData(); ### 추가한다. } (이하생략)... }
현재 UseModWiki 내에 존재하지 않는 페이지에 대해서는 TestPageTest 페이지 이름 다음에 ? 가 나와서 그 ?를 누르면 새 페이지를 만드는 형식으로 되어 있습니다. 이걸 wikiX 에서 사용하는 방식처럼 첫 문자에 Link를 거는 방식으로 바꾸는게 어떨까요?
페이지를 보다가 마우스로 긁어서 다른데로 옮기는 경우에 지금의 방식은 ? 가 나와서 상당히 귀찮더군요.
Bab2 님이 발견한 문제를 살펴보다가 깨달은 것인데, 모든 매크로가 문제를 안고 있습니다.
(줄앞에 공백이 하나 이상)<매크로>위와 같이 작성할 경우, 일단 매크로가 동작하여 출력물로 치환된 후에, 저 줄 앞에 공백 때문에 치환된 결과의 첫번째 라인만 다시 pre 태그가 붙어 버립니다. 캘린더의 경우 제가 html 출력물이 보기 좋으라고 주요 태그마다 \n 으로 줄바꿈을 시켜놨더니만, 결과적으로 다음과 같이 된 거죠.
(공백)<calendar()> 요것이 변환되어 <pre> (공백이그대로남아있음)<table> </pre> <tr> ... </table>즉 첫번째 table 태그만 pre 로 둘러쌓이는 겁니다. 이 문제는 모든 매크로에 동일하게 적용됩니다.
문제의 원인은, 매크로를 부르는 {{{
$_ = &MacroSubst($_); # Luke added}}} 이 라인은 CommonMarkup 함수 안에 있습니다. 그런데 제가 {{{ }}} 태그를 만들기 위해서, WikiToHTML 함수내에서 CommonMarkup 과 WikiLinesToHtml 함수의 순서를 바꾸었습니다. 그래서 매크로 치환 이후에 WikiLinesToHTML 이 불리면서 저 pre 치환을 이뤄버립니다.
매크로를 부르는 라인은 Luke 님이 넣은 것 같네요. 저 주석문을 보니... Luke 님의 K3 에서는 WikiLinesToHtml 이 먼저 불리고 그 다음에 CommonMarkup 이 불리게 되어 있기 때문에 그 때는 이런 문제는 없었을 겁니다. (하지만 직관적으로 봤을때 전체 마크업이 먼저고 라인 마크업이 나중에 오는 게 합당하다고 생각합니다. 또한 오리지날 UseModWiki 소스에서도 CommonMarkup 이 먼저 불리게 되어 있습니다)
그렇다면 문제의 해결을 위해서는... 저 MacroSubst 호출 루틴을 CommonMarkup 함수 내가 아니라, WikiLinesToHTML 에 넣던가, 아니면 한 단계 위로 빼내어 두 함수를 차례대로 부르는 WikiToHTML 에 넣는 것을 생각해볼 수 있겠는데, 이게 어떤 부작용을 만들지 상상조차 되지 않는터라... ^^; 테스트하는데 시간이 좀 걸리겠습니다. 다른 분들도 소스를 들여다보며 같이 고민 좀 해주시면 고맙겠죠. :-)
음.. 상위 단계인 WikiToHTML 로 뺐더니만, 이번에는 nowiki 태그 안에 매크로가 있을 경우 기존에는 그대로 출력되던 것이 이제는 죄다 매크로 변환이 되어 버리는군요. 딜레마에 빠지네.. 어찌하나..
"아무리 봐도 대책없음. 매크로를 사용하는 사용자가 주의해야 함. 매크로를 만드는 경우 출력에 newline 이 들어가지 않도록 주의해야 함" 으로 결론짓고 /반영된사용자의견으로 이동.