[텍스트큐브 플러그인] 블로그 아이콘 개선판 (onerror를 쓰면서 XHTML 유효성 겁사 통과하기)

  텍스트큐브에서 '블로그 아이콘 표시' 확장기능(플러그인)을 쓰면 XHTML 문법 검사에서 걸리는 항목이 생긴다. 이 확장기능이 <img> 태그에 onerror 항목을 넣어서 블로그 쪽그림(index.gif)을 찾을 수 없는 덧글에 아무개 그림을 나타내기 때문이다.

<img src="주소" alt="" width="32" height="32" onerror="this.src = '/plugins/BlogIcon/images/default.png'" /> 


  XHTML 문법은 HTML의 꾸밈 요소를 CSS나 자바스크립트에 떼어놓게 하고 있다. 텍스트큐브가 따르는 XHTML 1.0 transitional 문법을 철저히 따른다면 onerror는 HTML 태그 안에 넣지 않고 자바스크립트로 넣어야 한다.

  onerror 하나 때문에 자바스크립트를 써야 하는지에 대해서는 의견이 분분하다. 텍스트큐브 게시판에서 아래 게시물을 비롯하여 onerror 문제에 관하여 논한 게시물을 볼 수 있었다.

  XHTML을 따르면 문서가 깔끔해지고 검색기가 쉽게 긁어갈 수 있는 건 좋은데, onerror 같은 항목이 하나둘이 걸린다고 큰 문제가 되지는 않는다. 그래도 웹 표준도 지키고 아무개 그림도 잘 나타내기를 바라는 이들이 꽤 있는데, 뾰족한 수는 나오지 않았나 보다.

  치프님의 텍스트큐브 onerror 로 인한 문법오류 해결처럼 <img> 안에서 onerror를 지우면 문법 검사는 통과할 수 있다. 쪽그림을 못 찾은 덧글에 X표 상자가 나오는 게 흠이다. 쪽그림이 클수록 X표 상자가 커서 보기 흉하다.

  더 찾아 보니 deute님 img에 onerror이벤트를 tag의 속성이 아닌 자바스크립트로 등록하기에 실마리가 있었다. 자바스크립트로 onerror를 끼워넣는 방법이 인터넷 탐색기(IE)와 다른 웹 탐색기가 서로 다르다. 웹 표준을 따르는 웹 탐색기들은 객체.onerror에 넣거나 addEventListener를 써서 onerror를 끼워넣을 수 있지만, IE 8 이하는 addEventListener는 쓸 수 없고 attachEvent를 쓴다. deute님의 예제를 따른다면 이런 스크립트를 붙여서 쪽그림에 onerror를 넣을 수 있을 것이다.


