제로보드 사이트에서 몇몇 분들이 소스를 공개해 달라고 하셔서 원리를 설명 드릴까 합니다.

근데 참 어려운게 페이지 원리 이전에 위젯의 원리부터 설명해야할 필요가 있다는게... ㅠㅠ

위젯 프로그램은 ./widgets 라는 폴더안에 들어가 있으며, 이곳에 있어야지 실행가능 합니다.

newest_document 스킨을 이용한 페이지 기능 설치 방법을 설명 드리겠습니다.

추가, 수정에 필요한 파일들(실행 순서대로 나열합니다.)
newest_document/conf/info.xml <- 입력을 받기 위한 입력창
: 관리자페이지에서 코드 실행하기전에 이곳으로부터 정보를 입력 받습니다.
newest_document/newest_document.class.php <- 입력 받은 정보를 처리
: 입력 받은 정보를 적절히 정리해서 DB로 부터 결과값들을 받고 스킨 처리를 하는 파일
newest_document/queries/getNewestDocuments.xml <- DB Query용 XML 파일
: $page 번호 값에 따라서 결과를 출럭하기 위해 <navigation>에 내용을 추가 해야 합니다.
newest_document/queries/getNewestDocumentsCount.xml <- DB Query용 XML 파일
: 결과값용 Query와 다르게 페이지 기능을 만들기 위해 하나의 Query를 더 해야합니다.
newest_document/skins/default/list.html <- DB로 부터의 결과를 이용하여 표현하는 스킨 파일


- info.xml -
<var id="page_count">
<name xml:lang="ko">페이지 목록수</name>
<type>text</type>
<description xml:lang="ko">출력될 페이지의 수를 정하실 수 있습니다. (기본 5개)</description>
</var>
<var id="page_type">
<name xml:lang="ko">페이지 출력 여부</name>
<type>select</type>
<description xml:lang="ko">페이지를 출력할지 선택하세요.</description>
<options>
<name xml:lang="ko">N</name>
<value></value>
</options>
<options>
<name xml:lang="ko">Y</name>
<value>Y</value>
</options>
</var>
xml용으로 된 정보 입력 방식입니다. 위의 page_count와 page_type이라는 정보를 받고
페이지 네비게이션 출력 여부나 출력 시 몇개 까지 출력할지 등을 정할 수 있도록 추가합니다.


- newest_document.class.php [중요] -

이 파일에서 거의 모든 기능을 하기 때문에 이곳에서의 진행내용을 이해하지 못하면 만들기 어렵습니다.
우선, 페이지 기능을 만들기 위해서는 약간의 산수가 필요합니다.
그리고 계산을 위한 값이 만들어져야 겠지요.
$output = executeQueryArray('widgets.newest_document.getNewestDocuments', $obj);
이것을 기준점으로 위쪽은 정보를 어떻게 DB로 보낼지 입력 받은걸 처리하는 과정이며,
아래쪽은 DB에서로 부터 나온 결과물을 어떻게 처리할지의 과정이라고 보시면 됩니다.

/* 페이지 네비게이션 기능 추가 */
// 페이지 목록 수 (1,2,3,4....)
$page_count = $args->page_count;
if(!$page_count) $page_count = 5;
$obj->page_count = $page_count;

// 페이지 출력 여부
$page_type = $args->page_type;

// 페이지 번호 구하기
if($page_type=='Y') $obj->page = (Context::get('page'))? Context::get('page'): 1;
/* 페이지 네비게이션 기능 추가 끝 */
간단히 설명 들어갑니다.
info.xml로 부터 입력 받은 값들은 상단에 function proc($args) {} 선언으로 부터 넘어오게 됩니다.
$args에는 아까 입력했던 page_count나 page_type 등이 포함하여 많은 정보들이 넘어오게 됩니다.

$page_count = $args->page_count;
if(!$page_count) $page_count = 5;
$obj->page_count = $page_count;

