회원가입 | 고객센터 |
DESIGNONEX
디자인원엑스
About
Service
Q&A
PR리그
자유게시판N
갤러리
포인트게임
공지사항N
통계
로그인 회원가입
고객센터
6. 게시판

게시판 구조

A Administrator
2026.05.01 01:30(수정됨) 81 0

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

로그인 후 댓글을 작성할 수 있습니다.
6. 게시판 스킨 DX마켓 등록 2026.05.01 6. 게시판 게시판 스킨 제작 2026.05.01 6. 게시판 댓글 및 답글 구조 2026.05.01 6. 게시판 게시판 구조 2026.05.01
30
전체 회원
269
전체 게시글
144
전체 댓글
181
오늘 방문
28,530
전체 방문
1
현재 접속
인기글 7일 이내
최신글
최신댓글
목록