*이 포스트에서 다룬 문제점을 해결한 BBCode for Tistory 2.2가 배포되었습니다.
지난번 "BBCode for Tistory 활용하기"라는 포스트에서 BLUE'nLIVE님의 BBCode for Tistory를 소개해드리면서 댓글과 방명록에 BBCode 삽입 버튼을 달 수 있는 방법을 올린 적이 있습니다. 그 포스트가 올라온 뒤 여러 반응들이 있었는데요, 그 중에는 BBCode를 설치한 이후 W3C의 웹표준 규정에 어긋난다는 문의도 있었습니다.
사실 저 역시 블로그를 표준화하는 작업을 진행 중이었기에 그 문의에 적지 않은 신경이 쓰였습니다.
하지만 W3C 웹표준 규정에 어긋나는 부분은 제가 올린 BBCode 삽입 버튼 관련 코드가 아니라
BBCode for Tistory 2.1이기 때문에, 사실 저로서는 어찌할 수 있는 부분이 아니었습니다.
물론 저는 개인적으로 BLUE'nLIVE님의 코드를 수정해서 쓰고 있었지만
제 마음대로 수정판을 배포할 수는 없는 일이니까요.
그러다가 얼마전 BLUE'nLIVE님과 상의 후, 제 수정방법과 함께 수정된 코드를 공개하기로 했습니다.
물론 제가 올리게되는 수정 파일은 차후 BLUE'nLIVE님 께서 정식으로 배포하실 예정이기 때문에,
후에 BLUE'nLIVE님의 정식 배포판이 나오게 되면 그 포스트를 따로 링크할 계획입니다.
자, 그럼 본론으로 돌아갑니다.
일단 기존의 BBCode for Tistory 2.1이 어떤 부분에서 W3C 웹표준에 부합하지 않는지 설명하고,
그에 대한 해결책을 단계적으로 제시하겠습니다.
단, 이 내용은 XHTML과 Javascript에 어느정도 지식이 있으신 분들만 이해하실 수 있으므로
단순히 코드만 적용하고 싶으신 분은 빨간 박스의 내용대로만 따라하시면 됩니다.
먼저 현재의 BBCode for Tistory 2.1에는 다음과 같은 문제점이 있습니다:
1. <script>태그로 bbcode21.js를 불러오는 코드의 속성이 잘못되어있다.
→ <script language="javacript">를 <script type="text/javascript">로 바꾼다.
2. <p>태그 내에 <div>태그가 존재할 수 없지만 "BBCode 도우미"는
<p>태그 내에 <div>태그를 삽입하고 있다.
→ <p><div> ... </div></p>의 꼴을 <div><p> ... </p></div>꼴로 바꾼다.
3. XHTML Strict 1.0의 경우 <div>태그 내에 name속성을 사용할 수 없다.
XHTML Transitional 1.0의 경우 name을 사용할 수는 있지만 중복된 값을 가질 수 없다.
하지만 "BBCode 도우미"는 <div name="bbcode"> ... </div>태그를 삽입하고 있다.
→ name속성 대신 id혹은 class를 사용한다.
→ <script language="javacript">를 <script type="text/javascript">로 바꾼다.
2. <p>태그 내에 <div>태그가 존재할 수 없지만 "BBCode 도우미"는
<p>태그 내에 <div>태그를 삽입하고 있다.
→ <p><div> ... </div></p>의 꼴을 <div><p> ... </p></div>꼴로 바꾼다.
3. XHTML Strict 1.0의 경우 <div>태그 내에 name속성을 사용할 수 없다.
XHTML Transitional 1.0의 경우 name을 사용할 수는 있지만 중복된 값을 가질 수 없다.
하지만 "BBCode 도우미"는 <div name="bbcode"> ... </div>태그를 삽입하고 있다.
→ name속성 대신 id혹은 class를 사용한다.
1번 문제의 경우 수정하기가 매우 쉽습니다.
일단 티스토리 스킨의 skin.html파일을 AcroEdit등의 편집기로 연 다음,
<script language="javascript">를 <script type="text/javascript">로 수정하시면 됩니다.
수정하실 부분은 skin.html 윗부분에 위치한 코드와 끝부분에 위치한 코드, 이렇게 2군데 입니다.2번 문제 역시 간단합니다.
마찬가지로 skin.html파일에서,
<p><div name="bbcode">[##_guest_rep_desc_##]</div></p>를
<div name="bbcode"><p>[##_guest_rep_desc_##]</p></div>로,
<p><div name="bbcode">[##_rp_rep_desc_##]</div></p>를
<div name="bbcode"><p>[##_rp_rep_desc_##]</p></div>로 수정하시면 됩니다.
각각 두번씩 수정하셔야하므로 총 4군데를 수정하시게 됩니다.<div name="bbcode"><p>[##_guest_rep_desc_##]</p></div>로,
<p><div name="bbcode">[##_rp_rep_desc_##]</div></p>를
<div name="bbcode"><p>[##_rp_rep_desc_##]</p></div>로 수정하시면 됩니다.
3번 문제는 해결방법을 찾는데 약간 애를 먹었습니다.
일단, <div>태그에서는 name속성을 사용할 수 없기 때문에 name대신 id나 class를 사용해야합니다.
하지만 id속성을 사용할 경우, 각각의 <div>가 중복된 id값을 가질 수 없습니다.
뭔소리인지 잘 모르시겠다면 아래의 예를 참고하세요.
틀린 id 속성:
<div id="bbcode"></div> ... <div id="bbcode"></div> ... <div id="bbcode"></div> ...
올바른 id 속성:
<div id="bbcode1"></div> ... <div id="bbcode2"></div> ... <div id="bbcode3"></div> ...
<div id="bbcode"></div> ... <div id="bbcode"></div> ... <div id="bbcode"></div> ...
올바른 id 속성:
<div id="bbcode1"></div> ... <div id="bbcode2"></div> ... <div id="bbcode3"></div> ...
하지만 class속성의 경우 값이 중복되어도 상관없습니다.
즉, BBCode가 처리해야할 <div>태그를 모두 <div class="bbcode"></div>로 지정할 수 있다는거죠.
그래서 skin.html파일에서
<div name="bbcode">를 <div class="bbcode">로 모두 수정한 뒤,
bbcode21.js파일에서
if (tags[i].getAttribute('name') == 'bbcode' && tags[i].style.display != 'none')를
if (tags[i].getAttribute('class') == 'bbcode' && tags[i].style.display != 'none')로 수정했습니다.
if (tags[i].getAttribute('class') == 'bbcode' && tags[i].style.display != 'none')로 수정했습니다.
이론 상으로는 이렇게 수정하면 문제없이 작동해야합니다.
하지만 이상하게도 IE에서는 BBCode가 작동하지 않더군요.
그래서 두번째로 생각한 방법이 바로 id속성을 이용하는 것입니다.
앞서 말했듯이 id속성은 중복된 값을 사용할 수 없습니다.
따라서 치환자를 이용해서 모든 <div>태그에 다른 id값을 주었습니다.
먼저 skin.html파일에서
<div name="bbcode"><p>[##_guest_rep_desc_##]</p></div>를
<div id="bbcode_[##_guest_rep_id_##]"><p>[##_guest_rep_desc_##]</p></div>로
<div name="bbcode"><p>[##_rp_rep_desc_##]</p></div>를
<div id="bbcode_[##_rp_rep_id_##]"><p>[##_rp_rep_desc_##]</p></div>로 수정했습니다.
<div id="bbcode_[##_guest_rep_id_##]"><p>[##_guest_rep_desc_##]</p></div>로
<div name="bbcode"><p>[##_rp_rep_desc_##]</p></div>를
<div id="bbcode_[##_rp_rep_id_##]"><p>[##_rp_rep_desc_##]</p></div>로 수정했습니다.
그리고 bbcode21.js파일에서
if (tags[i].getAttribute('name') == 'bbcode' && tags[i].style.display != 'none')를
if (tags[i].getAttribute('id').substring(0,6) == 'bbcode' && tags[i].style.display != 'none')로 수정했습니다.
이렇게 수정한 이유는, <div>의 id값에 붙은 치환자 부분을 무시하고 "bbcode"라는 문자열만 뽑아서 검색하기 위해서입니다.if (tags[i].getAttribute('id').substring(0,6) == 'bbcode' && tags[i].style.display != 'none')로 수정했습니다.
그런데 이렇게 해놓고보니, 이번에는 IE에서만 정상작동을하고 다른 브라우저에서는 오작동을 하더군요.-_-;;
그래서 최종적으로 첫번째 방법과 두번째 방법을 짬뽕시키기로 했습니다.
즉, 브라우저가 IE이면 두번째 방법(id속성 이용)으로 BBCode를 처리하고,
IE가 아니면 첫번째 방법(class속성 이용)으로 BBCode를 처리하도록 if구문을 넣은거죠.
먼저 skin.html파일에서
<div name="bbcode"><p>[##_guest_rep_desc_##]를
<div class="bbcode" id="bbcode_[##_guest_rep_id_##]"><p>[##_guest_rep_desc_##]로
<div name="bbcode"><p>[##_rp_rep_desc_##]를
<div class="bbcode" id="bbcode_[##_rp_rep_id_##]"><p>[##_rp_rep_desc_##]로 수정했습니다.
<div class="bbcode" id="bbcode_[##_guest_rep_id_##]"><p>[##_guest_rep_desc_##]로
<div name="bbcode"><p>[##_rp_rep_desc_##]를
<div class="bbcode" id="bbcode_[##_rp_rep_id_##]"><p>[##_rp_rep_desc_##]로 수정했습니다.
마지막으로 bbcode21.js파일에서
if (tags[i].getAttribute('name') == 'bbcode' && tags[i].style.display != 'none')를...
if (browserName=='Microsoft Internet Explorer'){
if (tags[i].getAttribute('id').substring(0,6) == 'bbcode' && tags[i].style.display != 'none')
elements.push(tags[i]);
}
else{
if (tags[i].getAttribute('class') == 'bbcode' && tags[i].style.display != 'none')
elements.push(tags[i]);
}
로 수정했습니다.
if (browserName=='Microsoft Internet Explorer'){
if (tags[i].getAttribute('id').substring(0,6) == 'bbcode' && tags[i].style.display != 'none')
elements.push(tags[i]);
}
else{
if (tags[i].getAttribute('class') == 'bbcode' && tags[i].style.display != 'none')
elements.push(tags[i]);
}
로 수정했습니다.
*수정하시기 귀찮으신 분들을 위한 최종 수정판 bbcode21.js파일입니다.
압축 해제 후 기존의 bbcode21.js파일을 삭제한 뒤 새로 올리시면 됩니다.
압축 해제 후 기존의 bbcode21.js파일을 삭제한 뒤 새로 올리시면 됩니다.
이렇게하니 모두 정상작동하더군요.
웹표준에도 문제가 없습니다.
너무 복잡하다고 생각하시는 분들도 계시겠지만... 어쩔 수 없답니다;;
게다가 BLUE'nLIVE님께서 이 포스트의 수정사항을 포함한 업데이트 버전을 금방 내놓으실 듯 하기 때문에
꼭 지금 따라하지 못한다고 해도 큰 문제는 없습니다:)
'사소한 발견' 카테고리의 다른 글
| <엔즐군의 다이어리>가 네이버와 다음, 그리고 야후 검색에 등록되었습니다. (9) | 2008/06/22 |
|---|---|
| BBCode for Tistory를 W3C 표준에 맞게 적용하기 (16) | 2008/06/20 |
| 대용량 백업파일 쉽게 복구하기 (10) | 2008/05/31 |
| 동영상만 UCC? 이제는 문자다. (8) | 2008/05/30 |
AD-CLIX















bbcode21.zip
이올린에 북마크하기
이올린에 추천하기
댓글은 당신의 얼굴입니다.
이곳에 당신의 아름다운 얼굴을 남겨주세요!
수고하셨습니다.
역시 저의 [rb]마구잡이 코딩[/rb]의 한계를 여실히 보여주는군요.
다행히 내일이 주말이라 내일 작업할 수 있을 것 같습니다.
그리고, 3번의 경우 다른 방법을 찾아볼 필요가 있을 것 같습니다.
쪼금만 연구해보고 수정사항에 대해 포스팅하겠습니다.
완성되면 꼭 [u]트랙백[/u] 날려주세요
대단하십니다. 엔즐군님 쵝오!!
과찬이십니다;;
저도 Javascript쪽은 잘 알지 못해서 애를 좀 먹었으니까요;;
저에게도 관심을 [bb]ㅠ.ㅠ[/bb]
저능아 IE에서 getAttribute('class')는 제대로 해석하지 못하지만,
getAttributeNode('class').value 는 제대로 해석한다는 것을 알아냈습니다. [rb]v^.^[/rb]
(물론, FF, Opera 등에선 둘 다 정상동작합니다)
이것을 포함한 내용을 주말중에 포스팅하도록 하겠습니다.
오홋, 그렇다면 힘들게 [b]id속성[/b]을 쓸 필요도 없겠군요ㅠㅠ
어흥~ (통곡하는 소리)
저 함수는 로컬에선 잘 돌아가더니, 웹에 올리니까 ㅈㄹ이군요.
class를 쓰되, IE에선 getAttributeNode, 다른 브라우저는 getAttribute를 쓰도록 만들겠습니다.
도우미 수정은 완료했으니 토요일 중으로 포스팅이 가능할 것 같습니다.
헉, 이렇게 밤 늦게까지 뭐 하세요!! ㅋㅋ
아무튼 [color=red]IE가 문제[/color]인 것 같습니다ㅠㅠ
저 역시 블로그에 추가할 다른 자바스크립트를 짜고 있었는데 IE에서만 문제가 생기네요.
코드의 수정은 완료했습니다. 이제 정리만 하면 됩니다.
1. IE에서만 동작하는 코드를 사용할 때는
[blue]if (/msie/i.test (navigator.userAgent)) { 코드 }[/blue]
가 가장 널리 사용되며 속도도 빠릅니다. 고수님들의 코드를 훔쳐보니 그렇더군요.
2. getAttributeNode와 getAttribute는 위에 적은 대로 구분하도록 만들었습니다.
이제 자야겠습니다. ^^;;;
수정된 사항을 몽땅 반영한 내용을 포스팅하고 트랙백 걸었습니다.
다시한번 감사드립니다.
제 포스팅에도 있지만, 제 스킨에서 <script> 코드는 몽땅 수정했습니다. 많이 배웠습니다.
그리고… [rb]졸려요[/rb]
티끌만큼 수정했습니다. 워낙 조금 수정해서 그냥 별도의 포스팅은 하지 않고 수정했습니다.
참고하시기바랍니다.
[rb]이거[/rb] 잘 [rb]되나요?[/rb]
[bb]되는군요 -.-;;;[/bb]
손을 좀 대다보니 같은 태그가 2번 이상 등장하면 제 블로그에서는 정상적으로 표시되지 않았습니다.
이 부분을 수정해서 2.3으로 업글했는데, 저만의 문제였군요… 제길슨.
저는 2.1버전에서 제가 수정해놓은 상태를 유지해두었습니다. 다시 적용하는게 귀찮아서요<<
만약 문제점이 발견되면 그떄 2.3버전으로 갈아탈 예정입니다. ^^
예전에 하려다 바보같이 실패했던 bbcode를 이제사 적용했습니다.
엔즐군님의 정체는 무엇입니까!
어떻게 이런 실력까지....