회원가입 | 고객센터 |
DESIGNONEX
dxcms.kr
로그인 회원가입
고객센터
6. 게시판

게시판 구조

D DX
2026.05.01 01:30(수정됨) 118 1

1장. 게시판 시스템 개요

DXCMS의 게시판 시스템은 하나의 공통 핸들러(boards/handler.php)를 중심으로, 스킨•테마 폴백 체인을 통해 다양한 유형의 게시판을 단일 코드베이스로 운영합니다. 일반 게시판부터 갤러리•Q&A•쇼핑몰까지 모두 같은 URL 구조와 데이터 모델을 사용하며, 스킨으로 화면만 교체합니다.


1.1 핵심 설계 원칙

  • 단일 진입점 — 모든 게시판 요청은 boards/handler.php 하나로 집결
  • 스킨 폴백 체인 — 6단계 우선순위로 뷰 파일 자동 탐색 (없으면 기본 테마로 안전 폴백)
  • 막코딩 지원 — 스킨에서 Notice/Warning이 발생해도 CMS 전체는 정상 동작, 에러는 data/error.log에 기록
  • DB 독립 — PDO 기반, MySQL/MariaDB 완전 지원, PHP 5.6~8.x 호환
  • 멀티사이트 — site_domain 컬럼으로 도메인별 게시판 분리 가능
  • 크로스 플랫폼 — Windows IIS, Linux Apache/Nginx 모두 동일하게 동작


1.2 URL 구조

게시판 URL은 /{게시판키}/{액션}/{ID} 형태를 따릅니다.
/{board_key}/list              — 게시글 목록
/{board_key}/view/{id}         — 게시글 상세보기
/{board_key}/write             — 글쓰기
/{board_key}/edit/{id}         — 글 수정
/{board_key}/delete/{id}       — 글 삭제
/{board_key}/reply/{id}        — 답글 작성
/{board_key}/search            — 검색
/{board_key}/bulk              — 관리자 일괄 처리
/{board_key}/{custom_action}   — 스킨 커스텀 액션 (예: /shop/cart)


2장. 디렉토리 및 파일 구조


2.1 게시판 관련 디렉토리 전체 맵

boards/
  handler.php           ← 공통 핸들러 (진입점)
  skins/
    SKIN_GUIDE.md       ← 스킨 개발 가이드
    gallery/            ← 갤러리 스킨 (기본 제공)
    shop/               ← 쇼핑몰 스킨 (기본 제공)
    {커스텀스킨}/       ← 사용자 정의 스킨
  category/
    skins/default/      ← 기본 카테고리 탭 스킨

themes/default/board/
  list.php             ← 기본 목록 뷰
  view.php             ← 기본 상세 뷰
  write.php            ← 기본 글쓰기 뷰
  style.css            ← 게시판 기본 스타일

core/
  DxCategory.php       ← 카테고리 계층 관리 클래스
  DxBoardSkin.php      ← 스킨 파일 탐색 클래스
  DxThumb.php          ← 썸네일 자동 생성

data/uploads/boards/  ← 첨부파일 실제 저장 위치


2.2 스킨 내부 구조

하나의 스킨은 아래 파일/폴더로 구성됩니다. 필수는 skin.json 하나이며, 나머지는 선택 사항입니다.
boards/skins/{스킨이름}/
  skin.json          ← 스킨 메타 정보 (필수)
  list.php           ← 목록 뷰
  view.php           ← 상세 뷰
  write.php          ← 글쓰기/수정 폼
  parts/             ← 재사용 파셜 (row.php 등)
  actions/           ← 커스텀 액션
    {액션}.php       ← /게시판키/{액션} URL 자동 매핑
  assets/            ← CSS, JS, 이미지
    skin.css
    skin.js


2.3 skin.json 상세

스킨 메타 파일로, 관리자 스킨 목록에 표시되는 정보를 담습니다.
{
  "name": "갤러리",
  "description": "썸네일 그리드 갤러리.",
  "version": "5.5.0",
  "author": "DesignOneX",
  "actions": ["list", "view", "write"],
  "config": {
    "date_format": "Y-m-d",
    "per_page": "20"
  }
}
설명
name 스킨 표시 이름 (관리자 드롭다운에 노출)
description 스킨 설명
version 스킨 버전
author 스킨 제작자
actions 이 스킨이 처리할 액션 배열 (나머지는 기본 테마 폴백)
config 스킨 자체 설정 (dx_skin_config() 함수로 읽기)


3장. 스킨 폴백(탐색) 체인

