[강좌] 제로보드에서 코멘트 포함 최신글순 정렬 기능 추가하기
이름: capri91 [수정] 2005-06-13 19:03:49



#. 강좌를 시작하면서...

안녕하세요. 김성한입니다.

제로보드는 대중적으로 많이 쓰이는 유명한 게시판 소스입니다. 그 이전의 일반 게시판과는 다른 특징적인 기능중의 하나가 바로 코멘트 기능입니다. Re: 등으로 표시되는 예전의 댓글과 비교해서 코멘트 기능은 많은 장점을 가지고 있습니다. 한 게시물에 모든 관련글이 표시되므로 편리하고 직관적이며 보다 빠르고 자유로운 의견 교환이 가능합니다.

그런데 게시판을 이곳저곳 돌아다니다 보니 불편한 점이 있었습니다. 예전의 댓글 게시판에서는 최신글을 확인하기 위해서 날짜순 정렬을 선택하면 나중에 올라온 리플을 확인할 수 있었습니다. 그러나 요즘의 코멘트 게시판에서는 기본 정렬이 날짜순과 마찬가지라서 날짜순 정렬이 아무 소용이 없게 되어 코멘트를 포함한 최신글을 확인하기가 쉽지 않습니다.

그러던 중 2005년 1월에 NeXTcube 게시판을 업그레이드 하게 되었습니다. 이전의 댓글 게시판을 코멘트 게시판으로 DB 컨버팅 및 소스 변경하면서, 그동안 생각해두었던 코멘트를 포함해서 최신글순으로 정렬하는 기능을 추가하였습니다. 그리고 이번에 단군배로 게시판을 업데이트 하면서 마찬가지로 제로보드에도 코멘트를 포함해서 최신글순으로 정렬하는 기능을 추가하였습니다.

제로보드에서 코멘트 포함 최신글순 정렬 기능을 추가하기 위해서는 mysql DB, 제로보드 소스, 스킨 소스가 수정되어야 합니다. 그럼 본격적인 강좌를 시작하겠습니다.


1. mysql DB 수정

제로보드의 데이터가 있는 mysql DB를 살펴보면 게시물을 저장하는 테이블과 코멘트를 저장하는 테이블이 있습니다. 게시판 이름이 br이라고 할 경우를 예로 들어 설명하도록 하겠습니다.

zetyx_board_br (br 게시판의 게시물을 저장하는 테이블)
zetyx_board_comment_br (br 게시판의 코멘트를 저장하는 테이블)

그중에 zetyx_board_br 테이블을 보면 headnum와 reg_date 필드를 볼 수 있습니다. headnum는 기본 정렬에 해당되고, reg_date는 날짜순 정렬에 해당됩니다. 댓글이 없을 경우에 둘중 어느 것을 기준으로 해도 게시물 정렬이 같은 순서가 된다는 것을 알 수 있습니다.

여기에 최신글순 정렬을 가능하게 하려면 새로운 필드를 추가해야 합니다. 최신글순 정렬에 해당하는 필드는 게시물과 코멘트의 최신 갱신 날짜가 저장되어야 하므로 reg_date와 같은 형식으로 만들어줍니다. 다음과 같은 SQL 명령으로 recent date를 뜻하는 rdate라는 필드를 추가합니다.

ALTER TABLE zetyx_board_br ADD rdate int(13) not null default '0';

추가된 rdate 필드를 보면 모두 디폴트 값인 0로 되어 있습니다. 여기에는 게시물 등록 날짜인 reg_date 값을 넣어주면 충분합니다. 다음과 같은 SQL 명령으로 rdate 필드 값을 reg_date 필드 값과 같아지도록 갱신합니다.

UPDATE zetyx_board_br SET rdate=reg_date;

이것으로 최신글순 정렬에 필요한 mysql DB 수정은 끝났습니다. 그럼 제로보드 소스 수정으로 넘어갑니다.


2. 제로보드 소스 수정

1) ./schema.sql

mysql DB 수정 사항이 새로운 게시판을 생성할 때마다 적용되도록 하기 위해서 스키마 정보를 수정합니다. 다음과 같이 게시판 본체 테이블 부분에 rdate 필드를 추가합니다.

///////////////////////////////////////////////////////////////////////////
// 게시판 본체 테이블
///////////////////////////////////////////////////////////////////////////
    
... 중략 ...

    y char(255),
    
    rdate int(13) not null default '0',
    
    KEY headnum (division, headnum,arrangenum),

2) ./write_ok.php

