본문으로 건너뛰기

HtmlEditor

이 컨트롤은 무엇인가요?

HtmlEditorTinyMCE를 감싼 syn.uicontrols 컨트롤로, 게시판 본문이나 공지사항처럼 "서식 있는 문서(WYSIWYG)"를 편집할 때 사용합니다. 화면에 <syn_htmleditor> 태그를 배치하면 컨트롤이 초기화되면서 다음과 같은 일이 일어납니다.

  1. 원래 배치했던 엘리먼트는 id="<원래id>_hidden"으로 이름이 바뀌고 화면에서 숨겨집니다(display: none). 이 엘리먼트에는 옵션 값(JSON)만 보관됩니다. 이때 원래 엘리먼트 안에 적어둔 HTML(태그 내부 콘텐츠)이 에디터의 초기 값으로 사용됩니다.
  2. 같은 부모 아래 원래 id를 그대로 물려받은 새 <div>가 만들어지고, 그 안에 TinyMCE 에디터(tinymce.init(setting))가 렌더링됩니다.
  3. TinyMCE 엔진 자체(/lib/tinymce/tinymce.min.js)는 페이지에서 최초 1회만 비동기로 로드되며, 로드가 끝나기 전에 여러 개의 <syn_htmleditor>가 있으면 내부 대기열(editorPendings)에 쌓였다가 로드 완료 후 순서대로 초기화됩니다.
  4. syn-optionsrepositoryID를 지정하면, 에디터에 이미지를 붙여넣거나 드래그&드롭할 때 자동으로 파일 서버(fileManagerServer)에 업로드하고, 업로드된 이미지의 실제 경로로 <img> 태그를 교체해 줍니다.

SourceEditor(코드 편집)와의 차이

구분HtmlEditor ($htmleditor)SourceEditor ($sourceeditor)
기반 엔진TinyMCEMonaco Editor (VS Code 편집 엔진)
편집 대상서식 있는 문서(HTML 리치 텍스트) — 굵게, 표, 이미지 삽입 등소스 코드/구조화된 텍스트 — JavaScript, JSON, SQL, HTML 등
결과물HTML 마크업 문자열언어 문법에 맞는 순수 텍스트(소스 코드) 문자열
대표 기능툴바(굵게/이미지/표), 이미지 업로드(repositoryID + fileManagerServer)문법 강조(syntax highlight), 줄 번호, 미니맵, 코드 접기
용도 예게시판 본문, 이메일 템플릿, 공지사항스크립트/쿼리 편집, 설정 JSON 편집, 로그/코드 뷰어

즉, "사람이 읽는 문서를 예쁘게 꾸미고 이미지를 첨부하는 것"이 목적이면 HtmlEditor를, "코드나 JSON처럼 문법이 있는 텍스트를 정확하게 편집하는 것"이 목적이면 SourceEditor를 사용합니다.

언제 사용하나요?

  • 게시판/공지사항 본문, 이메일 템플릿처럼 굵게/색상/표/이미지 등 서식이 필요한 긴 문서를 사용자가 직접 작성하게 할 때
  • 문서 안에 이미지를 붙여넣거나 드래그&드롭으로 첨부해야 하고, 그 이미지를 파일 저장소(리포지토리)에 실제로 업로드해야 할 때
  • 단순한 여러 줄 텍스트(메모 등)만 필요하다면 TextArea를, 소스 코드/JSON처럼 문법이 있는 텍스트를 편집해야 한다면 SourceEditor를 대신 검토하세요.

빠른 시작

  1. 페이지에 <syn_htmleditor> 태그를 배치하고 id, syn-datafield, syn-options 속성을 지정합니다. 태그의 크기는 stylewidth/height로 지정합니다.
<syn_htmleditor id="edtComment" syn-datafield="Comment" style="width:100%; height:300px" syn-options="{
repositoryID: 'BDLLE01', controlText: '메모', belongID: ['MD01'],
plugins: ['autolink link image lists print hr anchor pagebreak searchreplace visualblocks visualchars code insertdatetime media nonbreaking table preview powerpaste advcode help'],
toolbar: 'styleselect | bold forecolor backcolor table | alignleft aligncenter alignright | pagebreak link image | preview code help',
resize: false
}"></syn_htmleditor>
  1. 페이지 하단에 syn.loader.js 스크립트 한 줄만 추가하면, 로더가 필요한 CSS/JS(HtmlEditor.js, HtmlEditor.css, TinyMCE 엔진)를 자동으로 주입하고 컨트롤을 초기화합니다.