넘어온 page_count에 값이 없으면 기본값을 생성하기 위해 위와 같은 처리를 해줍니다.
(넘어온 데이터를 굳이 $page_count로 불필요하게 만들어서 담는 이유는 DB처리 후에
페이지 계산을 위해서 필요하기 때문에 마 본인이 별도로 담아 놓은 것이니 큰 신경쓰지마시길 바랍니다.)

$page_type = $args->page_type;
DB로 넘어가는 값이 아닌 skin과 함수상의 처리이기 때문에 $obj로 넘기지 않습니다.
if($page_type=='Y') $obj->page = (Context::get('page'))? Context::get('page'): 1;

페이지를 사용하기로 했다면 현재 주소에 페이지가 있는지 검사 후 없으면 기본값 1로 대처하도록 합니다.
(Context::get('변수')는 주소창에서 index.php?aaa=bbb&ccc=ddd 등의 매개변수의 값을 뽑아오는 방법 입니다.)
$output = executeQueryArray('widgets.newest_document.getNewestDocuments', $obj);
$output_count = executeQueryArray('widgets.newest_document.getNewestDocumentsCount', $obj);
widgets.newest_document.getNewestDocuments 는
widgets/newest_document/getNewestDocuments.xml 의 정보를 불러오는 의미 입니다.


$output과 또 하나 $output_count 부분을 하나더 만들어서 페이지 계산을 위해
위젯의 결과물을 뽑으려고 하는 대상의 전체 게시물 수를 뽑습니다.
// 페이지용 Query에 오류가 생기면 그냥 무시
if(!$output_count->toBool()) return;
/* 페이지 네비게이션 기능 추가 */
$widget_info->page_type = $page_type;
$widget_info->total_count = $output_count->data[0]->count; // 전체 개시물 수
$widget_info->page = (!Context::get('page'))? 1:Context::get('page'); // 현재 페이지
// 총 페이지 수
$total_count = $widget_info->total_count/$list_count;
if($widget_info->total_count%$list_count != 0) $total_count+=1;
$widget_info->total_page = floor($total_count); // 총 페이지 수
$widget_info->page_count = $page_count; // 총 페이지 수
/* 페이지 네비게이션 기능 추가 끝 */
본격적으로 페이지 기능 구현을 위한 정보들을 뽑아 정리 합니다.
$widget_info->page_type = $page_type;

아까전에 $page_type으로 저장했던 info.xml에서 받아온 출력여부를 저장합니다.
(별도로 $widget_info로 저장한 이유는 skins파일에 한번에 모아서 정보를 보낼려고 하는 겁니다.)
$widget_info->total_count = $output_count->data[0]->count; // 전체 개시물 수
$output_count에서의 결과물이 단일일(한줄) 경우에는 위와 같이 직접 그 값에 접근시키면 됩니다.
$widget_info->page = (!Context::get('page'))? 1:Context::get('page'); // 현재 페이지

위에 DB로 넘기기전에 선언했던 방식인데 이곳에서도 선언하도록 했습니다.(페이지 계산을 위해)

페이지 기능 계산을 위해서는 총 게시물의 수, 한페이지당 출력 수, 페이지번호 수 등의 값이 필요합니다.
$total_count = $widget_info->total_count/$list_count;
전체 게시물수/현재 페이지 수 = 총 페이지번호가 나오겠지요.

if($widget_info->total_count%$list_count != 0) $total_count+=1;
변수는 0부터 시작하기 때문에 표현을 위해서 0이 나오면 1이 되도록 하나씩 더 합니다.

$widget_info->total_page = floor($total_count); // 총 페이지 수
floor() 함수를 이용해서 혹시나 나오는 소수점을 제거 합니다.
$widget_info->page_count = $page_count; // 총 페이지 수

페이지 갯수를 skin처리를 위해 넘깁니다.



