스레드에 참여하려면 로그인하세요.
eond
1개월 전
라이믹스 기반의 개인 미니홈피 서비스.
컨셉워드프레스 미니홈피의 라이믹스 버전. 라이믹스를 이미 운영 중인 사용자가 추가 비용·관리 부담 없이 미니홈피 기능을 얹을 수 있도록 모듈 형태로 제공할 예정입니다.
현재 상태워드프레스 버전 개발 진척에 맞춰 라이믹스 모듈로 포팅 예정. 우선순위는 워드프레스 다음입니다.
라이믹스 기반의 개인 미니홈피 서비스.
컨셉워드프레스 미니홈피의 라이믹스 버전. 라이믹스를 이미 운영 중인 사용자가 추가 비용·관리 부담 없이 미니홈피 기능을 얹을 수 있도록 모듈 형태로 제공할 예정입니다.
현재 상태워드프레스 버전 개발 진척에 맞춰 라이믹스 모듈로 포팅 예정. 우선순위는 워드프레스 다음입니다.
eond
1개월 전
라이믹스 버전 업그레이드를 자동화해주는 도구.
해결하는 문제라이믹스 수동 업그레이드는 파일 덮어쓰기 + DB 스키마 변경 + 캐시 갱신을 모두 신경 써야 합니다. 자동업그레이드는 이 과정을 한 번에 처리합니다.
안전 장치업그레이드 전 자동 백업 (파일 + DB)실패 시 롤백운영 환경 적용 전 스테이징 검증 옵션
라이믹스 버전 업그레이드를 자동화해주는 도구.
해결하는 문제라이믹스 수동 업그레이드는 파일 덮어쓰기 + DB 스키마 변경 + 캐시 갱신을 모두 신경 써야 합니다. 자동업그레이드는 이 과정을 한 번에 처리합니다.
안전 장치업그레이드 전 자동 백업 (파일 + DB)실패 시 롤백운영 환경 적용 전 스테이징 검증 옵션
eond
1개월 전
ERP·webmanager·yncare 등 CRM 서비스 구축이 가능한 라이믹스용 모듈.
활용라이믹스를 백오피스/ERP 플랫폼으로 활용하고 싶은 운영자를 위한 모듈. 회원/주문/정산/고객관리 등 실무 화면을 빠르게 구축합니다.
실제 적용webmanager — 호스팅 고객 관리yncare — 요양/돌봄 CRM각종 자체 운영 ERP
ERP·webmanager·yncare 등 CRM 서비스 구축이 가능한 라이믹스용 모듈.
활용라이믹스를 백오피스/ERP 플랫폼으로 활용하고 싶은 운영자를 위한 모듈. 회원/주문/정산/고객관리 등 실무 화면을 빠르게 구축합니다.
실제 적용webmanager — 호스팅 고객 관리yncare — 요양/돌봄 CRM각종 자체 운영 ERP
eond
1개월 전
대용량 메뉴를 손쉽게 구성·관리할 수 있는 라이믹스 전용 모듈.
해결하는 문제라이믹스 기본 메뉴 관리는 메뉴 항목이 많아질수록 편집이 불편합니다. 메뉴프로 모듈은 드래그&드롭, 트리 뷰, 일괄 편집을 제공해 수백 개 메뉴도 빠르게 정리할 수 있습니다.
주요 기능드래그&드롭 트리 편집메뉴 일괄 export/import권한별 메뉴 노출 설정아이콘·뱃지 부여
대용량 메뉴를 손쉽게 구성·관리할 수 있는 라이믹스 전용 모듈.
해결하는 문제라이믹스 기본 메뉴 관리는 메뉴 항목이 많아질수록 편집이 불편합니다. 메뉴프로 모듈은 드래그&드롭, 트리 뷰, 일괄 편집을 제공해 수백 개 메뉴도 빠르게 정리할 수 있습니다.
주요 기능드래그&드롭 트리 편집메뉴 일괄 export/import권한별 메뉴 노출 설정아이콘·뱃지 부여
eond
1개월 전
라이믹스 관리자 화면을 깔끔하고 직관적으로 개선한 어드민 테마.
특징한국 운영자에게 익숙한 좌측 사이드바 + 상단 검색 레이아웃다크 모드 지원모바일 반응형 — 외출 중에도 관리자 작업 가능자주 쓰는 메뉴 즐겨찾기 / 빠른 액션호환라이믹스 2.x 이상. 기존 어드민 기능을 그대로 유지하면서 UI 만 갈아끼웁니다.
라이믹스 관리자 화면을 깔끔하고 직관적으로 개선한 어드민 테마.
특징한국 운영자에게 익숙한 좌측 사이드바 + 상단 검색 레이아웃다크 모드 지원모바일 반응형 — 외출 중에도 관리자 작업 가능자주 쓰는 메뉴 즐겨찾기 / 빠른 액션호환라이믹스 2.x 이상. 기존 어드민 기능을 그대로 유지하면서 UI 만 갈아끼웁니다.
이온디
1개월 전
TL;DR
25개 이상의 RESTful API 엔드포인트
React/Vue/Flutter 등 어디서든 사용 가능
CORS + 세션 기반 안전한 인증
레이아웃 페이지에서도 동작하는 댓글 시스템
게시판, 회원, 댓글, 추천, 마이페이지 완벽 지원
들어가며: React 스킨의 숙제
Rhymix로 React 게시판 스킨을 만들면서 가장 큰 벽은 무엇이었을까요?
<!-- Rhymix 템플릿 엔진 -->
<ul>
<li loop="$document_list=>$document"…
TL;DR
25개 이상의 RESTful API 엔드포인트
React/Vue/Flutter 등 어디서든 사용 가능
CORS + 세션 기반 안전한 인증
레이아웃 페이지에서도 동작하는 댓글 시스템
게시판, 회원, 댓글, 추천, 마이페이지 완벽 지원
들어가며: React 스킨의 숙제
Rhymix로 React 게시판 스킨을 만들면서 가장 큰 벽은 무엇이었을까요?
<!-- Rhymix 템플릿 엔진 -->
<ul>
<li loop="$document_list=>$document">
{$document->getTitle()}
</li>
</ul>
// React 컴포넌트
function BoardList() {
const [documents, setDocuments] = useState([]);
// 어떻게 데이터를 가져올까?
}
템플릿 엔진과 React의 충돌
- SSR(서버 사이드 렌더링)과 CSR(클라이언트 사이드 렌더링)의 불일치
- 기존 proc* 액션들은 HTML 리다이렉트 방식
- JSON 데이터를 직접 가져올 방법이 없음
"JSON API가 있다면 얼마나 좋을까?"
이 절실한 필요에서 API 모듈이 탄생했습니다.
API 모듈이 해결한 문제들
문제 1: React/Vue 스킨 개발의 어려움
기존 방식
// procBoardInsertComment 호출
exec_json('procBoardInsertComment', {
document_srl: 123,
content: '댓글'
});
// → 게시판 모듈 컨텍스트가 없으면 실패
// → 레이아웃 페이지에서 사용 불가
API 모듈 방식
// REST API 호출
fetch('/modules/api/rest.php?type=comment_insert&document_srl=123', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: '댓글' }),
credentials: 'same-origin'
});
// → 어디서든 동작!
// → 게시판 스킨, 레이아웃 페이지, 위젯 모두 OK
문제 2: 크로스 플랫폼 앱 개발
기존 방식
- Rhymix는 웹 전용
- 모바일 앱이나 데스크톱 앱 개발 어려움
- 데이터를 가져올 표준 방법 없음
API 모듈 방식
// 동일한 API를 모든 플랫폼에서 사용
const API = 'https://eond.com/modules/api/rest.php';
// React Native (모바일 앱)
fetch(`${API}?type=document_list&mid=board`)
// Flutter (iOS/Android)
http.get(Uri.parse('${API}?type=document_list&mid=board'))
// Electron (데스크톱 앱)
fetch(`${API}?type=document_list&mid=board`)
하나의 API로 모든 플랫폼 지원!
문제 3: HTML 응답 vs JSON 응답
기존 Rhymix proc* 액션
// procBoardInsertDocument 호출
const response = await fetch('/index.php', {
method: 'POST',
body: formData
});
// 응답: HTML 페이지 (리다이렉트)
// JSON 파싱 시도 → SyntaxError 발생!
API 모듈
// REST API 호출
const response = await fetch('/modules/api/rest.php?type=document_insert', {
method: 'POST',
body: JSON.stringify(data)
});
// 응답: 항상 JSON
const result = await response.json();
// {
// "status": 1,
// "message": "성공",
// "data": { "document_srl": 123 }
// }
일관된 JSON 응답 형식!
API 모듈의 완벽한 기능
1. 게시판 API
게시글 목록 조회
GET /api?mid=board&act=dispApiDocumentList&page=1
// 파라미터
- page: 페이지 번호
- list_count: 페이지당 개수
- search_target: 검색 대상 (title, content, nick_name)
- search_keyword: 검색 키워드
- category_srl: 카테고리 필터
- sort_index: 정렬 기준 (list_order, regdate, readed_count)
- order_type: 정렬 방향 (asc, desc)
응답 예시
{
"status": 1,
"message": "성공",
"payload": {
"documents": [
{
"document_srl": 123,
"title": "게시글 제목",
"content": "게시글 요약...",
"nick_name": "작성자",
"regdate": "2024-11-10 12:00:00",
"readed_count": 100,
"comment_count": 5,
"voted_count": 10,
"thumbnail": "https://..."
}
],
"total_count": 150,
"total_page": 8,
"page": 1,
"list_count": 20,
"categories": [...],
"grant": {
"list": true,
"view": true,
"write_document": true,
"write_comment": true
}
}
}
게시글 상세 조회
GET /api?mid=board&act=dispApiDocument&document_srl=123
// 파라미터
- document_srl: 게시글 번호 (필수)
- skip_view_count: true면 조회수 증가 안 함
응답 예시
{
"status": 1,
"message": "성공",
"payload": {
"document": {
"document_srl": 123,
"title": "게시글 제목",
"content": "게시글 전체 내용...",
"nick_name": "작성자",
"user_id": "userid",
"regdate": "2024-11-10 12:00:00",
"readed_count": 101,
"comment_count": 5,
"voted_count": 10,
"category_srl": 1,
"tags": ["React", "Rhymix", "API"]
},
"comments": [...],
"files": [...],
"prev_document": {
"document_srl": 122,
"title": "이전글 제목"
},
"next_document": {
"document_srl": 124,
"title": "다음글 제목"
},
"grant": {
"view": true,
"write_comment": true,
"is_granted": false
}
}
}
스마트 이전글/다음글 필터링
API 모듈은 카테고리와 태그를 기반으로 관련된 이전글/다음글을 찾습니다:
현재 문서:
- 카테고리: "프로젝트"
- 태그: "React, TypeScript, API"
1차 시도 (필터링):
→ 같은 카테고리 + 공통 태그가 있는 문서
2차 시도 (Fallback):
→ 1차에서 결과 없으면 전체 게시판에서 찾기
게시글 작성
POST /modules/api/rest.php?type=document_insert
// Body (JSON)
{
"mid": "board",
"title": "게시글 제목",
"content": "게시글 내용",
"category_srl": 1, // 선택
"is_secret": "N", // 비밀글 여부
"tags": "React,API" // 선택
}
// 응답
{
"status": 1,
"message": "게시글이 등록되었습니다.",
"data": {
"document_srl": 123
}
}
게시글 수정/삭제
// 수정
POST /modules/api/rest.php?type=document_update
{
"document_srl": 123,
"title": "수정된 제목",
"content": "수정된 내용"
}
// 삭제
POST /modules/api/rest.php?type=document_delete
{
"document_srl": 123
}
2. 댓글 API
왜 레이아웃 페이지에서도 동작하나?
핵심은 독립적인 엔드포인트와 executeQuery 직접 사용입니다.
// API 모듈의 댓글 등록 (rest.php)
case 'comment_insert':
// 1. 세션에서 로그인 정보 가져오기
$logged_info = Context::get('logged_info');
// 2. executeQuery로 직접 DB에 삽입
$output = executeQuery(
'insertComment',
$comment_args
);
// 3. JSON 응답 반환
echo json_encode([
'status' => 1,
'message' => '댓글이 등록되었습니다.',
'data' => ['comment_srl' => $comment_srl]
]);
// → 게시판 모듈 컨텍스트 불필요!
댓글 작성
POST /modules/api/rest.php?type=comment_insert&document_srl=123
// Body (JSON)
{
"content": "댓글 내용",
"parent_srl": 0 // 대댓글이면 부모 댓글 번호
}
// 응답
{
"status": 1,
"message": "댓글이 등록되었습니다.",
"data": {
"comment_srl": 456
}
}
보안 체크
- ✅ 로그인 필수 (세션 기반)
- ✅ 게시글 존재 여부 확인
- ✅ 댓글 권한 체크
- ✅ SQL Injection 방지 (prepared statement)
- ✅ XSS 방지 (출력 이스케이프)
댓글 수정/삭제
// 수정
POST /modules/api/rest.php?type=comment_update
{
"comment_srl": 456,
"content": "수정된 내용"
}
// 삭제
POST /modules/api/rest.php?type=comment_delete
{
"comment_srl": 456
}
권한 체크
- 댓글 작성자 또는 관리자만 수정/삭제 가능
3. 추천/비추천 API
// 게시글 추천
POST /modules/api/rest.php?type=vote_up&document_srl=123
// 게시글 비추천
POST /modules/api/rest.php?type=vote_down&document_srl=123
// 추천/비추천 취소
POST /modules/api/rest.php?type=vote_cancel&document_srl=123
// 응답
{
"status": 1,
"message": "추천하였습니다.",
"data": {
"voted_count": 11 // 현재 추천 수
}
}
4. 회원 인증 API
비밀번호 찾기
POST /modules/api/rest.php?type=password_reset_request
// Body (JSON)
{
"user_id": "사용자아이디",
"email_address": "user@example.com"
}
// 응답
{
"status": 1,
"message": "비밀번호 재설정 링크가 이메일로 발송되었습니다."
}
동작 방식
1. 아이디와 이메일 주소 일치 확인
2. 1시간 유효한 인증 토큰 생성
3. 이메일로 재설정 링크 발송
회원가입
POST /modules/api/rest.php?type=member_signup
// Body (JSON)
{
"user_id": "userid",
"password": "비밀번호123",
"password_confirm": "비밀번호123",
"email_address": "user@example.com",
"nick_name": "닉네임",
"user_name": "이름",
"allow_mailing": "Y", // 메일 수신 동의
"allow_message": "Y" // 쪽지 수신 동의
}
// 응답
{
"status": 1,
"message": "회원가입이 완료되었습니다.",
"data": {
"member_srl": 12345,
"require_confirm": false // 이메일 인증 필요 여부
}
}
검증
- 비밀번호: 최소 8자, 영문+숫자 포함
- 아이디, 이메일, 닉네임 중복 체크
- 이메일 인증 설정 시 인증 메일 발송
5. 마이페이지 API
내 정보 조회
GET /modules/api/rest.php?type=member_my_info
// 응답
{
"status": 1,
"message": "성공",
"data": {
"member_srl": 12345,
"user_id": "userid",
"nick_name": "닉네임",
"user_name": "홍길동",
"email_address": "user@example.com",
"profile_image": "https://eond.com/files/member_extra_info/profile.jpg",
"regdate": "2024-01-15 10:00:00",
"last_login": "2025-12-03 09:30:00",
"point": 1500,
"level": 5
}
}
포인트 히스토리
GET /modules/api/rest.php?type=member_point_history&page=1
// 응답
{
"status": 1,
"message": "성공",
"data": {
"current_point": 1500,
"history": [
{
"point_srl": 789,
"point": 100, // 증감량 (+ 적립, - 차감)
"accumulated_point": 1500, // 해당 시점 누적
"comment": "게시글 작성",
"regdate": "2025-12-03 10:00:00"
},
{
"point_srl": 788,
"point": -50,
"accumulated_point": 1400,
"comment": "댓글 작성",
"regdate": "2025-12-02 15:30:00"
}
],
"total_count": 150,
"total_page": 8,
"page": 1
}
}
프로필 이미지 변경
POST /modules/api/rest.php?type=member_update_profile_image
Content-Type: multipart/form-data
FormData:
profile_image: [이미지 파일]
// 응답
{
"status": 1,
"message": "프로필 이미지가 변경되었습니다.",
"data": {
"profile_image": "https://eond.com/files/member_extra_info/..."
}
}
제한
- 파일 형식: JPG, PNG, GIF, WebP
- 최대 크기: 5MB
비밀번호 변경
POST /modules/api/rest.php?type=member_update_password
// Body (JSON)
{
"current_password": "현재비밀번호",
"new_password": "새비밀번호123",
"new_password_confirm": "새비밀번호123"
}
// 응답
{
"status": 1,
"message": "비밀번호가 변경되었습니다."
}
개인정보 수정
POST /modules/api/rest.php?type=member_update_info
// Body (JSON)
{
"nick_name": "새닉네임",
"user_name": "새이름",
"email_address": "new@example.com",
"allow_mailing": "Y",
"allow_message": "N"
}
// 응답
{
"status": 1,
"message": "개인정보가 수정되었습니다.",
"data": {
"member_srl": 12345,
"user_id": "userid",
"nick_name": "새닉네임",
"user_name": "새이름",
"email_address": "new@example.com",
"profile_image": "..."
}
}
활동 내역 조회
// 내가 쓴 글
GET /modules/api/rest.php?type=member_my_documents&page=1&list_count=20&mid=board
// 내가 쓴 댓글
GET /modules/api/rest.php?type=member_my_comments&page=1&list_count=20
// 스크랩한 글
GET /modules/api/rest.php?type=member_my_scraps&page=1&list_count=20
6. 인기글 API
GET /modules/api/rest.php?type=popular_documents
&mid=board
&page=1
&list_count=20
&period=7
&sort_by=readed_count
// 파라미터
- mid: 게시판 mid (필수)
- page: 페이지 번호 (기본 1)
- list_count: 페이지당 개수 (기본 20)
- period: 기간 (일 단위, 기본 7)
- sort_by: 정렬 기준
* readed_count: 조회수 (기본)
* voted_count: 추천수
* comment_count: 댓글수
// 응답
{
"status": 1,
"message": "성공",
"data": {
"documents": [
{
"document_srl": 123,
"title": "인기글 제목",
"content": "요약...",
"nick_name": "작성자",
"regdate": "2025-12-01 10:00:00",
"readed_count": 1000,
"voted_count": 50,
"comment_count": 30,
"thumbnail": "https://..."
}
],
"total_count": 100,
"total_page": 5,
"page": 1,
"period": 7,
"sort_by": "readed_count"
}
}
실전 활용 예시
예시 1: React 게시판 스킨
// TypeScript + React Hooks
import React, { useState, useEffect } from 'react';
interface Document {
document_srl: number;
title: string;
content: string;
nick_name: string;
regdate: string;
readed_count: number;
comment_count: number;
}
function BoardList({ mid }: { mid: string }) {
const [documents, setDocuments] = useState<Document[]>([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
useEffect(() => {
fetchDocuments();
}, [page]);
const fetchDocuments = async () => {
try {
const response = await fetch(
`/api?mid=${mid}&act=dispApiDocumentList&page=${page}`
);
const data = await response.json();
if (data.status === 1) {
setDocuments(data.payload.documents);
}
} catch (error) {
console.error('Error fetching documents:', error);
} finally {
setLoading(false);
}
};
if (loading) {
return <div className="loading">로딩 중...</div>;
}
return (
<div className="board-list">
{documents.map(doc => (
<article key={doc.document_srl} className="document-item">
<h2>
<a href={`/board/${doc.document_srl}`}>
{doc.title}
</a>
</h2>
<p className="content">{doc.content}</p>
<div className="meta">
<span className="author">{doc.nick_name}</span>
<span className="date">{doc.regdate}</span>
<span className="views">조회 {doc.readed_count}</span>
<span className="comments">댓글 {doc.comment_count}</span>
</div>
</article>
))}
<div className="pagination">
<button onClick={() => setPage(p => p - 1)} disabled={page === 1}>
이전
</button>
<span>페이지 {page}</span>
<button onClick={() => setPage(p => p + 1)}>
다음
</button>
</div>
</div>
);
}
export default BoardList;
예시 2: 레이아웃 페이지에 댓글 추가
// 홈페이지(레이아웃 페이지)에 댓글 시스템 추가
// 댓글 목록 로드
async function loadComments(documentSrl) {
const response = await fetch(
`/api?mid=notice&act=dispApiDocument&document_srl=${documentSrl}`
);
const data = await response.json();
if (data.status === 1) {
displayComments(data.payload.comments);
}
}
// 댓글 작성
async function submitComment(documentSrl, content) {
const response = await fetch(
`/modules/api/rest.php?type=comment_insert&document_srl=${documentSrl}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: content }),
credentials: 'same-origin' // 쿠키(세션) 전송 필수!
}
);
const result = await response.json();
if (result.status === 1) {
alert('댓글이 등록되었습니다.');
loadComments(documentSrl); // 댓글 목록 새로고침
} else {
alert('댓글 등록 실패: ' + result.message);
}
}
// 사용 예시
document.getElementById('comment-form').addEventListener('submit', (e) => {
e.preventDefault();
const content = document.getElementById('comment-content').value;
const documentSrl = 123; // 게시글 번호
submitComment(documentSrl, content);
});
예시 3: 모바일 앱 (React Native)
// React Native로 Rhymix 게시판 앱 만들기
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, TouchableOpacity } from 'react-native';
const API_URL = 'https://eond.com/modules/api/rest.php';
function BoardScreen() {
const [documents, setDocuments] = useState([]);
useEffect(() => {
fetchDocuments();
}, []);
const fetchDocuments = async () => {
try {
const response = await fetch(
`https://eond.com/api?mid=board&act=dispApiDocumentList`
);
const data = await response.json();
setDocuments(data.payload.documents);
} catch (error) {
console.error(error);
}
};
const vote = async (documentSrl) => {
const response = await fetch(
`${API_URL}?type=vote_up&document_srl=${documentSrl}`,
{ method: 'POST' }
);
const result = await response.json();
alert(result.message);
};
return (
<FlatList
data={documents}
keyExtractor={item => item.document_srl.toString()}
renderItem={({ item }) => (
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
<Text>{item.content}</Text>
<TouchableOpacity onPress={() => vote(item.document_srl)}>
<Text> 추천 {item.voted_count}</Text>
</TouchableOpacity>
</View>
)}
/>
);
}
보안 및 성능
보안 기능
1. CORS (Cross-Origin Resource Sharing)
// 허용된 도메인만 API 접근 가능
$allowed_origins = [
'https://eond.com',
'http://localhost:3000' // 개발용
];
2. 세션 기반 인증
// 쿠키(세션) 전송 필수
fetch('/modules/api/rest.php?type=comment_insert', {
method: 'POST',
credentials: 'same-origin' // 중요!
});
3. SQL Injection 방지
// executeQuery = PDO prepared statement
$output = executeQuery('insertComment', $args);
// → 자동으로 이스케이프 처리
4. XSS 방지
// 출력 시 자동 이스케이프
$comment->content = htmlspecialchars($content);
5. 권한 체크
// 댓글 수정/삭제 시 작성자 확인
if (!$oComment->isGranted()) {
return ['status' => 0, 'message' => '권한이 없습니다.'];
}
성능 최적화
1. 효율적인 쿼리
<!-- getDocumentList.xml -->
<query>
SELECT document_srl, title, content, nick_name, regdate
FROM documents
WHERE module_srl = #{module_srl}
ORDER BY list_order ASC
LIMIT #{list_count}
</query>
<!-- 필요한 컬럼만 조회 -->
2. 페이징 처리
// 대용량 데이터도 빠른 응답
GET /api?mid=board&page=1&list_count=20
// → 20개씩만 조회
3. JSON 직렬화 최적화
// 불필요한 데이터 제거
unset($document->variables);
unset($document->_filter);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
설치 및 시작하기
시스템 요구사항
필수
- Rhymix 2.0 이상
- PHP 7.4 이상
- PDO 확장 모듈
- JSON 지원
권장
- PHP 8.0 이상
- HTTPS 환경
- Gzip 압축 활성화
설치 방법
1. 모듈 다운로드
# Git으로 다운로드
git clone https://github.com/eond/api.git modules/api
# 또는 ZIP 파일 다운로드 후 압축 해제
2. 관리자 설정
1. 관리자 페이지 접속
http://yoursite.com/index.php?module=admin&act=dispApiAdminConfig
2. REST API 설정
- CORS 도메인 추가
- API 활성화
3. 저장
3. API 테스트
# 게시글 목록 조회
curl http://yoursite.com/api?mid=board&act=dispApiDocumentList
# 응답 확인
{
"status": 1,
"message": "성공",
"payload": { ... }
}
개발 환경 설정
React 프로젝트에서 사용
// src/api/board.js
const API_BASE = '/api';
const REST_API = '/modules/api/rest.php';
export const boardAPI = {
// 게시글 목록
getDocuments: async (mid, page = 1) => {
const response = await fetch(
`${API_BASE}?mid=${mid}&act=dispApiDocumentList&page=${page}`
);
return response.json();
},
// 댓글 작성
addComment: async (documentSrl, content) => {
const response = await fetch(
`${REST_API}?type=comment_insert&document_srl=${documentSrl}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content }),
credentials: 'same-origin'
}
);
return response.json();
}
};
버전 히스토리
v1.1.0 (2024-11-10) - 최신
✨ 마이페이지 API 추가
내 정보 조회
포인트 히스토리
프로필 이미지 변경
비밀번호 변경
개인정보 수정
내가 쓴 글/댓글 목록
스크랩한 글 목록
✨ 회원 인증 API 추가
비밀번호 찾기
회원가입
✨ 인기글 API 추가
v1.0.0 (2024-10-01)
API 모듈 첫 출시
✨ 게시판 API (목록, 상세, 작성, 수정, 삭제)
✨ 댓글 API (작성, 수정, 삭제)
✨ 추천/비추천 API
✨ CORS 지원
✨ 세션 기반 인증
로드맵
v1.2.0 (예정)
[ ] GraphQL 지원
[ ] 웹소켓 실시간 알림
[ ] 파일 업로드 API
[ ] 배치 작업 API
v2.0.0 (장기)
[ ] OAuth 2.0 인증
[ ] API 버전 관리
[ ] Rate Limiting
[ ] API 문서 자동 생성
FAQ
Q1. 기존 게시판 스킨과 호환되나요?
A. 네, API 모듈은 기존 게시판 스킨과 독립적으로 동작합니다. 기존 스킨을 유지하면서 새로운 React 스킨을 추가로 개발할 수 있습니다.
Q2. 모바일 앱에서 사용할 수 있나요?
A. 네, React Native, Flutter, Swift, Kotlin 등 모든 플랫폼에서 사용 가능합니다. RESTful API 표준을 따르므로 HTTP 요청만 가능하면 됩니다.
Q3. 보안은 안전한가요?
A. 네, CORS, 세션 인증, SQL Injection 방지, XSS 방지 등 모든 보안 기능이 구현되어 있습니다. PDO prepared statement로 DB를 안전하게 처리합니다.
Q4. 성능은 어떤가요?
A. 효율적인 쿼리와 JSON 직렬화로 빠른 응답 속도를 보장합니다. 페이징 처리로 대용량 데이터도 문제없습니다.
Q5. 라이선스는?
A. 상업용 유료 라이선스입니다. 구매 후 소스코드, 기술 지원, 업데이트를 제공받으실 수 있습니다. 자세한 사항은 https://eond.com 또는 admin@eond.com으로 문의해주세요.
Q6. 커스텀 API를 추가할 수 있나요?
A. 네, rest.php에 새로운 case를 추가하면 됩니다. 기존 API를 참고하여 쉽게 확장할 수 있습니다.
사용자 후기 (테스트 사용자)
"React로 게시판을 만들고 싶었는데, 데이터를 가져올 방법이 없어서 포기했었어요. API 모듈 덕분에 드디어 해냈습니다!"
— React 개발자 K
"레이아웃 페이지에서 댓글이 안 돼서 고민했는데, REST API로 간단하게 해결됐어요. 정말 편합니다."
— 커뮤니티 관리자 L
"Flutter로 모바일 앱을 만들고 있는데, API 모듈이 없었다면 불가능했을 겁니다. 감사합니다!"
— 앱 개발자 P
라이선스 및 구매
API 모듈은 상업용 유료 라이선스 제품입니다.
구매 정보
- 가격: 문의 필요
- 구매 문의: https://eond.com 또는 admin@eond.com
- 포함 사항: 소스코드, 기술 지원, 업데이트
지원 서비스
- 설치 및 설정 지원
- 기술 지원 (이메일, 포럼)
- 무료 업데이트 (1년간)
- 사용자 가이드 및 API 문서 제공
결론
API 모듈은 Rhymix의 가능성을 확장합니다.
API 모듈이 제공하는 가치
✅ React/Vue 스킨 개발: 완벽한 JSON API
✅ 크로스 플랫폼: 웹, 모바일, 데스크톱 앱
✅ 독립적인 엔드포인트: 어디서든 동작
✅ 표준 준수: RESTful API
✅ 보안: CORS + 세션 인증
지금 바로 시작하세요
React로 게시판을 만들고 싶으셨나요?
레이아웃 페이지에 댓글을 추가하고 싶으셨나요?
모바일 앱을 개발하고 싶으셨나요?
API 모듈이 모든 것을 가능하게 합니다.
다운로드: https://github.com/eond/api
API 문서: modules/api/README.md
데모: https://demo.eond.com/api
문의: admin@eond.com
작성일: 2025-12-03
카테고리: Rhymix, 모듈, API
태그: #API #Rhymix #JSON #RESTful #React #Vue #모바일앱
버전: API 모듈 v1.1.0
이온디
6개월 전
# MenuPro: Rhymix 사이트맵 관리의 새로운 표준
## TL;DR
- 🚀 메뉴 100개를 10분 만에 재배치 (기존 1시간 → 10분)
- 🎯 드래그 앤 드롭으로 사이트맵 간 자유로운 이동
- ✨ React 기반 현대적인 UI/UX
- 💾 일괄 저장으로 실수 방지
- 🔍 강력한 메뉴 검색 기능
---
<메뉴 아이템 수정부터 권한설정, 디자인설정까지 모두 하나의 화면에서>
## 들어가며: 왜 MenuPro를 만들었나?
Rhymix 관리자라…
# MenuPro: Rhymix 사이트맵 관리의 새로운 표준
## TL;DR
- 🚀 메뉴 100개를 10분 만에 재배치 (기존 1시간 → 10분)
- 🎯 드래그 앤 드롭으로 사이트맵 간 자유로운 이동
- ✨ React 기반 현대적인 UI/UX
- 💾 일괄 저장으로 실수 방지
- 🔍 강력한 메뉴 검색 기능
---
<메뉴 아이템 수정부터 권한설정, 디자인설정까지 모두 하나의 화면에서>
## 들어가며: 왜 MenuPro를 만들었나?
Rhymix 관리자라면 누구나 공감할 이 순간:
```
메뉴 하나 옮기기
→ 자동 저장
→ 페이지 새로고침
→ 다시 메뉴 찾기
→ 또 하나 옮기기
→ 자동 저장
→ 페이지 새로고침
→ ...반복...
```
10개의 메뉴를 정리하려면 10번의 새로고침.
100개의 메뉴를 재구성하려면? 상상만 해도 지칩니다.
**"더 나은 방법이 있지 않을까?"**
이 질문에서 MenuPro가 탄생했습니다.
---
<사이트맵 메뉴별로 디자인 설정을 쉽게 할 수 있다>
## MenuPro가 해결한 문제들
### 문제 1: 반복적인 새로고침
**기존 방식**
- 메뉴 하나 이동 → 자동 저장 → 새로고침
- 메뉴 100개 정리 = 새로고침 100번
- 소요 시간: 약 1시간
**MenuPro 방식**
- 메뉴 100개를 자유롭게 드래그 앤 드롭
- 모두 정리한 후 "저장" 버튼 클릭 1회
- 소요 시간: 약 10분
**생산성 6배 향상!** ⚡
### 문제 2: 복잡한 구조 파악의 어려움
**기존 방식**
```
게시판
├ 공지사항
├ 자유게시판
└ FAQ
커뮤니티
├ 갤러리
└ Q&A
```
어떤 메뉴가 어디에 속하는지 한눈에 보기 어려웠습니다.
**MenuPro 방식**
<img src="screenshot_tree_structure.png" alt="트리 구조 스크린샷" />
- 📊 시각적 트리 구조
- 🔽 접기/펼치기로 원하는 뎁스만 보기
- 🎨 계층별 들여쓰기와 연결선
- 🏷️ 메뉴 타입 아이콘 표시
### 문제 3: 사이트맵 간 이동의 번거로움
**기존 방식**
1. 메뉴 A를 사이트맵 1에서 삭제
2. 사이트맵 2로 이동
3. 메뉴 A를 다시 생성
4. 모든 설정을 다시 입력
**MenuPro 방식**
1. 메뉴 A를 드래그
2. 사이트맵 2로 드롭
3. 끝! ✨
모든 설정(권한, 스킨, 레이아웃)이 그대로 유지됩니다.
### 문제 4: 메뉴 찾기의 어려움
사이트가 커질수록 메뉴를 찾기가 점점 어려워집니다.
**MenuPro의 검색 기능**
```
검색어 입력: "공지"
→ "공지사항" 메뉴 하이라이트
→ 해당 사이트맵 자동 펼침
→ 메뉴까지 자동 스크롤
```
- 🔍 메뉴명으로 검색
- 🎯 mid(모듈 ID)로 검색
- ⚡ 실시간 검색 결과
---
<모든 사이트맵을 접어서 이동 가능한 사이트맵 메뉴>
## MenuPro의 핵심 기능
### 1. 드래그 앤 드롭 시스템
**3가지 드래그 타입 지원**
#### 타입 1: 같은 사이트맵 내 순서 변경
```
[사이트맵 A]
- 메뉴1
- 메뉴2 ← 드래그
- 메뉴3 ← 여기로 드롭
[결과]
- 메뉴1
- 메뉴3
- 메뉴2
```
#### 타입 2: 계층 구조 변경
```
[드래그 전]
- 메뉴1
- 메뉴2
└ 메뉴2-1
[메뉴1을 메뉴2 아래로 드래그]
[드래그 후]
- 메뉴2
├ 메뉴2-1
└ 메뉴1 ← 2차 메뉴가 됨
```
#### 타입 3: 사이트맵 간 이동
```
[사이트맵 A] [사이트맵 B]
- 메뉴1 - 메뉴A
- 메뉴2 ──드래그──→ - 메뉴B
- 메뉴3
[결과]
[사이트맵 A] [사이트맵 B]
- 메뉴1 - 메뉴A
- 메뉴3 - 메뉴B
- 메뉴2 ← 이동됨
```
**하위 메뉴 자동 이동**
- 메뉴2를 이동하면 메뉴2의 모든 하위 메뉴도 함께 이동
- 계층 구조 완벽 유지
<부모를 잃어버린 사이트맵 메뉴 찾기>
### 2. 일괄 저장 시스템
**변경 내역 실시간 추적**
```
[변경 내역 패널]
✓ 메뉴1: 순서 변경 (3 → 5)
✓ 메뉴2: 사이트맵 이동 (A → B)
✓ 메뉴3: 계층 변경 (1차 → 2차)
✓ 사이트맵 A: 순서 변경
[저장] [취소] [되돌리기]
```
- 📝 모든 변경사항 리스트로 표시
- ↩️ 저장 전 언제든 되돌리기
- 💾 한 번의 클릭으로 모두 적용
- ❌ 취소 버튼으로 전체 복원
**실수 방지 기능**
- 저장 전 확인 대화상자
- 중요한 변경(삭제 등)은 2단계 확인
- 변경 내역 미리보기
### 3. 사이트맵 관리
**사이트맵 순서 변경**
```
[드래그 앤 드롭으로 순서 변경]
메인 메뉴 서브 메뉴
↓ ↑ ↓ ↑
푸터 메뉴 모바일 메뉴
```
- 🖱️ 사이트맵 헤더 드래그로 순서 변경
- 💾 변경 즉시 저장
- 🔄 언제든 순서 재배치
**사이트맵 생성/편집/삭제**
```
[사이트맵 생성]
이름: 새 사이트맵
설명: (선택사항)
[생성]
[사이트맵 편집]
이름 클릭 → 인라인 수정 → Enter
```
- ➕ 빠른 사이트맵 생성
- ✏️ 이름 클릭으로 즉시 수정
- 🗑️ 삭제 시 하위 메뉴 처리 선택
### 4. 메뉴 검색 기능
**강력한 검색 옵션**
```
[검색창]
🔍 메뉴 찾기...
검색 대상:
☑ 메뉴명
☑ mid(모듈 ID)
☑ 설명
검색 결과:
📌 공지사항 (mid: notice)
📌 공지사항 > 중요공지 (mid: notice_important)
```
**검색 결과 처리**
- 🎯 검색된 메뉴 하이라이트
- 📂 해당 사이트맵 자동 펼침
- 📜 메뉴 위치로 자동 스크롤
- 🔢 검색 결과 개수 표시
### 5. 메뉴 아이템 관리
**메뉴 생성**
```
[메뉴 추가]
메뉴 타입 선택:
○ 위젯 페이지
○ 문서 페이지
○ 게시판
○ 외부 페이지
● 바로가기
[다음 단계로]
```
**지원하는 메뉴 타입**
- 📄 위젯 페이지
- 📝 문서 페이지
- 📋 게시판
- 🔗 외부 페이지
- ⚡ 바로가기
**메뉴 편집**
```
[메뉴 편집 사이드바]
기본 정보
├ 메뉴명: 공지사항
├ mid: notice
└ 설명: 중요한 공지를 올리는...
디자인
├ 레이아웃: el_basic
├ PC 스킨: board_default
└ 모바일 스킨: mobile_default
권한
├ 목록 권한: 전체
├ 글쓰기 권한: 회원
└ 댓글 권한: 회원
고급 설정
├ 새 창에서 열기: □
└ 확장 상태: □
```
**메뉴 삭제**
```
[메뉴 삭제 확인]
"공지사항" 메뉴를 삭제하시겠습니까?
연결된 모듈도 함께 삭제하시겠습니까?
○ 메뉴만 삭제 (모듈은 유지)
● 모듈도 함께 삭제 (복구 불가)
[취소] [삭제]
```
---
<실수로 연결이 끊어진 메뉴도 자동으로 제 자리를 찾아줍니다>
## 기술 스택: 현대적인 아키텍처
### 프론트엔드
**React 18 + TypeScript**
```typescript
// 타입 안정성과 최신 React 기능
interface MenuItem {
menu_item_srl: number;
name: string;
url: string;
parent_srl: number;
// ...
}
const MenuGrid: React.FC<MenuGridProps> = ({ menus, onSave }) => {
// Hooks 기반 상태 관리
const [selectedMenu, setSelectedMenu] = useState<MenuItem | null>(null);
// ...
};
```
**주요 라이브러리**
- **react-complex-tree**: 트리 구조 및 드래그 앤 드롭
- **@dnd-kit**: 사이트맵 순서 변경
- **shadcn/ui**: 세련된 UI 컴포넌트
- **Webpack 5**: 최적화된 번들링
**왜 React인가?**
- ⚡ 빠른 렌더링 (Virtual DOM)
- 🔄 효율적인 상태 관리
- 🧩 컴포넌트 재사용
- 📦 풍부한 생태계
### 백엔드
**Rhymix 2.1.8+ 네임스페이스 구조**
```php
namespace Rhymix\Modules\Menupro\Controllers;
class Admin extends Base
{
public function procMenuproAdminUpdateMenuItemsOrder()
{
// PSR-4 자동로드
// 명확한 네임스페이스
// 현대적인 PHP 코드
}
}
```
**MVC 패턴**
```
modules/menupro/
├── controllers/ # 요청 처리
│ ├── Admin.php # 관리자 액션
│ ├── Index.php # API 엔드포인트
│ └── Install.php # 설치/업데이트
├── models/ # 비즈니스 로직
│ └── Menu.php # 메뉴 데이터 관리
├── views/ # 화면 템플릿
│ └── admin/
│ └── config.blade.php
└── conf/
├── info.xml # 모듈 정보
└── module.xml # 액션 정의
```
**Blade v2 템플릿**
```blade
@version(2)
<div class="menupro-container">
@if($menus)
@foreach($menus as $menu)
<div class="menu-item">
{{ $menu->title }}
</div>
@endforeach
@else
<p>등록된 사이트맵이 없습니다.</p>
@endif
</div>
```
---
<다중 선택 이동 기능>
## 실전 활용 시나리오
### 시나리오 1: 대형 포털 사이트 메뉴 재구성
**상황**
- 100개의 메뉴가 있는 커뮤니티 사이트
- 카테고리별로 메뉴 그룹 재구성 필요
- 3개 사이트맵 → 5개 사이트맵으로 분리
**기존 방식 (약 2시간)**
```
1. 새 사이트맵 2개 생성 (10분)
2. 메뉴 하나씩 이동 (100번 × 1분 = 100분)
3. 순서 정리 (30분)
4. 테스트 및 수정 (20분)
```
**MenuPro 방식 (약 20분)**
```
1. 새 사이트맵 2개 생성 (2분)
2. 메뉴 드래그 앤 드롭으로 일괄 이동 (10분)
3. 순서 드래그로 정리 (5분)
4. 한 번에 저장 (1분)
5. 테스트 (2분)
```
**생산성 6배 향상!**
### 시나리오 2: 모바일/PC 메뉴 분리
**상황**
- 기존: PC와 모바일이 같은 메뉴 사용
- 목표: 모바일 전용 간소화 메뉴 구성
**MenuPro로 쉽게 해결**
```
1. "모바일 메뉴" 사이트맵 생성
2. PC 메뉴에서 주요 메뉴만 드래그 앤 드롭으로 복사
3. 불필요한 하위 메뉴 정리
4. 모바일 레이아웃에 "모바일 메뉴" 사이트맵 연결
```
**소요 시간: 5분**
### 시나리오 3: 시즌별 메뉴 교체
**상황**
- 이벤트 기간에만 보이는 메뉴
- 평상시에는 숨김 처리
**MenuPro 활용**
```
[평상시]
메인 메뉴
├ 홈
├ 소개
└ 게시판
[이벤트 사이트맵] ← 접어두기
├ 이벤트 안내
├ 참여 방법
└ 당첨자 발표
[이벤트 시작]
→ 이벤트 메뉴를 메인 메뉴로 드래그
→ 한 번에 저장
→ 완료!
```
---
## 설치 및 시작하기
### 시스템 요구사항
**필수**
- Rhymix 2.1.8 이상
- PHP 7.4 이상
- 모던 브라우저 (Chrome, Firefox, Safari, Edge)
**권장**
- PHP 8.0 이상
- SSD 스토리지
- 메모리 512MB 이상
### 설치 방법
**1. 모듈 다운로드**
```bash
# Git으로 다운로드
git clone https://github.com/eond/menupro.git modules/menupro
# 또는 ZIP 파일 다운로드 후 압축 해제
```
**2. 관리자 페이지 접속**
```
http://yoursite.com/index.php?module=admin&act=dispMenuproAdminConfig
```
**3. 기본 사용법**
```
1. 기존 사이트맵이 자동으로 로드됨
2. 드래그 앤 드롭으로 메뉴 정리
3. "저장" 버튼 클릭
4. 완료! 🎉
```
### 빌드 (개발자용)
```bash
# 의존성 설치
npm install
# 개발 모드 (Hot Reload)
npm run dev:menupro
# 프로덕션 빌드
npm run build:menupro
```
---
## 버전 히스토리
### v1.0.7 (2025-11-28) - 최신
- ✨ 위젯페이지/문서페이지 mid 필드 표시 및 수정 기능
- 🐛 프론트엔드 모듈 타입 인식 개선
### v1.0.6 (2025-11-28)
- ✨ getMenuDetail에서 enrichMenuItem 호출 추가
- 🐛 MenuGrid에 module_type 전달
### v1.0.5 (2025-11-28)
- 🐛 외부 페이지(OUTSIDE) 생성 시 "새 창에서 열기" 강제 설정 제거
### v1.0.4 (2025-11-28)
- ✨ 위젯페이지 모듈 타입 인식 개선 (enrichMenuItem 함수 추가)
### v1.0.3 (2025-11-27)
- 🐛 메뉴 아이템 mid 변경 시 실제 모듈 mid도 함께 변경되도록 수정
### v1.0.2 (2025-11-27)
- 🐛 **중요 버그 수정**: 메뉴 이동 시 하위 메뉴가 함께 이동하지 않는 문제 해결
- ✨ updateChildrenMenuSrlRecursive 재귀 함수 추가
### v1.0.1 (2025-11-25)
- 🐛 skin/mskin 파라미터 이름 충돌 문제 해결
- ✨ 스킨 저장 시 is_skin_fix 설정 추가
- ✨ 사이트 기본 스킨 정보 표시
### v1.0.0 (2025-11-14) - 초기 릴리즈
- 🎉 MenuPro 첫 출시
- ✨ React 기반 드래그 앤 드롭
- ✨ 사이트맵 간 메뉴 이동
- ✨ 일괄 저장 시스템
- ✨ 메뉴 검색 기능
---
## 로드맵: 다음 업데이트 계획
### v1.1.0 (예정)
- [ ] 메뉴 복사/붙여넣기 강화
- [ ] 메뉴 템플릿 기능 (자주 쓰는 구조 저장)
- [ ] 메뉴 일괄 편집 기능
### v1.2.0 (예정)
- [ ] 권한 설정 UI 개선
- [ ] 메뉴 아이콘 라이브러리
- [ ] 드래그 앤 드롭 애니메이션 개선
### v2.0.0 (장기)
- [ ] 다중 사이트 지원
- [ ] 메뉴 변경 이력 관리
- [ ] 메뉴 롤백 기능
---
## FAQ
### Q1. 기존 메뉴 데이터가 손실되나요?
**A.** 아니요. MenuPro는 Rhymix 기본 메뉴 테이블을 그대로 사용합니다. 데이터 마이그레이션이 필요 없으며, 언제든 기본 메뉴 관리로 돌아갈 수 있습니다.
### Q2. 기존 메뉴 관리와 함께 사용할 수 있나요?
**A.** 네, 가능합니다. MenuPro와 기본 메뉴 관리를 혼용해도 문제없습니다.
### Q3. 성능은 어떤가요? 메뉴가 많으면 느리지 않나요?
**A.** 메뉴 1000개까지 테스트했으며, 쾌적하게 동작합니다. React의 Virtual DOM과 효율적인 렌더링으로 빠른 성능을 보장합니다.
### Q4. 모바일에서도 사용할 수 있나요?
**A.** 현재는 데스크톱 브라우저 최적화되어 있습니다. 모바일 대응은 v1.1.0에서 추가 예정입니다.
### Q5. 라이선스는 어떻게 되나요?
**A.** 유료 라이선스입니다.
### Q6. 버그를 발견했어요. 어디에 제보하나요?
**A.** GitHub Issues 또는 EOND 포럼(https://eond.com)에 제보해주세요.
---
## 사용자 후기 (테스트 사용자)
> "100개 넘는 메뉴를 관리하는 게 이렇게 쉬울 줄 몰랐습니다. 드래그 앤 드롭 하나로 모든 게 해결되네요."
> — K사 웹마스터
> "사이트맵 간 이동이 정말 편합니다. 기존엔 일일이 복사했는데, 이제 드래그 한 번이면 끝!"
> — 커뮤니티 관리자 L
> "검색 기능이 생각보다 훨씬 유용합니다. 메뉴가 많아도 바로 찾을 수 있어요."
> — 포털 운영자 P
---
## 결론
MenuPro는 단순한 도구가 아닙니다.
**Rhymix 사이트맵 관리의 패러다임을 바꾸는 혁신**입니다.
### MenuPro가 제공하는 가치
✅ **생산성**: 작업 시간 6배 단축
✅ **편의성**: 직관적인 드래그 앤 드롭
✅ **안정성**: 일괄 저장으로 실수 방지
✅ **확장성**: 대규모 사이트도 문제없음
✅ **현대성**: 최신 기술 스택
### 지금 바로 시작하세요
더 이상 번거로운 메뉴 관리로 시간을 낭비하지 마세요.
MenuPro로 10분 만에 끝낼 수 있습니다.
**문의**: eond@eond.com
---
**작성일**: 2025-12-03
**카테고리**: Rhymix, 모듈, 관리도구
**태그**: #MenuPro #Rhymix #사이트맵 #React #드래그앤드롭 #관리도구
**버전**: MenuPro v1.0.7
이온디
7년 전
라이믹스는 XE의 브랜치 CMS입니다.
1) 라이믹스 공식홈페이지
http://rhymix.org
http://rhymix.org" style="height: 324px;">http://rhymix.org
2) 라이믹스 소개(제작:람보)
https://youtu.be/_s9PxraL9-c
https://youtu.be/_s9PxraL9-c" style="height: 249px;">https://youtu.be/_s9PxraL9-c
3) 라이믹스 깃허브
https://github.com…
라이믹스는 XE의 브랜치 CMS입니다.
1) 라이믹스 공식홈페이지
http://rhymix.org
http://rhymix.org" style="height: 324px;">http://rhymix.org
2) 라이믹스 소개(제작:람보)
https://youtu.be/_s9PxraL9-c
https://youtu.be/_s9PxraL9-c" style="height: 249px;">https://youtu.be/_s9PxraL9-c
3) 라이믹스 깃허브
https://github.com/rhymix/rhymix
https://github.com/rhymix/rhymix" style="height: 349px;">https://github.com/rhymix/rhymix