게시물 쓰기를 할 경우에는 최신글순 정렬을 위한 rdate 값에 등록 날짜가 저장되어야 합니다. 이는 새글이나 답글일 경우 모두 해당합니다. 다음과 같이 새글과 답글을 mysql DB에 저장할 때 rdate 필드가 들어가도록 수정합니다.

/***************************************************************************
* 신규 글쓰기일때
**************************************************************************/

... 중략 ...
                        
                mysql_query("insert into $t_board"."_$id (division, headnum, arrangenum, depth, prev_no, next_no, father, child, ismember, memo, ip, password, name, homepage, email, subject, use_html, reply_mail, category, is_secret, sitelink1, sitelink2, file_name1, file_name2, s_file_name1, s_file_name2, x, y, reg_date, islevel, rdate) values ('$division', '$headnum', '$arrangenum', '$depth', '$prev_no', '$next_no', '$father', '$child', '$member[no]', '$memo', '$ip', '$password', '$name', '$homepage', '$email', '$subject', '$use_html', '$reply_mail', '$category', '$is_secret', '$sitelink1', '$sitelink2', '$file_name1', '$file_name2', '$s_file_name1', '$s_file_name2', '$x', '$y', '$reg_date', '$member[is_admin]', '$rdate')") or error(mysql_error());

                 // 답글 데이타 입력;;
                mysql_query("insert into $t_board"."_$id (division, headnum, arrangenum, depth, prev_no, next_no, father, child, ismember, memo, ip, password, name, homepage, email, subject, use_html, reply_mail, category, is_secret, sitelink1, sitelink2, file_name1, file_name2, s_file_name1, s_file_name2, x, y, reg_date, islevel, rdate) values ('$division', '$headnum', '$arrangenum', '$depth', '$prev_no', '$next_no', '$father', '$child', '$member[no]', '$memo', '$ip', '$password', '$name', '$homepage', '$email', '$subject', '$use_html', '$reply_mail', '$category', '$is_secret', '$sitelink1', '$sitelink2', '$file_name1', '$file_name2', '$s_file_name1', '$s_file_name2', '$x', '$y', '$reg_date', '$member[is_admin]', '$reg_date')") or error(mysql_error());

여기서 유의할 점이 한가지 있습니다. 공지사항의 경우에는 게시판 최상단에 위치하기 위해서 reg_date 값이 아닌 headnum 값이 양수로 저장되어야 할 필요가 있습니다. 다음과 같이 공지사항이 아닌 경우와 공지사항인 경우를 구분해서 $rdate 변수값을 추가합니다.

                 // 공지사항이 아닐때;;

... 중략 ...

                        if($prev_data[0]) $prev_no=$prev_data[0]; else $prev_no="0";
                        $rdate=$reg_date;
                
                 // 공지사항일때;;

... 중략 ...

                        $prev_no=0;
                        $rdate=str_replace("-","",$headnum);

게시물을 수정할 때도 마찬가지로 공지사항에 유의합니다. 다음과 같이 공지를 일반글로 변경하는 경우와 그 반대의 경우를 구분해서 $rdate 변수값을 추가합니다.

                 // 공지 -> 일반글

... 중략 ...

                        $rdate=mysql_fetch_array(mysql_query("select reg_date from $t_board"."_$id where no='$no'"));
                        @mysql_query("update $t_board"."_$id set headnum='$headnum', prev_no='$prev_no', next_no='$next_no', child='$child', depth='$depth', arrangenum='$arrangenum', father='$father', name='$name', email='$email', homepage='$homepage', subject='$subject', memo='$memo', sitelink1='$sitelink1', sitelink2='$sitelink2', use_html='$use_html', reply_mail='$reply_mail', is_secret='$is_secret', category='$category', rdate='$rdate[0]' $del_que1 $del_que2 where no='$no'") or error(mysql_error());

                 // 일반글 -> 공지

... 중략 ...

                        $rdate=str_replace("-","",$headnum);
                        @mysql_query("update $t_board"."_$id set division='$division', headnum='$headnum', prev_no='$prev_no', next_no='$next_no', child='$child', depth='$depth', arrangenum='$arrangenum', father='$father', name='$name', email='$email', homepage='$homepage', subject='$subject', memo='$memo', sitelink1='$sitelink1', sitelink2='$sitelink2', use_html='$use_html', reply_mail='$reply_mail', is_secret='$is_secret', category='$category', rdate='$rdate' $del_que1 $del_que2 where no='$no'") or error(mysql_error());

3) ./comment_ok.php