<script src="/js/syn.loader.js"></script>
  1. 값을 읽거나 설정할 때는 페이지 스크립트에서 syn.uicontrols.$htmleditor를 사용합니다.
// 현재 값(HTML 문자열) 조회
var html = syn.uicontrols.$htmleditor.getValue('edtComment');

// 값 설정
syn.uicontrols.$htmleditor.setValue('edtComment', '<p>안녕하세요</p>');

// 값 초기화
syn.uicontrols.$htmleditor.clear('edtComment');

TinyMCE는 비동기로 로드/초기화됩니다. 페이지 로드 직후 곧바로 getValue/setValue를 호출하기보다는, 버튼 클릭 등 사용자 이벤트 시점에 호출하거나 {elID}_documentReady 이벤트(아래 API.md 참고)가 발생한 뒤에 호출하는 것이 안전합니다.

repositoryID를 지정하지 않으면 이미지 업로드 기능이 비활성화됩니다(붙여넣은 이미지는 data: URL 형태로 문서 안에 그대로 포함됩니다).

예제 실행하기

이 폴더의 example 디렉토리에 초보자용 실행 예제가 있습니다. 웹 서버를 통해 /uicontrols/HtmlEditor/example/*.html 경로로 접속해서 바로 확인할 수 있습니다.

  • basic.html: 기본(default) 옵션 그대로 에디터를 배치하고 getValue/setValue/clear 버튼으로 값을 다루는 가장 단순한 예제
  • custom-toolbar.html: plugins/toolbar 옵션을 직접 지정해 툴바를 목적에 맞게 구성하는 예제(실무 예시와 동일하게 표/미리보기/도움말 등을 추가)
  • events.html: {elID}_documentReady, {elID}_imageResized 같은 컨트롤 고유 이벤트와 isDirty/getValue/setValue/clear를 함께 보여주는 예제

각 예제는 <script src="/js/syn.loader.js"></script> 한 줄만으로 동작하도록 만들어졌습니다.

더 알아보기

  • 전체 옵션(Options), 메서드, 이벤트 목록은 같은 폴더의 아래 API 참조 섹션 문서를 참고하세요.
  • 실제 소스 코드는 HtmlEditor.js, HtmlEditor.css 파일에서 확인할 수 있습니다.
  • syn-options에 지정한 값은 TinyMCE의 tinymce.init(setting)에 그대로 전달되므로, API.md에 표로 정리한 옵션 외에도 TinyMCE 공식 설정 옵션을 함께 사용할 수 있습니다.

실전 예제 페이지

/uicontrols/HtmlEditor/example/ 경로의 예제를 아래 iframe에서 바로 확인할 수 있습니다.

basic.html

custom-toolbar.html

events.html

소스와 로드 파일

항목내용
컨트롤HtmlEditor
전역 별칭syn.uicontrols.$htmleditor
버전v2026.2.25
소스uicontrols/HtmlEditor/HtmlEditor.js
스타일uicontrols/HtmlEditor/HtmlEditor.css

API 참조

syn.uicontrols.$htmleditor

마크업

<syn_htmleditor id="edtComment" syn-datafield="Comment" style="width:100%; height:300px" syn-options="{
repositoryID: 'BDLLE01', controlText: '메모', belongID: ['MD01'],
plugins: ['autolink link image lists print hr anchor pagebreak searchreplace visualblocks visualchars code insertdatetime media nonbreaking table preview powerpaste advcode help'],
toolbar: 'styleselect | bold forecolor backcolor table | alignleft aligncenter alignright | pagebreak link image | preview code help',
resize: false
}"></syn_htmleditor>
  • 태그 이름 syn_htmleditorsyn.loader.jsSYN_ 접두사를 인식해 htmleditor 타입 컨트롤로 매핑하는 규칙을 따릅니다(HtmlEditor.js/HtmlEditor.css 및 TinyMCE 엔진을 자동 로드).
  • stylewidth/height가 에디터 컨테이너의 크기가 됩니다(지정하지 않으면 기본 320×240).
  • 태그 내부에 적어둔 HTML(자식 엘리먼트/텍스트)은 에디터의 초기 콘텐츠로 그대로 사용됩니다.
  • syn-options : JSON 형식의 문자열로 옵션(defaultSetting)을 덮어씁니다. 이 값은 그대로 tinymce.init(setting)에 전달되므로, 아래 표에 없는 TinyMCE 옵션도 함께 사용할 수 있습니다.
  • 컨트롤이 초기화되면 원래 태그는 id="<원래id>_hidden"으로 숨겨지고, 같은 id를 가진 새 <div>가 만들어져 그 안에 TinyMCE 에디터가 렌더링됩니다. 이후 getValue/setValue 등 API는 원래 지정했던 id를 그대로 사용합니다.

Options (defaultSetting)

HtmlEditor.jsdefaultSetting에 정의된 값입니다. syn-options 속성으로 필요한 값만 덮어써서 사용합니다.

옵션기본값설명
repositoryIDnull이미지 업로드를 저장할 파일 저장소(리포지토리) 식별자. 지정해야 에디터 안에서 이미지 붙여넣기/업로드가 동작합니다(자세한 내용은 아래 "참고" 참고).
dependencyIDnull업로드된 이미지들을 묶어 관리하는 임시 그룹 식별자. 지정하지 않으면 isNumberTempDependency에 따라 자동 생성됩니다.
isNumberTempDependencytruedependencyID를 지정하지 않았을 때, 현재 시각 틱(tick) 값으로 임시 발급(true)할지, $fileclient.getTemporaryDependencyID로 발급(false)할지 결정합니다.
fileManagerServer''이미지 업로드/조회 요청을 보낼 파일 서버 주소. 비어 있으면 syn.Config.FileManagerServer 값을 사용합니다.
fileManagerPath'/repository/api/storage'파일 서버 API 경로.
pageUploadFile'upload-file'이미지 업로드 요청 액션 이름.
pageActionHandler'action-handler'업로드된 파일 조회/의존관계 변경 등에 사용하는 액션 핸들러 이름.
imageFileSizeLimit6291456(6MB)에디터에 삽입 가능한 이미지 최대 크기(byte). 초과 시 알림창을 띄우고 업로드를 취소합니다.
images_file_types'jpeg,jpg,png,gif,bmp,webp,...'업로드 허용 이미지 확장자.
paste_data_imagestrue클립보드에서 이미지를 붙여넣기(data URL)로 허용할지 여부.
plugins['autolink link image lists print hr anchor pagebreak searchreplace visualblocks visualchars code insertdatetime media nonbreaking table paste help']TinyMCE 플러그인 목록.
toolbar`'styleselect \bold italic forecolor backcolor table \
menubarfalse상단 메뉴바(파일/편집/보기 등) 표시 여부.
height300에디터 높이(값이 없을 때 기본값). 실제로는 태그의 style.height가 우선 적용됩니다.
resizefalse사용자가 에디터 하단을 드래그해 크기를 조절할 수 있게 할지 여부.
language'ko_KR'TinyMCE UI 언어. 컨트롤이 한국어 번역 리소스를 내장하고 있습니다.
content_style본문 폰트를 'Noto Sans KR' 등으로 지정하는 CSS 문자열에디터 iframe 내부(본문 영역)에 적용할 스타일.
defaultHtmlContentnull지정하면 초기화 시 태그 내부 콘텐츠 대신 이 HTML을 초기 값으로 사용합니다.
verify_htmlfalseTinyMCE의 HTML 검증(스키마 필터링) 사용 여부.
table_default_attributes객체 설정표 삽입 시 기본 속성.
table_default_styles객체 설정표 삽입 시 기본 스타일.
table_sizing_mode'fixed'표 크기 조정 모드.
table_responsive_widthfalse표 너비를 반응형(%)으로 둘지 여부.
limitTableWidthnull지정하면 getValue() 호출 시, width 속성이 없는 <table>에 이 값을 강제로 채워 넣습니다.
limitGuideLineWidth''지정하면 편집 영역에 세로 가이드라인(빨간 선)을 그려 이 폭을 넘는지 시각적으로 표시합니다.
allowExternalLinkfalsereadonly이면서 이 옵션이 true이면 문서 내 iframe(임베드된 외부 콘텐츠)을 선택 가능한 상태로 표시합니다.
prefixHtml / suffixHtml''getValue() 결과 앞/뒤에 항상 붙일 고정 HTML. setValue() 호출 시에는 값에 이 문자열이 포함돼 있으면 자동으로 제거하고 반영합니다.
powerpaste_word_import / powerpaste_googledocs_import'merge'Word/Google 문서에서 붙여넣을 때 서식 처리 방식(PowerPaste 플러그인 사용 시).
deprecation_warningsfalseTinyMCE 사용 중단 경고를 콘솔에 출력할지 여부.
dataType'string'값의 데이터 타입 표기.
belongIDnull소속 그룹/컨테이너 식별자.
getter / setterfalse값 조회/설정 시 커스텀 훅 사용 여부(프레임워크 공통 옵션).
controlTextnull컨트롤에 표시할 라벨/보조 텍스트.
validatorsnull유효성 검증 설정.
transactConfig / triggerConfignull데이터 송수신(트랜잭션)/트리거 동작 관련 설정.

위 표에 없더라도 TinyMCE가 지원하는 생성 옵션(예: statusbar, branding, readonly, placeholder 등)은 syn-options에 그대로 추가해 사용할 수 있습니다. syn-options로 전달한 값이 tinymce.init(setting)setting 그 자체이기 때문입니다.

메서드

syn.uicontrols.$htmleditor.<메서드명>(...) 형태로 호출합니다.

메서드매개변수반환값설명
getValueelID, metastring에디터의 현재 HTML 값을 반환합니다. limitTableWidth/prefixHtml/suffixHtml 옵션이 있으면 결과에 자동 반영됩니다.
setValueelID, value, meta없음에디터의 HTML 값을 설정합니다. 에디터가 아직 초기화되지 않았다면 값을 태그에 임시 보관해 두었다가 초기화 완료 시점에 자동으로 반영합니다.
clearelID, isControlLoad없음에디터 내용을 빈 문자열로 초기화합니다.
isDirtyelIDboolean사용자가 초기 값 이후로 내용을 수정했는지 여부(TinyMCE editor.isDirty()).
setModeelID, mode없음에디터 모드를 전환합니다. mode'design'(편집 가능) 또는 'readonly'(읽기 전용).
insertContentelID, content없음현재 커서 위치에 HTML 조각을 삽입합니다.
execCommandelID, command, uiState, value, argsbooleanTinyMCE 명령을 실행합니다(예: 'bold', 'backColor'). TinyMCE 명령 목록 참고.
getHtmlEditorelID`object \null`
getHtmlSettingelID`object \null`
getDependencyIDelIDstring현재 이미지 업로드에 사용 중인 임시 dependencyID 값을 반환합니다.
setDependencyIDelID, dependencyID없음dependencyID 값을 변경합니다(주로 신규 저장 후 실제 키 값으로 교체할 때 사용).
updateDependencyIDelID, targetDependencyID, callback없음임시 dependencyID로 업로드된 파일들을, 저장이 끝난 뒤 실제 레코드 식별자(targetDependencyID)로 옮겨 연결합니다(서버의 UpdateDependencyID 액션 호출). 신규 등록 폼에서 임시로 이미지를 올려두었다가, 저장 성공 후 실제 PK로 소속을 변경할 때 사용합니다.
resizeImagefile, maxSizePromise업로드 전 이미지를 캔버스로 리사이즈합니다(내부적으로 images_upload_handler가 사용). maxSize가 0 이하이면 600px 기준으로 축소합니다.
controlLoadelID, setting없음컨트롤 초기화 진입점입니다. syn 프레임워크가 페이지 로드 시 자동으로 호출하며, 직접 호출할 필요는 없습니다.
setLocaleelID, translations, control, options없음다국어 텍스트 적용 훅입니다. 현재 구현은 빈 함수(별도 동작 없음)입니다.

⚠️ 참고용 메서드 — 현재 구현에 알려진 제약(버그)이 있음

getEditorSetting(elID)는 대기열(editorPendings)에서 아직 초기화되지 않은 컨트롤의 설정을 조회하려는 용도로 보이지만, 대기열에 항목을 넣을 때는 elID 속성명으로 저장하면서({ elID: elID, setting, intervalID }) 조회 시에는 item.id(존재하지 않는 속성)와 비교합니다. 따라서 이 메서드는 항상 null을 반환합니다. 직접 호출할 필요는 없으며(프레임워크 내부에서도 사용되지 않음), 초기화된 컨트롤의 설정이 필요하면 getHtmlSetting(elID)을 사용하세요.

이벤트

HtmlEditor는 다른 syn.uicontrols 컨트롤처럼 태그에 syn-events 속성을 선언하는 방식이 아니라, 페이지 스크립트의 event 객체에 정해진 이름의 함수를 선언해 두면 프레임워크가 자동으로 찾아서 호출하는 방식입니다. syn-events 속성은 필요 없습니다.

이벤트(함수명 규칙)매개변수발생 시점
{elID}_documentReady(elID, editor)에디터 초기화가 끝나고 초기 값 반영까지 마친 직후 1회 호출됩니다. getValue/setValue를 안전하게 호출할 수 있는 시점을 알기 위한 용도로 사용하세요.
{elID}_beforeUploadImageResize(elID, file, callback)이미지 업로드 직전, 기본 리사이즈 로직(resizeImage) 대신 커스텀 리사이즈를 적용하고 싶을 때 정의합니다. 정의돼 있으면 기본 리사이즈 대신 이 함수가 호출되며, 처리 후 callback({ blob, width, height })를 호출해 업로드를 이어가야 합니다. 정의하지 않으면 기본 리사이즈(최대 600px)가 적용됩니다.
{elID}_imageResized(elID, evt, editor, selectedImage)사용자가 에디터 안에서 이미지 크기를 드래그로 조절한 직후(TinyMCE ObjectResized) 호출됩니다. evt.width/evt.height를 검사해 원하는 최대 크기로 강제 조정하는 등의 용도로 사용합니다.
let $myPage = {
event: {
edtComment_documentReady(elID, editor) {
syn.$l.eventLog('edtComment_documentReady', elID);
},

edtComment_imageResized(elID, evt, editor, selectedImage) {
if (evt.width > 600) {
var ratio = evt.width / evt.height;
evt.width = 600;
evt.height = parseFloat(evt.width / ratio);
editor.dom.setStyle(selectedImage, 'width', evt.width);
editor.dom.setStyle(selectedImage, 'height', evt.height);
selectedImage.setAttribute('width', evt.width);
selectedImage.setAttribute('height', evt.height);
}
}
}
}

TinyMCE 자체의 다른 이벤트(예: 내용 변경 감지)가 필요하면 getHtmlEditor(elID)로 얻은 인스턴스에 TinyMCE 공식 이벤트 API를 직접 등록하세요.

var editor = syn.uicontrols.$htmleditor.getHtmlEditor('edtComment');
if (editor) {
editor.on('change', function () {
syn.$l.eventLog('edtComment_change', editor.getContent());
});
}

참고

  • 실제 구현 파일: HtmlEditor.js, HtmlEditor.css
  • 내부적으로 TinyMCE를 사용하며, 엔진 스크립트(/lib/tinymce/tinymce.min.js)는 페이지에서 최초 1회만 비동기로 로드됩니다. TinyMCE가 아직 로드되지 않은 상태에서 여러 <syn_htmleditor>가 배치돼 있으면, 로드가 끝날 때까지 내부 대기열(editorPendings)에 쌓였다가 순서대로 초기화됩니다.
  • 이미지 업로드와 repositoryID의 관계: syn-optionsrepositoryID를 지정하면, 컨트롤이 TinyMCE의 images_upload_handler를 자동으로 구성합니다. 사용자가 이미지를 붙여넣거나 드래그&드롭하면 다음 순서로 처리됩니다.
    1. 이미지 크기가 imageFileSizeLimit(기본 6MB)을 넘으면 업로드를 취소하고 알림을 띄웁니다.
    2. {elID}_beforeUploadImageResize 이벤트가 정의돼 있으면 그 함수로, 아니면 기본 resizeImage(최대 600px)로 이미지를 축소합니다.
    3. fileManagerServer + fileManagerPath(/repository/api/storage) + pageUploadFile(upload-file)로 RepositoryID/DependencyID와 함께 업로드합니다. DependencyIDdependencyID 옵션 값이며, 지정하지 않으면 자동으로 임시 값이 발급됩니다(isNumberTempDependency).
    4. 업로드 성공 후 서버에 파일의 실제 경로를 다시 조회(pageActionHandlerGetItem 액션)해서 <img src>를 그 경로로 교체합니다.
    5. repositoryID를 지정하지 않으면 이미지 업로드 핸들러 자체가 등록되지 않아, 붙여넣은 이미지는 브라우저 로컬 data: URL 형태로 문서 안에 그대로 포함됩니다(서버에 저장되지 않음).
    • 신규 등록 화면처럼 저장 전에는 실제 레코드 식별자가 없어 임시 dependencyID로 이미지를 올려두고, 저장이 성공한 뒤에는 updateDependencyID(elID, targetDependencyID, callback)을 호출해 실제 레코드 식별자로 파일 소속을 옮기는 패턴을 사용합니다.
  • getEditorSetting 메서드는 현재 소스 기준으로 항상 null을 반환하는 알려진 버그가 있습니다. 초기화된 컨트롤의 설정 조회에는 getHtmlSetting(elID)을 사용하세요.