번개장터 CMS (Content Management System)

Caito (이진우)
번개장터 기술 블로그
7 min readFeb 7, 2023

번개장터에서 콘텐츠를 만들고 관리하는 방법에 대해 소개합니다.

안녕하세요.
번개장터에서 FE 개발을 담당 하고있는 Caito 라고 합니다 😎
번개장터에서 현재 사용중인 컨텐츠 관리 도구 (CMS) 와
이것을 만들게 된 과정을 소개하려고 합니다.

CMS 가 왜 필요할까?

개발 리소스 가 너무 많이 들어갔다.

기획팀: 우리 이번에 이런 느낌의 기획전 하나 열어보는게 어때요?
디자인팀: 좋아요! 디자인 시안 전달 해드릴게요!
기획팀: 디자인 너무 멋져요 :) 개발팀에게 얼른 요청드릴게요.

개발팀: 이미 하고있는 일이 많아서 최소 몇일은 걸릴것 같아요 :(

위와 같은 일들이 빈번하게 생기고 있었습니다.

컨텐츠 만 빠르게 만들 수 있다면, 너무 좋을것 같잖아..?

컨텐츠의 핵심 기능은 “신속” 과 “반응” 이라고 생각했었던 저는,
이것저것 찾아보고 조사하기 시작했는데요,

기존에 번개장터에서 간단한 기획전을 만들 수 있게 스프레드 시트와
연동 시켜놓은 도구가 있었습니다.

스프레드 시트에 데이터를 넣으면 기획전이 생성되었다

이미지 , 단순 텍스트, 상품 리스트 3가지만 사용하여 컨텐츠를 만들어야 했기에,
조금 새로운 아이디어는 개발팀의 손길이 항상 필요 했었습니다.

그래서, 저는 새로운 도구를 만들어야겠다고 결심했습니다.

CMS 의 청사진을 그려보자

이미 만들어진 위지윅 에디터 또는 마크다운 에디터를 사용하려 했으나,
요구사항을 모두 구현하려면, 극한의 커스터마이징이 필요했습니다.
또, 무겁고 비효율적 이였습니다.
비효율을 싫어하는 저는, 이럴바엔 우리만의 도구를
처음부터 만들자고 생각했습니다.

일단 CMS 는 개발자들을 위한 도구가 아닌,
개발에 대해 잘 모르는 동료들을 위한 도구이다 보니
동료들의 입장에서 생각하고 개발을 시작하였습니다.

개발지식 없이 사용 가능한 도구를 만들자.

모든 데이터는 CMS 에서 UI 로 조작이 가능하게 만들어야 했습니다.
그리고, 모든 데이터는 메타데이터 형태로 저장하여 최고의 효율을 얻고자 하였습니다.

모든 옵션은 UI 로 편집이 가능하다

이렇게 데이터가 잘 분리되다 보니, 모든 데이터의 Type을 명확하게 지정할 수 있었습니다.

export interface IContentProductListModel {
columnType: IContentProductColumnType;
imageType: IContentProductListImageRatioType;
badgeLabelColor: string;
list?: IProductModel[];
pids?: number[];
backgroundColor: string;
useLocationTime: boolean;
badgeLabels?: string[];
showFilterSelector?: boolean;
exceptedWords: string[];
colorTheme?: IContentThemeType;
}
최종 생성된 상품 리스트 메타데이터

메타데이터만 있으면, 언제든 컨텐츠 생성이 가능하도록 만들고 싶었습니다.

메타데이터를 읽고, 컨텐츠를 랜더링하는 컴포넌트를 만들자

<BunjangContentViewer
osType={os}
headerHeight={50}
pathName={path} />

Path 가 컨텐츠의 Key 이므로, Key 를 기반으로 데이터를 읽어와
컨텐츠를 빌드할 수 있는 컴포넌트를 구성해야 했습니다.

조금 더 넓고 다양하게

단순 텍스트, 이미지, 상품 리스트 만으로는 동료들의 아이디어를 모두 실현할 수는 없었습니다.

그리하여, 현재 필요한 모든 형태의 데이터 타입을 선언하였고,
UI 에서 선택할 수 있게 구현하였습니다.

꽤 많아진 컨텐츠 타입

또한, 컨텐츠를 사용자가 클릭(터치) 하였을때, 다양한 종류의 지정된 콜백이 실행되어야 하였습니다.

컨텐츠 onClick Event 에 할당할 수 있는 액션들

이 부분도 모두 메타데이터의 형태로 지정할 수 있도록 UI 를 구성하였고
onClick Callback 에서 메타데이터를 읽어 적절한 액션이 발동할 수 있게 하였습니다.

function handleContentClick(linkData: IComputedLinkData) {
if (!linkData) return;
// LinkData 를 읽어서 적절한 Action 을 실행하자.
}

마지막으로, 모든 컨텐츠 타입을 랜더링 할 수 있도록 ContentViewer 컴포넌트를 추가로 업그레이드 하였습니다.

또한 ContentViewer 는 완전히 캡슐화 되어, 재귀적으로 랜더 될 수 있게 하였습니다.

ContentViewer (Parent) -> Tabs Component -> ContentViewers (Children) 구조

재귀적 랜더링으로 탭 컴포넌트, 팝업 컴포넌트 를 구현하였습니다.

더 사용하기 쉽게 만들어보자

메타데이터만 봐서는 결과를 볼 수 없었기에 실시간 미리보기 기능을 만들어야 했습니다.

이미 만들어 두었던 ContentViewer 컴포넌트를 재사용 하여, CMS 에 직접 삽입해 간단하게 구현할 수 있었습니다.

왼쪽(메타데이터 뷰) 오른쪽( 컨텐츠 최종)

또한, 비슷한 컨텐츠를 복제하기 쉽게
메타데이터를 내보내고, 불러올 수 있는 기능도 구현하였습니다.

내보내기 된 메타데이터의 일부 모습

결과는 어땠을까?

이제 어디서든 ContentViewer 와 Content Metadata 를 조합하여 컨텐츠를 랜더링 할 수 있게 되었습니다.

  1. 비약적으로 증가한 생산성
    컨텐츠 생성을 기획&디자인 만으로 할 수 있게 되었습니다.
  2. 수정이 쉬워졌다 -> 피드백 수용이 빨라졌다
    컨텐츠 수정이 쉬워짐으로 인해, 다양한 시도를 할 수 있게 되었습니다.
  3. FE 개발팀이 즐거워졌다
    다소 반복작업(?) 이였던 컨텐츠 생성 개발에서 조금 벗어날 수 있게 되었습니다.

마무리

CMS 로 발행한 컨텐츠가 점점 많아지고 있고,
기존 컨텐츠 들도 대체되고 있어 뿌듯합니다.

이정도면 성공적으로 자리잡은 프로젝트가 아닐까 싶습니다 :)

특별한 기술이나 아이디어는 없지만,
동료들과 회사를 위하는 마음 하나로 만들어진 결과물 인데요 :)

유저를 위한 서비스도 중요하지만,
동료들을 위한 서비스도 한번쯤 만들어 보는것은 어떨까요? 😃

--

--