웹마스터 팁

퍼머링크란게 주소번호(document_srl) 변경과 관계없이 유일한 주소를 가지게 되는 방식입니다.
(허나 zbXE는 게시물 이동되도 번호 그대로 더라고요;;)

또하나는 한글 주소로도 사용가능합니다.
텍스트큐브를 예로 들면 "http://textcube.org/entry/퍼머링크-입니다" 이런식의 주소 체계입니다.

아래 내용을 적용 후에 글 하나 등록하시면 xe_documents 테이블에 글제목이 extra_vars20 컬럼으로 저장되도록 했습니다.

주소체계는 "http://홈페이지/zbXE경로/board/:퍼머링크-입니다" 이렇게 했습니다.

동일한 제목으로 글 등록시 "퍼머링크-입니다-1"로 주소가 바뀌며 방식은 텍스트큐브 방식과 동일하게 해봤습니다.

예) http://www.animeclub.net/idea/:zbXE에-퍼머링크-달기 <-클릭해보세요

수정에 필요한 파일
제로XE/.htaccess
제로XE/module/board/board.view.php
제로XE/module/board/board.controller.php
제로XE/module/board/skin/xe_board/style_list.html
제로XE/module/document/document.admin.controller.php
제로XE/classes/context/Context.class.php

XML Query
제로XE/module/board/queries/getDocumentSrlInfo.xml
제로XE/module/board/queries/getPermaSearch.xml
->파일은 첨부함

제로XE/.htaccess 제일하단에 추가
1
2
3
# Permalink link
RewriteRule ^:(.*)$ ./index.php?entry=$1 [L]
RewriteRule ^([a-zA-Z0-9_]+)/:(.*)$ ./index.php?mid=$1&entry=$2 [L]

제로XE/board/board.view.php
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
* 게시글 목록을 추출함
**/
 
// 목록 구현에 필요한 변수들을 가져온다
$document_srl = Context::get('document_srl');
/*------------------------Permalink 추가-------------------------*/
    // document_srl 을 Permalink 주소로 변경
    $perma = (mb_detect_encoding(Context::get('entry')))?
        Context::get('entry'):
        iconv("EUC-KR","UTF-8", Context::get('entry'));
$oPermaController = &getController('board');
    if(!$document_srl) $document_srl = ($perma)? $oPermaController->getDocumentSrlInfo($perma):'';
/*------------------------Permalink 추가 끝-------------------------*/
$page = Context::get('page');
 
// document model 객체를 생성
$oDocumentModel = &getModel('document');
.......