다음은 skin파일에서 역으로 newest_document.class.php안의 함수를 호출하여 page 내용을 받아오기 위한 함수들 입니다.
/**
* @brief 다음 페이지 요청
**/
function WD_getNextPage($total_count, $total_page, $cur_page, $page_count = 10) {

$first_page = $cur_page - (int)($page_count/2);
if($first_page<1) $first_page = 1;
$last_page = $total_page;
if($last_page>$total_page) $last_page = $total_page;
if($total_page < $page_count) $page_count = $total_page;

$GLOBALS['wd_total_page'] = $total_page;
$GLOBALS['wd_first_page'] = $first_page;
$GLOBALS['wd_page_count'] = $page_count;
$GLOBALS['wd_last_page'] = $last_page;

$page->first_page = $first_page;
$page->last_page = $last_page;

return $page;
}

function WD_getNextPage2() {
$page = $GLOBALS['wd_first_page']+$GLOBALS['wd_i']++;
if($GLOBALS['wd_i'] > $GLOBALS['wd_page_count'] || $page > $GLOBALS['wd_last_page']) $page = 0;
return $page;
}

function WD_getNextClear() {
$GLOBALS['wd_i'] = 0;
}
($GLOBALS['변수'] 를 이용한 이유는 원래 제로XE에서 만들어져 있는 곳을 보면, $this->변수로 써 처리 되어있는데 저는 이게 이상하게 못불러오더라고요. 위젯이라서 그런가?? 아무튼, 그래서 어쩔 수 없이 저리 처리했으며 $GLOBALS로 들어간 변수는 처리할때만이 아니라 그 해당 페이지에서의 완전한 종결까지 누적되어야 하기 때문에 저렇게 사용하였습니다.)



- getNewestDocuments.xml -
<query id="getNewestDocuments" action="select">
<tables>
<table name="documents" />
</tables>
<columns>
<column name="*" />
</columns>
<conditions>
<condition operation="in" column="module_srl" var="module_srl" filter="number" />
<condition operation="equal" column="category_srl" var="category_srl" pipe="and" />
</conditions>
<navigation>
<index var="sort_index" default="list_order" order="order_type" />
<list_count var="list_count" default="20" />
<page_count var="page_count" default="10" />
<page var="page" default="1" />
</navigation>
</query>
페이지별로의 결과를 뽑기 위해서 아래의 내용을 추가합니다.
<navigation> 안에
<page_count var="page_count" default="10" />
<page var="page" default="1" />
를 추가해주세요.

- getNewestDocumentsCount.xml -
<query id="getNewestDocumentsCount" action="select">
<tables>
<table name="documents" />
</tables>
<columns>
<column name="count(*)" alias="count" />
</columns>
<conditions>
<condition operation="in" column="module_srl" var="module_srl" filter="number" />
<condition operation="equal" column="category_srl" var="category_srl" pipe="and" />
</conditions>
<navigation>
<index var="sort_index" default="list_order" order="order_type" />
</navigation>
</query>
getNewestDocuments.xml 의 정보와는 다르게 전체 게시물 수를 구하기 위해
<column name="*" /> 을
<column name="count(*)" alias="count" /> 으로

<navigation> 에서 아래의 것을 제거합니다.
<list_count var="list_count" default="20" />


- list.html -
<!--@if($widget_info->page_type=='Y')-->
<!-- 페이지 네비게이션 -->
<div class="pageNavigation">
<a href="{getUrl('page','','document_srl','','division',$division,'last_division',$last_division)}" class="goToFirst">
<img src="./images/common/bottomGotoFirst.gif" alt="{$lang->first_page}" width="7" height="5" /></a>
<!-- 페이지 정보 구하기 위해 선언 -->
{@$page_view = WD_getNextPage($widget_info->total_count,$widget_info->total_page,$widget_info->page,$widget_info->page_count)}
<!-- 중복 페이지 정보 출력을 위해 사전 초기화 -->
{@WD_getNextClear()}
<!--@while($page_no = WD_getNextPage2())-->
<!--@if($widget_info->page == $page_no)-->
<span class="current">{$page_no}</span>
<!--@else-->
<span class="pageNavigations"><a href="{getUrl('page',$page_no,'document_srl','','division',$division,'last_division',$last_division)}" class="pageNavigation2">{$page_no}</a></span>
<!--@end-->
<!--@end-->
<a href="{getUrl('page',$page_view->last_page,'document_srl','','division',$division,'last_division',$last_division)}" class="goToLast">
<img src="./images/common/bottomGotoLast.gif" alt="{$lang->last_page}" width="7" height="5" /></a>
</div>
<!--@end-->
중요한 부분만 설명하겠습니다.

