확장변수 활용¶
게시판의 확장변수를 활용하여 다양한 추가 정보를 관리하는 방법을 학습합니다.
확장변수 출력¶
기본 확장변수 표시¶
<!-- 글 보기에서 확장변수 출력 -->
<div class="extra-vars">
{@$extra_vars = $oDocument->getExtraVars()}
<table class="extra-vars-table" cond="$extra_vars">
<tbody>
<tr loop="$extra_vars=>$key,$val" cond="$val->value">
<th>{$val->name}</th>
<td>
<!-- 텍스트 -->
<span cond="$val->type == 'text'">{$val->value}</span>
<!-- 텍스트에어리어 -->
<div cond="$val->type == 'textarea'">{nl2br($val->value)}</div>
<!-- 선택박스 -->
<span cond="$val->type == 'select'">{$val->value}</span>
<!-- 체크박스 (다중선택) -->
<div cond="$val->type == 'checkbox'">
{@$values = is_array($val->value) ? $val->value : array($val->value)}
<span loop="$values=>$v" class="checkbox-value">{$v}</span>
</div>
<!-- 라디오 -->
<span cond="$val->type == 'radio'">{$val->value}</span>
<!-- 날짜 -->
<span cond="$val->type == 'date'">{zdate($val->value, 'Y-m-d')}</span>
<!-- 이메일 -->
<a cond="$val->type == 'email_address'" href="mailto:{$val->value}">{$val->value}</a>
<!-- 홈페이지 -->
<a cond="$val->type == 'homepage'" href="{$val->value}" target="_blank">{$val->value}</a>
<!-- 전화번호 -->
<a cond="$val->type == 'tel'" href="tel:{$val->value}">{$val->value}</a>
<!-- 주소 -->
<div cond="$val->type == 'kr_zip'">
{@$address = unserialize($val->value)}
<span class="postcode">[{$address[0]}]</span>
<span class="address">{$address[1]} {$address[2]}</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
이미지 확장변수 처리¶
<!-- 이미지 확장변수 -->
{@$extra_vars = $oDocument->getExtraVars()}
<div class="extra-images" cond="$extra_vars">
<div loop="$extra_vars=>$key,$val" cond="$val->type == 'image' && $val->value">
<h4>{$val->name}</h4>
<img src="{$val->value}" alt="{$val->name}" class="extra-image" />
<!-- 라이트박스 연동 -->
<a href="{$val->value}" data-lightbox="extra-images" data-title="{$val->name}">
<img src="{$val->value}" alt="{$val->name}" style="max-width: 200px;" />
</a>
</div>
</div>
리스트에서 확장변수 활용¶
확장변수를 리스트에 표시¶
<!-- 게시판 목록에서 확장변수 출력 -->
<table class="board-list">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
{@
// 리스트에 표시할 확장변수 정의
$list_extra_vars = array('product_price', 'location', 'event_date');
}
<th loop="$list_extra_vars=>$var_idx">
{@$extra_var_info = $module_info->extra_vars[$var_idx]}
{$extra_var_info->name}
</th>
<th>작성자</th>
<th>날짜</th>
</tr>
</thead>
<tbody>
<tr loop="$document_list=>$no,$document">
<td>{$no}</td>
<td class="title">
<a href="{getUrl('document_srl',$document->document_srl)}">
{$document->getTitle()}
</a>
</td>
<!-- 확장변수 값 출력 -->
{@$doc_extra_vars = $document->getExtraVars()}
<td loop="$list_extra_vars=>$var_idx">
{@$value = $doc_extra_vars->{$var_idx}->value}
<!-- 가격 형식 -->
<span cond="$var_idx == 'product_price' && $value">
{number_format($value)}원
</span>
<!-- 날짜 형식 -->
<span cond="$var_idx == 'event_date' && $value">
{zdate($value, 'Y.m.d')}
</span>
<!-- 기본 텍스트 -->
<span cond="$var_idx == 'location'">
{$value}
</span>
</td>
<td>{$document->getNickName()}</td>
<td>{$document->getRegdate('Y.m.d')}</td>
</tr>
</tbody>
</table>
확장변수로 필터링¶
특정 확장변수 값으로 필터¶
<!-- 확장변수 필터 폼 -->
<form action="{getUrl()}" method="get" class="extra-filter">
<input type="hidden" name="vid" value="{$vid}" />
<input type="hidden" name="mid" value="{$mid}" />
<!-- 가격 범위 필터 -->
<div class="filter-group">
<label>가격대</label>
<select name="price_range" onchange="this.form.submit()">
<option value="">전체</option>
<option value="0-50000">5만원 이하</option>
<option value="50000-100000">5-10만원</option>
<option value="100000-200000">10-20만원</option>
<option value="200000-">20만원 이상</option>
</select>
</div>
<!-- 지역 필터 -->
<div class="filter-group">
<label>지역</label>
<select name="location" onchange="this.form.submit()">
<option value="">전체</option>
<option value="서울">서울</option>
<option value="경기">경기</option>
<option value="인천">인천</option>
<option value="부산">부산</option>
</select>
</div>
</form>
<!-- PHP에서 필터링 처리 -->
{@
// 가격 필터링
$price_range = Context::get('price_range');
if($price_range) {
$range = explode('-', $price_range);
$min_price = intval($range[0]);
$max_price = intval($range[1]);
$filtered_list = array();
foreach($document_list as $document) {
$extra_vars = $document->getExtraVars();
$price = intval($extra_vars->product_price->value);
if($max_price) {
if($price >= $min_price && $price <= $max_price) {
$filtered_list[] = $document;
}
} else {
if($price >= $min_price) {
$filtered_list[] = $document;
}
}
}
$document_list = $filtered_list;
}
// 지역 필터링
$location = Context::get('location');
if($location) {
$filtered_list = array();
foreach($document_list as $document) {
$extra_vars = $document->getExtraVars();
if($extra_vars->location->value == $location) {
$filtered_list[] = $document;
}
}
$document_list = $filtered_list;
}
}
확장변수 검색¶
확장변수 포함 검색¶
<!-- 확장변수 검색 폼 -->
<form action="{getUrl()}" method="get" class="search-form">
<input type="hidden" name="vid" value="{$vid}" />
<input type="hidden" name="mid" value="{$mid}" />
<input type="hidden" name="act" value="IS" />
<div class="search-basic">
<select name="search_target">
<option value="title_content">제목+내용</option>
<option value="title">제목</option>
<option value="content">내용</option>
<option value="extra_vars">확장변수</option>
</select>
<input type="text" name="search_keyword" value="{$search_keyword}" />
</div>
<!-- 확장변수별 상세 검색 -->
<div class="search-advanced">
<h4>상세 검색</h4>
{@$module_extra_vars = $module_info->extra_vars}
<div loop="$module_extra_vars=>$var" class="search-extra-var">
<label>{$var->name}</label>
<!-- 텍스트 검색 -->
<input cond="in_array($var->type, array('text', 'textarea', 'email_address', 'homepage', 'tel'))"
type="text"
name="s_{$var->eid}"
placeholder="{$var->desc}" />
<!-- 선택 검색 -->
<select cond="in_array($var->type, array('select', 'radio'))" name="s_{$var->eid}">
<option value="">전체</option>
{@$options = explode("\n", $var->default)}
<option loop="$options=>$opt" value="{trim($opt)}">{trim($opt)}</option>
</select>
<!-- 체크박스 검색 -->
<div cond="$var->type == 'checkbox'" class="checkbox-group">
{@$options = explode("\n", $var->default)}
<label loop="$options=>$opt">
<input type="checkbox" name="s_{$var->eid}[]" value="{trim($opt)}" />
{trim($opt)}
</label>
</div>
<!-- 날짜 검색 -->
<div cond="$var->type == 'date'" class="date-range">
<input type="date" name="s_{$var->eid}_from" />
~
<input type="date" name="s_{$var->eid}_to" />
</div>
</div>
</div>
<button type="submit">검색</button>
</form>
확장변수 통계¶
확장변수별 통계 표시¶
<!-- 확장변수 통계 -->
<div class="extra-var-stats">
{@
// 확장변수 통계 계산
$stats = array();
foreach($document_list as $document) {
$extra_vars = $document->getExtraVars();
// 카테고리형 확장변수 통계
if($extra_vars->product_type) {
$type = $extra_vars->product_type->value;
if(!isset($stats['product_type'][$type])) {
$stats['product_type'][$type] = 0;
}
$stats['product_type'][$type]++;
}
// 가격 평균
if($extra_vars->product_price) {
$price = intval($extra_vars->product_price->value);
$stats['price']['sum'] += $price;
$stats['price']['count']++;
$stats['price']['min'] = min($stats['price']['min'] ?: $price, $price);
$stats['price']['max'] = max($stats['price']['max'] ?: 0, $price);
}
}
if($stats['price']['count']) {
$stats['price']['avg'] = $stats['price']['sum'] / $stats['price']['count'];
}
}
<!-- 통계 표시 -->
<div class="stat-group" cond="$stats['product_type']">
<h4>상품 유형별 통계</h4>
<ul>
<li loop="$stats['product_type']=>$type,$count">
{$type}: {$count}개
</li>
</ul>
</div>
<div class="stat-group" cond="$stats['price']">
<h4>가격 통계</h4>
<ul>
<li>평균가: {number_format($stats['price']['avg'])}원</li>
<li>최저가: {number_format($stats['price']['min'])}원</li>
<li>최고가: {number_format($stats['price']['max'])}원</li>
</ul>
</div>
</div>
커스텀 확장변수 위젯¶
확장변수 기반 위젯¶
<!-- 인기 상품 위젯 (조회수 + 확장변수) -->
<div class="popular-products-widget">
{@
// 조회수 높은 상품 가져오기
$args = new stdClass();
$args->module_srl = $module_info->module_srl;
$args->sort_index = 'readed_count';
$args->order_type = 'desc';
$args->list_count = 5;
$output = executeQueryArray('board.getDocumentList', $args);
$popular_products = $output->data;
}
<h3>인기 상품</h3>
<ul class="product-list">
<li loop="$popular_products=>$product">
{@$extra_vars = $product->getExtraVars()}
<a href="{getUrl('document_srl', $product->document_srl)}">
<!-- 썸네일 -->
<img cond="$product->getThumbnail()"
src="{$product->getThumbnail(100,100)}"
alt="{$product->title}" />
<div class="product-info">
<h4>{$product->title}</h4>
<span class="price" cond="$extra_vars->product_price">
{number_format($extra_vars->product_price->value)}원
</span>
<span class="location" cond="$extra_vars->location">
{$extra_vars->location->value}
</span>
</div>
</a>
</li>
</ul>
</div>
확장변수 입력 폼 커스터마이징¶
동적 확장변수 폼¶
<!-- 글쓰기 폼에서 확장변수 커스터마이징 -->
<script>
jQuery(function($) {
// 특정 확장변수 선택에 따라 다른 필드 표시/숨김
$('select[name="extra_vars[product_type]"]').change(function() {
var type = $(this).val();
// 중고차일 때만 주행거리 표시
if(type == '중고차') {
$('.extra_vars_mileage').show();
} else {
$('.extra_vars_mileage').hide();
}
// 부동산일 때만 평수 표시
if(type == '부동산') {
$('.extra_vars_area').show();
} else {
$('.extra_vars_area').hide();
}
}).trigger('change');
// 가격 입력 포맷팅
$('input[name="extra_vars[product_price]"]').on('input', function() {
var value = $(this).val().replace(/[^0-9]/g, '');
var formatted = Number(value).toLocaleString('ko-KR');
$(this).val(formatted);
});
});
</script>
모범 사례¶
- 필드 타입: 용도에 맞는 확장변수 타입 선택
- 유효성 검사: 입력값 검증 철저히
- 성능 고려: 많은 확장변수 사용시 인덱싱
- UI/UX: 직관적인 입력 폼 제공
- 데이터 정합성: 일관된 데이터 형식 유지
다음 단계¶
확장변수 활용을 마스터했다면, 스케치북 스킨 분석을 학습하세요.