제로XE/board/board.controller.php
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class boardController extends board {
 
/**
* @brief 초기화
**/
function init() {
}
/*------------------------Permalink 추가-------------------------*/
/**
* @brief Permalink 주소로 document_srl 알아오기
**/
function getDocumentSrlInfo($perma) {
// $perma로 document_srl의 정보를 구함
if($perma) {
$args->extra_vars20 = $perma;
$output = executeQuery('board.getDocumentSrlInfo', $args);
}
 
    if(!$output->toBool()) return $output;
 
$list = $output->data;
if(!$list) return;
if(!is_array($list)) $list = array($list);
 
foreach($list as $key => $val) {
$document_srl = $val->document_srl;
}
 
return $document_srl;
}
 
/**
* @brief Permalink 주소를 검사
**/
function getEntrySearch($obj){
    $output = executeQuery('board.getPermaSearch', $obj);
    if(!$output->toBool()) return $output;
    $list = $output->data;
    if(!$list) return;
    if(!is_array($list)) $list = array($list);
    foreach($list as $val) {
        $perma->count = ($val->entry == 0) ? true : false;
    }
    return $perma;
}
 
/**
* @brief Permalink value 처리(HTML,특수문자 등 제거)
**/
function getEntryReplace($obj){
    $title_arr = array("?","!","@","#","$","%","^","&","\\",";",":",".","/","=");
    $title = strip_tags($obj->extra_vars20);
    $title = str_replace($title_arr,"",$title);
    $title = str_replace(" ","-",$title);
    $perma->extra_vars20 = $title;
    // Permalink 처리를 위한 controller 객체 생성
$oPermaController = &getController('board');
    $permaSearch = $oPermaController->getEntrySearch($perma);
 
    $i = 0;
    while(!$permaSearch->count)
    {
    $i++;
    $perma->extra_vars20 = $title."-".$i;
    $permaSearch = $oPermaController->getEntrySearch($perma);
    }
    return $perma->extra_vars20;
}
/*------------------------Permalink 추가 끝-------------------------*/     
/**
* @brief 문서 입력
**/
function procBoardInsertDocument() {
.........
  
이어서...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// document module의 model 객체 생성
$oDocumentModel = &getModel('document');
 
// document module의 controller 객체 생성
$oDocumentController = &getController('document');
/*------------------------Permalink 추가-------------------------*/
// entry url 처리를 위한 controller 객체 생성
$oPermaController = &getController('board');
/*------------------------Permalink 추가 끝-------------------------*/
// 이미 존재하는 글인지 체크
$oDocument = $oDocumentModel->getDocument($obj->document_srl, $this->grant->manager);
 
// 이미 존재하는 경우 수정
if($oDocument->isExists() && $oDocument->document_srl == $obj->document_srl) {
/*------------------------Permalink 추가-------------------------*/
        // 기존 permalink 정보와 같은지 확인
        if($oDocument->get('extra_vars20')!=$obj->extra_vars20){
        // permalink 결과 저장
        $ebj->extra_vars20 = ($obj->extra_vars20)?$obj->extra_vars20:$obj->title;
        $obj->extra_vars20 = $oPermaController->getEntryReplace($ebj);
        }
/*------------------------Permalink 추가 끝-------------------------*/
$output = $oDocumentController->updateDocument($oDocument, $obj);
$msg_code = 'success_updated';
 
// 그렇지 않으면 신규 등록
} else {
/*------------------------Permalink 추가-------------------------*/
        // permalink 결과 저장
        $ebj->extra_vars20 = ($obj->extra_vars20)?$obj->extra_vars20:$obj->title;
        $obj->extra_vars20 = $oPermaController->getEntryReplace($ebj);
/*------------------------Permalink 추가 끝-------------------------*/
$output = $oDocumentController->insertDocument($obj);
$msg_code = 'success_registed';
$obj->document_srl = $output->get('document_srl');
}
............

제로XE/module/board/skin/xe_board/style_list.html
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!-- 공지사항 출력 -->
<!--@foreach($notice_list as $no => $document)-->
<tr class="notice">
    <!--@if($module_info->display_number!='N')--><td class="notice"><!--@if($document_srl == $document->document_srl)--><img src="./images/common/iconArrowD8.gif" border="0" alt="" /><!--@else-->{$lang->notice}<!--@end--></td><!--@end-->
    <!--@if($grant->is_admin)--><td class="checkbox"><input type="checkbox" name="cart" value="{$document->document_srl}" onclick="doAddDocumentCart(this)" <!--@if($document->isCarted())-->checked="checked"<!--@end--> /></td><!--@end-->
    <td class="title">
    <!--@if($module_info->use_category == "Y" && $document->get('category_srl'))-->
    <strong class="category">{$category_list[$document->get('category_srl')]->title}</strong>
    <!--@end-->
<!------------------------Permalink 변경------------------------->
    <a href="{getUrl('document_srl', $document->document_srl, 'listStyle', $listStyle, 'cpage','','entry',$document->get('extra_vars20'))}">{$document->getTitle($module_info->subject_cut_size)}</a>
<!------------------------Permalink 변경 끝------------------------->
    <!--@if($document->getCommentCount())-->
..........

이어서...
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<!-- 일반 글 출력 -->
<!--@foreach($document_list as $no => $document)-->
<tr class="bg{($no+1)%2+1}">
    <!--@if($module_info->display_number!='N')--><td class="num"><!--@if($document_srl == $document->document_srl)--><img src="./images/common/iconArrowD8.gif" border="0" alt="" /><!--@else-->{$no}<!--@end--></td><!--@end-->
    <!--@if($grant->is_admin)--><td class="checkbox"><input type="checkbox" name="cart" value="{$document->document_srl}" onclick="doAddDocumentCart(this)" <!--@if($document->isCarted())-->checked="checked"<!--@end--> /></td><!--@end-->
    <td class="title">
    <!--@if($module_info->use_category == "Y" && $document->get('category_srl'))-->
    <strong class="category">{$category_list[$document->get('category_srl')]->title}</strong>
    <!--@end-->
<!------------------------Permalink 변경------------------------->
    <a href="{getUrl('document_srl', $document->document_srl, 'listStyle', $listStyle, 'cpage','','entry',$document->get('extra_vars20'))}">{$document->getTitle($module_info->subject_cut_size)}</a>
<!------------------------Permalink 변경 끝------------------------->                      
    <!--@if($document->getCommentCount())-->
............

제로XE/module/document/document.admin.controller.php
285
286
287
288
289
290
291
292
293
294
295
296
/*------------------------Permalink 추가-------------------------*/
$oPermaController = &getController('board');
        $ebj->extra_vars20 = ($obj->extra_vars20)?$obj->extra_vars20:$obj->title;
        $obj->extra_vars20 = $oPermaController->getEntryReplace($ebj);
/*------------------------Permalink 추가 끝-------------------------*/
// 글의 등록
$output = $oDocumentController->insertDocument($obj, true);
if(!$output->toBool()) {
    $oDB->rollback();
    return $output;
}
................

제로XE/classes/context/Context.class.php
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
// rewrite모듈을 사용하고 인자의 값이 4개 이하일 경우
if($this->allow_rewrite && $var_count < 10) {
$var_keys = array_keys($get_vars);
 
        if($var_count == 1) {
    if($var_keys[0]=='mid') return $this->path.$get_vars['mid'];
    elseif($var_keys[0]=='document_srl') return $this->path.$get_vars['document_srl'];
} elseif($var_count == 2) {
    asort($var_keys);
    $target = implode('.',$var_keys);
    if($target=='act.mid' && !preg_match('/([A-Z]+)/',$get_vars['act'])) return sprintf('%s%s/%s',$this->path,$get_vars['mid'],$get_vars['act']);
    elseif($target=='document_srl.mid'return sprintf('%s%s/%s',$this->path,$get_vars['mid'],$get_vars['document_srl']);
    elseif($target=='act.document_srl'+
 '+
 ')  return sprintf('%s%s/%s',$this->path,$get_vars['document_srl'],$get_vars['act']);
    elseif($target=='mid.page'return sprintf('%s%s/page/%s',$this->path,$get_vars['mid'],$get_vars['page']);
    elseif($target=='category.mid'return sprintf('%s%s/category/%s'+
 ',$this->path,$get_vars['mid'],$get_vars['category']);
    elseif($target=='act.mid'return sprintf('%s%s/%s',$this->path,$get_vars['mid'],$get_vars['act'+
 ']);
} elseif($var_count == 3) {
            asort($var_keys);
    $target = implode('.',$var_keys);
    if($target=='act.document_srl.key') {
    return sprintf('%s%s/%s/%s',$this->path,$get_vars['document_srl'],$get_vars['+
 'key'],$get_vars['act']);
    } elseif($target=='document_srl.entry.mid') {/*-----------Permalink 추가-----------*/
    return sprintf('%s%s/:%s',$this->path,$get_vars['mid'],$get_vars['entry']); /*-----------Permalink 추가-----------*/
    } elseif($target=='category.mid.page') {
    return sprintf('%s%s/category/%s/page/%s',$this->path,$get_vars['mid'],$get_vars['+
 'category'],$get_vars['page']);
    } elseif($target=='mid.search_keyword.search_target' && $get_vars['search_target']=='tag') {
    return sprintf('+
 '%s%s/tag/%s',$this->path,$get_vars['mid'],str_replace(' ','-',$get_vars['search_keyword']));
.......


/*------------------------Permalink 추가-------------------------*/
/*------------------------Permalink 추가 끝-------------------------*/
이부분만 추가하거나 수정해주세요

위 파일 줄라인 번호는 다를 수 있으니 비슷한 곳 찾으셔서 등록해주세요.



ps :
1. 소스 적용 이후 제대로 동작 안될 수도 있습니다. 자료는 백업 후 적용하세요. (제가 많이 허접합니다. ^^;)
2. 보안점이나 사항이 있다면 같이 개선했으면 합니다. 저 잘 못합니다. ^^;
3. 게시판 설정에서 확장변수 20번 설정해서 사용하면 제목따라가지 않고 원하는 이름으로 입력가능합니다.
4. 변수명이나 명칭정하는게 좀 엉성해서... 멋진 변수명들 없을까요?? ^^


5. 조금 오류가 있어서 Context.class.php와 style_list.html 수정했습니다. 08.03.13 13:50
제목 글쓴이 날짜
XE 1.2.1에서 xe_default 게시판 스킨 사용시 IE에서 글입력폼이 안보일 때 [2] 현의느낌 2009.04.28
글읽기에서 글쓴이의 닉네임을 이름으로 변경하기 하얀마법 2010.10.29
zbXE에 퍼머링크 달기 [3] file 라르게덴 2008.03.13
숫자 아이디 사용법 [6] Slick 2008.01.10
리눅스에서 제로보드 xe를 위한 환경 구축하기 [6] 써니a 2007.08.18
메인 페이지 수정이 안되는 경우 file nurungso 2010.11.07
새로운 채팅 서비스 웹톡! [3] file 명랑폐인™ 2010.12.06
어느게시판이든 모두 적용이 가능한 그림판입니다.^^ [1] web 2010.12.07
[허접팁] 파일첨부가 안됩니다 [1] 클럽다이 2009.05.23
클릭마다 조회수 올리기 [1.4.0] [12] file 지B 2009.04.04
레이아웃 편집, 게시판 상/하단 내용에 위젯 스타일 적용하기 [2] LutZ 2010.09.12
새글 (댓글) 작성후 자동으로 이메일 보내질때 작성자 서명을 붙이는법 [1] 왕초봉 2010.04.10
외부프로그램에서 제로보드 xe 및 그누보드 회원 연동(로그인) 하기 - 초간단 [1] 한이73 2010.02.03
[생초보팁] 페이지 내용 줄간격 css 에혀라X 2010.11.30
파일 첨부할때 HTTP Error 메세지 창이 뜨면서 첨부되지 않을때 해결방법 [1] file DuRi 2010.11.22
개인 홈페이지에서 아주 손쉽게 배경음악을 깔아놓는 법 [5] 지녁 2010.11.25
[생초보팁] 서브메뉴 배경이미지 활용하기 [4] file 에혀라X 2010.11.24
XE 일일이 메뉴출력하지 말고 XE함수들로 한번에 처리하세요! [1] 소렌트. 2010.04.11
xe 파일첨부 시 증발하는 현상 해결 팁 [5] iwishiwas.idtail.com 2009.07.28
제로보드에서 아이프레임(iframe) 높이 자동조절(파폭,IE, 모두 작동) [10] HaruKaze 2009.03.17