Animato

태터툴즈 1.1.2 Animator가 배포됐다. 그러나 태터툴즈를 개인적으로 패치한 부분이 많아 일단 설치를 보류하고 있었다. 그러다 실수로 판올림한 뒤 어떤 파일을 어떻게 패치했는지 기록을 남기기 위해 이 글을 작성하게 되었다.

태터툴즈 릴리즈

어제 태터툴즈 1.1.2 Animato가 배포됐다. 공지를 보고 바로 판올림할까 하는 생각도 해봤지만 현재 패치한 것이 많고 1.1.1에서 어떤 것을 패치했는지 기억이 나지않아 나중에 확인한 뒤 설치하기 위해 일단 설치를 보류하고 있었다.

그러나 오늘 Me2DayBlog API 기능을 시험해볼 생각으로 티스토리의 블로그 API가 포함되어 있는 태터툴즈 1.1.2를 설치했다. 보통은 파일을 백업하고 판올림을 하는데 오늘 평상시 보다 많은 글을 올리다 보니 눈에 뭐가 쒸웠는지 백업도 하지 않은채로 판올림을 해 버렸다.

이렇게 판올림을 하니 지난 번에 무엇을 어떻게 패치했는지 생각이 나지 않아 기억을 더듬어 패치하고 예전과 비슷한 형태로 동작하는 것을 보고 이 글을 작성하려고 했다. 글을 쓰려고 관리자로 로그인하니 접속자가 100만명이 넘었다는 것을 알았다. 그래서 부랴 부랴 블로그 방문자 수가 백만명을 돌파했습니다라는 글을 올렸다.

태터툴즈 패치

이번에 태터툴즈를 판올림하면서 한 패치는 다음과 같다. 내가 한 패치는 이 페이지 끝에 첨부 파일로 제공된다. 따라서 패치에 자신이 없는 사람은 이 파일을 내려받아 사용해도 된다.

블로그 Index.php 파일

보통 https://offree.net/처럼 블로그의 주소를 입력하면 '관리도구/스킨/출력 설정'에서 설정한 '한 쪽당 글 수'에 따라 블로그 페이지가 표시된다. 그러나 나는 '한 쪽당 글 수를 1로 설정'하고 있고 블로그에 접속하면 바로 가장 최근 글로 가도록 패치해서 사용하고 있다. 예를들어 주소에서 https://offree.net/을 치고 들어오면 자동으로 최근 글인 https://offree.net/entry/Million-Visitors로 연결된다.

이렇게 하는 이유는 간단하다. 글에 있는 모든 링크를 절대 주소로 만들기 위해서이다. 이 패치를 하지않으면 블로그 아래쪽의 페이저(|1|2|3|...|697|)의 링크는 https://offree.net/?page=1 처럼 표시되지만 이 패치를 해주면 아래쪽 페이저에도 https://offree.net/entry/Join-Me2Day처럼 절대 주소로 표시되기 때문이다.

이렇게 패치하는 방법은 간단하다. 일단 FTP를 지원하는 편집기(예: EditPlus)로 /blog/index.php 파일을 열고 가장 마지막의 print $view를 주석으로 처리한 뒤 다음처럼 두줄을 추가하면된다.

//print $view;
if(ereg('MSIE 6',$_SERVER['HTTP_USER_AGENT'])) $slogan=iconv('UTF-8', 'EUC-KR', $entries[0]['slogan']);
else $slogan=$entries[0]['slogan'];
header("Location:".불blogURL."/entry/".불slogan);
?>

목록 한쪽 당 글 수 패치

태터툴즈 패치: 목록 한 쪽당 글 수에서 설명한 것처럼 태터툴즈 1.1 이상에서는 '한 쪽당 글 수'와 무관하게 '목록 한 쪽당 글 수' 만큼 블로그의 글이 출력된다. 따라서 검색시 출력되는 목록을 '한쪽 당 글 수' 만큼 출력하도록 패치해서 사용하고 있다. 물론 1.1.2에서는 목록만 출력할 것인지 아니면 페이지를 출력할 것인지를 설정할 수 있지만 이전에 사용한 방법이 편하기 때문에 이 패치를 사용한다. 검색시 출력되는 페이지를 '한 쪽당 글 수'로 설정하려면 좋아하는 편집기로 /blog/search/index.php 파일을 연 뒤 다음처럼 패치하면된다.

변경전========================================================================
list($entries,$paging)=getEntriesWithPagingBySearch($owner,
    $search,$suri['page'],$blog['entriesOnList'],$blog['entriesOnList']);

변경후========================================================================
list($entries,$paging)=getEntriesWithPagingBySearch($owner,
    $search,$suri['page'],$blog['entriesOnList'],$blog['entriesOnPage']);

