텍스트큐브 댓글
텍스트큐브는 최근에 올라온 댓글과 트랙백을 사이드바에 표시해 주는 기능을 가지고 있다. 출력할 글의 길이는 모두 텍스트큐브의 '스킨 상세 설정'에서 설정할 수 있다. 다만 자르는 문자의 수는 실제 출력되는 문자의 수와는 다소 차이가 있다. 그 이유는 텍스트큐브 기본 문자 집합이 UTF-8이고 UTF-8에서는 문자를 한 바이트가 아니라 두 바이트 이상으로 표시하기 때문이다. 이렇다 보니 스킨 설정에서 댓글의 길이와 트랙백의 길이를 설정, 댓글과 트랙백이 한 줄 또는 두줄로 출력될 수 있도록 만들어도 예상을 벗어나 배치가 어그러지는 때가 종종 있다. 이 문제는 다음 두 가지 상황에서 발생한다.
목차
텍스트큐브 댓글
텍스트큐브는 최근에 올라온 댓글과 트랙백을 사이드바에 표시해 주는 기능을 가지고 있다. 출력할 글의 길이는 모두 텍스트큐브의 '스킨 상세 설정'에서 설정할 수 있다. 다만 자르는 문자의 수는 실제 출력되는 문자의 수와는 다소 차이가 있다. 그 이유는 텍스트큐브의 기본 문자 집합이 UTF-8이고 UTF-8에서는 문자를 한 바이트가 아니라 두 바이트 이상으로 표시하기 때문이다.
이렇다 보니 스킨 설정에서 댓글의 길이와 트랙백의 길이를 설정, 댓글과 트랙백이 한 줄 또는 두줄로 출력될 수 있도록 만들어도 예상을 벗어나 배치가 어그러지는 때가 종종 있다. 이 문제는 다음 두 가지 상황에서 발생한다.
- 글이나 이름에 영어가 많이 포함된 경우
한글과 영어는 내부적으로 처리하는 바이트 수가 다르다. 따라서 스킨 설정에서 30자로 제한하면 한글은 고작 '10자' 정도 출력된다. 반면에 똑 같이 설정해도 영어로 되어 있으면 '15자' 정도가 출력된다. 따라서 한글과 영어는 글자를 자를 때 서로 다른 기준으로 잘라야 한다. 그러나 '텍스트큐브'는 한글과 영어를 구분하지 않고 자르기 때문에 한글인 경우에는 공간이 널널해도 영어가 포함되어 있으면 다음 행으로 넘어 간다. - 댓글을 쓰는 사람의 별명 또는 블로그 이름이 긴 경우
최근글은 제목과 달린 댓글의 수만 출력되기 때문에 대부분 설정한 대로 동작한다. 그러나 댓글 목록과 트랙백 목록에는 글 내용(글 제목), 별명(블로그 이름), 날짜가 함께 출력된다. 따라서 댓글을 쓰는 사람이 "별명을 길게" 적거나 블로그 "이름이 긴" 경우에는 또 예상치않게 배치가 어긋난다. 글쓴 사람의 별명이나 블로그의 이름도 특정한 길이로 자르면 좋을 텐데 별명이나 이름은 자르지 않는다[1].
실제 사례
①은 별명을 아주 길게 쓴 경우이다. 보통 블로거는 이런 별명을 사용하지 않는다. 그러나 익명 사용자 중에는 별명을 제목으로 생각하고 별명을 아주 길게 쓰는 때가 종종 있다. 이 경우 ①처럼 배치가 깨진다. ②는 이름에 영어를 사용한 경우다. 한글과 영어는 내부적으로 처리하는 바이트 수가 다르기 때문에 똑 같은 기준으로 자르면 영어는 잘리지 않고 표시된다. ③과 ④는 블로그의 이름이 긴 경우다. 물론 예에 나온 제목은 상당히 짧은 편이다. '♥양선생Blog♥희망한국~이명박탄핵 쥐박이 제거★'처럼 긴 이름을 사용하는 경우도 종종 있다.
패치하기
따라서 스킨을 1단으로 바꾸면서 배치가 어긋나는 것이 보기에 좋지 않아서 이번 기회에 패치했다. 'library/view/view.php' 파일만 패치하면 된다. 패치할 함수는 'getRecentEntriesView'(최근글 목록), 'getRecentCommentsView'(댓글 목록), 'getRecentTrackbacksView'(트랙백 목록)[2]이다. 먼저 다음 함수를 'view.php' 파일 마지막에 추가한다. 모두 이 함수를 이용해서 한글과 영어를 판정한다.
function checkHangul($query_key) {
$query_key = str_replace(" ", "", $query_key);
$stepsize=1;
$flag = true;
for ($i=0; $i < strlen($query_key); $i = $i + $stepsize)
{
if(ord($query_key[$i]) < 128) $eng++;
else $kor++;
}
return ($kor > $eng) ? false : true;
}
함수를 보면 알 수 있지만 영어와 한글을 세고 한글이 많으면 거짓을 영어가 많으면 참을 되돌려 주는 함수이다. 더 자세한 내용은 PHP 매뉴얼을 참조하기 바란다.
- 영어와 한글을 다른 기준으로 자르기
-
getRecentEntriesView
함수
getRecentEntriesView 함수에서 1000행을 찾아 변경후처럼 바꾸면 된다. 행 번호는 패치하면서 매긴 번호이기 때문에 원본의 행번호와는 다를 수 있다.//변경전 1000: $contentContainer["recent_entry_{$entry['id']}"] = htmlspecialchars(UTF8::lessenAsEm($entry['title'], $skinSetting['recentEntryLength'])); //변경후 1000: $trimLen=checkHangul($entry['title'])?$skinSetting['recentEntryLength']*2/3:$skinSetting['recentEntryLength']; 1001: $contentContainer["recent_entry_{$entry['id']}"] = htmlspecialchars(UTF8::lessenAsEm($entry['title'], $trimLen));
getRecentCommentsView
함수
getRecentCommentsView 함수에서 1019해을 찾아 변경후처럼 바꾸면 된다. 행 번호는 패치하면서 매긴 번호이기 때문에 원본의 행번호와는 다를 수 있다.// 변경전 1019: $contentContainer["recent_comment_{$comment['id']}"] = htmlspecialchars(UTF8::lessenAsEm(strip_tags($comment['comment']), $skinSetting['recentCommentLength'])); //변경후 1019: $trimLen=checkHangul(strip_tags($comment['comment']))?$skinSetting['recentCommentLength']*2/3:$skinSetting['recentCommentLength']; 1020: $contentContainer["recent_comment_{$comment['id']}"] = htmlspecialchars(UTF8::lessenAsEm(strip_tags($comment['comment']), $trimLen));
getRecentTrackbacksView
함수
getRecentTrackbacksView 함수에서 1039행을 찾아 변경후처럼 바꾸면 된다. 행 번호는 패치하면서 매긴 번호이기 때문에 원본의 행번호와는 다를 수 있다.//변경전 1039: dress('rcttb_rep_desc', htmlspecialchars(UTF8::lessenAsEm($trackback['subject'], $skinSetting['recentTrackbackLength'])), $view); //변경후 1039: $trimLen=checkHangul($trackback['subject'])?$skinSetting['recentTrackbackLength']*2/3:$skinSetting['recentTrackbackLength']; 1040: dress('rcttb_rep_desc', htmlspecialchars(UTF8::lessenAsEm($trackback['subject'], $trimLen)), $view);
패치한 결과 왼쪽이 패치전, 오른쪽이 패치후이다. 그림에서 알 수 있듯이 이렇게 패치하면 글에 영어가 많이 포함되도 설정된 값 이하로 자르기 때문에 한글과 비슷한 길이로 잘린다는 것을 알 수 있다.
- 별명을 스킨 설정에 따라 자르기
-
최근글에는 별명이 없기 때문에 'getRecentCommentsView' 함수와 'getRecentTrackbacksView' 함수만 패치하면 된다.
getRecentCommentsView
함수: 패치하는 방법은 전과 같다.//변경전 1023: dress('rctrp_rep_name', htmlspecialchars(UTF8::lessenAsEm($comment['name'], $skinSetting['recentCommentLength'])), $view); //변경전 1023: $trimLen=checkHangul($trackback['site']) ? $skinSetting['recentCommentLength'] : $skinSetting['recentCommentLength']/3; 1024: dress('rctrp_rep_name', htmlspecialchars(UTF8::lessenAsEm($comment['name'], $trimLen+1)), $view);
getRecentTrackbacksView
함수': 패치하는 방법은 전과 같다.//변경전 1043: dress('rcttb_rep_name', htmlspecialchars(UTF8::lessenAsEm($trackback['site'], $skinSetting['recentTrackbackLength'])), $view); //변경후 1043: $trimLen=checkHangul($trackback['site']) ? $skinSetting['recentTrackbackLength']/4 : $skinSetting['recentTrackbackLength']/3; 1044: dress('rcttb_rep_name', htmlspecialchars(UTF8::lessenAsEm($trackback['site'], $trimLen+1)), $view);
두 가지 패치를 하고 skin.html을 조금 손 보면 다음 그림처럼 최근글 목록, 댓글 목록, 트랙백 목록을 깨끗하게 정리할 수 있다.
Trackback
Trackback Address :: https://offree.net/trackback/2405
Comments
-
-
-
-
-
-
최면 2009/03/23 09:43
요즘 자잘한 버그들이 너무 많이 눈에 띄네요 ㅠ.ㅜ
예전 태터툴즈 때는 그냥 이런게 있다는 것 자체만으로 만족했었는데..
눈이 높아졌나봅니다.. -
inureyes 2009/03/24 02:08
/library/component 안의 문자열을 다루는 UTF8 클래스를 보면, (1.7이면 Eolin.PHP.Core일듯) 1바이트에서 4바이트까지 유니코드 영역의 문자 길이를 다르게 취급하고 있습니다.
lessenAsByte는 길이 기준이 아니라 바이트 기준으로 자릅니다. UTF-8 영역 기준에 따라 영문자는 1바이트, 한글은 3바이트로 자르기 때문에 일반적인 경우 출력이 1,2글자 단위로 보이는 것과 달라서 위와 같은 문제가 생길겁니다. 그런데 lessenAsEm의 경우에는 영문자를 제외하면 다 2바이트로 자르도록 되어 있을텐데, 동작이 이상하게 돌아가나 봅니다. 한 번 테스트 해 보고 고민해 보도록 하겠습니다. :) -
-
-
Facebook