<script type="text/javascript">
<!--
var imgs = document.getElementsByTagName('img');
for(var i=0;i<imgs.length;++i) {
if(imgs[i].className === 'blogIcon') {
if(navigator.userAgent.indexOf("MSIE ")>-1) {
imgs[i].attachEvent("onerror",function(e) { e.srcElement.src ="/plugins/BlogIcon/images/default.png"; } // IE

} else {
imgs[i].onerror = function(e) { e.target.src = '/plugins/BlogIcon/images/default.png';}; // FireFox, chrome, Opera, ...
}
}
}
//-->
</script>


  그런데 이 스크립트를 텍스트큐브에 넣었을 때 IE에서 잘 되지 않았다. deute님의 예제에서는 스크립트가 하나만 있어서 문제가 없었지만, IE 8 이하에서 다른 자바스크립트가 함께 들어 있으면 어디서 엉키는지 몰라도 아무개 그림이 잘 나오지 않는다. 다른 웹 탐색기들은 별다른 문제가 없었다. IE 8이하에서는 <img> 안에 onerror를 넣어야 아무개 그림을 잘 나타낼 수 있었다.

  그래서 확장기능의 index.php를 아래처럼 IE 8 이하에서는 <img> 안에 onerror를 넣고, 나머지 웹 탐색기들은 addEventListener로 onerror를 넣도록 바꾸었다.

<?php
function BlogIcon_main($target, $mother) {

....

if ($mother['secret'] == 1) {
if (empty($mother['homepage'])) {
$imageStr = "<img src=\"{$pluginURL}/images/secret.png\" alt=\"\" width=\"{$ico_size}\" height=\"{$ico_size}\" />";
} else {
$slash = ($mother['homepage']{strlen($mother['homepage']) - 1} == '/' ? '' : '/');
preg_match("/(?P<name>\w+) (?P<version>\d+)/", $_SERVER['HTTP_USER_AGENT'], $browser);
if($browser['name'] == "MSIE" /*&& $browser['version'] < 9*/) $onerror = "onerror=\"this.src = '{$pluginURL}/images/secret.png'\""; else $onerror = "";
$imageStr = "<img class=\"blogIcon_secret\" src=\"{$mother['homepage']}{$slash}index.gif\" alt=\"\" width=\"{$ico_size}\" height=\"{$ico_size}\" {$onerror} />";
}
} else {
if (empty($mother['homepage'])) {
$imageStr = "<img src=\"{$pluginURL}/images/default.png\" alt=\"\" width=\"{$ico_size}\" height=\"{$ico_size}\" />";
} else {
$slash = ($mother['homepage']{strlen($mother['homepage']) - 1} == '/' ? '' : '/');
preg_match("/(?P<name>\w+) (?P<version>\d+)/", $_SERVER['HTTP_USER_AGENT'], $browser);
if($browser['name'] == "MSIE" /*&& $browser['version'] < 9*/) $onerror = "onerror=\"this.src = '{$pluginURL}/images/default.png'\""; else $onerror = "";
$imageStr = "<img class=\"blogIcon\" src=\"{$mother['homepage']}{$slash}index.gif\" alt=\"\" width=\"{$ico_size}\" height=\"{$ico_size}\" {$onerror} />";
}
}

return "{$imageStr} {$target}";
}

function BlogIcon_script($target) {
preg_match("/(?P<name>\w+) (?P<version>\d+)/", $_SERVER['HTTP_USER_AGENT'], $browser);
if($browser['name'] == "MSIE" && $browser['version'] < 9) return $target;

global $pluginURL; $script = "<script type=\"text/javascript\">".CRLF;

$script .= "<!--".CRLF;
$script .= " var imgs = document.getElementsByTagName('img');".CRLF;
$script .= " for(var i=0;i<imgs.length;++i) {".CRLF;
$script .= " if(imgs[i].className === 'blogIcon') {".CRLF;
$script .= " imgs[i].addEventListener('error', function(e) {e.target.src = '{$pluginURL}/images/default.png';}, false);".CRLF;
$script .= " }".CRLF;
$script .= " else if(imgs[i].className === 'blogIcon_secret') {".CRLF;
$script .= " imgs[i].addEventListener('error', function(e) {e.target.src = '{$pluginURL}/images/secret.png';}, false);".CRLF;
$script .= " }".CRLF;
$script .= " }".CRLF; $script .= "//-->".CRLF;
$script .= "</script>".CRLF; return $target.CRLF.$script;
}

....


  index.xml의 <binding>과 </binding> 사이에 다음 한 줄을 끼워넣어서 새로 넣은 BlogIcon_script()의 내용이 </body> 앞에 출력되게 한다.

<tag name="SKIN_body_end" handler="BlogIcon_script" />


  이렇게 하면 아무개 그림도 잘 나오고 XHTML 문법 검사도 통과할 수 있다. 그래도 IE 8 이하에서는 HTML 안에 onerror가 들어가니 이 방법은 꼼수일 수밖에 없다. 아직 눈으로 확인하지 않았지만 IE 9부터는 addEventListener를 쓸 수 있다고 하니 IE 8까지만 예외로 하면 될 것 같다.

바꾼 내역

  • 텍스트큐브 자료실에 개선판을 올렸습니다. (2011.4.28)
  • IE 9도 IE 8 이하와 다르지 않음을 뒤늦게 발견하고, IE에서 판 번호 구분 없이 동작하도록 고쳐 올립니다. (2011.10.18)
  • 여러 웹 누비개들에서 addEventListener로 넣는 방법이 통하지 않아서 객체.onerror로 넣도록 자바스크립트를 고쳤습니다. (IE만 HTML 태그로 넣음) (2013.12.14)
  • 불여우(Firefox)도 IE처럼 HTML 태그로 onerror 속성을 넣게 했습니다. (2013.12.18)
BlogIcon_1.3.3_for_TC1.8.zip
블로그 아이콘 플러그인 수정판 1.3.3 (2013.12.18)
index.xml.zip
텍스트큐브 1.8 이전판을 위한 index.xml 파일

글 걸기 주소 : 이 글에는 글을 걸 수 없습니다.

덧글을 달아 주세요

  1. 아르 2011/04/26 23:32 고유주소 고치기 답하기

    onerror때문에 blogicon을 포기했었는데 좋은 자료 감사드립니다.
    한번 적용해봐야겠습니다.^^

  2. 비밀방문자 2013/03/28 20:11 고유주소 고치기 답하기

    관리자만 볼 수 있는 덧글입니다.

    • 팥알 2013/03/28 21:01 고유주소 고치기 답하기

      반갑습니다.

      출력된 HTML만 보아서는 플러그인이 작동하지 않아서 블로그 아이콘의 그림 태그(<img>)가 들어가지 않고 있는 것 같습니다. 먼저 관리자 화면에서 플러그인이 작동하고 있는지 확인해 보시면 좋을 것 같습니다. 작동 상태에 이상이 없는 데 그림이 나오지 않는다면 좀 고민해 보아야 할 것 같습니다.

    • 연이 2013/03/28 21:23 고유주소 고치기 답하기

      제가 ㅠㅠ 플러그인을 활성화 시켜도 이미지가 나오질 않아요 ㅠㅠ default이미지만 나옵니당 ㅠㅠ

    • 팥알 2013/03/28 21:36 고유주소 고치기 답하기

      처음 보았을 때는 아예 작동하지 않았던 것 같은데,
      방금 제가 글을 달아 보니 잘 나오는 것 같습니다.
      글쓴이가 index.gif를 올린 웹 주소를 넣지 않으면 기본 쪽그림만 나옵니다.

      연이님의 블로그에는 문제가 없지만, lightbox 플러그인과 충돌하여 IE가 아닌 웹 누비개에서 쪽그림이 나오지 않는 문제가 있어서 수정판(땜질판?)을 내놓아야 할지 고민 중이긴 합니다.

  3. 비밀방문자 2013/03/28 22:00 고유주소 고치기 답하기

    관리자만 볼 수 있는 덧글입니다.

    • 팥알 2013/03/28 22:09 고유주소 고치기 답하기

      질문 자꾸 하셔도 괜찮습니다.
      저도 초보 시절에 비슷한 까닭으로 많이 헤맸거든요.
      요즈음은 오히려 텍스트큐브 쓰는 분이 반갑기도 하고요.

      관리자 화면에서 '설정 → 블로그'로 들아가면 '블로그 아이콘' 항목이 있습니다.
      거기에서 찾아보기 단추를 눌러 쪽그림(아이콘)을 넣으면 됩니다.

      덧글에 글쓴이 자신의 쪽그림이 잘 나오게 하려면 '설정 → 개인정보'로 들어가서 대표 주소를 지정하면 됩니다.
      '외부 주소'를 골라서 블로그 주소를 적어 주어도 됩니다.

  4. 연이 2013/03/28 23:12 고유주소 고치기 답하기

    와 성공했습니다.
    외부주소를 대표주소로 사용하니 바로 되네용 +_+
    넘넘 감사드립니다 >_<