텍스트큐브 1.6부터는 단일 블로그의 경우에는 아파치의 mod_rewrite 를 사용하지 않아도 사용이 가능합니다. 이 경우 예쁜 주소 (http://example.com/entry/테스트글) 는 불가능하지만, 거의 비슷한 형식의 주소 (http://example.com/index.php?/entry/테스트글) 로 사용할 수 있습니다.

이렇게 변경되는 과정에서 텍스트큐브 설치 디렉토리 안의 모든 파일 접근을 텍스트큐브가 관리하기 때문에 기존에 사용하던 텍스트큐브 디렉토리 안의 다른 프로그램 (구글 사이트맵이나 통계용 플러그인) 들이 동작하지 않는 경우가 있습니다. 이 경우에는 텍스트큐브가 설치된 디렉토리 안의 .htaccess의 내용에 몇가지를 추가해서 그 문제를 해결할 수 있습니다.

예를 들어, 텍스트큐브 루트 디렉토리에 sitemap.php가 있는 경우 웹 주소를 통해서 접근하도록 하기 위해서는RewriteBase / 줄 바로 아랫줄에 다음의 두 줄을 추가합니다.

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(sitemap\.php) sitemap.php [L]

첫번째 줄은 그 아랫줄이 실행되기 위한 조건입니다. '만약 요청한 파일이 있다면'의 의미입니다. -f는 파일, -d는 디렉토리입니다. 그 다음줄은 '^(sitemap.php) 이 있으면 뒤의 파일로 이동하고 종료하라' 의 의미입니다. ^()은 정규식인데, 정규식에 관해서는 creorix님이 작성하시는 정규식 강좌를 참조하시면 됩니다.

응용해서, 두 개 이상의 파일일 경우를 작성해 보겠습니다.

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(sitemap\.php|statistics\.php) $1 [L]

sitemap.php이나 statistics.php가 있으면 그 파일을 실행하라~ 는 의미입니다. 정규식 대응때 $1, $2는 앞에 나온 조건의 괄호 하나하나에 차례대로 대응이 됩니다.

참 쉽죠?

이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
inureyes입니다. :p
2008/01/11 16:41 2008/01/11 16:41
inureyes 이 작성.

아래의 팁은 TNF 포럼사용자 지원 게시판의 글타래 중 요약된 글입니다.

원본 글타래는 이 곳에서 보실 수 있습니다.

질문 :

태그가 키워드이기도 할 때 포스트 밑에 나오는 태그 옆에 + 모양의 이미지(plugins/KeywordUI/images/flag_green.gif)가 표시되는데요, 전에 coolant 스킨을 사용할 때에는 아무 문제가 없었는데 태터용 스킨으로 교체하니 이미지 주변에 굵게 테두리가 형성되는군요. 보기가 흉해서 수정하려고 봤는데 막막하더라고요.

여기서 질문 1 - 스킨 내 css를 수정해서 테두리를 없애려면 어디를 어떻게 고쳐야 할까요? 본문 내의 다른 이미지들은 모두 테두리가 없는 상태입니다.

그래서 이번에는 플러그인 설정에 가서 '태그 설명에 키워드를 사용합니다'를 해제해 보았습니다. 하지만 더이상 키워드-태그 동시동작은 안함에도 불구하고 이미지는 여전히 같이 뜨더군요; 플러그인은 한번도 들여다본 경험이 없는데 난감해졌습니다.

질문 2 - '태그 설명에 키워드를 사용합니다'를 해제했을 때에도 표시되는 이미지, 어떻게 없애야 할까요?

답변 :

그 부분을 아예 출력되지 않도록 하기 위해서는 plugins/KeywordUI의 index.xml을 열어서

<listener event="ViewTagLists">KeywordUI_bindTag</listener>

요 줄을 지워 주시면 됩니다.

아니면 css를 조정해서, 이미지에 테두리 표시가 되지 않도록 하는 방법도 있겠습니다. 이렇게 하면 기능도 사용할 수 있고, 테두리도 없어지겠죠.

플러그인의 '태그 설명에 키워드를 사용합니다' 옵션은, 특정 태그 페이지 (http://example.com/tag/테스트) 를 보여줄 때, 같은 이름의 키워드 로그 (이 경우에는 '테스트'라는 이름의 키워드 로그) 가 작성되어 있는 경우 그 키워드 로그를 마치 태그의 설명인 것 처럼 태그 목록 앞에 붙여주는 기능입니다. http://forest.nubimaru.com/tag/TNF 를 보시면, 태그 목록 앞에 설명이 있죠? 그걸 지원하는 기능입니다.

도움이 되셨으면 합니다~

이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
inureyes입니다. :p
2008/01/01 17:50 2008/01/01 17:50
inureyes 이 작성.

개별 글 주소로 접근했을 경우에 아래 표시되는 페이지 번호나 네비게이션을 보기 싫은 경우가 있습니다. 이 경우 간단하게 소스를 수정하시면 됩니다.

우선 /lib/piece/blog/end.php 의 71번째 줄을 찾은 후 아래와 같이 조건을 추가해 줍니다.
원래는
if (isset($paging)) {

이렇게 된 부분을
if (isset($paging) && count($entries) > 1) {

으로 바꾸면 글이 하나만 출력되는 경우에는 페이지 번호가 출력되지 않습니다.

이 글은 태터툴즈 레트로 게시판의 질문에 대한 답으로 작성 되었습니다. 이후 이러한 팁이 궁금하시면 howto 로그의 방명록에 질문을 남겨주세요^^

이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
inureyes입니다. :p
2007/10/07 19:10 2007/10/07 19:10
inureyes 이 작성.

앞의 글을 읽지 않으셨다면 반드시 앞의 글을 먼저 보시길 추천합니다. :)

실제 구조


앞의 글에서 보았던 구조를 한 번 더 복잡하게 뒤집어 봅시다.

resize_image

앞 글의 마지막 그림보다 살짝 복잡해 졌습니다. 이상과 실제 구현의 차이란 이렇게 나는 것이기도 합니다.

굉장히 복잡해 보이지만 시계 방향으로 돌아가는 흐름을 감지하실 수 있을 것입니다. rewrite -> interface -> view -> skin -> browser로 이어지는 흐름을 '지하철 2호선' 에 비유하면 나머지 지하철들도 점차 보이실겁니다. 주 흐름에 대해서는 앞의 글에서 대충 설명했으니 이번에는 이 그림에 추가된 부분들을 보도록 하지요.

컴포넌트의 storage binder는 실제로 데이터를 저장하는 부분입니다. 태터툴즈 1.1부터 차츰 추상화의 길을 걷고 있지만 아직 최종적인 목표까지는 요원합니다. component 디렉토리 안에 텍스트큐브에서 사용되는 데이터 객체들이 지정되어 있고, 그 객체들은 Eolin.PHP.Core 안의 DBQuery 클래스를 사용하여 데이터 베이스 입출력이나 파일 입출력을 시도합니다. 대부분의 데이터 객체들은 Textcube.data 라는 시작 이름을 가지고 있지만, 1.5부터 추가된 캐시 모듈의 경우에는 데이터 객체가 아니라 긴 시간을 갖는 버퍼이기 때문에 Needlworks.Cache.PageCache 에 위치하고 있습니다.

그러면 각 부분의 소스를 어디서 찾을 수 있는지 한 번 볼까요?

구조와 소스의 대응


resize_image

앞의 글을 잘 읽으셨다면 대충 이제 감이 오실 수도 있을 시점이긴 합니다만...

각 부분에 해당되는 파일들이 어디에 위치하고 있는지 일목요연하게 볼 수 있는 도표입니다. 이젠 더 복잡하게 그릴 자리도 남아있지가 않기 때문에 이정도로 정리가 되겠습니다. 이 도표가 '실제 기능 순서' 대로 그려져 있기 때문에 이번에는 디렉토리 구조를 중심으로 위의 그림을 다시 그려 보겠습니다.

resize_image

어느 디렉토리가 어디에 해당되는지 좀 보이시나요?

위의 그림을 다 쪼개 놓은 후에 디렉토리 구조대로 뭘 하는지 적어놓은 도표입니다.

외계어?


위의 설명까지 읽으면 감이 잡히는 경우와 잡히지 않는 경우가 있을겁니다. 공부라는 것이 으레 그렇듯이, 이론만 열심히 한다고 이해되는 경우는 드물지요. 실제와의 차이가 상당히 있기 때문에 그걸 좁혀 나가려면 역시 연습문제 밖에 방법이 없습니다.

소스 보기 팁


PHP/MySQL을 좀 아는데 그래도 위의 설명들이 전부 외계어 처럼 보이신다고요? 그러한 경우를 위해서 '뜯어보는 순서'를 적어보도록 하겠습니다.

  • 인터페이스를 고치고 싶으시면 /blog 디렉토리를 보세요.
  • 함수의 기능을 추적하고 싶으면 /lib/model 에서 시작합니다.
  • 출력되는 형태를 바꾸고 싶으면 /lib/view를 수정합니다.
  • 블로그나 관리자 화면의 아웃라인을 바꾸고 싶으면 /lib/piece를 봅니다.
  • 플러그인에 특화된 기능이나 들여오기/내보내기를 수정하고 싶으면 /components를 봅니다.
  • EAF의 동작이나 AJAX 구현을 공부하거나 수정하고 싶으면 /scripts를 봅니다.
어디서부터 손을 대야 할 지 짐작되지 않을때 위의 팁이 도움이 될 수 있으실 것입니다.

텍스트큐브 1.5 소스에서 꼭 알아두어야 하는 점!


1. 경우에 따라 같은 기능을 하는 함수가 /lib/model에도 구현되어 있고 /components 에도 구현되어 있습니다.
이러한 부분은 텍스트큐브의 역사에서 비롯됩니다. 1.1 마일스톤까지 사용하던 최적화 프로그램 때문에, 최적화 프로그램으로 소스를 처리한 이후에는 lib 디렉토리가 사라집니다. 이러한 경우 플러그인이나 백업/복원 등에서 해당 기능을 하는 함수들을 사용하기 위해서 컴포넌트가 만들어 졌습니다. 현재는 전체적인 기능을 컴포넌트 쪽으로 이전해 나가는 중입니다.

2. 데이터베이스에 날리는 쿼리 형태가 여러가지가 있습니다.
데이터베이스 접근의 추상화가 진행되고 있기 때문입니다. 이를 위하여 최종적으로는 TableQuery class의 확장형을 사용할 예정입니다. 현재는 mysql_ 형태의 php 내장 함수를 바로 사용하는 부분과, DBQuery 클래스를 사용하는 부분이 대다수, TableQuery의 프로토타입을 사용하는 경우가 소수 존재합니다. 쿼리를 날리는 방법이 여러 부분에 걸쳐 다르기 때문에 혼동을 일으킬 수 있으므로, 가급적이면 변화의 중간 형태로 도입된 DBQuery 클래스를 사용하시기 바랍니다.

이상으로 간단하게나마 텍스트큐브 구조를 훑어 보았습니다. 소스 고치기에 도움이 되셨으면 좋겠네요.  다음 코어 드릴러는 Eolin.PHP.Core에 관한 간단한 설명들이 될 예정입니다.


이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
inureyes입니다. :p
2007/09/17 00:05 2007/09/17 00:05
inureyes 이 작성.

텍스트큐브 1.5의 자동 저장 기능은 페이지가 열린 시간부터 5분마다 자동저장을 시도하고,  글 입력을 멈춘 후 5초가 지나면 자동 저장을 시도합니다. 이 간격을 조정하고 싶으면 /blog/owner/entry/edit/item.php 파일을 수정하면 됩니다.

5분마다 강제로 자동 저장하는 간격을 수정하려는 경우
   862                         <script type="text/javascript">
   863                             //<![CDATA[
   864                                 entryManager = new EntryManager();
   865                                 reloadUploader();
   866                                 window.setInterval("entryManager.saveDraft();", 300000);
   867                             //]]>
   868                         </script>

에서 300000 부분을 수정하면 됩니다. 단위가 밀리초이기 때문에 원하는 초에 1000을 곱한 값을 적어주시면 됩니다.

글 입력을 멈춘 후 5초마다 저장하는 간격을 바꾸고 싶으신 분은
   414                                     this.saveDraft = function () {
   415                                         this.autoSave = true;
   416                                         if (this.nowsaving == true) {
   417                                             this.timer = null;
   418                                             this.autoSave = false;
   419                                             return;
   420                                         }
   421                                         this.timer = null;
   422                                         if (this.delay) {
   423                                             this.delay = false;
   424                                             this.autoSave = false;
   425                                             this.timer = window.setTimeout("entryManager.saveDraft()", 5000);
   426                                             return;
   427                                         }
   428                                         this.save();
   429                                         return;
   430                                     }
의 425번째 줄의 5000을 원하는 숫자로 수정하시면 됩니다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
inureyes입니다. :p
2007/09/16 13:57 2007/09/16 13:57
inureyes 이 작성.

첫 글을 어떻게 적어야 하나 고민 중입니다. 하필 맡은 부분이 '코어'라고들 말하는 텍스트큐브 소스이기 때문에, 파고들자면 한이 없고 그러면 그게 기술문서들이나 별반 다를 바가 없게 됩니다. 코어는 결국 파고 드는만큼 알 수 있는데, 텍스트큐브의 코어 구조는 변화의 급물살을 타고 있지요.

어떻게 시작하면 좋을까 고민하다가, 예전 태터캠프의 기술 세션 발표 주제였던

'뭘 바꾸고 싶을 때 어디를 건드리면 되냐?'

라는 부분을 중심으로 드릴링 해 볼 까 합니다.

시작

자 그럼 한 번 파 볼까요?


MVC


MVC는 공학쪽에 있는 분들에게는 익숙한 용어입니다만, 보통은 잘 쓰지 않는 말입니다.
 
MVC 다이어그램

대충 이런겁니다. (그림은 위키백과에서)

블로그를 예로 들겠습니다. 사용자가 접속하면 블로그 프로그램이 보내는 기본적인 출력view을 보게 되죠. 사용자가 링크를 누른다거나 보관함을 본다거나 댓글을 적는 등의 선택을 하게 되면 제어기controller가 그 움직임을 받아 들입니다. 제어기는 상황에 맞는 동작을 하기 위해 동작에 필요한 모델model 과 동작을 전달하게 됩니다. 그러면 모델은 이를 바탕으로 출력을 만들어내고, 출력은 경우에 따라 모델과 상호동작하면서 그 결과를 다시 사용자에게 보여줍니다.

그러면 텍스트큐브를 한 번 보죠.

resize_image

텍스트큐브의 기본적인 다이어그램.

윗 그림은 가장 기본적인 텍스트큐브의 구조입니다. 인터페이스interface는 제어기와 출력의 조합이고, 라이브러리library는 모델과 출력의 조합입니다. 위의 원칙을 기억하세요. 텍스트큐브는 MVC를 잘 따르고 있기 때문에 소스를 수정하기 위해서는 우선 자신이 원하는 부분이 Model / view / control 중 어디에 해당되는지 생각해 보면 됩니다.

위에 드린 설명을 꼭 기억하세요!
'이론상' 저렇지만 이제 빨간 약을 드실 시간입니다.

모피어스?

모 영화에 출연하신 모 분과는 정말로 관계가 없습니다.


지하 100미터


위의 MVC가 웹 프로그램에 그대로 적용되지는 않겠습니다. 우선 보여주고 명령을 내리는 부분은 서버와 저 멀리 떨어진 브라우저이고, 따라서 실제로 인터넷 익스플로러나 파이어폭스에 가서 보여주는 부분은 그 자체로도 하나의 프로그램입니다. AJAX는 자바스크립트 언어로 작성된 프로그램이 사용자의 웹 브라우저로 전송된 후, 서버에 설치된 프로그램과 서로 이야기하면서 동작합니다. 따라서 텍스트큐브는 크게 '브라우저쪽의 텍스트큐브' 와 '서버쪽의 텍스트큐브'  이 두 프로그램이 서로 이야기를 나누며 동작한다고 생각하시면 됩니다.

그러면 그걸 반영해서 조금은 더 엘리건트한 그림을 봅시다.

resize_image

살짝 복잡해지고 있습니다. 네. 그렇습니다.

위와 '본질적'으로는 같은 그림입니다만 좀 다르게 보일겁니다. 복잡하죠...

윗쪽은 웹 브라우저에서 돌아가는 부분이고, 아랫쪽이 서버에서 돌아가는 부분입니다. 텍스트큐브 블로그에 접속하게 되면 브라우저로 위의 부분들이 전송되고, 자바스크립트 플랫폼이 돌아가게 됩니다.

링크를 누른다거나 댓글, 트랙백 등등의 정보가 전송되면 서버에서는 apache rewrite module을 사용해서 (.htaccess가 하는 일입니다) 전송된 주소의 값을 분석한 후, 실제 코드 주소와 코드로 넘어가는 값을 분리해 냅니다.

그 결과가 인터페이스로 전달됩니다. (인터페이스가 blog/ 디렉토리 아래의 부분들입니다) 그러면 인터페이스에서는 넘어온 값들에 따라 지정된 일을 하기 위해 model을 부릅니다. (lib/model 디렉토리 아래에 있습니다)

모델은 컴포넌트 (components 디렉토리 아래에 있습니다) 와 상호작용하며, 데이터베이스를 읽거나 계산을 하는 등의 동작을 하면서 그 결과를 view(/lib/view 디렉토리 아래에 있습니다) 로 보내어 출력할 html 코드를 만들어냅니다. 이 과정에서 스킨 파서 (/lib/blog.skin.php) 를 이용해서 스킨 파일을 오려내어 필요한 부분을 view에서 읽어들인 후 치환자등에 html을 입히게 됩니다. 이 때 스킨 파서의 dress라는 함수를 이용합니다.

그리고 브라우저로 화면을 전달하여 뿌려주게 되지요.
플러그인이나 ajax 과정 등을 일단 다 생략한 아주 기본적인 블로그 화면 출력은 이렇게 이루어집니다.

다음 시간에는 조금 더 복잡한 그림으로 찾아 뵙겠습니다.^^

축하

다들 여기까지 오신다고 수고하셨습니다!


이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
inureyes입니다. :p
2007/09/04 23:45 2007/09/04 23:45
inureyes 이 작성.

HOWTO 사이트를 처음 이야기 한지는 오래 되었습니다만 이제서야 시작합니다.

올해 봄쯤으로 거슬러 올라갑니다. TNF 포럼의 유마님께서 '코드를 이해하려면 어떻게 해야 할지'에 관하여 문의 메일을 주셨었습니다. 당시에 이런 저런 도움을 많이 드리고 싶었습니다. 의욕이 있는 사람에게 불가능한 것은 거의 없지요.

하지만 도움을 드리지를 못했습니다. 당시는 태터툴즈 1.1에서 1.2를 준비하던 때였고, 다들 코딩 말고 학업이나 생업등 다른 일들이 있기 때문이었습니다. 'PHP'라는 언어와 텍스트큐브(당시엔 태터툴즈 였습니다만) 에 대해 하나씩 차근차근 설명 드리기에는 시간이 도저히 나지를 않았습니다.

벌써 그 때부터 거의 반 년이 흘렀습니다. 이제 태터툴즈는 텍스트큐브가 되었고, 니들웍스가 구성되고, 소스의 여러 부분에 걸쳐 각 부분을 맡으신 여러 커미터 분들이 많이 계십니다. 텍스트큐브에서는 팀블로그도 잘 지원하게 되었습니다. 이제는 트랙백도 검색이 되지요. 예전에는 힘들었겠지만 지금은 충분히 가능하다 싶습니다.

블로그 플랫폼으로 해 볼 수 있는 여러가지 가능성들이 있습니다. HOWTO 사이트는 그 중 하나의 모습을 보여드릴 것입니다. 하지만, 사실 이 사이트는 예전 메일을 주셨던 유마님과, 아마도 굉장히 많을 '유마님들' 을 위한 것입니다.


몇 페이지를 넘기는 기술 문서보다 예제 하나가 더 쉬운 경우들이 있습니다.

텍스트큐브를 단장하고 싶은 분들에 대한 쉬운 허브가 되기를 바래봅니다.


이올린에 북마크하기(0) 이올린에 추천하기(0)
Writer profile
inureyes입니다. :p
2007/09/04 22:27 2007/09/04 22:27
inureyes 이 작성.

텍스트큐브를 다양한 언어권에 대응되도록 언어를 추가하셨을 때, 다른 분들과 공유하고 싶은 경우 있으면 이 글에 트랙백을 날려주세요. :)
이올린에 북마크하기
Writer profile
inureyes입니다. :p
2007/09/01 22:19 2007/09/01 22:19
inureyes 이 작성.

텍스트큐브 소스의 수정이나 기능 추가에 대하여 다른 분들과 공유하고 싶은 팁이 있으면 이 글에 트랙백을 날려주세요. :)
이올린에 북마크하기
Writer profile
inureyes입니다. :p
2007/09/01 22:18 2007/09/01 22:18
inureyes 이 작성.

텍스트큐브 플러그인 제작이나 응용하는 다양한 방법들을 다른 분들과 공유하고 싶은 팁이 있으면 이 글에 트랙백을 날려주세요. :)
이올린에 북마크하기
Writer profile
inureyes입니다. :p
2007/09/01 22:17 2007/09/01 22:17
inureyes 이 작성.