절대 주소

얼마 전부터 절대 주소를 표시하는 방법을 숫자가 아닌 문자로 하고 있다. SEO에서 주장하는 것처럼 검색 엔진에 더 잘 검색되는지 확인하기 위한 것이다. 그런데 문제는 페이지의 절대 주소는 다 문자로 표시되는데 페이지 내의 최근 글, 댓글, 걸린 글은 문자가 아니라 숫자로 표시된다. 따라서 이 부분 역시 패치해서 사용하고 있다.

나처럼 최근글, 댓글, 걸린글까지 문자로 표시하고 싶다면 좋아하는 편집기로 /blog/entry/index.php 파일을 연 뒤 다음처럼 패치하면 된다. 빨간색으로 표시된 부분이 바뀐 부분이다.

  • 최근글

    변경전========================================================================
    **getRecentEntries 함수**
    $result=DBQuery::query("SELECT e.id, e.title, e.comments
        FROM {$database['prefix']}Entries e
        LEFT JOIN {$database['prefix']}Categories c ON e.owner = c.owner 
        AND e.category = c.id
        WHERE e.owner = $owner AND e.draft = 0 $visibility AND e.category >= 0
        ORDER BY published DESC LIMIT {$skinSetting['entriesOnRecent']}");
    
    **getRecentEntriesView 함수**
    dress('rctps_rep_link',"$blogURL/{$entry['id']}",$view);
    
    변경후========================================================================
    **getRecentEntries 함수**
    $result=DBQuery::query("SELECT e.id, e.title, e.comments, e.slogan
        FROM {$database['prefix']}Entries e
        LEFT JOIN {$database['prefix']}Categories c ON e.owner = c.owner 
        AND e.category = c.id
        WHERE e.owner = $owner AND e.draft = 0 $visibility AND e.category >= 0
        ORDER BY published DESC LIMIT {$skinSetting['entriesOnRecent']}");
    
    **getRecentEntriesView 함수**
    dress('rctps_rep_link',"$blogURL/entry/{$entry['slogan']}",$view);
    
  • 댓글

    변경전========================================================================
    **getRecentComments 함수**
    $sql=doesHaveOwnership()?"SELECT * FROM
            {$database['prefix']}Comments
        WHERE
            owner = $owner".($isGuestbook!=false?" AND entry=0":" AND entry>0")."
            AND isFiltered = 0
        ORDER BY
            written
        DESC LIMIT ".($count!=false?$count:$skinSetting['commentsOnRecent']):
        "SELECT r.* 
        FROM
            {$database['prefix']}Comments r
            LEFT JOIN {$database['prefix']}Entries e ON r.owner = e.owner 
            AND r.entry = e.id
            LEFT JOIN {$database['prefix']}Categories c ON e.owner = c.owner
            AND e.category = c.id
        WHERE
            r.owner = $owner AND e.draft = 0 AND e.visibility >= 2 AND
            (c.visibility > 1 OR e.category = 0) ".($isGuestbook!=false?"
            AND r.entry = 0":" AND r.entry > 0")." AND isFiltered = 0
        ORDER BY
            r.written
        DESC LIMIT
            ".($count!=false?$count:$skinSetting['commentsOnRecent']);
    
    **getRecentCommentsView 함수**
    dress('rctrp_rep_link',"$blogURL/{$comment['entry']}#comment{$comment['id']}",$view);
    
    변경후========================================================================
    **getRecentComments 함수**
    $sql=doesHaveOwnership()?"SELECT r.*, e.slogan
        FROM
            {$database['prefix']}Comments r, {$database['prefix']}Entries e
        WHERE
            r.owner = $owner".($isGuestbook!=false?" AND r.entry=0":" 
            AND r.entry>0")."AND r.isFiltered = 0 AND r.entry = e.id
        ORDER BY
            r.written
        DESC LIMIT ".($count!=false?$count:$skinSetting['commentsOnRecent']):
        "SELECT r.*, e.slogan
        FROM
            {$database['prefix']}Comments r
            LEFT JOIN {$database['prefix']}Entries e ON r.owner = e.owner 
            AND r.entry = e.id
            LEFT JOIN {$database['prefix']}Categories c ON e.owner = c.owner
            AND e.category = c.id
        WHERE
            r.owner = $owner AND e.draft = 0 AND e.visibility >= 2 AND
            (c.visibility > 1 OR e.category = 0) ".($isGuestbook!=false?"
            AND r.entry = 0":" AND r.entry > 0")." AND isFiltered = 0
        ORDER BY
            r.written
        DESC LIMIT
            ".($count!=false?$count:$skinSetting['commentsOnRecent']);
    
    **getRecentCommentsView 함수**
    dress('rctrp_rep_link',"$blogURL/entry/{$comment['slogan']}#comment{$comment['id']}",$view);
    
  • 걸린글

    변경전========================================================================
    **getRecentTrackbacks 함수**
    $sql=doesHaveOwnership()?"SELECT *
        FROM
            {$database['prefix']}Trackbacks
        WHERE
            owner = $owner AND isFiltered = 0
        ORDER BY
            written
        DESC LIMIT ".($count!=false?$count:$skinSetting['trackbacksOnRecent']):
        "SELECT t.*
        FROM
            {$database['prefix']}Trackbacks t
            LEFT JOIN {$database['prefix']}Entries e ON t.owner = e.owner 
            AND t.entry = e.id
            LEFT JOIN {$database['prefix']}Categories c ON e.owner = c.owner
            AND e.category = c.id
        WHERE
            t.owner = $owner AND e.draft = 0 AND e.visibility >= 2 AND
            (c.visibility > 1 OR e.category = 0) AND t.isFiltered = 0
        ORDER BY
            t.written
        DESC LIMIT ".($count=false?$count:$skinSetting['trackbacksOnRecent']);
    
    **getRecentTrackbacksView 함수**
    dress('rcttb_rep_link',"$blogURL/{$trackback['entry']}#trackback{$trackback['id']}",$view);
    
    변경후========================================================================
    **getRecentTrackbacks 함수**
    $sql=doesHaveOwnership()?"SELECT t.*, e.slogan
        FROM
            {$database['prefix']}Trackbacks t, {$database['prefix']}Entries e
        WHERE
            t.owner = $owner AND t.isFiltered = 0 AND t.entry = e.id
        ORDER BY
            t.written
        DESC LIMIT ".($count!=false?$count:$skinSetting['trackbacksOnRecent']):
        "SELECT t.*, e.slogan
        FROM
            {$database['prefix']}Trackbacks t
            LEFT JOIN {$database['prefix']}Entries e ON t.owner = e.owner 
            AND t.entry = e.id
            LEFT JOIN {$database['prefix']}Categories c ON e.owner = c.owner
            AND e.category = c.id
        WHERE
            t.owner = $owner AND e.draft = 0 AND e.visibility >= 2 AND
            (c.visibility > 1 OR e.category = 0) AND t.isFiltered = 0
        ORDER BY
            t.written
        DESC LIMIT ".($count=false?$count:$skinSetting['trackbacksOnRecent']);
    
    **getRecentTrackbacksView 함수**
    dress('rcttb_rep_link',"$blogURL/entry/{$trackback['slogan']}#trackback{$trackback['id']}",$view);
    

myEolin

내가 myEolin 기능 중 유일하게 사용하는 기능은 블로그 아래쪽에 달려있는 '이올린에 북마크할 수 있는 책갈피'와 '이올린에 추천할 수 있는 추천'이다. 그런데 이 기능은 ViewPost 핸들러를 사용해서 글의 끝부분에 붙기 때문에 위치를 마음대로 바꿀 수 없다. 따라서 이 위치를 마음대로 바꿀 수 있도록 태그로 만들어 사용하고 있다. 나처럼 'myEolin 플러그인'을 패치해서 사용하려면 좋아하는 편집기로 /plugins/myEolin/index.php 파일을 연 뒤 다음처럼 바꾸면 된다.

변경전========================================================================
**Bm_myEolin 함수**
global $hostURL, $blogURL, $pluginURL,$owner,$permalink,$entry,$configVal;

if($entry['visibility'] >= "2" ){
    $target .= '<div class="EolinBmVote">';
    $img = $pluginURL."/images/bookmarkToEolin.gif";
    $img2 = $pluginURL."/images/voteToEolin.gif";
    $permalink = $hostURL. (isset($permalink)?$permalink:'');

    $ownership = false;
    if(true==function_exists('doesHaveOwnership')){
        $ownership = doesHaveOwnership();
    }

    if($ownership != false){
        $url = "http://api.eolin.com/myEolin/getEntryInfo.js?permalink="
        .rawurlencode($permalink)."&id=".불entry['id']."&log=0";
    }else{
        $url = "http://api.eolin.com/myEolin/getEntryInfo.js?permalink="
        .rawurlencode($permalink)."&id=".불entry['id']."&log=1";
    }       

    $target .=  '<span class="EolinBookmarkBtn"><a href="#void"  
    title="이올린에 북마크하기"  onclick="bookMarkEolin('.불entry['id'].
    ', ''.불permalink.'', 'bookmark');return false;">
    <img src="'.불img.'" 
    style="vertical-align:middle;" /></a></span>';
    if($entry['visibility'] == "3" && $getMyvote == 1){
        $target .=  '(<span id="bookmarkEolin'.불entry['id'].'" 
        class="EolinBookmarkCount">0</span>)
        <span class="EolinVoteBtn"><a href="#void"  
        title="이올린에 추천하기"
        onclick="bookMarkEolin('.불entry['id'].',''.불permalink.'', 'vote')
        ;return false;">
        <img src="'.불img2.'" 
        style="vertical-align:middle;" />
        </a></span>(<span id="voteEolin'.불entry['id'].
        '" class="EolinVoteCount">0</span>)';
        $target .= "<script language=\"JavaScript\"
        type=\"text/javascript\">//<![CDATA[    
                    apiEolinURL.push(\"".불url."\");
                    //]]></script>";

        //$target .= "<script src='".불url."' 
        type='text/javascript' ></script>";
    }
    $target .= "</div>";
}

변경후========================================================================
**Bm_myEolin 함수**
global $hostURL, $blogURL, $pluginURL,$owner,$permalink,$entry,$configVal,$entryView;

if($entry['visibility'] >= "2" ){
    $myeolin .= '<div class="EolinBmVote">';
    $img = $pluginURL."/images/bookmarkToEolin.gif";
    $img2 = $pluginURL."/images/voteToEolin.gif";
    $permalink = $hostURL. (isset($permalink)?$permalink:'');

    $ownership = false;
    if(true==function_exists('doesHaveOwnership')){
        $ownership = doesHaveOwnership();
    }

    if($ownership != false){
        $url = "http://api.eolin.com/myEolin/getEntryInfo.js?permalink="
        .rawurlencode($permalink)."&id=".불entry['id']."&log=0";
    }else{
        $url = "http://api.eolin.com/myEolin/getEntryInfo.js?permalink="
        .rawurlencode($permalink)."&id=".불entry['id']."&log=1";
    }       


    $myeolin .=  '<span class="EolinBookmarkBtn"><a href="#void"  
    title="이올린에 책갈피"    onclick="bookMarkEolin('.불entry['id'].
    ', ''.불permalink.'', 'bookmark');return false;">
    <img src="'.불img.'" 
    style="vertical-align:middle;" />책갈피</a>
    </span>';
    if($entry['visibility'] == "3" && $getMyvote == 1){
        $myeolin .=  '(<span id="bookmarkEolin'.불entry['id'].'" 
        class="EolinBookmarkCount">0</span>)
        <span class="EolinVoteBtn"><a href="#void"  
        title="이올린에 추천하기"
        onclick="bookMarkEolin('.불entry['id'].',''.불permalink.'', 'vote');
        return false;">
        <img src="'.불img2.'" 
        style="vertical-align:middle;" />
        추천</a></span>(<span id="voteEolin'.불entry['id'].
        '" class="EolinVoteCount">0</span>)';
        $myeolin .= "<script language=\"JavaScript\"
        type=\"text/javascript\">//<![CDATA[    
                    apiEolinURL.push(\"".불url."\");
                    //]]></script>";

        //$myeolin .= "<script src='".불url.
        "' 
        type='text/javascript' ></script>";
    }
    $myeolin .= "</div>";
}
misc::dress('myeolin_vote', $myeolin, $entryView);
return $target;

내려받기

변경된 소스를 보면 알 수 있지만 전역 변수에 $entryView를 추가하고 if($entry['visibility'] >= "2" ){ 이하의 $target를 모두 $myeolin으로 바꾸고 return 문 앞에 misc::dress('myeolin_vote', $myeolin, $entryView);만 추가하면 된다.

일단 이렇게 소스를 바꾼 뒤 책갈피와 추천 링크를 표시할 곳에 [ ##_myeolin_vote_## ] 치환자를 삽입하면 된다. [ ##_myeolin_vote_## ]는 공백없이 입력해야 한다.

프로그램에 대한 지식이 전혀 없어 죽어도 소스를 패치할 수 없는 사람은 다음 링크에서 내려받아 사용하기 바란다. 나와 똑 같이 사용하고 싶다면 폴더째 올려 덮어쓰면 되고 부분적으로 패치하고 싶은 사람은 파일별로 올려서 사용하면 된다.

압축 파일에 포함된 파일은 다음과 같다.

blog/index.php      블로그 주소를 치고 들어오면 자동으로 최근글로 분기
blog/search/index.php   검색 결과에서 페이지를 한 쪽 당 글수로 표시
blog/entry/index.php    절대 주소를 문자로 한 경우 페이지내의 모든 링크를 문자로 표시
plugins/myEolin/index.php   이올린의 책갈피와 추천 링크를 치환자로 변경

관련 글타래