본문 바로가기
기타_모아/기타

[Spec] WZDAPI

by KANG Stroy 2008. 10. 17.
728x90
728x90

WZD Widget API Specification

  •  이 문서는 위자드닷컴에서 사용하는 위젯 프로그램의 규약을 정의합니다.

개요

  • 위자드웍스는 일반 사용자와 업체에서 자유로이 웹 위젯을 제작하여 위자드닷컴(http://wzd.com)에 등록할 수 있는 기능을 제공합니다.
  • WZDAPI를 이용해 개발되는 웹 위젯들은 이 규약에 명시되어 있는 제반 기능을 사용할 수 있으며, 언급된 몇 가지 제약 조건들을 만족해야 합니다.

예제

  • 이 문서에서는 다음과 같이 예제를 표현합니다.

이 문단은 코드를 나타냅니다.
파란색은 사용자의 의도에 따라 변경될 부분을 의미합니다.
초록색은 이 글에서 설명 중인 부분을 의미합니다.
붉은색은 오류가 있는 부분임을 의미합니다.


구성

  • WZDAPI를 따르는 위젯은 다음 조건들을 만족해야 합니다.
    • 위젯은 XHTML 형식의 파일 하나로 구성됩니다.
    • 이 파일은 UTF-8 문자셋으로 작성되어야 합니다.
    • 이 파일의 XML namespace로 http://wzdapi.com/widget/ 을 포함해야 합니다.
  • 위 조건들을 만족하지 않는 경우 해당 위젯 파일은 위자드닷컴에 정상적으로 등록이 불가능하므로 유의하십시오.
  • 이 파일에 주어진 외부 CSS나 외부 자바스크립트 파일은 위자드닷컴에 등록할 때 자동으로 제외됩니다. 개발 및 테스트를 마친 후 위자드닷컴에 등록하실 때는 반드시 필요한 외부 CSS나 외부 자바스크립트 파일을 XHTML 문서 안에 포함시켜 등록하십시오.

위젯 이름

  • 위젯 XHTML 문서는 head 태그 안에 위젯 이름을 포함한 여러가지 정보를 담게됩니다.
  • 위젯의 이름은 다음과 같이 표현됩니다.

<title>이 위젯의 이름이 여기에 들어갑니다.</title>

위젯 정보

  • 이름을 제외한 나머지 정보는 meta 태그를 통해 표현됩니다. 형식은 다음과 같습니다.

<meta name="항목 이름" content="항목 값" />

  • 위젯이 필수적으로 포함하여야 할 정보들은 다음과 같습니다.
항목 이름 의미
apiVersion 이 위젯이 사용한 API 버전, 반드시 값은 "1.0"이어야 합니다.
author 이 위젯을 제작한 사람·단체의 이름
  • 그 밖에 아래와 같은 정보들을 명시할 수 있습니다.
항목 의미 의미
website 이 위젯을 제작한 사람·단체의 웹사이트의 주소
description 이 위젯에 대한 설명
version 이 위젯의 버전
autoRefresh 이 위젯이 내용을 갱신할 시간 간격 (분 단위)

<meta name="apiVersion" content="1.0" />
<meta name="author" content="Bart Simpson" />
<meta name="website" content="http://www.thesimpsons.com/" />
<meta name="description" content="All the things about the Simpsons." />
<meta name="version" content="0.99" />
<meta name="autoRefresh" content="60" />

아이콘

  • 위젯 목록이나 제목표시줄에 나타날 아이콘을 다음과 같이 지정합니다. 위자드닷컴에서는 32 × 32 이상 48 × 48 이하의 크기를 지원합니다.

<link rel="icon" type="image/png" href="http://mysite.com/myicon.png" />

종류 설명

기본값

(속성이 생략 되었을 경우)

text 일반 문자열을 입력 받을 수 있는 기입란을 보여줍니다. (빈 문자열)
textarea 여러 줄의 문자열을 입력 받을 수 있는 기입란을 보여줍니다. (빈 문자열)
hidden 입력란을 외부에 보여주지 않습니다. (빈 문자열)
boolean 참과 거짓을 선택할 수 있는 선택란을 보여줍니다.

false

list widget:option 태그를 이용하여 다수의 항목을 정의하게 되며, 이들 중 하나를 고를 수 있는 선택란을 보여줍니다.
widget:option의 사용법은 아래의 예를 참고하세요.
(첫 번째 항목)
range list와 비슷하나 widget:option 태그 대신 min, step, max속성을 사용하여
다수의 숫자 목록에서 고를 수 있는 선택란을 보여줍니다.
(가장 작은 값)

<widget:preferences>

<widget:preference name="name" type="text" label="이름" defaultValue="홍길동" />

<widget:preference name="ssn" type="hidden" label="주민등록번호" defaultValue="800101-2143657" />

<widget:preference name="sex" type="boolean" label="성별" defaultValue="true"/>

<widget:preference name="age" type="range" label="나이대" defaultValue="20" min="0" step="10" max="100" />

<widget:preference name="address" type="textarea" label="주소" defaultValue="지하철 1호선 시청역&#10;3번 출구 25번째 계단" />

<widget:preference name="occupation" type="list" label="띠" defaultValue="0">

<widget:option label="쥐" value="0" />

<widget:option label="소" value="1" />

<widget:option label="호랑이" value="2" />

<widget:option label="토끼" value="3" />

<widget:option label="용" value="4" />

<widget:option label="뱀" value="5" />

<widget:option label="말" value="6" />

<widget:option label="양" value="7" />

<widget:option label="원숭이" value="8" />

<widget:option label="닭" value="9" />

<widget:option label="개" value="10" />

<widget:option label="돼지" value="11" />

</widget:preference>

</widget:preferences>


CSS

  • 위젯 XHTML 문서에서 style 태그를 사용하여 CSS을 포함할 수 있습니다. 제약 조건은 다음과 같습니다.
    • style 태그의 media 문은 무시됩니다.
    • @rule은 사용할 수 없습니다.
    • CSS rule은 html, head와 그 아래에 속하는 태그를 포함할 수 없습니다.
    • CSS rule은 특정 HTML id를 지칭하는 # 제어자를 사용할 수 없습니다.
  • 다른 사항에 대해서는 사용자가 이용하는 브라우저의 기능을 따릅니다.

<style>
@import 'http://wzd.com/candy.css';
* { margin: 0; }
html { font-family: sans-serif; }
body { font-size: 75%; }
a { color: blue; }
a:hover { color: red; }
p { color: green; }
#container { width: 10em; }
.item { background: silver }
</style>

  • 위자드웍스에서 기본적으로 적용하는 CSS는 다음과 같습니다.

 * { margin: 0; padding: 0; }
body { font: 75% sans-serif; }
a { text-decoration: none; }
a:hover { text-decoration: underline; }


HTML

  • 위젯 XHTML 문서의 body 태그 안에 구성은 사용자의 위자드닷컴에 접속하여 위젯을 불러올 때나 위젯을 새로 추가했을 때 그대로 적용됩니다.
  • 제약 조건은 다음과 같습니다.

    • id, accesskey 속성을 사용할 수 없습니다.
    • onclick, onmouseover 등과 같은 이벤트 핸들러 속성을 사용할 수 없습니다. 자바스크립트를 통해 동적으로 이벤트를 지정하십시오.
    • a 태그의 href 속성은 "javascript:"로 시작하는 값을 가질 수 없습니다.
    • Internet Explorer에서 인식하는 conditional comment는 위자드닷컴에서는 지원하지 않습니다.
    • h1, h2, h3 태그는 위자드닷컴에서 다른 용도로 사용중이므로 문서의 구조화를 위해 사용을 지양 해 주십시오.

<body>
<ol class="football_club">
<li>Liverpool</li>
<li>Manchester United</li>
<li>Arsenal</li>
<li>Chelsea</li>
</ol>
<form id="search">
<fieldset>
<legend>선수 이름으로 검색</legend>
<input type="text" onfocus="highlight(this)" />
<input type="submit" class="submit" value="찾기" />
</fieldset>
</form>
<p><a href="javascript:window.open('http://www.premierleague.com/')">EPL</a></p>
</body>


Javascript

XHTML과 Javascript

  • XHTML에서는 script 태그 안에서도 <, >, & 등의 문자를 반드시 이스케이핑 해야하므로 javascript 코드를 쓰기에는 불편하므로 이를 위해 보통 XML의 CDATA 기능을 사용하게 됩니다. 이 경우,XHTML을 완벽히 지원하지 않는 브라우저에 위해 다음과 같은 방법으로 문제를 피할 수 있습니다.

 <script>
//<![CDATA[
// 여기에 javascript 코드가 들어갑니다.
//]]>
</script>


DOM

  • WZDAPI에서는 일반 웹페이지에서와는 달리 DOM의 최상위 window나 document 등의 객체를 사용할 수 없습니다. 아래에 나올 widget 객체를 이용하여 위젯과 위자드닷컴이 동작하게 됩니다.

라이브러리


widget 객체

이벤트 핸들러

종류 설명
onLoad 위젯이 사용자의 웹브라우저에서 새로 시작할 때 호출됩니다.
onRefresh 위젯의 autoRefresh 설정에 의해, 또는 사용자가 설정값을 변경하여 저장하는 순간 호출됩니다.
onResize(Number width, Number height) 사용자에 의해 위젯의 크기가 변경되었을 경우 호출됩니다. 인자로는 폭과 높이를 넘겨줍니다.
onUpdateTitle(String newTitle)

사용자에 의해, 또는 widget.setTitle 메소드에 의해 위젯 제목이 변경되었을 경우 호출됩니다. 인자로 새 제목을 넘겨줍니다.

widget.onLoad = function() {

widget.body.removeClassName('loading');

var region = widget.getValue('region');

MyWidget.setup(region);

};
widget.onRefresh = function() {

var region = widget.getValue('region');

MyWidget.setup(region);

};

widget.onResize = function(width, height) {

var elem = widget.body.getElementsByTagName('ul')[0];

elem.style.width = width + 'px';

elem.style.height = height - 65 + 'px';

};

widget.onUpdateTitle = function(newTitle) {

widget.setValue('myTitle', newTitle);

};


메소드

종류 설명
log(String msg) 웹브라우저가 지원하는 경우 javascript 콘솔 창에 메시지를 보여 줍니다.
setTitle(String newTitle) 위젯의 제목을 newTitle로 변경합니다.
getValue(String name) 위젯 설정의 name을 이름으로 하는 설정 값을 가져옵니다.
setValue(String name, Object value) 위젯 설정의 name을 이름으로 하는 설정을 value를 값으로 변경합니다.
createElement(String tagName) tagName을 태그의 이름으로 하는 DOM element를 생성합니다.
openURL(String url) 웹주소 url을 새 창으로 엽니다.

var MyWidget = {

onHit: function() {

widget.log("You've just clicked!");

var hit = widget.getValue('hit') + 1;

widget.setValue('hit', hit);

widget.setTitle('MyGreatWidget (' + hit + ')');

widget.openURL('http://ie7.com');

return false;

}

};

widget.onLoad = function()

{

var elem = widget.createElement('img');

elem.src = '/anEvil.gif';

elem.onclick = MyWidget.onHit;

widget.body.appendChild(elem);

};


속성

종류 설명
body 일반 HTML 문서의 document.body에 해당하는 위젯의 최상위 DOM element를 가리킵니다. 이 element는 기본적으로 UWA.$element 확장이 적용되어 있습니다. 자세한 내용은 아래를 참고하세요.
lang 사용자의 언어 설정을 알려줍니다. ISO 639-1을 따르는 두 개의 소문자 알파벳으로 표현됩니다. (ko, en, ja, 등)
locale 사용자의 지역 설정을 알려줍니다. ISO 3166-1 alpha-2을 따르는 두 개의 대문자 알파벳으로 표현됩니다. (KR, US, JP, 등)

var MyTranslation = {

ko: {

title: '심슨',

text: '호머, 마지, 바트, 매기, 리사',

locale: {

KR: '한국',

US: '미국',

unknown: '알 수 없는 지역'

}

},

en: {

title: 'The Simpsons',

text: 'Hormer, Marge, Bart, Maggie, Lisa',

locale: {

KR: 'South Korea',

US: 'United States',

unknown: 'Unknown location'

}

}

};

widget.onLoad = function()

{

var aTranslation = MyTranslation[widget.lang] || MyTranslation.ko;

widget.setTitle(aTranslation.title);

widget.body.innerHTML = aTranslation.text + ' / ' +

(aTranslation.locale[widget.locale] || aTranslation.locale.unknown);

};


UWA 객체

종류 설명
$element(DOMElement el) DOM element를 확장시킵니다. 확장된 DOM element에 대한 설명은 아래에서 다룹니다.

var elem = widget.body.getElementsByClassName('EPL')[0];
elem = UWA.$element(elem);
elem = elem.getElementsByClassName('LiverpoolFC')[0];


UWA.Data 객체

종류 설명
getText(String url, Function callback) 웹주소 url로 부터 내용을 받아 문자열 형태로 callback 함수에 넘겨줍니다.
getJson(String url, Function callback) 웹주소 url로 부터 JSON 형태의 데이터를 받아 callback 함수에 넘겨줍니다. 해당 데이터가 올바른 JSON 형식이 아닐 경우 callback은 호출되지 않습니다.
getXml(String url, Function callback) 웹주소 url로 부터 XML 형태의 데이터를 받아 callback 함수에 넘겨줍니다. 해당 데이터가 올바른 XML 형식이 아닐 경우 callback은 호출되지 않습니다.
getFeed(String url, Function callback) 웹주소 url로 부터 RSS 형태의 데이터를 받아 callback 함수로 넘겨줍니다. 넘겨주는 데이터의 구조는 아래에서 설명합니다.
request(String url, Object options) 웹주소 url로 부터 데이터를 받아 callback 함수로 넘겨줍니다. options는 Prototype 라이브러리의 Ajax.Request 클래스가 두 번째 인자로 받아들이는 옵션 구조체와 같습니다. 이 메소드는 위의 네 가지 메소드로는 해결하기 어려운 HTTP 요청을 보내야 할 경우를 위해 준비되었습니다.
  • UWA.Data.getFeed를 통해 넘겨 받은 데이터의 구조는 다음과 같습니다.
    • htmlUrl : RSS피드를 제공하는 사이트의 주소입니다.
    • title : RSS피드의 제목입니다.
    • content : RSS피드의 요약문입니다.
    • items (배열) : RSS피드가 가진 모든 글을 배열로 가지며 각각은 다음의 항목을 가집니다.
      • title : 글의 제목입니다.
      • link : 글의 웹페이지 주소입니다.
      • content : 글의 내용 또는 요약본입니다.
      • date : 글의 작성 시각입니다.

UWA.Data.getText('http://asdf.com', function(text) {

widget.body.innerHTML = text.escapeHTML();

});

UWA.Data.getFeed('http://blog.wzd.com/rss', function(feed) {

widget.setTitle(feed.item[0].title + ' - ' + feed.title);

widget.body.innerHTML = feed.item[0].content.escapeHTML();

});


UWA.Controls.Pager

  • 이 클래스는 페이지 컨트롤을 생성합니다.
종류 설명
생성자() 새 페이지 컨트롤을 생성합니다.
onChange(Number pageNo) 사용자가 페이지를 전환하기 위해 버튼을 누르면 이 이벤트가 호출되며, 인자로 페이지 번호를 넘겨줍니다.
setMaxPageNumber(Number pageNo)

총 페이지 수를 pageNo로 설정합니다.

selectPage(Number pageNo) 페이지 번호 pageNo를 선택합니다.
appendTo(DOMElement el) 페이지 컨트롤을 el의 마지막 자식으로 붙입니다.

var pager = new UWA.Controls.Pager();

pager.onChange = function(pageNo) {

widget.body.getElementsByClassName('contents')[0].innerHTML = '총 3페이지 중 ' + pageNo + '번째 페이지';

};

pager.setMaxPageNumber(3);

pager.selectPage(0);

pager.appendTo(widget.body.getElementsByClassName('pagerHere')[0]);


 UWA.Controls.TabView

  • 이 클래스는 탭 컨트롤을 생성합니다.
종류 설명
생성자(Type type) type 형태의 탭 컨트롤을 생성합니다. type 값에는 UWA.Controls.TabView.TYPE1 (기본값), UWA.Controls.TabView.TYPE2가 들어갈 수 있으며 생략 가능합니다. 이 두 값은 차후에 변경될 예정입니다.
appendTo(DOMElement el) 탭 컨트롤을 el의 마지막 자식으로 붙입니다.
observe(String type, Function callback)

type은 항상 문자열 'activeTabView'입니다. 사용자가 탭을 선택할 때 마다 callback을 호출합니다. callback은 인자 하나를 받으며, addTab에 사용된 id가 넘어옵니다.

Pager와는 달리 onChange를 제공하지 않습니다.

addTab(String id, { text: html }) 고유이름을 id로 하는 새 탭을 추가합니다. 탭 내용에는 html이 들어가며, 문자열에 들어있는 HTML 코드는 적용됩니다.
selectTab(String id) 고유이름이 id인 탭을 선택합니다.

var tabView = new UWA.Controls.TabView();

tabView.observe('activeTabView', function(id) {

widget.body.getElementsByClassName('contents')[0].innerHTML = 'Have you got any question to ' + id + '?';

});

tabView.addTab('Hormer', { text: 'Hormer' });

tabView.addTab('Marge' , { text: 'Marge' });

tabView.addTab('Bart' , { text: 'Bart' });

tabView.addTab('Maggie', { text: 'Maggie' });

tabView.addTab('Lisa' , { text: 'Lisa' });

tabView.selectTab('Bart');

tabView.appendTo(widget.body.getElementsByClassName('tabHere')[0]);


UWA.Controls.Drawer

  • 이 클래스는 접기 버튼을 생성합니다.
종류 설명
생성자() 새 접기 컨트롤을 생성합니다. 펼쳐진 상태로 시작합니다.
show() 펼친 상태로 변경합니다.
hide() 접은 상태로 변경합니다.
toggle() 접은 경우 펼친 상태, 펼쳐진 경우 접은 상태로 변경합니다.
onChange(Boolean folded) 사용자가 버튼을 누르면 이 이벤트가 호출되며, 인자로 접힌 상태인지의 여부를 넘겨줍니다.
appendTo(DOMElement el) 접기 컨트롤을 el의 마지막 자식으로 붙입니다.

var drawer = new UWA.Controls.Drawer();
drawer.hide();
drawer.onChange = function(folded) {

widget.body.getElementsByClassName('ul')[0][folded ? 'hide' : 'show']();

};
drawer.appendTo(widget.body.getElementsByClassName('drawerHere')[0]);


HTMLElement의 UWA.$element 확장

  • UWA.$element 메소드에 의해 DOM element를 확장할 수 있으며, 확장된 DOM element는 Prototype 라이브러리의 Element 메소드와 함께 아래의 메소드를 추가적으로 갖게 됩니다.
종류 설명
getChildren() 자식 element 배열을 얻습니다.
getParent() 부모 element를 얻습니다.
setHTML(String html) 내용을 html로 채웁니다. 문자열에 들어있는 HTML 코드가 적용됩니다.
setText(String text) 내용을 text로 채웁니다. 문자열에 들어있는 HTML 코드는 표현되지 않고 문자 그대로 표시됩니다.
appendText(String text) element의 마지막에 text를 추가합니다. HTML 코드는 표현되지 않고 문자 그대로 표시됩니다.
setContent(String content) setHTML과 같습니다.
addContent(String content) element의 마지막에 div 태그를 추가하고 content를 그 내용물로 채웁니다. HTML 코드가 적용됩니다.

String 확장 메소드

종류 설명
Boolean isEmail() 문자열이 E-mail 주소 형식이면 참을 돌립니다.
String trim() 앞뒤의 공백을 제거한 문자열을 돌립니다.
String truncate(Number length) length 만큼 문자열을 자른 후, 마지막에 ...을 붙입니다.

var str = '\tbill@gates.net\n';
str.isEmail(); // true
str = str.trim(); // str == 'bill@gates.net'
str = str.truncate(10); // str == 'bill@gates'


Array 확장 메소드

종류 설명
Array normalize(Number sum) 배열의 모든 값의 합이 sum이 되도록 각 값을 같은 비율로 곱한 배열을 돌립니다.
Boolean equals(Array anArray) anArray와 순서대로 각 항목의 값이 같은지 비교합니다.

var a = [10, 20, 30, 40];
a = a.normalize(10); // a == [1, 2, 3, 4]
a.equals([1, 2, 3, 4]); // true
a.equals([4, 3, 2, 1]); // false



예제

  • 아래 예는 간단한 메모 위젯입니다. 전체 구조를 파악하는데 참고하십시오.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:widget="http://wzdapi.com/widget/">

<head>

<title>메모장</title>

<meta name="author" content="WzdWorks" />

<meta name="description" content="간단한 메모장입니다." />

<meta name="apiVersion" content="1.0" />

<widget:preferences>

<preference name="memo" type="hidden" />

</widget:preferences>

<style>

/*<![CDATA[*/

textarea {

border: 1px solid black;

width: 100%;

height: 100%;

overflow: auto;

}

/*]]>*/

</style>

<script>

//<![CDATA[

var Memo = {

onChange: function() {

widget.setValue('memo', this.value);

}

};

widget.onLoad = function()

{

var elem = widget.body.getElementsByTagName('textarea')[0];
elem.value = widget.getValue('memo');
elem.onchange = Memo.onChange;

};

//]]>

</script>

</head>

<body>

<textarea></textarea>

</body>

</html>


에뮬레이터 사용하기

  • 작성한 위젯을 테스트하기 위해서는 emulator.js를 문서에 연결하셔야 합니다. 아래와 같이 외부 js로 연결하면 위자드닷컴에 위젯을 올릴 때 별도의 수정을 하지 않아도 되는 장점이 있습니다. 단, 반드시 다른 스크립트보다 앞에 위치해야 합니다.

<head>
...
<script src="http://wzdapi.com/widget/emulator.js"></script>

<script>
//<![CDATA[
...
//]]>
</script>
...
</head>


타 규약과의 호환성


개정 이력

  • 2007년 6월 3일 - WZDAPI 1.0 Specification (Beta) 제정


2006-2007 © The WiZarD Works ¦ http://wzdworks.com/

728x90

'기타_모아 > 기타' 카테고리의 다른 글

오늘의 양식 October 21, 2008  (0) 2008.10.21
붉은 애무  (0) 2008.10.21
도키오  (0) 2008.10.15
아름다운 지구인 플래닛 워커  (0) 2008.10.09
한 걸음만 더  (0) 2008.10.08

댓글