게시판 스킨 기본 구조¶
게시판 스킨이란?¶
게시판 스킨은 게시판 모듈의 화면을 담당하는 템플릿입니다. 목록, 글쓰기, 글보기, 댓글 등 게시판의 모든 화면을 정의합니다.
필수 파일 구조¶
skins/board/
└── my_board_skin/
├── conf/
│ └── info.xml # 스킨 정보
├── css/
│ └── board.css # 스타일시트
├── js/
│ └── board.js # 자바스크립트
├── images/ # 이미지 파일들
├── list.html # 목록 화면 (필수)
├── view.html # 글보기 화면 (필수)
├── write_form.html # 글쓰기 폼 (필수)
├── delete_form.html # 글삭제 폼 (필수)
├── comment.html # 댓글 템플릿 (필수)
├── comment_form.html # 댓글 폼 (필수)
├── file_link.html # 첨부파일 링크
├── file_image.html # 이미지 첨부파일
└── _header.html # 공통 헤더 (선택)
info.xml 작성¶
<?xml version="1.0" encoding="UTF-8"?>
<skin version="0.2">
<title xml:lang="ko">커스텀 게시판 스킨</title>
<description xml:lang="ko">사용자 정의 게시판 스킨입니다.</description>
<version>1.0</version>
<date>2024-01-01</date>
<author email="user@example.com">
<name xml:lang="ko">제작자명</name>
</author>
<!-- 스킨 설정 변수 -->
<extra_vars>
<var name="colorset" type="select">
<title xml:lang="ko">컬러셋</title>
<description xml:lang="ko">게시판 테마를 선택하세요</description>
<options value="default">
<title xml:lang="ko">기본</title>
</options>
<options value="blue">
<title xml:lang="ko">블루</title>
</options>
<options value="green">
<title xml:lang="ko">그린</title>
</options>
</var>
<var name="list_count" type="text">
<title xml:lang="ko">목록 개수</title>
<description xml:lang="ko">한 페이지에 표시할 게시글 수</description>
<default>20</default>
</var>
<var name="thumbnail_width" type="text">
<title xml:lang="ko">썸네일 너비</title>
<description xml:lang="ko">목록에서 썸네일 이미지 너비 (px)</description>
<default>150</default>
</var>
<var name="show_category" type="select">
<title xml:lang="ko">카테고리 표시</title>
<options value="Y">
<title xml:lang="ko">표시</title>
</options>
<options value="N">
<title xml:lang="ko">숨김</title>
</options>
</var>
</extra_vars>
</skin>
주요 변수들¶
시스템 변수¶
<!-- 모듈 정보 -->
{$module_info->mid} <!-- 모듈 아이디 -->
{$module_info->browser_title} <!-- 브라우저 제목 -->
{$module_info->description} <!-- 모듈 설명 -->
<!-- 권한 정보 -->
{$grant->write} <!-- 글쓰기 권한 -->
{$grant->view} <!-- 글보기 권한 -->
{$grant->comment} <!-- 댓글 권한 -->
{$grant->is_admin} <!-- 관리자 권한 -->
<!-- 페이지 정보 -->
{$page} <!-- 현재 페이지 -->
{$total_count} <!-- 전체 게시글 수 -->
{$page_navigation} <!-- 페이지 네비게이션 -->
<!-- 현재 액션 -->
{$act} <!-- 현재 실행 중인 액션 -->
스킨 설정 변수¶
<!-- 스킨 설정값 사용 -->
{$skin_vars->colorset} <!-- 선택한 컬러셋 -->
{$skin_vars->list_count} <!-- 목록 개수 -->
{$skin_vars->thumbnail_width} <!-- 썸네일 너비 -->
{$skin_vars->show_category} <!-- 카테고리 표시 여부 -->
공통 헤더 패턴¶
_header.html 활용¶
<!-- _header.html -->
{@
// 스킨 설정
$colorset = $skin_vars->colorset ?: 'default';
$show_category = $skin_vars->show_category == 'Y';
}
<!-- CSS 로드 -->
<load target="css/board.css" />
<load target="js/board.js" />
<!-- 컬러셋별 CSS -->
<load target="css/colorset_{$colorset}.css" cond="$colorset != 'default'" />
<div class="board-container colorset-{$colorset}">
<!-- 게시판 헤더 -->
<div class="board-header">
<h1 class="board-title">{$module_info->browser_title}</h1>
<p class="board-description" cond="$module_info->description">
{$module_info->description}
</p>
<!-- 카테고리 목록 -->
<div class="category-list" cond="$show_category && $category_list">
<ul>
<li><a href="{getUrl('category', '')}" class="active"|cond="!$category">전체</a></li>
<li loop="$category_list => $key, $val">
<a href="{getUrl('category', $key)}"
class="active"|cond="$category == $key">
{$val->title} ({$val->count})
</a>
</li>
</ul>
</div>
</div>
각 파일에서 헤더 포함¶
<!-- list.html, view.html 등에서 -->
<include target="_header.html" />
<!-- 여기에 각 페이지별 내용 -->
</div> <!-- board-container 닫기 -->
액션별 파일 매핑¶
주요 액션과 템플릿 파일¶
dispBoardContent → list.html
dispBoardWrite → write_form.html
dispBoardModify → write_form.html
dispBoardView → view.html
dispBoardDelete → delete_form.html
procBoardInsertDocument → write_form.html (오류 시)
액션 체크 패턴¶
<!-- write_form.html에서 신규/수정 구분 -->
<!--@if($act == 'dispBoardModify')-->
<h2>글 수정</h2>
<input type="hidden" name="document_srl" value="{$oDocument->document_srl}" />
<!--@else-->
<h2>글 쓰기</h2>
<!--@endif-->
반응형 구조¶
모바일 우선 접근법¶
/* 기본 (모바일) 스타일 */
.board-container {
padding: 10px;
font-size: 14px;
}
.board-list table {
width: 100%;
font-size: 13px;
}
/* 태블릿 */
@media (min-width: 768px) {
.board-container {
padding: 20px;
font-size: 15px;
}
.board-list table {
font-size: 14px;
}
}
/* 데스크탑 */
@media (min-width: 1024px) {
.board-container {
padding: 30px;
font-size: 16px;
}
.board-list table {
font-size: 15px;
}
}
모바일 감지¶
{@
// 모바일 여부 체크
$is_mobile = Mobile::isFromMobilePhone();
}
<!--@if($is_mobile)-->
<!-- 모바일 전용 레이아웃 -->
<div class="mobile-board">
<!-- 모바일 목록 -->
</div>
<!--@else-->
<!-- 데스크탑 레이아웃 -->
<table class="board-table">
<!-- 테이블 목록 -->
</table>
<!--@endif-->
스킨 상속¶
부모 스킨 확장¶
<!-- info.xml에서 부모 스킨 지정 -->
<skin version="0.2">
<title xml:lang="ko">확장 게시판 스킨</title>
<parent>default</parent> <!-- 부모 스킨 지정 -->
<!-- 추가 설정 -->
<extra_vars>
<var name="custom_option" type="text">
<title xml:lang="ko">커스텀 옵션</title>
</var>
</extra_vars>
</skin>
필요한 파일만 재정의하면 부모 스킨의 나머지 파일들을 상속받습니다.
다국어 지원¶
언어 파일 구조¶
lang/
├── ko.php <!-- 한국어 -->
├── en.php <!-- 영어 -->
└── jp.php <!-- 일본어 -->
ko.php 예제¶
<?php
$lang->board_list = '목록';
$lang->board_write = '글쓰기';
$lang->board_view = '상세보기';
$lang->board_modify = '수정';
$lang->board_delete = '삭제';
$lang->board_reply = '답글';
$lang->no_documents = '등록된 게시글이 없습니다.';
?>
템플릿에서 사용¶
<button type="button">{$lang->board_write}</button>
<p cond="!$document_list">{$lang->no_documents}</p>
캐싱 고려사항¶
스킨 캐시 무효화¶
// 스킨 파일 수정 후 캐시 삭제
{@
if(__DEBUG__) {
// 개발 중에는 캐시 사용 안 함
Context::set('_use_cache', false);
}
}
조건부 캐싱¶
<!-- 자주 변경되지 않는 부분만 캐싱 -->
<!--@cache('board_categories_' . $module_info->module_srl, 3600)-->
<div class="category-list">
<!-- 카테고리 목록 -->
</div>
<!--@endcache-->
디버깅 도구¶
스킨 변수 확인¶
<!--@if(__DEBUG__ && $logged_info->is_admin == 'Y')-->
<div class="debug-panel" style="background: #f0f0f0; padding: 10px; margin: 10px 0;">
<h4>디버그 정보</h4>
<details>
<summary>스킨 변수</summary>
<pre>{print_r($skin_vars, true)}</pre>
</details>
<details>
<summary>모듈 정보</summary>
<pre>{print_r($module_info, true)}</pre>
</details>
</div>
<!--@endif-->
개발 모드 표시¶
<!--@if(__DEBUG__)-->
<div class="dev-notice" style="background: #ff0; padding: 5px; text-align: center;">
개발 모드 - 이 메시지는 운영 환경에서는 표시되지 않습니다.
</div>
<!--@endif-->