XE 모듈 만들기

Study4U 2012.09.13 15:10 조회 수 : 7360

XE 모듈을 만들면서 학습한 내용을 정리합니다. 개인적으로 기록을 하기 위한 목적이기에, 더 많은 정보를 얻고자 하는 분은 XE 개발문서나 XE 공식 사이트에서 문의하기 바랍니다.


[DB 테이블 생성하기]

1. 모듈에서 사용할 DB는 schemas 폴더에서 스키마 파일을 만들면 해당 파일이름으로 DB 테이블이 생성됩니다.

xml 파일이름과 xml 파일내의 table name 은 같은 이름으로 합니다.


<table name="book_manage">
    <column name="books_srl" type="number" size="11" notnull="notnull" primary_key="primary_key" auto_increment="auto_increment" />
    <column name="member_srl" type="number" size="11" notnull="notnull" default="0" index="idx_packages" />
    <column name="denied" type="char" size="1" default="N" index="idx_is_denied" />
    <column name="regdate" type="date" index="idx_regdate " />
</table>


2. 이미 같은 이름의 DB 테이블이 있는 경우 새로 생성되지 않으므로, 이전의 테이블을 삭제하거나, 다른 이름으로 만들어야 합니다.


1단계 - [액션 정의]

XE에서 사용할 액션($act) 을 정의해야 합니다.


1. conf 폴더내의 module.xml 파일에서 정의하게 됩니다.


<action name="dispTestAdminManage" type="view" standalone="true" />

<action name="procTestAdminManageInseart" type="controller" standalone="true" />


action name 은 첫글자는 항시 대문자이어야 하며, 모든 글자를 대문자로 지정할 수는 없습니다. 

예) 올바른 액션이름 : dispTestAdminManage, 잘못된 액션 이름 : disTESTAdminManage , disptestAdminManage

action name 에 Admin 이 들어가면, 관리자 페이지에서 사용되는 액션입니다.

type 에 view 라고 하면, 모듈명.admin.view.php 파일내에서 액션이름의 함수를 구현하면 됩니다.

controller 이라고 하면, 마찬가지로 모듈명.admin.controller.php 파일에 액션이름의 함수를 구현하면 됩니다.

controller 은 주로 게시판같은 경우, 새로운 게시판을 생성, 삭제, 수정할때 사용되는 액션을 구현하면 됩니다.


2단계 - [모듈에서 페이지로 값 전달방법]


1. tpl 폴더에 있는 파일들이 관리자페이지에서 사용되는 html 파일들입니다. 필요한 경우 파일을 새로 생성하면 됩니다.


2. 보통 header.html 파일에 서브 메뉴 버튼들이 구현되어 있습니다. 일반적으로 그곳에 액션을 링크해 주면 됩니다.

<li <!--@if($act=='dispTestAdminManage')-->class="active"<!--@end-->><a href="{getUrl('act','dispTestAdminManage')}">자료관리</a></li>


3. 모듈명.admin.view.php 파일에서 module.xml 에 정의한 액션함수를 입력하고, $this->setTemplateFile 을 사용해서 출력에 사용되는 파일을 지정하면 됩니다.


function dispTestAdminManage() {

$oModuleAdminModel = &getAdminModel('module');

$skin_content = $oModuleAdminModel->getModuleMobileSkinHTML($this->module_info->module_srl);

Context::set('skin_content', $skin_content);

$this->setTemplateFile('example');

}


참고로 Context::set() 함수를 사용해서 출력되는 페이지에 변수값을 넘길 수 있습니다.


4. 그리고, tpl 폴더내에 example.html 파일을 새로 생성해서 페이지에 출력할 내용을 구현하면 됩니다.


3단계 - [페이지에서 모듈로 폼값 전송방법]


1. HTML 파일내에 여러 형태의 입력 폼을 만듭니다.


<!--%import("filter/first_process.xml")-->

<form action="./" method="post" name="first_form" onsubmit="return procFilter(this, first_process);">

<input type="hidden" name="mid" value="{$mid}" />

<input type="text" name="txtname" value="{$logged_info->user_name}" />

<input type="submit" value="전송" />

</form>



폼값을 모듈로 전송하기전에 filter/first_process.xml 파일에서 입력된 폼값의 유효성을 체크하게 됩니다.


또는


<form ruleset="formcheckaction="./" name="first_form" method="post" enctype="multipart/form-data" >

<input type="hidden" name="mid" value="{$mid}" />

<input type="text" name="txtname" value="{$logged_info->user_name}" />

<input type="submit" value="전송" />

</form>



폼값을 모듈로 전송하기전에 ruleset/formcheck.xml 파일에서 입력된 폼값의 유효성을 체크하게 됩니다.


2. first_process.xml 파일은 아래와 같은 구조를 갖습니다.

 <filter name="first_process" module="document" act="procFirstForm confirm_msg_code="confirm_submit">

<form>

<node target="txtname" required="true" />

</form>

<parameter>

<param name="username" target="txtname" />

</parameter>

<response callback_func="doCallBack">

<tag name="error" />

<tag name="message" />

