1

주제: patchworks: 코어 수정에 대한 설명

안녕하세요. lifthrasiir입니다. 다들 토끼군이라고 부르지만 그건 넘어 가고;

patchworks 프로젝트는 태터툴즈의 (현재는 위지윅) 편집기와 (현재는 TTML) 포매터를 완전히 모듈화시키고 그 바탕에 새로운 편집기·포매터 플러그인을 만들려는 프로젝트입니다. 서브버전 커밋이 계속 안 되는 고난을 겪으면서 오늘 r3035로 커밋을 했는데, 여기에 있는 내용이 상당히 많기 때문에 구체적으로 어떻게 바뀌었는지 설명하려고 글을 씁니다.

...심심하신 분께서는 1.2 브랜치 체크아웃해서 테스트해 보시고 피드백해 주셔도 됩니다.


편집기와 포매터

약간 혼란스러울 수 있는 개념인데, 편집기와 포매터는 연관은 있지만 엄연히 다른 개념입니다. 편집기는 날 텍스트로 된 걸 보기 좋게 꾸며서 편집하기 좋게 인터페이스를 제공하는 것이고, 포매터는 이런 날 텍스트를 실제로 HTML로 렌더링하는 역할을 하게 됩니다. 따라서 편집기는 사실상 자바스크립트로 구현되고 포매터는 PHP로 구현된다고 보면 됩니다. 날 텍스트의 형태는 포매터에 따라 달라질 수 있기 때문에 보통 편집기와 포매터가 함께 제공된다고 생각할 수 있겠습니다.

편집기 인터페이스

각각의 편집기는 하나의 자바스크립트 오브젝트로 구현됩니다. 이 오브젝트는 편집기에 관련된 모든 일(이벤트 처리나 포맷 변환 등등...)을 하게 되며, 여러 개의 편집기 오브젝트가 공존할 경우에도 동작하도록 구현하는 게 좋습니다. 다만 현재 구현은 속성 창 때문에 하나의 오브젝트만 활성화되도록 되어 있습니다. 이 오브젝트는 외부에 네 개의 메소드를 노출시키는데,
- editor.initialize(textarea): 주어진 textarea 엘리먼트 주변에 필요한 요소들(속성 창 등)을 추가하고 이벤트 핸들러를 설치합니다.
- editor.finalize(): editor.initialize의 반대 역할로, 추가했던 요소들과 이벤트 핸들러 등을 모두 지워서 textarea를 다시 원래대로 되돌려 놓습니다. 이 메소드는 다른 편집기를 선택할 때 현재 편집기를 비활성화시키기 위해 필요합니다.
- editor.syncTextarea(): 원래 textarea가 아닌 다른 곳(위지윅 에디터 같은 경우)에서 편집이 일어 나고 있을 때 그 변경 사항을 원래 textarea에 동기화하는 역할을 합니다. textarea를 그대로 쓴다면 아무 일도 하지 않습니다.
- edtior.addObject(data): 편집기에 data로 명시된 그림·동영상·주크박스 등을 삽입합니다. data는 {mode: 'Image1L', objects: [...]} 형태의 오브젝트로 objects 속성에는 추가되어야 할 것들의 경로와 옵션, 설명 등이 배열로 들어 있습니다. 성공하면 true를, 아니면 false를 반환합니다.

거꾸로 편집기에서는 (아마 편집기에서나 쓰일 법한) 다음과 같음 전역 함수를 사용할 수 있습니다.
- savePosition(textarea): 주어진 textarea의 현재 선택 영역을 보존합니다. insertTag와 함께 쓰입니다.
- insertTag(textarea, prefix, postfix): 주어진 textarea의 현재 선택 영역의 앞뒤에 prefix와 postfix라는 텍스트를 추가합니다.
- editorChanged(): entryManager에게 현재 편집기에 있는 내용이 바뀌었음을 알립니다. 자동 저장에 쓰입니다.

포매터 인터페이스

포매터 인터페이스는 두 개의 PHP 함수로 구현됩니다. 하나는 텍스트를 받아서 HTML로 변환하는 함수(formatfunc)이고, 또 하나는 텍스트를 받아서 RSS 등에 쓸 수 있는 짧은 요약문을 반환하는 함수(summaryfunc)입니다. 이 때 주의할 점은 summaryfunc은 전문·부분 공개 설정을 읽어서 적절히 잘라 주고 하는 역할도 갖고 있다는 것입니다. (나중에 코어가 바뀌는 것을 염두에 두고 이렇게 했습니다.) formatfunc과 summaryfunc은 같은 형태의 인자를 받는데,

function formatfunc($owner, $id, $content, $keywords = array(), $useAbsolutePath = false);
// $owner, $id: 해당 글이 어디에 속해 있는지를 보임.
// $content: 변환될 글의 내용.
// $keywords: 키워드의 목록. 배열이 아니면 키워드 기능을 무시함. (키워드가 실제로 어떻게 해석되는지는 포매터마다 다름)
// $useAbsolutePath: 참이면 URL에 절대 경로를 사용하도록 함.

여기서 텍스트를 어떻게 지지고 볶는 지는 포매터 나름입니다.