코멘트 쓰기를 할 경우에는 최신글순 정렬을 위한 rdate 값에 마지막으로 코멘트가 등록된 날짜가 저장되어야 합니다. 이때에도 위와 마찬가지로 공지사항이 아닌 경우와 공지사항인 경우를 구분해야 합니다. 다음과 같이 조건문으로 rdate 값이 들어가도록 수정합니다.

// 코멘트 갯수를 구해서 정리
        $total=mysql_fetch_array(mysql_query("select count(*) from $t_comment"."_$id where parent='$no'"));
        mysql_query("update $t_board"."_$id set total_comment='$total[0]' where no='$no'") or error(mysql_error());

// 코멘트 갯수를 구해서 정리
        $total=mysql_fetch_array(mysql_query("select count(*) from $t_comment"."_$id where parent='$no'"));
        $rnotice=mysql_fetch_array(mysql_query("select headnum from $t_board"."_$id where no='$no'"));
        if($rnotice[0]>-2000000000) {
                mysql_query("update $t_board"."_$id set total_comment='$total[0]',rdate='$reg_date' where no='$no'") or error(mysql_error());
        } else {

                mysql_query("update $t_board"."_$id set total_comment='$total[0]' where no='$no'") or error(mysql_error());
        }

4) ./del_comment_ok.php

작성했던 코멘트를 삭제할 경우에도 rdate 값이 마지막 코멘트 등록 날짜로 갱신되어야 합니다. 다음과 같이 조건문으로 rdate 값이 갱신되도록 수정합니다.

// 코멘트 갯수 정리
         $total=mysql_fetch_array(mysql_query("select count(*) from $t_comment"."_$id where parent='$no'"));
         mysql_query("update $t_board"."_$id set total_comment='$total[0]' where no='$no'") or error(mysql_error());

// 코멘트 갯수 정리
        $total=mysql_fetch_array(mysql_query("select count(*) from $t_comment"."_$id where parent='$no'"));
        $rnotice=mysql_fetch_array(mysql_query("select headnum from $t_board"."_$id where no='$no'"));
        if($rnotice[0]>-2000000000) {
                if($total[0]<1) {
                        $reg_date=mysql_fetch_array(mysql_query("select reg_date from $t_board"."_$id where no='$no'"));
                } else {
                        $reg_date=mysql_fetch_array(mysql_query("select reg_date from $t_comment"."_$id where parent='$no' order by reg_date desc limit 0,1"));
                }
                mysql_query("update $t_board"."_$id set total_comment='$total[0]',rdate='$reg_date[0]' where no='$no'") or error(mysql_error());
        } else {

                mysql_query("update $t_board"."_$id set total_comment='$total[0]' where no='$no'") or error(mysql_error());
        }


3. 스킨 소스 수정

마지막으로 제로보드의 스킨 소스에 관련글순 정렬과 최신글순 정렬을 위한 링크를 추가해주면 끝입니다. 스킨 디렉토리에 링크를 추가하는 방법에는 두가지가 있습니다. 첫번째는 기존의 날짜순 정렬(reg_date)을 최신글순 정렬(rdate)로 바꾸면 됩니다. 두번째는 상단이나 하단, 혹은 원하는 위치에 다음과 같이 링크를 추가해주면 됩니다.

<a href=zboard.php?id=<?=$id?>&select_arrange=headnum&desc=asc>[관련글순 정렬]</a>
<a href=zboard.php?id=<?=$id?>&select_arrange=rdate&desc=desc>[최신글순 정렬]</a>


#. 강좌를 마치면서...

참고로 제로보드 버젼에 따라서 desc 정렬 옵션의 철자가 틀린 경우가 존재합니다. 제로보드 소스 디렉토리에서 &desc=$des라고 잘못 표기되어 있는 파일들을 찾아서 &desc=$desc로 수정해주시면 됩니다.

이제 제로보드에서 코멘트 포함 최신글순 정렬 기능을 사용할 수 있게 되었습니다. 아래 그림은 각각 관련글순 정렬과 최신글순 정렬을 사용한 예시입니다. 게시판 상단의 [최신글순 정렬]을 선택하면 코멘트를 포함해서 최신글순으로 정렬되며, 반대로 [관련글순 정렬]을 선택하면 기본 정렬로 되돌아갑니다.


관련글순 정렬


최신글순 정렬


