Thread 매크로
/LongComments매크로의 확장판. 게시판이나 토론 페이지 등 글이 쓰레드모드로 달리는 경우, 페이지를 직접 수정하는 것에 익숙하지 않은 사람들이 편하게 글을 새로 올리거나 기존 글에 답글을 달 수 있게 하는 것이 목적.
아이디어는 UseModWiki소스수정/Threads에서 시작되었고, 실제 디자인과 구현은 좀 다르다. 사용자 의견에 자세히 썼으니 참조할 것.
- 필수 요구 사항:
- 선택 요구 사항:
- /매크로모듈화가 된 상태를 기준으로 소스를 작성했음. 모듈화가 되어 있지 않은 버전을 쓰는 경우는 wiki.pl 안에 직접 추가해 줄 것.
- 사용법: <thread(숫자)>
- 원래는 "<thread(페이지이름,숫자)>"였는데, ext1.89 이후 바뀌었음. /Comments와Thread매크로개선
- 숫자는 /Comments매크로에서와 동일
- 숫자가 양수냐 음수냐에 따라 동작이 달라진다
- 숫자가 양수일 경우는 새글이 입력창 위쪽에, 최근글이 아래 오는 순서로 달린다.
- 숫자가 음수일 경우는 새글이 입력창 아래쪽에, 최근글이 위에 오는 순서로 달린다.
- 숫자의 범위에 따라 페이지 수정 권한의 적용이 달라진다.
- 숫자의 절대값이 100 보다 작을 경우는, 페이지 수정 권한이 없는 경우는 코멘트창에 아예 입력을 할 수 없다.
- 100 이상일 경우는, 수정 권한에 관계 없이 코멘트를 달 수 있다. (심지어 관리자가 잠근 페이지의 경우도 코멘트를 달 수 있다) 따라서 페이지 수정은 금지하고 코멘트 입력창을 이용하여 댓글만 달 수 있게 할 경우는 이 숫자를 100 이상으로 주면 된다.
- 단점: 한 글에 대한 답글들은 최근 글이 위에 오게 달린다. 즉,
원글-+
+- 답글3 <= 답글1, 답글2, 답글3의 순서대로 작성되었을 때 답글3이 제일 위에 옴
+- 답글2 -+
| +- 답글2의 답글2
| +- 답글2의 답글1
+- 답글1
- 즉 일반적으로 페이지 수정을 통해서 다는 순서와 반대라서 혼동의 여지가 있는데, 이것은 도저히 어찌할 수 없었음. 누군가 심플한 해결책을 제시해 주길.
- 편법으로, /사용자추가매크로에 있는 mysign 매크로를 추가하면 새로 달린 글의 서명 옆에 "NEW"또는 "Today"표시가 달리므로 새로 올라온 글을 그나마 쉽게 알아볼 수 있다.
wiki.pl 수정
sub MacroComments {
my ($itself,$id,$up,$long,$threadindent) = @_;
my $idvalue;
my $temp;
my $txt;
my $abs_up = abs($up);
my ($threshold1, $threshold2) = (100000000, 1000000000);
...
if ($long) {
$hidden_long = &GetHiddenValue("long","1") . "<br>";
}
if (((!&UserCanEdit($id,1)) && (($abs_up < 100) || ($abs_up > $threshold2))) || (&UserIsBanned())) {
...
$txt =
$q->startform(-name=>"comments",-method=>"POST",-action=>"$ScriptName") .
&GetHiddenValue("action","comments") .
&GetHiddenValue("id","$id") .
&GetHiddenValue("pageid","$pageid") .
&GetHiddenValue("up","$up") .
(($threadindent ne '')?&GetHiddenValue("threadindent",$threadindent):"") .
T('Name') . ": " .
$name_field . " " .
T('Comment') . ": " .
$hidden_long .
$comment_field . " " .
$submit_button .
$q->endform;
if ($threadindent ne '') {
if ($threadindent >= 1) {
my $memotitle = ($threadindent == 0)?T('Write New Thread'):T('Write Comment');
$txt = &MacroMemo("", $memotitle, $txt, "threadmemo");
} else {
$txt = T('Write New Thread') . $txt;
}
}
return $txt;
}
sub DoComments {
...
my $string;
my $long = &GetParam("long", "");
my $threadindent = &GetParam("threadindent", "");
my $abs_up = abs($up);
my ($threshold1, $threshold2) = (100000000, 1000000000);
if ($newcomments =~ /^\s*$/) {
...
if ($threadindent ne '') {
$newcomments =~ s/^\s*//g;
$newcomments =~ s/\s*$//g;
$newcomments =~ s/(\n)\s*(\r?\n)/$1$2/g;
$newcomments =~ s/(\r?\n)/ \\\\$1/g;
my ($comment_head, $comment_tail) = ("", "");
my $newup;
if (($abs_up >= 100) && ($abs_up <= $threshold2)) {
$newup = $Now - $threshold2;
} else {
$newup = $Now;
}
$comment_tail = "<thread($id,$newup," . ($threadindent+1) . ")>";
if ($threadindent >= 1) {
for (1 .. $threadindent) {
$comment_head .= ":";
}
$comment_head .= " ";
} else {
$comment_head = "<thread>\n";
$comment_tail .= "\n</thread>";
}
if (($up > 0) && ($up < $threshold1)) {
$string =~ s/(\<thread\($id,$up(,\d+)?\)\>)/$comment_head$newcomments <mysign($name,$timestamp)>\n$comment_tail\n\n$1/;
} else {
$string =~ s/(\<thread\($id,$up(,\d+)?\)\>)/$1\n\n$comment_head$newcomments <mysign($name,$timestamp)>\n$comment_tail/;
}
} elsif ($long) {
$newcomments =~ s/^\s*//g;
$newcomments =~ s/\s*$//g;
...
if (((!&UserCanEdit($id,1)) && (($abs_up < 100) || ($abs_up > $threshold2))) || (&UserIsBanned())) {
$pageid = "";
}
DoPostMain($string, $id, "*", $Section{'ts'}, 0, 0, $pageid);
return;
}
macros/thread.pl 추가
/매크로모듈화가 되어 있지 않은 버전이라면 아래 매크로를 기존의 방식으로 wiki.pl에 직접 추가해 준다.
$MacroFunc{"thread"} = \&thread;
sub thread {
my ($txt) = @_;
$txt =~ s/(&__LT__;thread\(([^,]+),([-+]?\d+),(\d+)\)&__GT__;)/&MacroThread($1,$2,$3,1,$4)/gei;
$txt =~ s/(&__LT__;thread\(([^,]+),([-+]?\d+)\)&__GT__;)/&MacroThread($1,$2,$3,1,0)/gei;
$txt =~ s/(&__LT__;thread&__GT__;((.)*?)&__LT__;\/thread&__GT__;)/&MacroThreadBlock($2)/geis;
return $txt;
}
sub MacroThread {
my ($itself, $id, $up, $long, $threadindent) = @_;
my $txt;
if ($threadindent > 0) {
my $marginleft = 0;
$marginleft = 3.3*($threadindent-1) if ($threadindent > 0);
$txt = "<DIV class='threadreply' style='margin-left: $marginleft"."em'>";
} else {
$txt = "<DIV class='threadnew'>";
}
$txt .= &MacroComments($itself, $id, $up, $long, $threadindent)."</DIV>";
return $txt;
}
sub MacroThreadBlock {
my ($blocktext) = @_;
my $txt;
$txt = "<DIV class='threaditem'>" . $blocktext . "</DIV>";
return $txt;
}
1;
translations/korean.pl 수정
아래 두 번역 항목 추가
Write New Thread
새 글 쓰기
Write Comment
위 글에 의견달기
wiki.css 수정
아래 항목들을 입맛대로 고쳐서 추가
/* thread */
/* 새 글 쓰기 박스 */
DIV.threadnew {
background-color:#F8F8F8;
border: 1px solid gray;
padding: 5px 5px 5px 5px;
}
/* 답글 달기 박스 */
DIV.threadreply {
border-bottom: 1px dashed gray;
padding: 1px 1px 1px 1px;
}
/* 답글 달기를 클릭했을 때 열리는 내부 박스 */
DIV.threadmemo {
border:1px solid silver;
padding-left:5px;
}
/* 하나의 쓰레드 블럭 (새 글 하나와 그에 딸린 답글들) */
DIV.threaditem {
border-left: 2px solid #888888;
padding: 5px;
}
/* "위 의견에 답글 달기" 링크 */
A.threadmemo:link, A.threadmemo:active, A.threadmemo:visited, A.threadmemo:hover {
background: transparent;
color: gray;
text-decoration: none;
}
A.threadmemo:hover
{
text-decoration: underline;
}
추가 업데이트 내역
ext1.89 - /Comments와Thread매크로개선을 위해 수정되었읍니다. /Comments와Thread매크로개선페이지에서 참조하세요.
ext1.92 - 리플을 시간순으로 삽입, 나중에 달린 리플이 더 아래에 달리게 하였습니다. 또한, 리플을 달고 화면이 갱신되었을 때 자신이 단 리플을 바로 볼 수 있도록 URL에 앵커를 붙이게 하였습니다. 따로 수정내역을 위에 적지는 않으니 아래 두 파일을 보도록 하세요
사용자 의견
이 매크로의 모티브(?)는 UseModWiki소스수정/Threads에서 왔습니다만, 실제로 구현하는데 디자인이나 접근 방법이 사뭇 다릅니다. 여기서 구현한 방식은 아래와 같은 의도로 만들어졌습니다.
- 조프위키의 구현을 따르려면 완전히 별도의 매크로와 액션을 추가해야 하는데, 이 상태에서 "홈페이지 수정권한에 따른 코멘트입력가능 여부"등의 코드를 추가하자니 동일한 코드가 너무 많이 겹치게 되어서, 어떻게든 기존의 /Comments매크로의 코드를 쓰려고 했음.
- 애초의 이 매크로의 모티브가 직접 페이지 수정을 하지 않고도 편하게(위키에 익숙하지 않은 사람들 입장에서) 답글을 달 수 있게 하는 것이라면, 쓰레드 중간에 답글을 삽입하더라도 페이지 수정을 할 필요 없게 각 답글마다 그 답글에 다시 답글을 달 수 있게 했음.
그래서 매크로 이름(thread)도 조프위키에서 구현한 것(threads)과 겹치지 않게 지었습니다. 매크로 치환 후 생성되는 DIV의 클래스도 threaditem을 제외하면 겹치지 않으므로, 조프님 위키에 사용된 방식을 원할 경우는 그냥 그쪽에 있는 소스를 가져다 쓰면 됩니다. :-) 테스트해 보지는 않았지만, 아마 ext버전에 그대로 가져가 써도 문제는 없어 보입니다. 다만 커멘트를 달 수 있는 권한 처리 같은 것이 되어 있지 않아서, 페이지 권한이 없는 사용자의 경우 아마 입력폼에 쓸 수는 있지만 달기 버튼을 누르면 저장이 안 될 겁니다.
가로선 넣어달라고 한건 접니다만, 조프처럼 새로선으로 하는 것이 더 보기 좋은 듯합니다.
또한, 답글의 경우는 가로선등으로 구분하지 말고 새 글에 대해서만 구분하는 것이 보기 좋을 듯 하네요.
- 그 세로선이 문제인데... 그러면 한 글타래의 시작과 끝을 알리는 태그가 별도로 필요합니다. 뭐 넣으려면 못 할 것은 없고... 그 점선을 안 쓰는 게 좋겠다는 말이라면, 긴 댓글이 서너개 달린 상태에서 점선 없이 보면 정말 각각의 글을 구분하기 힘들더군요.
세로선까지 넣어봤습니다. /ThreadTest에서 해 보시고 의견 주세요.
대만족하며 사용했습니다만, 불여우로 깔끔하게 나와서 별 문제없는 줄 알았는데 IE로 보니 선과 겹치고, 입력창도 좀 이상하게 나오더군요. 흑흑 div값을 조정해야 하는 듯 한데 어디를 건드려야 하는지 전혀 종잡을 수가..
- IE 버그라고 하니 대책이 없네요. div 의 padding 등을 제가 바꿔봤지만 별 무소득이었습니다. (제 홈에서 세로선을 빼 버린 이유가 달리 있는게 아니라.. ㅠ,.ㅠ)
- 그런것이었군요. 에휴. 그냥 IE사용자를 무시해야겠군요.
- 세로선 어떻게 빼요?
- 방법하나) 위에 보면 wiki.pl 소스에서 "# 새 글 앞뒤에 <thread>, </thread>라는 표식이 생기는 게 싫으면 이 두 줄을 주석처리"라고 되어 있는 곳의 두 줄을 주석처리하거나 없애 버리세요 (원초적 봉쇄)
방법둘) thread.pl 파일의 " $txt =~ s/(&__LT__;thread&__GT__;((.)*?)&__LT__;\/thread&__GT__;)/&MacroThreadBlock($2)/geis;" 이 줄에서 &MacroThreadBlock($2) 라는 문자열을 다 지워버려서 "...//geis"의 형태가 되게 하세요. (치환만 하지 않는 방법)
- 아우..막상 빼보니 세로선이 무척 아쉽네요. 흑흑 뭔가 방법이 없을려나..
- 조프위키 쪽의 구현을 가져가서 쓰세요. 제 코드와 딱히 충돌하지 않을테니 ext버전에 그냥 추가하셔도 됩니다.
thread 매크로의 단점인, "한 글의 리플들은 리플이 달린 역순으로 배치된다"를 극복할 방법을 찾았습니다. 매크로의 인터페이스를 바꿀 필요 없이 패치만 해 주면 이후 달리는 글들은 시간 순으로 배치가 될 텐데, 단점이라면 "내가 글을 입력한 자리(즉 원 글의 바로 아래)와 실제 답글이 달리는 자리가 달라지게 된다"겠군요. 아무리 그래도... 바꾸는 게 낫겠죠?
- 네.
- 역시? :-)
TestPage/Thread에서 테스트할 수 있습니다.
태그를 쓸수있는 옵션을 추가하는 건 어떨까요? 게시판처럼 html체크하면 태그도 사용가능하고, 체크 안하면 지금이랑 똑같은 방식으로..
- 음 그것도 괜찮겠군요. 고민해볼께요 ^^
http://me2day.net/yongyeol 얘네처럼 한 스레드에 앵커링크를 걸수있게하는 건 어떨까요?
- "한 스레드에 앵커링크를 걸 수 있다"는 게 무슨 뜻인지 저 사이트를 보면서도 모르겠습니다, 자세히 설명해 주시길 부탁드릴께요~
- 아.. 제가 좀 너무 뜸금 없었군요. 위 미투제이 가보시면 링크 등 간단한 포스팅의 퍼머링크가 모두 각각 있습니다. (날짜 부분을 누르면 됩니다.) 근데, 그 퍼머링크가 날자 + 시간으로 된 앵커링크를 이용해서 이루어져 있더군요. 스레드애서 논의되는 내용을 메신저 등으로 남에게 알릴때 스레드가 짧으면 상관없는데, 좀 길 경우 그 해당 스레드에 대해 앵커링크가 있으면 알려주기 편할 것 같다는 생각을 보면서 하게되어서 말씀드린겁니다.
- 아 네, 이해했습니다 :-) 근데 지금 스레드 매크로가 글 아래 위치하고 있는 이상, 매크로를 치환해서 앵커링크를 제공하더라도 죽어도 자기 위의 글로 가게는 못하고 기껏해야 의견달기 폼 위치로 이동할 것 같은데요. (아니면 mysign에다가 링크 출력을... 그건 좀 아니다 싶긴 한데)
- 그러게요..[누가 음반점을 죽였는가? - AppleForum] 애플포럼의 경우 제목 옆애 #을 달아서 링크를 표시하고 있군요. 근데 저건 또 해당 HTML페이지가 따로 있는 거라 약간 다른 경우고.. 스레드에 제목난이 따로 있는 것도 아니니 해당이 안되고.. 딱히 마땅한 방법이 떠오르진 않는군요..크흑.
- 그냥 어느정도 길어지면 H태그로 나눠서 앵커링크를 거는 것이 가장 현실적일 것 같기도 하는군요.
- 제 utf 테스트 위키인 /cgi-bin/utf/wiki.pl?횡설수설 에 가서 한 번 보세요. 근데 스레드가 두개 뿐이라서 별로 안 와닿을테고, /cgi-bin/utf/wiki.pl?횡설수설/2006 에 가서 "위 글에 의견달기" 왼쪽에 있는 #이 해당 스레드의 앵커입니다.
말씀드린 바와 같이, 그걸 누르면 "위 글의 의견달기"로 이동하기 때문에, 자기가 알려주고픈 글은 그 바로 위에 있어서 스크롤을 해야 하고, 바로 아래 있는 글과 혼동될 여지가 매우 커 보입니다만, 암튼 태그를 그 이상 위로 끌어올릴 방법을 모르겠습니다. :-D
스레드에 글을 적고 "달기" 버튼을 눌렀을 때, 아예 페이지에 저장하는 시점에 앵커를 삽입할 수는 있겠습니다. 즉 제가 지금 적고 있는 이 글 바로 앞에 또다른 매크로 내지는 [#번호]가 저장이 되는 거죠. 그걸 출력할 때 치환하면 편하겠습니다만, 솔직히 지금도 스레드 한번 저장할 때마다 <thread(.. 매크로가 늘어나서 페이지 편집 화면에 들어가면 정신이 없는 터라... 그런 걸 더 늘리고 싶지가 않습니다. :-)
그리고 수작업으로 걸어준다면야, 굳이 헤드라인을 넣을 필요 없이 (오히려 헤드라인에 의한 번호는 자기 앞에 몇개의 헤드라인이 있느냐에 따라 달라지니까 바뀌어 버리기 십상이고), [#여기] 이런 식으로 적어주시면 그 자리에 a name="여기" 태그가 출력됩니다.
그러면 사용자 의견의 Nyxity님 첫 글로 가기처럼 사용할 수 있겠지요.
- 수동 기능 괜찮네요. 몰랐어요.
참고로 주절주절에서는 진작부터 지원하고 있긴 합니다만, (HTML로 변환된 소스 보면 ti숫자~가 보입니다)
1. 있다는걸 알려주는 방법을 안 만들어놨다.
2. 한달 지나면 페이지가 바뀌니 딱히 활성화 시키고 싶지 않다.
는 두가지 문제가 있습니다.
- 커억, 그 ti숫자는 저도 봤었는데... 주절주절에 답글 달고 저장하면 자동으로 그 글로 이동하잖아요.. 그게 a name= 태그가 아니라 그냥 div 태그 안에 id 속성을 찾아서 가 주나 보네요???
그럼 굳이 <a name="숫자"></a> (부등호를 quote하지 않게 했더니만 이젠 반대로 꼬박꼬박 lt gt 써줘야 하는 불편이..) 를 삽입할 필요가 없이 아무 태그에나 id를 붙이면, URL에 #id 붙여서 갈 수 있는 건가 봐요?
- 에. 그건 사실 브라우저가 지원해야 하는 듯 하기도 합니다만, 그렇죠. id는 쓸수 있는 문자셋 제약이 있고, 한 문서내에서 유니크해야 한다는 제약 정도?
thread를 지우는 기능은 어떨까요? 여러 스레드중 지우고 싶은 것이 생겨도 내용이 많아질 경우 페이지 편집으로 찾아서 지우는 것이 꽤 번거로울 때가 있더군요.
- 음... 쓸때는 맘대로지만 지울 때는 아니라서, 지울 게 어느 부분인지를 표시할 방법이 없습니다. 어떤 일련번호를 포함한 표식을 각 쓰레드마다 넣는다고 해도, 페이지 내에 그 표시가 수동으로 적혀 있지 않다는 보장도 없고... 그래도 나쁘지 않은 생각이니 고민해볼게요.
최근에 보니까 스레드매크로가 하위로 내려가는 것이 잘 안되는 것 같아요.
:이런식으로 한 단계 아래까지는 잘 적용되는데,
:: 2단계부터 들여쓰는 부분이 적용이 안 되는 것같아요.
NLL대화록논란, 뉴라이트교과서문제 보면 의견달기 부분은 들여쓰기가 적용되어 잇는데, 막상 들여쓰는 본문이 적용이 안되는 것같습니다. 전에는 잘 되었던 것같은데.. -- 211.217.139.101 2013-6-30 6:47 pm
- 지금 뉴라이트교과서문제 페이지에 좀 달아봤는데, 잘 되는 것 같은데요?
- 어라. IE에서는 제대로 보이네요. 크롬에서는 들여쓰기가 안 된 것처럼 보이고..
이렇게 보이거든요..
- 으음 어떻게 손을 댈 방안이...
- 아, 역시 그렇군요. 신경 써주셔서 감사합니다.
위키위키분류