핸들러는 요청된 액션(list, view, write 등)에 맞는 뷰 파일을 아래 6단계 순서로 탐색합니다. 앞 단계에서 파일을 찾으면 뒤 단계는 탐색하지 않습니다.
 
우선순위 경로 설명
1 boards/skins/{스킨}/{액션}/handler.php 완전 독립 핸들러 — DB쿼리부터 렌더까지 직접 처리
2 boards/skins/{스킨}/{액션}.php 스킨 독립 뷰
3 themes/{현재테마}/board/{스킨}/{액션}.php 테마 스킨 전용 뷰
4 themes/{현재테마}/board/{액션}.php 테마 공통 뷰
5 themes/default/board/{스킨}/{액션}.php 기본 테마 스킨 전용 뷰
6 themes/default/board/{액션}.php 최종 폴백 (항상 존재, 이것도 없으면 500 오류)

실전 팁
list.php 하나만 만들어도 됩니다. view, write는 themes/default/board/로 자동 폴백됩니다.
완전히 새로운 로직이 필요한 경우: boards/skins/{스킨}/list/handler.php 를 만들면
DB 쿼리부터 렌더링까지 모두 그 파일에서 처리합니다 — 공통 핸들러를 전혀 타지 않습니다.


3.1 커스텀 액션 (표준 외 URL)

boards/skins/{스킨}/actions/ 폴더에 PHP 파일을 넣으면 /{게시판키}/{파일명} URL이 자동 생성됩니다.
// boards/skins/shop/actions/cart.php
// URL: /shop-board/cart

$db    = $GLOBALS['dx_handler_context']['db'];
$auth  = $GLOBALS['dx_handler_context']['auth'];
$board = $GLOBALS['dx_handler_context']['board'];
// ... 원하는 로직 작성


4장. DB 스키마 상세

게시판 시스템과 관련된 핵심 테이블은 8개입니다. 모두 dx_ 접두사를 기본으로 사용하며, 설치 시 config.php에서 변경 가능합니다.


4.1 dx_boards — 게시판 설정

게시판 하나당 레코드 하나. 글쓰기 권한, 스킨, 기능 ON/OFF 등 모든 게시판 설정이 이 테이블에 저장됩니다.
 
컬럼명 타입 기본값 설명
id INT UNSIGNED AUTO_INCREMENT PK
board_key VARCHAR(100) - URL에 사용되는 고유 키 (영문+숫자+-_)
board_name VARCHAR(191) - 게시판 표시 이름
description TEXT NULL 게시판 설명
board_type ENUM normal normal / gallery / qa / faq / news
skin VARCHAR(100) default 사용할 스킨 이름 (boards/skins/ 폴더명)
group_id INT 0 게시판 그룹 ID (메뉴 묶음 용도)
read_level TINYINT 0 읽기 권한: 0=전체, 1=회원, 9=관리자
write_level TINYINT 1 쓰기 권한: 0=전체, 1=회원, 9=관리자
comment_level TINYINT 1 댓글 권한: 0=전체, 1=회원, 9=관리자
per_page TINYINT 20 목록 페이지당 글 수
use_comment TINYINT 1 댓글 사용: 1=사용, 0=미사용
use_file TINYINT 1 첨부파일 사용: 1=사용, 0=미사용
use_notice TINYINT 1 공지글 사용 여부
use_category TINYINT 0 카테고리 사용: 1=사용, 0=미사용
use_tag TINYINT 0 태그 사용 여부
use_anonymous TINYINT 0 비회원 글쓰기 허용 여부
use_survey TINYINT 0 설문 기능 사용 여부
file_count TINYINT 5 글당 최대 첨부파일 수
show_list_in_view TINYINT 0 뷰 페이지 하단에 목록 표시 여부
use_breadcrumb TINYINT 1 상단 브레드크럼 표시 여부
thumb_type VARCHAR(20) crop 썸네일 유형: fit|crop|width|height
thumb_w SMALLINT 300 썸네일 가로 픽셀
thumb_h SMALLINT 200 썸네일 세로 픽셀
thumb_crop VARCHAR(20) center 크롭 기준: center|top|left
cat_skin VARCHAR(50) default 카테고리 탭 스킨 이름
site_domain VARCHAR(191) (빈값) 멀티사이트 도메인 (빈값=전체 공통)
status TINYINT 1 1=활성, 0=비활성
sort_order SMALLINT 0 메뉴 정렬 순서 (낮을수록 위)


4.2 dx_posts — 게시글