참고: http://www.nextcube.org/board/browse/1111/1155
이름: onion[삭제] [수정] 2007-03-14 19:26:37
후우우... 고수같으니..(중얼중얼)
이름: capri91[삭제] [수정] 2007-03-14 22:22:21
양파님이야말로 다방면에 걸친 고수 아니십니까... ^^;
이름: onion[삭제] [수정] 2007-03-15 17:59:39
저는 이제 바보에요.. 바보.. 두뇌나이 54세의 바보라구요~ (파쿠만사)
이름: capri91[삭제] [수정] 2007-03-15 21:50:45
헉, 그새 닌텐도 DS Lite를 지르셨군요. 마눌님 무서워 전 아무 것도 못지릅니다. -.-;
이름: onion[삭제] [수정] 2007-03-15 23:11:08
...lite아니에요... Linux설치한다고 설칠때 지른 예전 구버전이옵니다..-.-;
그러고보니 솔로부대가 이런건 좋군요..(히죽)
이름: capri91[삭제] [수정] 2007-04-19 23:23:48
1) zboard.php 파일에서 다음 부분을 아래와 같이 바꿔보시기 바랍니다. 수정한 이후에는 날짜순 정렬을 클릭하면 최신글순 정렬로 대치됩니다.

$a_date="<a onfocus=blur() href='$PHP_SELF?$href&select_arrange=reg_date&desc=$t_desc'>";

$a_date="<a onfocus=blur() href='$PHP_SELF?$href&select_arrange=rdate&desc=$t_desc'>";

2) 작성일의 날짜 대신 코멘트의 날짜로 표시하는 것은 힘들 것 같습니다. DB 쿼리를 뜯어 고쳐야 하는 부분이기 때문에 쉽게 바꾸기는 어려울듯 합니다.
이름: 독자[삭제] [수정] 2007-06-02 15:30:16
성한님 위에 질문남긴 독자입니다. 아주 잘 작동하고 있습니다. 다시 한번 감사의 인사를 드립니다.

그런데 제가 이번에 트랙백 기능을 추가해서 사용중인데.. 트랙백 역시 코멘트 형태로 저장됨에도 불구하고 트랙백이 오면 해당 게시물이 위로 뜨질 않습니다. 아래의 트랙백 팁을 사용중에 있습니다.

http://www.daerew.com/bbs/zboard.php?id=4_study_zreroboard&page=4&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=295

저기서 트랙백을 받는 파일인 zerotb.php에서 rdate와 '$reg_date'를 추가한 후 네이버 블로그에서 트랙백을 보내봤더니 트랙백 주소가 잘못되었다며 트랙백 자체가 작동되지 않았습니다.

         // 코멘트 입력
        mysql_query("insert into zetyx_board_comment_".$bbs_id." (parent,ismember,name,password,memo,reg_date,ip,rdate) values ('$parent','0','$name','$password','$memo','$reg_date','$REMOTE_ADDR','$reg_date')")
        or ($result = array("error" => 1, "message" => "Server DB Error."));

rdate와 '$reg_date'를 제거하면 트랙백은 정상적으로 보내지더군요. 하지만 이 경우 트랙백이 와도 게시물이 떠오르질 않습니다.

어떻게 해결할 방법이 없을런지요? 귀찮게 해드려 정말 죄송합니다..
이름: capri91[삭제] [수정] 2007-06-04 15:34:39
zerotb.php 파일을 수정해야 될 것 같기는 한데, 저도 뭐가 문제인지 모르겠군요. zerotb.php 제작자에게 문의해 보시는 것이 나을 것 같습니다.
이름: 독자[삭제] [수정] 2007-06-04 17:28:46
예 답변 주셔서 감사합니다. 언제나 좋은 하루 맞으시길...
이름: 토미[삭제] [수정] 2008-04-08 03:12:59
안녕하세요, capri91님께서 제로보드 팁공유 게시판에 올려주신 "제로보드에서 코멘트 포함 최신글순 정렬기능 추가하기" 게시물을 보고 따라해보니까 잘 되더라고요^^

우선 너무나 감사드립니다.


단, 코멘트를 작성하고 지워도 최신글에 그대로 반영되어 있는 문제가 있어서 이를 해결할 수 있는 방법이 없을까 궁금해서 문의를 드립니다.

게시물이야 삭제하면 목록자체에서 사라지니까 문제가 안되는데 코멘트는 작성하고 삭제해도 원본게시물이 그대로 최신글로 남아있으니까 조금 문제가 되더라고요^^


혹시 방법이 없을까요?^^
이름: capri91[삭제] [수정] 2008-04-08 17:05:29
작성했던 코멘트를 삭제할 경우에도 rdate 값을 갱신해주어야 하는데 제가 빠뜨렸네요. 알려주셔서 감사합니다.

위의 강좌 내용(2-4)에 코멘트 삭제시 수정되어야 할 코드(./del_comment_ok.php)를 추가했습니다. 테스트 해보시고 혹시 문제가 있으면 알려주세요.