view plaincopy to clipboardprint?{@$page_view = WD_getNextPage($widget_info->total_count,$widget_info->total_page,$widget_info->page,$widget_info->page_count)} {@$page_view = WD_getNextPage($widget_info->total_count,$widget_info->total_page,$widget_info->page,$widget_info->page_count)}
아까 넘겼던 전체 게시물 수, 전체 페이지 갯수, 현재 페이지, 출력될 페이지상의 번호 갯수 를 WD_getNextPage로 넘겨 처리 받아서 $page_view로 결과를 담습니다.

해당 함수에서 결과로 나오는 값은

view plaincopy to clipboardprint? $GLOBALS['wd_total_page'] = $total_page; $GLOBALS['wd_first_page'] = $first_page; $GLOBALS['wd_page_count'] = $page_count; $GLOBALS['wd_last_page'] = $last_page; $page->first_page = $first_page; $page->last_page = $last_page; $GLOBALS['wd_total_page'] = $total_page; $GLOBALS['wd_first_page'] = $first_page; $GLOBALS['wd_page_count'] = $page_count; $GLOBALS['wd_last_page'] = $last_page; $page->first_page = $first_page; $page->last_page = $last_page;
이것들이며 $GLOBALS은 누적, 다른곳에서의 호출을 위해 사용하고 $page는 최초 페이지 번호(당연히 1이겠죠), 마지막 페이지 번호를 담습니다.

view plaincopy to clipboardprint?{@WD_getNextClear()} {@WD_getNextClear()}
상하로 중복 출력을 위해서 항상 시작전 결과값 중에 $GLOBALS['wd_i'] 횟수가 남아있다면 이를 0으로 초기화 합니다.

view plaincopy to clipboardprint?<!--@while($page_no = WD_getNextPage2())--> <!--@if($widget_info->page == $page_no)--> <span class="current">{$page_no}</span> <!--@else--> <span class="pageNavigations"><a href="{getUrl('page',$page_no,'document_srl','','division',$division,'last_division',$last_division)}" class="pageNavigation2">{$page_no}</a></span> <!--@end--> <!--@end--> <!--@while($page_no = WD_getNextPage2())--> <!--@if($widget_info->page == $page_no)--> <span class="current">{$page_no}</span> <!--@else--> <span class="pageNavigations"><a href="{getUrl('page',$page_no,'document_srl','','division',$division,'last_division',$last_division)}" class="pageNavigation2">{$page_no}</a></span> <!--@end--> <!--@end-->
이제 while 문을 써서 $page_no가 나올때까지 반복합니다.

view plaincopy to clipboardprint?function WD_getNextPage2() { $page = $GLOBALS['wd_first_page']+$GLOBALS['wd_i']++; if($GLOBALS['wd_i'] > $GLOBALS['wd_page_count'] || $page > $GLOBALS['wd_last_page']) $page = 0; return $page; } function WD_getNextPage2() { $page = $GLOBALS['wd_first_page']+$GLOBALS['wd_i']++; if($GLOBALS['wd_i'] > $GLOBALS['wd_page_count'] || $page > $GLOBALS['wd_last_page']) $page = 0; return $page; }
한번 실행할때 마다 $GLOBALS['wd_i'] 증가와 함께 WD_getNextPage을 선언했을때의 페이지 관련 정보를 더해서 그 마지막 페이지 이상인지 이하인지를 계산해서 결과를 보냅니다.
여기서 전체페이지번호 수와 증가 페이지번호수를 비교, 마지막 페이지번호를 비교해서 while 계속을 진행할지 멈출지를 계산합니다.

d
df



by Anna 안나 2008. 11. 6. 00:42