AnimeClub - zbXE... : zeroboard XE

XpressEngine에 관련 내용에 대해서 이야기 합니다.

icon 위젯 프로그램에 페이지 기능 달기

조회 수:4935 댓글:4 등록일:2008.09.02 10:00:50 (*.234.236.247)
제로보드 사이트에서 몇몇 분들이 소스를 공개해 달라고 하셔서 원리를 설명 드릴까 합니다.

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

위젯 프로그램은 ./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-->

중요한 부분만 설명하겠습니다.

{@$page_view = WD_getNextPage($widget_info->total_count,$widget_info->total_page,$widget_info->page,$widget_info->page_count)}

아까 넘겼던 전체 게시물 수, 전체 페이지 갯수, 현재 페이지, 출력될 페이지상의 번호 갯수 를 WD_getNextPage로 넘겨 처리 받아서 $page_view로 결과를 담습니다.

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

        $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이겠죠), 마지막 페이지 번호를 담습니다.

{@WD_getNextClear()}

상하로 중복 출력을 위해서 항상 시작전 결과값 중에 $GLOBALS['wd_i'] 횟수가 남아있다면 이를 0으로 초기화 합니다.

<!--@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가 나올때까지 반복합니다.

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 계속을 진행할지 멈출지를 계산합니다.



profile
조회 수 :
4935
등록일 :
2008.09.02
10:00:50 (*.234.236.247)
엮인글 :
http://animeclub.net/zbXE/60687/f2c/trackback
게시글 주소 :
http://animeclub.net/60687

뮤랑이

2008.10.03
11:14:22
(*.50.11.85)

이것을 포인트랭킹 위젯에 적용시켜서
예를들어 목록을 20개로 정해놓으면 첫 페이지는 1~20등,
다음 페이지를 선택하면 21~40등 이 나오게 하고 싶은데 어찌해야 할까요?
도움 부탁드릴게요.

라르게덴

2008.10.06
09:36:21
(*.234.236.247)
profile
위의 내용을 잘 관찰하시고 응용하여 적용하시면 되겠습니다.
(응용이라는게 거의 대부분 명칭(폴더명,파일명,쿼리문의값명)을 바꾸는 정도라고 생각됩니다.)

ElonShoen

2008.10.24
15:50:32
(*.138.97.245)

안녕하세요 질문글 남깁니다..!!

여기서..진짜 게시판처럼 검색기능을 포함하려면 어떻게해야될까요?

라르게덴

2008.10.24
22:22:44
(*.79.64.78)
profile
간단한 답변으로 나올 질문이 아니네요 ^^
document 모듈에서 document.model.php에 getDocumentList() 함수에서
검색 내용 부분을 그대로 위젯에 적용시키는 수밖에 없을 듯 합니다.
그리고 그 부분의 테스트는 이미 이전글, 다음글 위젯에서 얼추 했던 부분이라
가능합니다.

하지만 그게 되는 위젯이나 강좌 등을 만들라고 하면 좀 난감합니다. 시간이 없어서요 제가 ^^
List of Articles
번호 제목 글쓴이 날짜 조회 수
193 질문-답변 Cooliris PicLens alljoy 2014-02-19 22913
192 질문-답변 운영잔님 질문드립니다. [1] 인터넷짱 2013-06-08 20837
191 질문-답변 아래글에 이어서.. [4] secret 동쪽에태양 2013-02-24 9
190 질문-답변 piclens 을 수정 하고 싶어요 ^^ [2] secret 동쪽에태양 2013-02-17 3
189 질문-답변 로마네스크 재질문 [2] secret 인터넷짱 2013-01-22 5
188 질문-답변 piclens 1.2 요청합니다. [1] alljoy 2013-01-10 14075
187 질문-답변 로마네스크 최근글 질문입니다. [2] file 인터넷짱 2013-01-04 10438
186 질문-답변 아래글 이전글-다음글 관련 확인했는데... 고민하다가 2012-08-13 13467
185 질문-답변 이전글-다음글 관련 문의드립니다. [2] secret 고민하다가 2012-07-31 5
184 질문-답변 이전글 다음글 다시 질문드립니다. [2] 감사합니다. 2012-05-15 13713
183 질문-답변 이전글 다음글 문의드립니다, [2] 감사합니다 2012-05-09 56871
182 질문-답변 로마네스크 최근 문서 출력 위젯 [3] 종구이 2012-03-31 21358
181 질문-답변 json 추출 글 보고 문의 드립니다. [2] cosmos 2012-03-28 25682
180 질문-답변 이전글 다음글 출력에 관한문의 [2] file 봄날2 2012-03-16 22712
179 질문-답변 이전글 다음글 1.1 버튼색상요 [5] 열공365 2012-03-15 15818
178 질문-답변 흠.. 어떻게 하는거죠?? 위젯이 이상해요..; [3] file 2012-02-27 19965
177 질문-답변 이전글 다음글 위젯이요 [2] 열공365 2012-02-20 35816
176 질문-답변 게시판글을 xml로 파싱하는 방법을 부탁드립니다. [2] ibwj 2011-11-24 29228
175 질문-답변 Cooliris PicLens 애드온 1.5..... [3] secret alljoy 2011-10-30 7
174 질문-답변 위젯: 썸네일 생성에 대해서 질문있어요 [2] 아메아메몬 2011-03-25 18496



CATEGORY
ALL [600]
공지 [3]
[551]
사진 [39]
정보 [6]
소식 [2]
정보 [4]

Skin Info

slide_in
 갱신
 
arrow_in