01. 모듈 개발하기

조회 수 1575 추천 수 0 2009.08.24 15:08:35
sol *.13.13.164

개발자의 눈으로 본 모듈이란?

개발자 입장에서 모듈이란 XE의 정상적인 프로세스를 통하는 프로그램 입니다. 정상적인 프로세스는 Context Class를 통해 요청이 들어와 모듈에서의 처리 거처 Display Class 통해 html/json/XML-RPC로 출력이 되는 과정입니다.

XE 에서는 install, session, rss, tag, editor, layout등 모듈의 조합으로 구성되어져 있고 나머지 라이브러리는 모듈의 동작을 도와주기 위해 있습니다. 대부분의 모듈은 모듈별 Database의 Table이 있고 게시판 모듈과 같이 Document 모듈을 이용하여 만든 모듈도 있습니다. 또 cafeXE, textyle hub와 같이 가상 사이트 기능(vid)을 이용한 사이트 분양형 모듈도 만들 수 있습니다.

모듈 디렉토리 및 파일 구조

모든 모듈은 XE_ROOT(XE 설치디렉토리)/modules/ 에 위치 합니다. 

  • 모듈명
    • conf : 모듈 설명과 act의 권한 등 설정을 위한 XML 파일이 있습니다.
      • info.xml : 모듈의 소개와 제작자등의 정보가 있습니다.
      • module.xml : 모듈의 act 정의와 권한 등 모듈의 동작과 관련된 정보가 있습니다
    • lang : 언어팩 파일들이 있습니다.
      • ko.lang.php
    • schemas : 모듈에서 쓸 Database Table schema 에 대한 XML 파일이 있는 디렉토리입니다.
    • queries : XE의 XML Query 파일들이 있습니다.
    • tpl : 관리자 화면의 템플릿 파일들이 있습니다.
    • skins : 사용자 스킨 템플릿 파일들이 있습니다.
      • 스킨명
        • skin.xml : 스킨의 제작자 정보 및 스킨 별 설정 변수에 대한 정보가 있습니다.
    • 모듈명.class.php : 모듈의 최상위 클래스이며 모듈의 설치/ 업데이트/ 캐시파일 삭제/ 특정 Action의 권한제어등 모듈의 대표적인 기능을 수행하는 클래스 파일입니다.
    • 모듈명.view.php : 서비스를 위한 View Action이 구현되어 있는 파일입니다.
    • 모듈명.model.php : 모듈의 model 과 관련된 것들이 구현되어 있습니다. 일반적으로 XE에서 model은 view나 controller에서 사용하기 위한 method로서 존재하지만 UI(Javascript, Flash)등에서 직접 데이터를 요청하는 Action이 존재할 수도 있습니다.
    • 모듈명.controller.php : 서비스를 위한 Controller Action이 구현되어 있는 파일입니다. XE에서는 일반적으로 Javascript AJAX등을 이용하여 이 controller를 직접 호출하고 있습니다.
    • 모듈명.admin.view.php : 파일이름에 admin이 있을 경우 Admin이 포함된 Action이 요청되면 자동으로 불려지게 됩니다. 관리자 기능을 위한 View Action이 구현되어 있습니다.
    • 모듈명.admin.model.php : 일반적으로 model의 경우 굳이 admin model class를 만들지 않아도 되지만 효율성이나 일반적으로 요청되면 안되는 Model Action들이 구현되어 있습니다.
    • 모듈명.admin.controller.php : 관리자 기능을 위한 Controller Action이 구현되어 있습니다.
    • 모듈명.api.php : controller, model의 경우는 XE에서는 AJAX나 Flash를 통한 XMLRPC 혹은 JSON 방식으로 요청을 받고 결과를 출력하지만 view class의 경우 기본적으로 HTML로 출력하게 되어 있습니다. 하지만 XMLRPC/ JSON 으로 view class를 요청받았을 경우 api.php 에 해당 Action이 정의되어 있으면 결과물이 HTML 이 아닌 api.php 에서 정리한 결과를 XMLRPC나 JSON 으로 출력하도록 할 수 있습니다.
    • 모듈명.wap.php : 핸드폰에서 wap으로 접속했을 경우 다른 출력을 하도록 할 수 있습니다.
    • 모듈명.smartphone.php : IPhone과 스마트 폰과 같은 장치에서 접속했을 경우 다른 출력을 하도록 할 수 있습니다.

모듈의 정보 info.xml 작성방법

<?xml version="1.0" encoding="UTF-8"?>
<module version="0.2">
    <title xml:lang="ko">모듈명</title>
    <description xml:lang="ko">모듈설명</description>
    <version>0.1(버전)</version>
    <date>2009-08-13(제작일)</date>
    <category>service(모듈분류)</category>
    <author email_address="sol@ngleader.com(제작자 이메일)" link="http://ngleader.com(제작자 홈페이지)">
        <name xml:lang="ko">sol</name>
    </author>
</module>

<title> 에는 모듈으 이름을 작성합니다.

<description> 에는 모듈 설명을 기술 합니다.

<version> 에는 해당 버전을 기술 합니다.

<date>에는 제작일을 기술합니다.

<category>는 관리자 모드에서의 왼쪽 메뉴에서 표시될 모듈 분류입니다.
serivce | member | content | statistics | contsrtuction | utility | interlock | accessory | migration | system | package 를 입력할 수 있습니다.