PS. 제로보드 관련 강좌에 대한 피드백을 받는 곳은 이 글타래입니다. 새 글쓰기로 올리신 토미님의 글은 적합한 장소인 이곳으로 옮겼습니다. 양해바랍니다.
이름: 토미[삭제] [수정] 2008-04-08 21:38:00
확인하고 수정해주셔서 너무 감사드립니다^^
혹시 앞으로 본 게시물 관련하여 문의사항이 있으면 여기 댓글형태로 문의드릴께요^^

게시판의 질서(?)를 흐트린점 사과드립니다 (__)
이름: 피우[삭제] [수정] 2008-10-12 11:04:39
이것을 방명록형태의 게시판에서
게시물에 답글이 달렸을때에도 적용시킬 수 있나요?
이름: capri91[삭제] [수정] 2008-10-12 11:36:05
일반적인 게시판에만 적용됩니다. 방명록 등에는 아마 적용되지 않을 것이라 생각합니다...
이름: 피우[삭제] [수정] 2008-10-12 16:16:24
혹시나 가능하시다면 http://www.zeroboard.com/zb4_qna/17367143 답변부탁드릴수 있을까요
이름: capri91[삭제] [수정] 2008-10-12 17:29:29
피우님의 방명록에 적용해보시고 가능 여부를 알려주세요...
이름: 피우[삭제] [수정] 2008-10-12 17:41:46
http://azurebeluga.ivyro.net/bbs/zboard.php?id=pds

시험중인 방명록입니다.
여기서 글을 쓰고 수정하면 확실히 rdate 값이 바뀌어서 순서가 바뀝니다.
그런데 제가 원하는건 답글이 달리면 그 글이 맨위로 오르게 하고 싶습니다. 그래서

if($mode=="reply") @mysql_query("update $t_board"."_$id set rdate='$reg_date' where no='$s_data[father]'",$connect);

이 함수를 write_ok 에 넣고 시험해봤지만 아무리 답글을 달아도 응답이 없네요...
이름: capri91[삭제] [수정] 2008-10-13 10:43:14
방명록에서 select_arrange=rdate와 select_arrange=reg_date 변수를 주었을 때, 정렬을 비교해보니 순서가 바뀌는데요. 제대로 적용된 것 아닌가요?
이름: 피우[삭제] [수정] 2008-10-14 13:51:49
해결보았습니다. 제가 원했던 것은 방명록은 코멘트가 아닌 답글이어서, 답글을 달았을때 부모글의 rdate를 갱신하는 함수를 넣고자 했던거였는데요,
write_ok의 답글일때 부분에

mysql_query("update $t_board"."_$id set rdate='$reg_date' where no='$s_data[no]'");

를 넣어줌으로 해결되었습니다. 여러가지로 참고로 공부가 되었습니다. 감사합니다.
이름: capri91[삭제] [수정] 2008-10-14 15:52:43
방명록 밑에 달린 답글을 comment 라고 생각했는데 reply 였던 모양이군요. 별로 도움이 되어 드리지 못해서 죄송합니다. 그래도 잘 해결되었다니 다행이네요...
  이 름  암 호  보안코드  
번호작성자날짜조회제    목
527capri912005-08-1912120   [소개] Mac OS X를 일반 PC에서! (12)
526박영수2005-08-013987   NeXTSTEP에서 최상의 랜카드?? (1)
525산적2005-07-143750   처분되었습니다. (9)
524홍정의2005-07-094060   넥스트에서의 LAN 설정방법 (3)
523최준2005-07-045975   빌드에 관해서 도움 부탁합니다. (16)
522넥스트2005-07-014541   성한님이 쓰신, 넥스트 history를 약간 수정했습니다. (18)
521홍정의2005-06-273732   HP build & Greeting (3)
520최준2005-06-263980   감개무량하군요. (17)
519오뎅2005-06-164040   [질문] PostScript 파일에 대하여... (4)
518연우2005-06-143819   Openstep 4.2J for Mach (6)
517capri912005-06-1329877   [강좌] 제로보드에서 코멘트 포함 최신글순 정렬 기능 추가하기 (20)
516김준우2005-06-133348   성한님 에러메시지가.. (4)
515김준우2005-06-123859   성한님..^^ 오픈스텝 부팅디스크는.. (5)
514김준우2005-06-113402   헬프~~ NeXTSTEP BOOT 디스크가 부팅이 안되요.. (2)
513김준우2005-06-103634   넥스트 스테이션에 SCSI CD-Rom을 붙이는데.. (3)
[≪] [<] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [>] [≫]