CMS 어댑터와 데이터 저장 위치 (v10)
이 문서는 2026-09-28에 새로 썼습니다.
10.5.0이 T2Editor v10에서 가장 큰 구조 변경을 만들었습니다. 그런데 이 위키 84건 어디에도integration/cms나t2editor_db라는 문자열이 한 번도 등장하지 않습니다. "내 데이터가 어디에 쌓이는가"를 모르고 서버를 옮기면 글이 사라집니다.
1. 10.5.0이 무엇을 바꿨나 — 릴리즈 노트 원문
S1 10.5.0 릴리즈 노트에서 그대로:
CMS 연결 구조 독립화- 그누보드5와 라이믹스 관련 처리를 에디터 코어와 각 플러그인에 흩어 놓지 않고, CMS별 연결 계층으로 분리했습니다.- CMS 감지, 관리자 인증, 데이터 경로, 업로드 방식과 응답 처리를 각 CMS 어댑터가 담당합니다. 기존 10.4.0의 공개 함수와 라이믹스 스킨 연결 구조는 계속 사용할 수 있도록 호환성을 유지했습니다.- 특정 CMS 연결에서 오류가 발생하더라도 다른 CMS 처리나 에디터 전체 초기화까지 중단되지 않도록 오류 범위를 분리했습니다.CMS별 데이터 경로 정리- 그누보드5에서는 data/editor, 라이믹스에서는 files, 독립 실행 환경에서는 T2Editor/data를 기준으로 데이터를 관리합니다.- 업로드 미디어를 제외한 관리자 설정, 캐시, 협업 상태, 업데이트 상태 등의 내부 데이터는 t2editor_db 아래에 모아 CMS 데이터 폴더가 불필요하게 복잡해지지 않도록 했습니다.- 기존 위치에 저장된 데이터와 경로 정보는 가능한 범위에서 새 구조로 이전하거나 계속 인식합니다.그리고 10.5.1:
그누보드5 내부 데이터 저장 위치 정리* 이미지와 첨부파일은 기존처럼 data/editor 폴더에 저장됩니다.* 관리자 설정, 인증 정보, 협업 데이터, 업데이트 기록, 서드파티 설치 정보는 data/t2editor_db 폴더에 별도로 저장됩니다.* 기존 data/editor/t2editor_db 데이터는 새 위치로 자동 이전됩니다.⇒ 읽는 사람이 알아야 할 핵심은 한 문장입니다: "이미지·첨부파일은 예전 위치에 그대로 두고, 나머지 내부 데이터만 새 폴더로 뺐다. 예전 데이터를 자동으로 옮겨 준다."
2. 어댑터가 무엇을 하는가
CMS 관련 코드는 integration/cms/ 아래에 있습니다. v10.5.1에서 파일은 11개입니다.
integration/cms/
├── registry.php 11,221 B 어댑터 등록·조회·호출 (코어가 CMS 이름을 분기하지 않음)
├── bootstrap.php 856 B adapters/*.php 를 전수 로드 (알파벳순 정렬)
├── adapters/
│ ├── gnuboard5.php 7,039 B priority 300
│ ├── rhymix.php 10,600 B priority 250
│ ├── wordpress.php 5,696 B priority 200 ← 단, 아래 §2-3 참조
│ └── standalone.php 887 B priority -1000 (마지막 fallback)
├── legacy-php-api.php 2,657 B 10.4.0 공개 함수 호환
├── legacy-auth-api.php 1,312 B 인증 호환
├── legacy-browser-api.js (브라우저 쪽 호환)
└── rhymix/iframe_autoregister.php (라이믹스 동영상 iframe 자동 등록)
어댑터는 "각각의 capability"만 등록합니다. 코어가 CMS 이름을 분기하지 않는다는 것이 설계 원칙입니다 — integration/cms/registry.php:3 원문: Developer note: 코어는 CMS 이름을 분기하지 않는다. 새 CMS는 어댑터 capability만 등록한다.
| capability | 하는 일 | 물어보는 어댑터 |
|---|---|---|
matches_root / validate_context | 이 CMS가 맞는지 판단 | 전원 |
data_layout | 데이터 경로 결정 | 전원 (워드프레스는 없음) |
auth_bootstrap / auth_authorize | 관리자 인증 | 그누보드5·라이믹스 |
handles_upload + upload | 업로드를 CMS에 넘길지 | 라이믹스·워드프레스 |
editor_html | CMS가 에디터에 주입하는 스크립트 | 전원 |
bootstrap_compat | CMS 상수 자동 정의 | 그누보드5 |
root_url | CMS 루트 URL | 전원 |
오류 격리: integration/cms/registry.php:111-119 — 어댑터 호출이 예외를 던지면 error_log 에만 남기고 기본값을 돌려줍니다. 한 CMS 어댑터가 죽어도 에디터 전체가 죽지 않습니다. S1 10.5.0의 "오류 범위를 분리했습니다"의 실체입니다.
2-1 · 그누보드5 어댑터 (adapters/gnuboard5.php:96-135)
CMS를 인식하는 조건을 코드가 직접 말합니다 (:5-14):
- 에디터 폴더가
<그누보드 루트>/plugin/editor밖이면 안 됨 (:10) <루트>/config.php,<루트>/common.php,<루트>/lib/common.lib.php3개가 모두 있어야 함 (:11)config.php안에define('_GNUBOARD_', …)가 있어야 함 (:12)
관리자 판정 (:40-48): $is_admin === 'super' 이거나 mb_id 가 cf_admin 과 hash_equals 로 일치하면 관리자입니다.
왜 common.php 를 함수 안에서 require 하면 안 되는지 — 어댑터 주석에 20줄로 적혀 있습니다 (:16-38). 그누보드5의 is_admin() / get_member() 가 global $x; 로 값을 읽는데, PHP의 global 은 진짜 전역 심볼 테이블만 봅니다. 함수 안에서 require 하면 그 값이 그 함수의 지역 스코프에 갇히므로 최고관리자도 항상 "로그인 필요"로 오판됩니다. 그래서 t2editor_g5_common_path() 는 경로만 돌려주고, 실제 require_once 은 최상위 문장으로 실행해야 합니다. 이건 그누보드5를 다루는 사람이 알아야 할 함정입니다.
2-2 · 라이믹스 어댑터 (adapters/rhymix.php)
- CMS 상수:
RX_BASEDIR(S2 guide.txt §4.1 "폴더 이름은t2editor여야 한다"가 여기서 걸립니다) - 업로드를 CMS에 위임합니다:
handles_upload이true를 반환하고upload가t2editor_rx_upload을 호출합니다. ⇒ S2 guide.txt §4.3 원문대로 "업로드는 편집기가 직접 파일을 놓지 않고 라이믹스의 업로드 창구로 넘긴다." - 스킨 계약 준수:
skin.xml과config.blade.php가 배포판 루트에 있습니다. 10.5.0은 "기존 10.4.0의 공개 함수와 라이믹스 스킨 연결 구조는 계속 사용할 수 있도록 호환성을 유지했습니다"를 명시했습니다. - 동영상 iframe 자동 등록:
integration/cms/rhymix/iframe_autoregister.php가Rhymix\Framework\Filters\MediaFilter로 T2 비디오 플레이어를 등록합니다. S1 10.5.1: "별도 애드온 설정 없이 T2Editor 동영상 iframe이 작동하도록 하는 기존 목적은 유지됩니다." 즉 v10은 애드온이 필요 없습니다. (S2 guide.txt §7.3은 v11에서 애드온을 켜라고 안내하므로, v10 사용자에게 그 안내를 하지 마십시오.)
2-3 · ⭐ 워드프레스 어댑터는 "브리지"입니다
php// integration/cms/adapters/wordpress.php t2editor_cms_register_adapter('wordpress', array( 'label' => 'WordPress bridge', 'priority' => 200, 'validate_context' => function () { return false; }, // ← 항상 false 'editor_html' => 't2editor_wp_editor_html_adapter', 'handles_upload' => function ($fileField, $kind) { return t2editor_wp_bridge_requested() && t2editor_wp_available_adapter(); }, 'upload' => 't2editor_wp_upload_adapter', ));
validate_context 가 항상 false 를 반환합니다. ⇒ 워드프레스용 어댑터는 자동 감지 대상이 아닙니다. "워드프레스에 설치하면 데이터 경로·관리자 인증이 워드프레스 방식으로 바뀐다"는 기대는 실현되지 않습니다.
| 받는 것 | 못 받는 것 |
|---|---|
| 워드프레스 미디어 라이브러리 업로드 | CMS 관리자 연동 |
워드프레스 nonce · upload_files 권한 확인 | CMS별 데이터 경로 분리 |
워드프레스용 코드가 data_layout 을 등록하지 않았으므로, 데이터 경로는 config/t2_cms_data.php:27-29 의 기본값(스탠데얼론 규칙) 으로 떨어집니다.
2-4 · 스탠드얼론 어댑터 (adapters/standalone.php)
php'priority' => -1000, // 마지막 'validate_context' => function ($context, $editorPath) { return true; }, // 항상 true
항상 최종 fallback 입니다. 주석에도 "독립 환경은 항상 최종 fallback이며 CMS 전용 상수나 런타임을 로드하지 않는다"고 적혀 있습니다. ⇒ 어떤 CMS로도 감지되지 않으면 스탠데얼론으로 처리됩니다. 잘못된 설치라도 조용히 스탠데얼론이 되므로, 의도한 CMS로 잡혔는지 확인하고 싶으면 t2editor_detect_cms() 결과를 보십시오.
3. ⭐ 배치별 표 — 이것만 보시면 됩니다
3-1 · 폴더 위치와 데이터 경로
| 그누보드5 | 라이믹스 | 스탠드얼론 | 워드프레스 | |
|---|---|---|---|---|
| 에디터 설치 위치 | g5/plugin/editor/t2editor/ | rhymix/modules/editor/skins/t2editor/ | 웹에서 보이는 아무 폴더 | CMS가 주는 위치(어댑터 미사용) |
| CMS 감지 | ✅ matches_root 3조건 | ✅ RX_BASEDIR | ⚠️ fallback(항상) | ❌ validate_context=false |
| 업로드 미디어(데이터) | <그누보드 데이터>/editor | <라이믹스 루트>/files | <에디터 폴더>/data | 스탠데얼론 규칙으로 fallback |
| 내부 데이터(t2editor_db) | <그누보드 데이터>/t2editor_db | <files>/t2editor_db (fallback) | <에디터 폴더>/data/t2editor_db | 스탠드얼론 규칙으로 fallback |
| 권한 | G5_DIR_PERMISSION / G5_FILE_PERMISSION (없으면 0755/0644) | 0755 / 0644 | 0755 / 0644 | 스탠데얼론 규칙 |
| 업로드를 CMS에 위임 | ❌ (에디터가 직접) | ✅ | ❌ | ✅ (브리지, CMS 연결 시) |
| 관리자 인증 | CMS 로그인 또는 자체 비밀번호 | CMS 로그인 또는 자체 비밀번호 | 자체 비밀번호 필수 | 자체 비밀번호 |
코드 근거 (S3 실측, file:line):
| 사실 | 근거 |
|---|---|
그누보드5 업로드는 <데이터>/editor, db는 <데이터>/t2editor_db | integration/cms/adapters/gnuboard5.php:118-130 — 주석에도 "Uploaded media keeps its historical URL under <공용 데이터>/editor" |
라이믹스는 <루트>/files 만 반환 | integration/cms/adapters/rhymix.php 의 data_layout — db_path 를 주지 않음 |
db_path 가 없으면 <data_path>/t2editor_db 로 채워짐 | config/t2_cms_data.php:36-39 |
스탠데얼론은 <에디터>/data, db_path 미지정 → fallback | integration/cms/adapters/standalone.php |
그누보드5는 어댑터가 db_path 를 준다 | integration/cms/adapters/gnuboard5.php:126-127 (media=:120-121, db=:126-127, 권한=:128-129) |
| 어댑터가 layout을 안 주면 스탠드얼론 기본값 | config/t2_cms_data.php:27-29 |
| 폴더 권한 기본 0755 / 0644 | config/t2_cms_data.php:50-51 |
⚠ 가장 많이 오해하는 지점 하나: 라이믹스에서t2editor_db는 어댑터가 지정한 위치가 아니라 fallback 규칙으로 정해집니다. 라이믹스 어댑터는db_path를 주지 않기 때문에<라이믹스 루트>/files/t2editor_db가 됩니다. 그누보드5만 어댑터가db_path를 명시적으로 줍니다.
3-2 · 내부 폴더에는 직접 들어가지 마십시오
data/t2editor_db/ 아래에 보호 파일이 있습니다 (v10.5.1 트리 실측 6개):
data/t2editor_db/.htaccess
data/t2editor_db/index.html
data/t2editor_db/collab/.htaccess
data/t2editor_db/collab/index.php
data/t2editor_db/t2admin-private/.htaccess
data/t2editor_db/t2admin-private/index.php
S1 10.5.1 원문: 내부 데이터 폴더 접근 보호 강화 — 관리자 인증 정보와 협업 데이터가 저장되는 내부 폴더에 직접 접근 방지 파일을 추가했습니다. 브라우저에서 해당 폴더 주소를 직접 입력해도 내부 파일 목록이 노출되지 않도록 보완했습니다.
⚠ .htaccess 는 Apache 전용입니다. nginx 는 이 파일을 읽지 않습니다. nginx · LiteSpeed · Caddy 환경이라면 웹서버 설정에서 해당 경로를 별도로 차단해야 합니다. v10.5.1 배포판은 그 설정을 제공하지 않습니다.3-3 · 백업할 때 같이 챙길 것
| 배치 | 백업 대상 |
|---|---|
| 스탠드얼론 | data/ 전체(업로드 + t2editor_db + t2admin-private + collab) + 배포판 readme.txt |
| 그누보드5 | <그누보드 데이터>/editor (업로드) + <그누보드 데이터>/t2editor_db (설정·인증·협업) + 배포판 readme.txt |
| 라이믹스 | <루트>/files 전체 + 배포판 readme.txt |
readme.txt를 백업에 반드시 포함하십시오. 라이선스가 그 파일 안에 있으므로, 빠뜨리면 재배포 위반입니다(readme.txt:59,:118).
4. ⭐ v9에서 v10으로 오면서 무엇이 이동했나
4-1 · 이동이 자동으로 일어난다
php// config/t2_storage.php:237-282 t2editor_storage_has_legacy_state() // 잘 알려진 이전 위치들을 전수 확인한다: $basePath . '/data' // 구버전 스탠드얼론 규칙 (10.4.0까지 CMS도 이쪽) $basePath . '/collab' // 구 <에디터>/collab $dataPath . '/t2editor_db' // ← 그누보드5의 옛 중첩 위치 $dataPath . '/t2editor_db/{t2admin-private, collab, t2pack}' $dataPath . '/{webrtc_turn_config.json, rate_limits.json, limits.json}'
그리고 주석 (:253-257) 이 그누보드5 문제를 정확히 짚습니다:
// Some CMS adapters (gnuboard5) now isolate t2editor_db outside the// media data folder (e.g. <데이터>/t2editor_db instead of
// <데이터>/editor/t2editor_db). Treat the old nested location as
// legacy state whenever it no longer matches the resolved db_path.옛 위치가 있으면 새 위치로 옮깁니다 (t2editor_storage_prepare(), config/t2_storage.php:285-…).
4-2 · media는 일부러 옮기지 않습니다
config/t2_storage.php:262-265 주석:
// Media payloads are deliberately excluded so their published URLs stay valid.⇒ 이미지·첨부파일 주소는 안 바뀝니다. 10.5.0 릴리즈 노트도 "이미지와 첨부파일은 기존 위치에 유지"로 말합니다. 예전에 올린 글의 이미지 주소가 깨지지 않는 이유입니다.
4-3 · 알아두면 좋은 것 3가지
- 이전 중 충돌은 조용히 덮어쓰지 않습니다.
config/t2_storage.php:59-121— "Move a legacy tree into its new home without overwriting newer files." 다르면.legacy-<hash>접미사로 남습니다. ⇒ 이전이 끝난 뒤t2editor_db안에*.legacy-*파일이 보이면 그것이 충돌 흔적입니다. 지우기 전에 내용을 비교하십시오. - 이전 중에도 웹 접근 차단이 걸립니다. 같은 파일의 주석: "Symlinks are never followed or copied."
- 이전은 첫 요청에 한 번만 일어나며, lock 파일로 동시 요청을 막습니다(
config/t2_storage.php:333-334).
4-4 · 10.4.0 → 10.5.x 에서 옮겨지는 것 (별도)
S1 10.4.0: "비밀번호나 운영 관련 정보처럼 민감한 데이터는 외부에서 직접 접근할 수 없는 안전한 곳으로 옮겨 보관하도록 개선됐습니다." — 이것이 t2admin-private/ 입니다. 10.4.0에서 관리자 인증 정보가 여기 들어갑니다.
5. 데이터 경로를 바꾸고 싶다면 (개발자)
config/t2_cms_data.php:30-40 에 상수 오버라이드 지점이 있습니다.
| 상수 | 뜻 |
|---|---|
T2EDITOR_DATA_PATH | 데이터(업로드) 폴더 경로 |
T2EDITOR_DATA_URL | 그 폴더의 URL |
T2EDITOR_DB_PATH | 내부 DB 폴더 경로 |
T2EDITOR_DB_URL | 그 폴더의 URL |
T2EDITOR_PRIVATE_PATH | 비공개 상태 폴더 경로 |
상수를 먼저 정의하면 어댑터가 정한 값보다 우선합니다. 다만 어댑터의 CMS 규약(그누보드5=data/editor, 라이믹스=files)을 깨면 CMS가 관리하는 첨부 파일 목록과 어긋납니다. CMS 위에서는 임의로 바꾸지 마십시오. 스탠드얼론에서만 안전합니다.
6. 자주 보이는 오해
관련 문서: 01-installation-guide.md · N-02-admin-console-guide.md · N-06-server-sanitize-and-content-style.md · N-03-migration-v9-to-v10.md
| 오해 | 사실 |
|---|---|
| "T2Editor는 CMS 안에 데이터를 쌓지 않는다" | ❌ 그누보드5·라이믹스 안에도 쌓습니다 — CMS의 데이터 폴더를 빌려 씁니다. S2 guide.txt §3.3이 그 이유를 "편집기가 자기 폴더 안에 데이터를 쌓지 않는다. 업로드·캐시는 g5/data/editor/, 내부 DB는 g5/data/t2editor_db/"로 말합니다 |
"t2editor_db 는 어디에나 있다" | ❌ 배치마다 다릅니다. §3-1 표 참조 |
| "10.5.1로 올리면 업로드 이미지 주소가 바뀐다" | ❌ media는 이동하지 않습니다(config/t2_storage.php:262-265) |
| "워드프레스에 설치하면 CMS로 인식된다" | ❌ validate_context 가 항상 false (adapters/wordpress.php) |
| "그누보드5 데이터 폴더 권한은 707" | ❌ CMS 상수(G5_DIR_PERMISSION)를 따릅니다. 화면에 표시된 감지 권한을 보십시오 |
"이전은 data/ 전체를 옮긴다" | ❌ T2Editor 소유 상태 경로만 옮깁니다 |
N-xx 번호 체계 메모 (2026-09-28 확정)
이 위키의 N- 번호는 2026-09-28에 등록부를 확정하면서 붙였습니다. 확정된 신규 문서는 4건입니다.
| 번호 | 슬러그 | 내용 |
|---|---|---|
| N-02 | N-02-admin-console-guide.md | 통합 관리 페이지 가이드 |
| N-03 | N-03-migration-v9-to-v10.md | v9 → v10 이관 안내서 |
| N-05 | N-05-cms-adapter-and-data-paths.md | CMS 어댑터와 데이터 저장 위치 |
| N-06 | N-06-server-sanitize-and-content-style.md | 서버측 본문 정제와 게시 화면 스타일 |
N-01 · N-04 · N-07은 비어 있습니다. 번호를 미리 예약하면 그 번호가 "예정된 문서가 있다"는 뜻으로 읽히고, 실제로 그런 문서가 생기지 않으면 독자가 찾다 포기합니다. 필요해지는 시점에 그때 번호를 쓰십시오. 이전 문안에서 [[N-02-admin-console-guide.md]]·[[N-05-cms-adapter-and-data-paths.md]]처럼 가리키던 링크는 이 등록부 기준으로 교정되었습니다(N-08 → N-02, 라이믹스 경로는 N-05에 포함).
7. 내가 틀릴 수 있는 것 3가지
- "감지가 실제로 잘 된다"를 재현하지 못했습니다. 표는
validate_context/matches_root코드를 읽은 결과이며, 그누보드5·라이믹스에 실제로 설치해 돌려 보지는 않았습니다. 특히 10.5.1이 "그누보드5 로그인 정보를 불러오는 위치가 적절하지 않아" 고친 판본인데(S1), 어느 파일이 문제였는지 코드로만 짚었습니다. 그래서 §2-1의 함정은 설명일 뿐 "이렇게 하면 됩니다"가 아닙니다.
- 워드프레스 데이터 경로의 "스탠드얼론 규칙 fallback"은 코드 경로를 따라간 결과이지 실제 설치 확인이 아닙니다. 워드프레스에서 CMS 통합이 실제로 어떻게 동작하는지(어댑터 미등록 시 host 정보를 읽는 다른 경로가 있는지)는 워드프레스 환경이 없어 확인하지 못했습니다.
[확인 필요]
t2editor_db의 정확한 최종 위치는 "어댑터 반환값 + 상수 오버라이드 + 이전 처리"의 결과입니다. 제가 표로 제시한 경로는 상수가 없을 때의 값입니다. 사용자가T2EDITOR_DB_PATH를 정의했거나 이전이 실패한 경우 다릅니다. 서버에서 확실히 확인하려면T2EDITOR_DB_PATH정의 여부와t2editor_db실물 위치를 함께 보십시오.