모든 게시판의 글이 이 테이블에 저장됩니다. ID는 밀리초 타임스탬프 기반으로 자동 생성되어 순서와 시간이 동일합니다.
 
컬럼명 타입 기본값 설명
id BIGINT UNSIGNED 밀리초ID PK — 밀리초 타임스탬프로 자동 생성
board_id INT UNSIGNED - 소속 게시판 ID (dx_boards.id 참조)
parent_id BIGINT 0 답글 시 원글 ID (0=최상위 글)
member_id INT 0 작성 회원 ID (0=비회원)
author_name VARCHAR(100) NULL 비회원 작성자명
author_pass VARCHAR(255) NULL 비회원 비밀번호 (bcrypt 해시)
title VARCHAR(191) - 제목
content LONGTEXT - 본문 (HTML 허용, XSS 필터링 후 저장)
category VARCHAR(100) NULL 선택된 카테고리 이름
tags VARCHAR(191) NULL 쉼표 구분 태그 문자열
link VARCHAR(500) NULL 단일 링크 URL (레거시, 다중링크는 post_links)
thumbnail VARCHAR(191) NULL 썸네일 이미지 경로
view_count INT 0 조회수 (세션 기반 중복 방지)
like_count INT 0 좋아요 수
comment_count INT 0 댓글 수
is_notice TINYINT 0 공지글 여부 (1=공지)
is_secret TINYINT 0 비밀글 여부 (1=비밀글)
dl_level TINYINT 0 첨부파일 다운 권한: 0=전체, 1=회원, 2=관리자
dl_limit INT 0 1인당 최대 다운로드 수 (0=무제한)
dl_point INT 0 다운로드 시 차감 포인트
ip VARCHAR(45) NULL 작성자 IP (IPv6 포함)
status TINYINT 1 1=정상, 0=삭제됨
popular_score INT 0 인기점수 = 조회×1 + 좋아요×5 + 댓글×3 (7일 시간감쇠)
created_at DATETIME - 작성일시
updated_at DATETIME NULL 수정일시


4.3 dx_categories — 카테고리 (무한 계층)

게시판별 분류 체계를 저장합니다. parent_id=0이 최상위이며, depth와 path 컬럼으로 계층 깊이와 조상 경로를 추적합니다.
 
컬럼명 타입 기본값 설명
id INT UNSIGNED AUTO_INCREMENT PK
board_id INT 0 소속 게시판 ID (0=공통 분류)
parent_id INT 0 상위 카테고리 ID (0=최상위)
name VARCHAR(191) - 카테고리 이름
slug VARCHAR(100) (빈값) URL 슬러그 (미사용 시 name으로 필터)
depth TINYINT 0 계층 깊이 (0=최상위, 1=2단계, ...)
path VARCHAR(500) (빈값) 조상 ID 경로 (예: 0/5/12 — 빠른 트리 탐색용)
color VARCHAR(20) blue 카테고리 색상 키 (blue|green|red|orange|purple|slate)
show_in_list TINYINT 1 목록 페이지 탭에 표시 여부
show_in_view TINYINT 1 뷰 페이지 배지에 표시 여부
sort_order SMALLINT 0 같은 계층 내 정렬 순서
status TINYINT 1 1=활성, 0=비활성
created_at DATETIME - 생성일시


4.4 dx_comments — 댓글

게시글에 달리는 댓글과 대댓글을 저장합니다. parent_id=0이 최상위 댓글이며, depth로 대댓글 깊이를 표현합니다.
 
컬럼명 타입 기본값 설명
id BIGINT UNSIGNED 밀리초ID PK
post_id BIGINT - 소속 게시글 ID
parent_id BIGINT 0 상위 댓글 ID (0=최상위)
member_id INT 0 작성 회원 ID (0=비회원)
author_name VARCHAR(100) NULL 비회원 작성자명
content TEXT - 댓글 내용
depth TINYINT 0 댓글 깊이 (0=댓글, 1=대댓글)
status TINYINT 1 1=정상, 0=삭제
created_at DATETIME - 작성일시


4.5 dx_post_files — 첨부파일

게시글 첨부파일 정보를 저장합니다. 실제 파일은 data/uploads/boards/{게시판키}/ 에 저장됩니다.
 