<tag name="status" />

<tag name="move" />

</response>

</filter>



1) filter name 은 파일이름과 같은 이름이어야 하며, 1번에서 procFilter(this, first_process) 와 같은 이름이어야 합니다.
2) module 에 모듈이름을 입력하고, act 에는 모듈.control.php 에 정의된 함수, 폼값을 받아서 처리할 모듈 함수를 입력하면 됩니다.
3) act 의 procFirstForm 함수명은 conf/module.xml 파일내에도 정의되어 있어야 합니다.
4) 그리고 중요한 점은 아래와 같이 module.xml 에서 type 은 controller 로 정의되어야 합니다.
<action name="procFirstForm" type="controller" standalone="true" />
5) 마지막으로 모듈.controller.php 파일내에서 procFirstForm 함수를 정의해서 사용하면 됩니다.
6) procFirstForm 함수에서 폼값을 받는 방법은 Context::get('username'); 을 이용해서 원하는 항목만 받아서 DB 등에 저장하면 됩니다. 또는 모든 폼값을 사용할때는 Context::getRequestVars(); 을 이용할 수 있습니다.

7) <node target="txtname" required="true" /> 는 위에서 txtname 이라는 이름의 INPUT 폼을 체크하여, required ="true" 즉, 입력값이 없는 경우 메세지창을 띄우게 됩니다.

8) <param name="username" target="txtname" /> 는 node target 에서 넘겨받은 값을 지정한 파라미터값에 저장합니다. 즉, 모듈 함수(procFirstForm)에서 사용할 실제적인 폼값이 전송되는 부분입니다.

9) <response callback_func="doCallBack"> 는 모듈 함수(procFirstForm)가 DB저장등의 모든 작업을 마치고 이전 페이지로 넘어오는 자바스크립트 콜백 함수이름입니다. 만약 콜백함수가 필요없다면 해당구문을 삭제하면 됩니다.
리턴되어 출력되는 페이지의 자바스크립트.js 문서에 doCallBack(ret_obj) 함수를 정의하면 됩니다.
다음과 같이 정의해서 사용하면 됩니다.
function doCallBack(ret_obj) {
alert(' status 에 리턴된 값은 '+ret_obj['status']+' 입니다.');
location.href  = current_url.setQuery('mid',ret_obj['move']); //결과페이지 이동
}

참고로 모듈의 액션함수인 procFirstForm 에서 add() 함수를 이용해서 리턴시킬 값를 입력하면 됩니다.
$this->add('move', $mid); 



3. formcheck.xml 의 ruleset 구조는 다음과 같습니다.


<?xml version="1.0" encoding="utf-8"?>

<ruleset version="1.5.0">

    <fields>

<field name="txtname" required="true" />

</fields>

</ruleset>



즉, 모듈에서 동작 과정은  


DB 생성 및 module.xml 에 액션 함수정의 -> 스킨(페이지 구현) --> 모듈.View(액션 함수 구현, 변수) --> Filter(XML 폼체크) --> 모듈.Controller(PHP 함수, 폼값 처리) -–> 스키마(DB 저장) -> 리턴(콜백) -> 결과 페이지 이동


[리스트목록등에서 페이징 사용방법]


1. xml DB 쿼리파일에서 navigation 부분에 아래와 같이 page 구문을 추가합니다.


<navigation>

... 중략...

<page_count var="page_count" default="10" />

<page var="page" default="1" />

</navigation>


2. 위에서 page 를 추가한 경우, DB 결과값에 page_navigation 라는 속성변수가 자동 생성됩니다. 모듈의 액션함수에서 다음과 같이 값을 전달합니다.

$obj->page = Context::get('page');

$obj->list_count = 20;

$obj->page_count = 10;

$output = executeQuery('모듈명.XML DB파일이름', $obj);

Context::set('page_navigation', $output->page_navigation);

return $output;


3. 위에서 받은 $page_navigation 변수를 아래와 같이 HTML 문서의 적당한 위치에 표현하면 됩니다.

<a href="{getUrl('page', '')}" class="direction">&laquo; FIRST</a>

<block cond="$page_navigation->first_page + $page_navigation->page_count > $page_navigation->last_page && $page_navigation->page_count != $page_navigation->total_page">

{@$isGoTo = true}

<a href="{getUrl('page', '')}">1</a>

<a href="#goTo" class="tgAnchor" title="{$lang->cmd_go_to_page}">...</a>

</block>


<!--@while($page_no = $page_navigation->getNextPage())-->

{@$last_page = $page_no}

<strong cond="$page_no == $page">{$page_no}</strong>

<a cond="$page_no != $page" href="{getUrl('page', $page_no)}">{$page_no}</a>

<!--@end-->


<block cond="$last_page != $page_navigation->last_page">

{@$isGoTo = true}

<a href="#goTo" class="tgAnchor" title="{$lang->cmd_go_to_page}">...</a>

<a href="{getUrl('page', $page_navigation->last_page)}">{$page_navigation->last_page}</a>

</block>


<a href="{getUrl('page', $page_navigation->last_page)}" class="direction">LAST &raquo;</a>