편집기·포매터 플러그인

이번 작업으로 편집기와 포매터를 위한 플러그인 XML 포맷이 새로 생겼으며, 다음과 같습니다.

<binding>
    <formatter xml:lang="ko" id="markdown" name="마크다운 포매터">
        <format>FM_Markdown_format</format>
        <summary>FM_Markdown_summary</summary>
        <usedFor editor="markdown">마크다운 마크업</usedFor>
        <usedFor editor="plain" />
    </formatter>
    <editor xml:lang="ko" id="markdown" name="마크다운 편집기">
        <initialize>FM_Markdown_editorinit</initialize>
        <usedFor formatter="markdown">마크다운 마크업</usedFor>
    </editor>
</binding>

<formatter> 및 <editor> 엘리먼트는 각 편집기·포매터를 식별하기 위한 식별자(id)를 갖습니다. 이 식별자는 꼭 필요하며, 다른 플러그인과 겹치지 않도록 적절히 잡아 주시는 게 좋습니다. (이 속성은 한 플러그인이 서로 비슷한 여러 편집기·포매터를 가질 경우를 감안하여 추가되었습니다.)

<format>, <summary>, <initialize>는 각각 HTML 변환 및 요약(포매터)과 초기화 코드(편집기)를 명시합니다. format과 summary는 앞에서 설명한 formatfunc과 summaryfunc과 같고, initialize는 해당 편집기 정보를 담은 하나의 인자를 받아서 편집기 초기화에 사용될 자바스크립트 코드를 반환합니다. initialize의 반환값은 switch문-_-에 들어 가기 때문에, 성공하면 return 문으로 해당 오브젝트를 반환하도록 하고 실패하면 break;로 빠져 나가 기본 편집기를 쓰도록 해야 합니다.

<usedFor>는 편집기와 포매터 사이의 연관 관계를 표시합니다. 예를 들어서 위의 설정에서는 "마크다운 포매터는 마크다운 편집기(markdown)와 기본 편집기(plain)에 쓰일 수 있다"는 것을 나타냅니다. 안에 텍스트 데이터가 있으면 해당 편집기-포매터 짝에 별도의 이름을 붙여 줍니다. (물론 아직 쓰이지는 않습니다만...) 편집기와 포매터가 서로를 가리키는 선언을 가지고 있어도 됩니다만, 이름이 따로 붙여져 있을 경우 둘 중 어느 게 사용될 지는 알 수 없습니다. (따라서 같은 이름을 쓸 것을 권장합니다)

아무 편집기·포매터 플러그인도 없을 때는 기본적으로 HTML 포매터(html)와 날 텍스트 편집기(plain)만이 사용됩니다. 이 포매터와 편집기는 기본적인 작업만을 수행하며, 새로운 플러그인을 만들고자 할 때 참고할 수 있고 편집기가 따로 없는 포매터를 위해서도 사용할 수 있습니다.

기타 코어 수정

- <prefix>Entries 테이블에 편집기와 포매터를 나타내는 두 개의 필드가 추가되었습니다.
- XML 백업 포맷에 편집기와 포매터 속성이 추가되었습니다. 속성이 없으면 현재 기본 설정을 사용하기 때문에 호환성은 유지됩니다.
- language/messages.php가 추가되었습니다. 이 파일은 관리자 언어 설정에 따라 자바스크립트 코드를 생성하며, PHP랑 비슷하게 _t() 함수를 구현합니다. 자바스크립트 등에서 지역화된 문자열이 필요할 때 쓸 수 있습니다. (N.B. 이 코드는 블로그 언어 설정에서도 쓸 수 있게 하는 게 좋겠지만 약간 모호한 경우가 있어서 뒤로 미룹니다.)
- 편집기에서 사용하는 자바스크립트 및 CSS 등을 추가할 수 있게 하기 위한 ShowAdminHeader 이벤트가 추가되었습니다. 각 함수는 알아서 $suri를 파싱해서 여기에 출력을 해야 하나 말아야 하나를 결정해야 합니다;
- EAF의 STD.addEventListener가 addEventListener 외에도 removeEventListener를 추가하도록 했습니다. 용도는 물론 편집기 finalize 메소드에서 쓰려고...


이상이 r3035(와 글 쓰면서 수정한-_- r3036)의 수정 목록입니다. 질문이 있거나 버그가 있거나(...없기를-_-) 심심하거나 <del>밥 뜯어내고 싶다거나</del> 하면 이 글타래에 달아 주세요.

2

답글: patchworks: 코어 수정에 대한 설명

lifthrasiir 작성:

<del>밥 뜯어내고 싶다거나</del> 하면 이 글타래에 달아 주세요.

처음보는 분이 프로젝트에 글타래를!! 라고 생각하는 찰라 그 유명한[..] 토끼군님이라는 사실을 알았네요;;
반갑습니다~

좀 다른 얘기지만 태그는 bbcode를 이용하여 사용하실 수 있습니다~

하늘은 스스로 삽질하는 자를 삽으로 팬다

3

답글: patchworks: 코어 수정에 대한 설명

나니 작성:
lifthrasiir 작성:

<del>밥 뜯어내고 싶다거나</del> 하면 이 글타래에 달아 주세요.

처음보는 분이 프로젝트에 글타래를!! 라고 생각하는 찰라 그 유명한[..] 토끼군님이라는 사실을 알았네요;;
반갑습니다~

...유명하다니 llorz

나니 작성:

좀 다른 얘기지만 태그는 bbcode를 이용하여 사용하실 수 있습니다~

<del>(이나 <s> 같은 거...)은 없더군요.

4

답글: patchworks: 코어 수정에 대한 설명

이야... 대단하십니다! svn update 때리러 가야겠군요! 후기는 그 때 다시!

5

답글: patchworks: 코어 수정에 대한 설명

TTML 포매터를 통하여 포스트를 출력할 때 무참하게 깨져 나옵니다.

참고 스샷 올립니다^^

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'

6

답글: patchworks: 코어 수정에 대한 설명

어제 TTML을 업데이트했습니다.
다른 플러그인은 괜찮습니다만, 미투데이와 플톡을 블로그에 출력해주는 플러그인만 에러가 발생합니다.

그러나, 지금은 어떤 것이 문제인지는 모르겠씁니다. 일단, 스샷 부터~

유마 (2007-03-20 14:28:58)에 의해 마지막으로 수정

7

답글: patchworks: 코어 수정에 대한 설명

전 지극히 잘 되는군요.

당신의 삶속에 매화꽃 향기처럼 늘 아름다운 향기로 가득하길...
# J.Parker

8

답글: patchworks: 코어 수정에 대한 설명

예. 제가 올렸던 문제는 플러그인에서 해결이 되었습니다. ^^ 그게 해결되고 나니, 그 다음은 별 문제가 없어보입니다.
글도 하나 써봤고요.. 위의 본문에 적혀 있듯이 다른 방식이겠지만, 사실 제가 글을 쓸때는 별 차이를 모르겠더군요...
아무래도 기술적인 변화인가 봅니다.

9

답글: patchworks: 코어 수정에 대한 설명

inureyes 작성:

TTML 포매터를 통하여 포스트를 출력할 때 무참하게 깨져 나옵니다.

참고 스샷 올립니다^^

키워드가 있는 경우를 실수로 테스트하지 않고 커밋했네요;;; r3043에서 고쳤습니다.

유마 작성:

예. 제가 올렸던 문제는 플러그인에서 해결이 되었습니다. ^^ 그게 해결되고 나니, 그 다음은 별 문제가 없어보입니다.
글도 하나 써봤고요.. 위의 본문에 적혀 있듯이 다른 방식이겠지만, 사실 제가 글을 쓸때는 별 차이를 모르겠더군요...
아무래도 기술적인 변화인가 봅니다.

지금은 기술적인 변화이지만 다른 편집기 및 포매터가 등장하면 곧 현실(?)로 느끼실 수 있을 겁니다. smile

10

답글: patchworks: 코어 수정에 대한 설명

lifthrasiir 작성:

지금은 기술적인 변화이지만 다른 편집기 및 포매터가 등장하면 곧 현실(?)로 느끼실 수 있을 겁니다. smile

예. 지금까지의 편집기 와는 다르니까 태터에 포함되는 것이라고 생각하고 있습니다.

언넝 현실(?)이 와서 그 변화를 느꼈으면 좋겠습니다. lol

잘 모르니깐, 뭐가 다른 건지 궁금해집니다. ^^a

가끔씩 TTML 와 HTML 을 왔다갔다 할 때.... 글 내용을 잡아 먹는 것 같습니다.
그러니까, HTML쪽에 있는 태그가 가끔씩.......... 사라집니다 그와 함께 글들도 그 부분만 사라지고..

제 실수 인지 TTML 과 HTML 의 이동간에 생기는 문제인지는 더 살펴봐야겠습니다!

유마 (2007-03-23 18:12:57)에 의해 마지막으로 수정

11

답글: patchworks: 코어 수정에 대한 설명

문제를 찾았습니다.

포매터 TTML로 글을 쓰다가 중간에 하이퍼링크 걸기를 누르고 링크를 걸었을 경우, 그 때 이후에 글을 쓰면.. 계속 써집니다.
이까지는 별반 다를 게 없습니다. 이전과.

그러나, 수동으로 만져야 될 것이 있어 포매터 HTML 로 전환하는 순간,
TTML 에서 글 쓰다가 하이퍼링크를 건 곳 부터... 썼던 글이 날아가버립니다.

이렇게 사용하는 것이 맞는지 아닌지 몰라도.. 여튼 사라집니다. --a 요고, 타격이 좀 큽니다..  내 글 ㅜ.ㅜ

포매터 HTML 말고, 위지웍 에디터에서의 edit <-> html 변환을 사용하니 사라지지 않고 계속 존재 합니다.
이제 이걸로 사용해야겠군요.

유마 (2007-03-23 20:35:00)에 의해 마지막으로 수정

12

답글: patchworks: 코어 수정에 대한 설명

수정된 듯 합니다. smile

"Everything looks different on the other side."

-Ian Malcomm, from Michael Crichton's 'The Jurassic Park'