컬럼명 타입 기본값 설명
id INT UNSIGNED AUTO_INCREMENT PK
post_id BIGINT - 소속 게시글 ID
orig_name VARCHAR(191) - 원본 파일명 (사용자 업로드 이름)
save_name VARCHAR(191) - 저장 파일명 (날짜_랜덤8자리.확장자)
save_path VARCHAR(191) - 저장 경로 (boards/{key}/{save_name})
file_size INT 0 파일 크기 (바이트)
file_ext VARCHAR(20) - 확장자 (소문자)
download_count INT 0 다운로드 횟수
is_thumb TINYINT 0 썸네일 파일 여부
thumb_path VARCHAR(191) NULL 썸네일 경로 (갤러리 스킨용)
created_at DATETIME - 업로드 일시


4.6 dx_post_links — 다중 링크

게시글 하나에 여러 링크를 첨부할 수 있습니다. 클릭 수는 dx_link_clicks 테이블에 IP+날짜 기준으로 중복 방지 후 집계됩니다.
 
컬럼명 타입 설명
post_id BIGINT 소속 게시글 ID
url VARCHAR(500) 링크 URL (http 없으면 https:// 자동 보정)
label VARCHAR(100) 링크 제목 (선택, 비워두면 URL 표시)
sort_order SMALLINT 정렬 순서
click_count INT 클릭 수 (편집 시 기존 URL과 동일하면 유지)


4.7 dx_global_notices — 전체 공지

모든 게시판 상단에 공통 표시되는 공지입니다. 게시 기간(start_at~end_at)을 설정하여 자동으로 노출/숨김 처리됩니다.
 
컬럼명 타입 설명
title VARCHAR(191) 공지 제목
title_color VARCHAR(20) 제목 색상 (hex, 비우면 기본색)
link_url VARCHAR(500) 클릭 시 이동 URL (선택)
link_target VARCHAR(10) _self 또는 _blank
start_at DATETIME 게시 시작일 (NULL=즉시)
end_at DATETIME 게시 종료일 (NULL=무기한)
sort_order SMALLINT 정렬 순서 (낮을수록 위)
status TINYINT 1=활성, 0=비활성

5장. 카테고리 시스템 (DxCategory)

카테고리는 무한 계층(parent_id 트리) 구조로, DxCategory 클래스가 DB 조회•트리 빌드•평면 변환을 담당합니다.


5.1 DxCategory 주요 메서드

메서드 설명
getByBoard($boardId, $showIn) 게시판의 카테고리 행 배열 반환. showIn=list|view|"" (전체)
buildTree($rows, $parentId) 평면 배열 → 계층 트리 변환 (재귀). sort_order → id 순
flattenTree($tree, $depth) 트리 → 평면 select 옵션용 배열. label에 들여쓰기 기호 포함
getFlatByBoard($boardId, $showIn) getByBoard + buildTree + flattenTree 한번에 처리
getDescendantNames($boardId, $catName) 선택한 카테고리 + 모든 하위 카테고리 이름 배열 반환 (목록 필터용)
renderList($board, $currentCat, $theme) 목록 페이지 카테고리 탭 자동 렌더링 (2단 구조)
renderView($board, $catName, $theme) 뷰 페이지 카테고리 배지 렌더링


5.2 계층 구조 예시

depth 0이 최상위, depth 1이 그 하위입니다. parent_id가 상위 id를 참조합니다.
 
분류 (depth=0, parent_id=0)
  └ 서브분류1 (depth=1, parent_id=분류.id)
       └ 서브서브분류 (depth=2, parent_id=서브분류1.id)
  └ 서브분류2 (depth=1, parent_id=분류.id)

💡 상위 분류 클릭 시 동작
상위 분류(depth=0)를 클릭하면 해당 분류의 모든 하위 분류 글까지 함께 표시됩니다.
getDescendantNames()가 선택 카테고리와 모든 자손의 이름을 수집하여 WHERE IN (?) 쿼리를 생성합니다.


5.3 카테고리 탭 렌더링 (2단 구조)

renderList()는 아래 2단 탭 구조를 자동 렌더링합니다:
  • 1단 탭 — 전체 + 최상위 분류들 (depth=0)
  • 2단 탭 — 선택된 최상위 분류의 하위 분류들 (depth=1+)
  • 하위 분류가 없는 최상위 분류는 1단만 표시
  • 스킨 파일 없으면 _renderListDefault() 내장 탭 사용 (Tailwind CSS)


6장. 목록(list) 기능 완전 분석

게시판 목록은 단순한 리스트 출력 외에도 검색•필터•정렬•일괄처리•캐시•SEO까지 담당합니다.


6.1 목록 데이터 처리 흐름

  1. 캐시 확인 — 비로그인+검색없음+기본페이지 조건이면 DxCache에서 60초 캐시 데이터 반환
  2. 파라미터 수집 — page, s(검색어), sf(검색필드), cat(카테고리), tag(태그)
  3. 쿼리 조립 — board_id + status=1 + is_notice=0 조건에 검색/카테고리/태그 필터 추가
  4. 공지글 쿼리 — use_notice=1인 게시판은 is_notice=1 글 최대 5개 별도 조회
  5. 전체 공지 쿼리 — dx_global_notices에서 게시 기간이 현재인 공지 조회
  6. 카테고리 조회 — use_category=1이면 DxCategory::getFlatByBoard()로 탭 데이터 조회
  7. 캐시 저장 — 읽기 전용 조건이면 60초 캐시 저장
  8. SEO 빌드 — DxSeo::build('board_list') 호출
  9. 렌더링 — _brd_render('list', $ctx) 호출 → 스킨 폴백 체인


6.2 검색 파라미터

파라미터 설명
?s=검색어 검색어 (2자 이상이면 popular_keywords 테이블에 자동 기록)
?sf=both 검색 필드: both(제목+내용), title, content, author, category
?sf=like 정렬: 좋아요 많은 순 (like_count DESC)
?sf=popular 정렬: 인기점수 순 (popular_score DESC)
?cat=분류명 카테고리 필터 (하위 분류 포함 자동 필터)
?tag=태그명 태그 필터 (LIKE %태그%)
?page=N 페이지 번호 (1부터 시작)


6.3 관리자 일괄 처리 (Bulk)

관리자 로그인 시 목록에 체크박스가 표시되며, 아래 일괄 작업이 가능합니다.
  • 일괄 삭제 — 선택한 글 + 댓글 + 첨부파일 + 좋아요 + 스크랩 완전 삭제
  • 일괄 이동 — 선택한 글을 다른 게시판으로 이동 (board_id 변경)
  • 일괄 복사 — 선택한 글을 다른 게시판으로 복사 (첨부파일 링크도 복사)

⚠️ IIS 주의사항
IIS 환경에서는 /board/bulk URL 라우팅이 불가한 경우가 있습니다.
이를 위해 bulk 처리는 /board/list 로 POST 요청하여 bulk_act 파라미터로 구분합니다.


7장. 상세보기(view) 기능 완전 분석


7.1 view 컨텍스트 변수 전체 목록

$ctx 배열로 스킨 파일에 전달되는 변수입니다.
 
변수 설명
$board 게시판 설정 배열 (dx_boards 레코드)
$post 게시글 데이터 + 작성자 이름(member_name), 프로필(member_profile_img) 포함
$files 첨부파일 배열 (dx_post_files, id 오름차순)
$comments 댓글 배열 (dx_comments + 작성자 정보, id 오름차순)
$postLinks 다중 링크 배열 (dx_post_links, sort_order 오름차순)
$prevPost 이전 글 (id, title, created_at)
$nextPost 다음 글 (id, title, created_at)
$viewList 뷰 하단 목록 배열 (show_list_in_view=1일 때만)
$survey 설문 데이터 (use_survey=1이고 설문이 있을 때)
$surveyQuestions 설문 문항 배열
$surveyVoted 현재 사용자의 설문 참여 여부 (bool)
$surveyResults 설문 결과 집계 배열 (공개 조건 충족 시)
$surveyEnded 설문 마감 여부 (bool)
$categories 카테고리 배열 (사이드바·모바일 탭용)


7.2 조회수 중복 방지

세션 기반으로 같은 사용자의 중복 조회를 방지합니다.
  • 같은 세션에서 이미 본 글이면 조회수 증가 없음 (세션 키: viewed_post_{id})
  • 세션이 없는 환경(비로그인 GET 최적화)에서도 안전하게 처리
  • 조회 시 popular_score 자동 갱신: 조회×1 + 좋아요×5 + 댓글×3 × 시간감쇠
  • 시간감쇠: 7일마다 10%씩 감소 (최소 10% 유지)


7.3 비밀글 보호

is_secret=1인 글은 아래 조건을 만족해야 내용을 볼 수 있습니다:
  • 관리자 — 항상 열람 가능
  • 작성자 본인 — member_id가 일치하는 로그인 회원
  • 그 외 — 403 오류 반환


8장. 글쓰기 및 수정(write/edit)


8.1 권한 체계

write_level 컬럼 값에 따라 접근이 제어됩니다:
  • 0 — 비회원 포함 누구나 작성 가능
  • 1 — 로그인 회원만 (미로그인 시 로그인 페이지로 리다이렉트)
  • 9 — 관리자만 작성 가능

8.2 저장 데이터 처리

POST 요청 수신 시 아래 순서로 처리합니다:
  1. 비회원 글쓰기 캡챠 검증 (use_captcha=1이고 비로그인 상태일 때)
  2. 입력값 XSS 필터링 — DxSanitizer::text() / editorContent() 사용
  3. dl_ 컬럼 존재 여부 체크 (migrate 미실행 환경 대응, 없으면 자동 제외)
  4. 신규: insertWithMicrotimeId() 로 밀리초 타임스탬프 ID 생성
  5. 수정: title/content/category/tags/is_notice/is_secret/updated_at 만 UPDATE
  6. 첨부파일 업로드 처리 (dx_board_upload_files())
  7. 삭제할 파일 처리 (delete_files[] 체크박스)
  8. 다중 링크 저장 (dx_board_save_links())
  9. 설문 저장 (dx_board_save_survey(), use_survey=1일 때만)
  10. 갤러리 타입이면 DxThumb::autoFromPost() 썸네일 자동 생성
  11. 게시판 목록 캐시 무효화 (DxCache::deletePrefix)
  12. 실시간 알림 세션 저장 (dx_post_live_broadcast)


8.3 첨부파일 보안

파일 업로드 시 아래 보안 정책이 적용됩니다:
  • 블랙리스트 방식 — php, asp, jsp, sh 등 서버 실행 확장자만 차단, 나머지는 허용
  • 이중 확장자 차단 — image.php.jpg 처럼 중간에 위험 확장자가 있으면 차단
  • .htaccess 자동 생성 — 업로드 폴더에 PHP 실행 차단 htaccess 자동 생성 (Apache)
  • web.config 자동 생성 — IIS 환경용 PHP 실행 차단 web.config 자동 생성
  • 파일명 랜덤화 — 날짜_랜덤8자리.확장자 형식으로 저장 (원본명은 DB에 보존)
  • 크기 제한 — upload_max_size 설정 + php.ini upload_max_filesize 중 더 작은 값 적용


9장. 설문 기능 (use_survey)

게시판 설정에서 use_survey=1 로 활성화하면, 글쓰기 폼에 설문 섹션이 추가됩니다. 하나의 게시글에 설문 하나를 첨부할 수 있습니다.


9.1 설문 관련 테이블

  • dx_surveys — 설문 메타 (제목, 마감일, 비회원 허용, 결과 공개 조건)
  • dx_survey_questions — 문항 (단일선택/복수선택/단답형, 선택지 JSON, 필수 여부)
  • dx_survey_answers — 응답 데이터 (회원ID 또는 IP 기반)
  • dx_survey_votes — 참여 로그 (중복 참여 방지, 회원=UNIQUE, 비회원=IP 기반)


9.2 결과 공개 조건

show_result 공개 조건
always 항상 공개 (참여 여부 무관)
after_vote 참여 후 공개 (기본값)
after_end 마감일 이후에만 공개
관리자 조건 무관 항상 열람 가능


10장. 인기점수(popular_score) 시스템

조회, 좋아요, 댓글 수를 가중 합산하고, 시간이 지날수록 점수를 낮추는 감쇠 공식을 적용합니다.


10.1 점수 계산 공식

기본 점수 = 조회수 × 1 + 좋아요 × 5 + 댓글수 × 3

시간 감쇠 = max(0.1,  1.0 - floor(경과일수 / 7) × 0.1)
  → 7일마다 10% 감소, 최소 10% 유지

최종 popular_score = round(기본점수 × 시간감쇠)


10.2 인기순 정렬 사용

목록 URL에 sf=popular 파라미터를 추가하면 인기점수 내림차순으로 정렬됩니다.
예시: /{board_key}/list?sf=popular


11장. 스킨 개발 가이드


11.1 스킨에서 사용 가능한 헬퍼 함수

함수 설명
dx_skin_asset('skin.css') 스킨 assets/ 폴더의 파일 URL 반환
dx_skin_config('key', '기본값') skin.json의 config 값 읽기
dx_skin_part('row', ['post'=>$post]) 스킨 parts/ 폴더 파셜 include
$GLOBALS['dx_board_skin'] 현재 스킨 이름 읽기
dx_base_url($path) 사이트 기준 절대 URL 생성
dx_method('POST') HTTP 메서드 확인
dx_get('key', '기본값') GET 파라미터 안전 읽기
dx_post('key', '기본값') POST 파라미터 안전 읽기
dx_csrf_field() CSRF 토큰 hidden 필드 HTML 반환


11.2 list.php 기본 템플릿

아래는 최소한의 list.php 스킨 예시입니다. $board, $posts, $total, $page, $perPage 등이 자동으로 주입됩니다.
<?php if (!defined('DX_CMS')) exit; ?>

<h1><?php echo htmlspecialchars($board['board_name'], ENT_QUOTES); ?></h1>

<?php foreach ($posts as $p): ?>
  <div>
    <a href="<?php echo dx_base_url($board['board_key']'/view/'.$p['id']); ?>">
      <?php echo htmlspecialchars($p['title'], ENT_QUOTES); ?>
    </a>
    <span><?php echo $p['created_at']; ?></span>
  </div>
<?php endforeach; ?>


11.3 제공 스킨 목록

스킨명 타입 특징
default 기본 게시판 테이블 형 목록, 검색, 공지, 카테고리 탭, 관리자 bulk 지원
gallery 갤러리 썸네일 그리드, 라이트박스, 좋아요, 실시간 소켓 지원
shop 쇼핑몰 상품 목록, 장바구니(/cart), 주문/결제 커스텀 액션 포함


12장. 관리자 사용방법


12.1 게시판 생성

  1. 관리자 → 게시판 관리 → 게시판 추가 버튼 클릭
  2. 게시판 키 입력 — URL에 사용될 영문자/숫자/하이픈/언더스코어 (예: notice, free-board)
  3. 게시판 이름 입력 — 화면에 표시될 이름
  4. 게시판 유형 선택 — normal / gallery / qa / faq / news
  5. 스킨 선택 — boards/skins/ 폴더에 있는 스킨이 자동으로 드롭다운에 표시됨
  6. 권한 설정 — 읽기/쓰기/댓글 각각 0=전체/1=회원/9=관리자
  7. 기능 설정 — 댓글•파일•공지•카테고리•태그•설문 ON/OFF
  8. 저장


12.2 카테고리 관리

  1. 관리자 → 게시판 관리 → 해당 게시판 → 카테고리 탭 클릭
  2. 카테고리 추가 — 이름, 상위 카테고리, 색상, 목록/뷰 표시 여부 설정
  3. 순서 변경 — sort_order 숫자 수정 (낮을수록 먼저)
  4. 계층 설정 — 상위 카테고리를 선택하면 depth 자동 계산
  5. 비활성화 — status=0으로 변경하면 프런트에서 숨겨짐


12.3 전체 공지 관리

  1. 관리자 → 전체 공지 → 공지 추가
  2. 제목, 색상, 링크 URL, 링크 타겟(_self/_blank) 입력
  3. 게시 기간 설정 — 시작일과 종료일 (비워두면 즉시~무기한)
  4. 정렬 순서 설정 — sort_order 낮을수록 위에 표시
  5. 저장 — 모든 게시판 목록 상단에 자동 표시됨


12.4 게시글 관리 (목록에서)

목록 페이지에서 관리자는 아래 작업을 수행할 수 있습니다:
  • 체크박스 선택 — 글 앞의 체크박스를 클릭하여 일괄 처리 대상 선택
  • 일괄 삭제 — 선택한 글을 댓글•파일•좋아요•스크랩까지 완전 삭제
  • 일괄 이동 — 선택한 글을 다른 게시판으로 이동 (게시판 선택 화면으로 이동)
  • 일괄 복사 — 선택한 글을 다른 게시판으로 복사


12.5 설문 게시글 작성

  1. use_survey=1인 게시판에서 글쓰기 클릭
  2. 제목•본문 작성
  3. 설문 추가 체크박스 체크
  4. 설문 제목, 마감일, 비회원 참여 허용, 결과 공개 조건 설정
  5. 문항 추가 — 단일선택(radio)/복수선택(checkbox)/단답형(text)
  6. 선택형 문항은 선택지를 줄바꿈으로 구분하여 입력
  7. 저장 — 글 저장과 동시에 설문도 저장됨
  8. 수정 시 설문 체크박스를 해제하면 해당 설문이 비활성화됨


13장. 훅(Hook) 연동 포인트

플러그인이나 테마에서 게시판 동작을 커스터마이징할 때 사용하는 훅입니다.
 
훅 이름 발생 시점 및 전달 인자
dx_board_before 핸들러 최초 진입 시 (board, action, skin, id 전달)
dx_board_list_context 목록 $ctx 배열 확정 직전 (context 참조 전달 — 변경 가능)
dx_board_view_context 상세보기 $ctx 배열 확정 직전
dx_board_write_context 글쓰기 폼 $ctx 배열 확정 직전
dx_board_before_save 글 저장 직전 — $data 참조 전달로 추가 필드 처리 가능
dx_after_write 글 저장 완료 후 (post_id, board, data 전달)
dx_board_after_save 글 저장 후 — redirect URL 변경 가능
dx_board_before_delete 글 삭제 직전 (post, board 전달)
dx_board_after_delete 글 삭제 완료 후 (post_id, board 전달)
dx_board_after 핸들러 처리 완료 후
 
💡 훅 사용 예시
// 글 저장 전 커스텀 필드 추가
dx_add_hook('dx_board_before_save', function($args) {
    $args['data']['custom_field'] = '값';
});


14장. 캐시 및 성능 최적화


14.1 게시판 목록 캐시

아래 조건을 모두 만족할 때 목록 데이터를 60초 캐시합니다:
  • 비로그인 상태
  • 검색어 없음 (?s= 파라미터 없음)
  • 카테고리/태그 필터 없음
  • action이 list (search 액션은 캐시 안함)

캐시 무효화는 글 작성/수정/삭제 시 자동으로 처리됩니다:
DxCache::deletePrefix('board_list_' . $boardKey . '_');
카테고리 변경 시에는 아래 캐시도 함께 삭제해야 합니다:
DxCache::deletePrefix('cat_board_');  // 카테고리 목록 캐시


14.2 DB 인덱스

게시글 목록 쿼리 성능을 위한 복합 인덱스가 포함되어 있습니다:
-- 게시판 목록 (WHERE board_id=? AND status=1 ORDER BY id DESC)
KEY idx_board_status_id (board_id, status, id)

-- 인기글 정렬 (ORDER BY popular_score DESC)
KEY idx_board_status_score (board_id, status, popular_score)


15장. 오류 처리 및 디버깅


15.1 에러 로그

CMS 관련 오류는 data/error.log 에 자동 기록됩니다. 서버 콘솔에는 출력되지 않습니다.
로그 형식: [날짜시간][레벨][파일:라인] 내용
[2026-05-10 14:23:01][ERROR][boards/handler.php:45] ...


15.2 DX_DEBUG 모드

config.php에서 DX_DEBUG를 true로 설정하면 스킨에서 발생한 Notice/Warning 목록이 화면 하단에 표시됩니다. 프로덕션 환경에서는 반드시 false로 유지하세요.
// config.php
define('DX_DEBUG', true);  // 개발 시에만 사용


15.3 스킨 파일 없음 오류

6단계 폴백 체인을 모두 탐색했음에도 뷰 파일이 없으면 500 오류 박스를 표시하며, 탐색한 경로 목록을 보여줍니다. 이 오류가 발생하면:
  1. boards/skins/{스킨}/ 폴더에 list.php, view.php, write.php가 있는지 확인
  2. skin.json의 actions 배열에 해당 액션이 포함되어 있는지 확인
  3. themes/default/board/ 에 기본 파일이 존재하는지 확인

댓글0

로그인 후 댓글을 작성할 수 있습니다.
3.8 Extend 구조 코어 수정 없이 CMS를 확장하는 방법 2026.05.02 8. 플러그인 플러그인 DX마켓 등록 2026.05.01 8. 플러그인 플러그인 제작 2026.05.01 8. 플러그인 플러그인 구조 2026.05.01 7. 테마 테마 DX마켓 등록 2026.05.01 7. 테마 테마 제작 2026.05.01 7. 테마 테마 구조 2026.05.01 6. 게시판 스킨 DX마켓 등록 2026.05.01 6. 게시판 게시판 스킨 제작 2026.05.01 6. 게시판 댓글 및 답글 구조 2026.05.01 6. 게시판 게시판 구조 2026.05.01 5. 관리자 기능 사용법 DX 마켓 2026.04.21 5. 관리자 기능 사용법 사이트 설정 2026.04.21 5. 관리자 기능 사용법 소셜 로그인 2026.04.21 5. 관리자 기능 사용법 멀티사이트 2026.04.21 5. 관리자 기능 사용법 테마 2026.04.21 5. 관리자 기능 사용법 플러그인 2026.04.21 5. 관리자 기능 사용법 실시간 소켓 2026.04.21 5. 관리자 기능 사용법 다운로드 통계 2026.04.21 5. 관리자 기능 사용법 통계 2026.04.21
31
전체 회원
502
전체 게시글
767
전체 댓글
441
오늘 방문
33,173
전체 방문
2
현재 접속
인기글 7일 이내
최신글
최신댓글
목록