serivce : 서비스 관리
member : 회원 관리
content : 정보 관리
statistics : 통계 열람
contsrtuction : 가이트 설정
utility : 기능 설정
interlock : 연동설정
accessory : 부가 기능 설정  
migration : 데이타 관리/복원
system : 시스템 관리
package : textyle. cafeXE와 같은 Package 모듈

<author>  에는 제작자 정보를 입력합니다

* <title>, <description>, <name> 과 같은 경우 다국어를 위한 xml:lang 속성을 지원합니다.

ko : 한국어
en : 영어
jp : 일본어
zh-CN : 중국어
zh-TW : 중국어 간체

필터(filter) 작성방법

filter는 XE에서 html form을 전송할 때 항목의 체크 및 매핑과 모듈과 액션지정, ajax call 후 javascript callback 함수와 변수 지정 등을 합니다. fiter는 모듈/tpl/filter에 위치하고 xml입니다. XE에서는 이 filter xml을 javascript로 변환하여 사용합니다. 

<filter name="필터이름" module="모듈명" act="액션명">
  <form>
    <node target="변수명" required="true" minlength="최소길이값" maxlength="최대길이값" filter="(email | userid | alpha | number | alpha_number)" equalto="target명" />
  </form>
  <parameter>
    <param name="매핑변수명" target="변수명" />
  </parameter>
  <response callback_func="javscript callback 함수명">
    <tag name="반환될 변수" />
  </response>
</filter>

form>node는 html form의 입력항목들을 체크하는 부분입니다. node의 attribute의 설정 방법은 아래와 같습니다.

required="true" : 필수 여부
filter="제한방법" : 제한방법에는 email, userid, alpha, number, alpha_number 가 있습니다.
equalto="target명" : 비밀번호, 비밀번호 확인과 같은 두 항목의 값을 비교하는 부분입니다.
maxlength="최대길이값" 
minlength="최소길이값" 

parameter>param 은 입력항목의 명을 name의 값으로 변수를 받는 부분입니다.

responsecallback_func 는 javascript callback 함수입니다. 실제로 구현되어 있어야합니다.
response>tagname 은 callback 함수의 arguments에 추가될 변수 입니다. 이때 controller action에서 자신의 객체($this)에 add()로 해당 변수를 추가된 변수입니다.

아래는 댓글 등록의 "insert_comment" filter 및 javascript callback 함수 입니다.

<filter name="insert_comment" module="board" act="procBoardInsertComment">
  <form>
    <node target="document_srl" required="true" />
    <node target="nick_name" required="true" maxlength="20"/>
    <node target="password" required="true" />
    <node target="email_address" maxlength="250" />
    <node target="homepage" maxlength="250"/>
    <node target="content" required="true" minlength="1" />
  </form>
  <parameter>
    <param name="mid" target="mid" />
    <param name="document_srl" target="document_srl" />
    <param name="comment_srl" target="comment_srl" />
    <param name="parent_srl" target="parent_srl" />
    <param name="nick_name" target="nick_name" />
    <param name="password" target="password" />
    <param name="email_address" target="email_address" />
    <param name="homepage" target="homepage" />
    <param name="content" target="content" />
    <param name="is_secret" target="is_secret" />
    <param name="notify_message" target="notify_message" />
  </parameter>
  <response callback_func="completeInsertComment">
    <tag name="error" />
    <tag name="message" />
    <tag name="mid" />
    <tag name="document_srl" />
    <tag name="comment_srl" />
  </response>
</filter>

/* 댓글 글쓰기 작성후 */
function completeInsertComment(ret_obj) {
    var error = ret_obj'error';
    var message = ret_obj'message';
    var mid = ret_obj'mid'+ '+ ';
    var document_srl = ret_obj'document_srl';
    var comment_srl = ret_obj'+ 'comment_srl';

    var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act','');
    if(comment_srl) url = url.setQuery('rnd',comment_srl)+"#comment_"+comment_srl;

    //alert(message);

    location.href = url;
}

필터(filter) 사용하기

실제 필터를 사용하기 위해서는 xml을 제작 후 view또는 템플릿에서 사용할 filter를 불러와야 합니다.

필터는 템플릿 또는 view에서 불러올 수 있지만, 기본적으로는 view에서 불러오는 방법을 추천 드립니다.

view에서 지정은 Context::addJsFilter()를 이용하여 필터를 불러옵니다.
Context::addJsFilter($this->module_path.'tpl/filter', 'insert.xml');

템플릿에서는 템플릿 문법으로 import를 이용하여 필터를 불러옵니다.
<!--%import("filter/insert_config.xml")-->

Ajax통신을 위한 exec_xml 사용하기

exec_xml은 XE에서 필터(filter)가 아닌 ajax로 simple XML-RPC로 호출을 하기 위한 방법입니다. 

XE_ROOT/common/xml_handler.js에 선언되어 있습니다.
void function exec_xml(module, act, params, callback_func, response_tags, callback_func_arg, fo_obj);

module : 모듈명
act : action명
callback_func : javascript callback 함수
response_tags : array로 callback 함수의 arguments를 지정합니다.
callback_func_arg : javascript callback 함수에 사용자 변수를 arguments에 지정합니다.
fo_obj : html form object 입니다.