Search

블록 메이커

블록 메이커는 Beta(베타) 기능이에요!
Beta 기간에는 사용된 문법의 하위 호환이 보장되지 않아요.
Beta 기간에 개발된 블록들의 경우 추후 문법 변경에 의해서 수정이 요청될 수 있어요.

기본 개념

사용자

웹사이트

에디터를 통해서 제작된 사이트이며, 방문자(및 구매자)가 사이트를 방문하여 컨텐츠를 보거나 상품을 구매해요.
웹사이트는 쇼핑 기능이 없는 ‘홈페이지’와 쇼핑 기능을 포함하는 ‘쇼핑몰’ 모두를 포함해요.

에디터

웹사이트를 제작하기 위한 툴이에요.
사용자는 에디터를 활용하여 사이트와 페이지를 구성 및 디자인하고 발행(공개)해요.
사용자는 에디터로 블록을 웹사이트에 삽입하고 설정할 수 있어요.
웹사이트를 제작하는 과정에서 프리뷰(Preview)를 통해 발행하기 전에 미리 구성과 디자인을 확인할 수 있어요.

블록

에디터를 통해 웹사이트의 페이지에 삽입하여 페이지를 구성할 수 있는 디자인 단위에요.
블록은 하나의 행(Row)를 모두 차지하게 삽입될 수도 있고, 하나의 행 내의 열(Column)에 삽입될 수도 있어요.
하나의 블록은 에디터를 통해서 여러 페이지의 여러 위치에 삽입될 수 있고 각 삽입 위치에서 별도로 디자인 설정될 수 있어요.

블록 메이커

블록을 제작하는 툴이에요.
블록 메이커를 통해 제작된 블록에디터에서 활용하여 웹사이트를 구성할 때 사용될 수 있어요.

세팅 빌더

블록의 컨텐츠나 동작, 디자인을 사용자에디터를 통해서 직접 설정할 수 있는 패널을 제작하는 툴이에요.
특정 블록을 선택하여 나오는 코드 수정 창에서 [세팅 빌더] 탭을 눌러서 사용할 수 있어요.

“안녕 블록 메이커!” — 기본 문법 소개

<style> h1 { color: red; font-size: 24px; } </style> <template> <h1>안녕 블록 메이커!</h1> <ul> <li>제목 색상: red</li> <li>제목 사이즈: 24px</li> </ul> <button>설명 보기</button> </template> <script> const container = bm.container; const context = bm.context; function clicked(e) { e.preventDefault(); if (e.target.matches('button')) { alert(`제목 색상은 red이고 사이즈는 24px 이에요!`); } } container.addEventListener('click', clicked, true); </script>
HTML
복사
블록을 만들기 위해서는 HTML/CSS/JavaScript에 대한 기본적인 지식이 필요해요!
간단한 블록을 만들기 위해서는 HTML/CSS 정도로도 구현이 가능하지만, 동작 복잡도가 있는 블록을 만들기 위해서는 기본적인 HTML/CSS/JavaScript 지식이 필요해요.
예시 코드는 빨간색의 “안녕 블록 메이커” 텍스트를 포함하는 <h1> 태그를 그리고 <button>을 클릭 시 설명을 출력하는 블록의 예시에요.

기본 블록 문법 설명

하나의 블록은 하나의 코드 파일로 구성돼요.
하나의 블록은 크게 3개의 최상위 HTML 태그인 <style> , <template> , <script> 태그로 구성될 수 있고, 태그별로 하나만 최상위 태그로 가질 수 있어요.
<style>: 구현하려는 블록의 Style(CSS)을 입력할 수 있어요.
<template>: 구현하려는 블록의 기본적인 템플릿(HTML)을 입력할 수 있어요.
<script>: 구현하려는 블록의 JavaScript 코드를 입력할 수 있어요.

{{property.myHelloPhrase}} 블록 메이커!“ — 사용자가 설정할 수 있는 블록 만들기

{ "property": { "myHelloPhrase": "🖐🏻", "myColor": "blue", "myFontSize": 36, } }
JavaScript
복사
세팅 빌더를 통해 정의된 설정들(property)과 각 설정의 값들을 포함한 컨텍스트(Context) 객체 예시
<style> h1 { color: {{property.myColor}}; font-size: {{property.myFontSize}}px; } </style> <template> <h1>{{property.myHelloPhrase}} 블록 메이커!</h1> <ul> <li>제목 색상: {{property.myColor}}</li> <li>제목 사이즈: {{property.myFontSize}}px</li> </ul> <button>설명 보기</button> </template> <script> const container = bm.container; const context = bm.context; function clicked(e) { e.preventDefault(); if (e.target.matches('button')) { const myColor = context.property.myColor; const myFontSize = context.property.myFontSize; alert(`제목 색상은 ${myColor}이고 사이즈는 ${myFontSize}px 이에요!`); } } container.addEventListener('click', clicked, true); </script>
HTML
복사
이제 사용자는 <h1> 의 색상과 글자 크기를 설정할 수 있고, “안녕”이라는 문구를 고쳐 쓸 수 있어요.

갑자기 주어진 상황!

블록을 제작하는 중에 블록의 사용자가 <h1> 태그 내 “색상, 글자 크기나 컨텐츠 일부를 직접 수정할 수 있도록 지원”해달라는 요청이 왔어요.
사용자는 아쉽게도 코드를 직접 수정하지 못하는 분이어서, 컨텐츠와 디자인을 바꾸고 싶을 때마다 항상 코드 수정을 위해 연락이 와요.

사용자가 설정할 수 있는 블록

블록 메이커는 사용자가 코드 변경 없이도 블록을 설정(커스터마이징)해 직접 블록의 컨텐츠와 디자인, 동작을 설정할 수 있도록 기능적으로 지원하고 있어요.
1.
세팅 빌더를 통해 블록에서 지원하려는 설정 가능한(커스터마이징 가능한) 값들(변수명, 타입, …)을 정의.
2.
설정값들을 블록 코드상에서 컨텍스트(Context)를 통해 접근하고 사용하도록 지원.
3.
사용자에디터에서 웹사이트 제작 시 블록을 페이지에 삽입하고 입맛에 맞게 설정!

컨텍스트(Context)

컨텍스트(Context)는 블록의 UI를 그리거나 블록 동작에 참고 및 활용할 수 있는 데이터를 담고 있는 일종의 JSON 객체(Object)에요.
블록을 만드는 과정에서 세팅 빌더를 통해서 정의한 설정과 설정의 값(디폴트 값 혹은 사용자가 설정한 값)들이 컨텍스트 객체 내 property 라는 객체 내에 키와 값이 전달돼요.
세팅 빌더와 컨텍스트 객체 내 property 를 활용하여 블록을 제작하면, 한 번 제작한 블록에서 코드 수정 없이도 사용자가 UI나 동작을 에디터에서 설정할 수 있도록 블록을 제작할 수 있어요.
컨텍스트 객체는 <style> , <template> , <script> 모든 태그 내에서 접근해 활용할 수 있어요.
<style>: Handlebars.js 문법을 통해서 컨텍스트 객체에 접근할 수 있어요.
<template>: Handlebars.js 문법을 통해서 컨텍스트 객체에 접근할 수 있어요.
<script>: bm.context를 통해서 컨텍스트 객체에 접근할 수 있어요.
Handlebars.js 문법이 어려워 보이는데 혹시 다 알아야 할까요?
사용자가 설정한 값을 HTML/CSS에서 단순히 읽어서 사용하시는 경우에는 모든 문법을 자세히 알 필요 없이 property 값에 접근하기 위한 {{property.*}} 문법만 기억해도 괜찮아요!

<style> 태그

<style> h1 { color: red; /* Handlebars.js 문법으로 컨텍스트 객체 내 property 값에 접근 */ font-size: {{property.myFontSize}}px; } </style>
HTML
복사
CSS 및 Handlebars.js 로 작성된 스타일 예시
블록에 적용될 CSS 코드를 입력할 수 있어요.
입력된 CSS 코드는 웹사이트에 삽입된 각 블록 별로 격리되어 적용돼요.
일반적인 CSS 문법과 다르게 추가로 Handlebars.js 문법을 지원해요.
Handlebars.js 문법으로 컨텍스트(Context) 값에 접근해서 동적인 디자인 구성에 활용할 수 있어요.
컨텍스트(Context) 값으로 동적인 디자인을 구성하지 않는다면, Handlebars.js 문법 없이 기본적인 CSS 코드만 입력하여 사용해도 괜찮아요.
기본 HTML 디자인이 이상해요!
블록 메이커를 통해 제작되는 블록들은 다양한 기기에서 여러 테마에 적용되어도 최대한 동일한 블록 UI를 제공할 수 있도록 브라우저에서 기본 적용되는 디폴트 CSS 스타일이 대부분 초기화(Reset)되어 있어요.

<template> 태그

<template> <h1>Hello Block Maker!</h1> <!-- Handlebars.js 문법으로 컨텍스트 객체 내 property 값에 접근 --> <p>{{property.myDescription}}</p> </template>
HTML
복사
HTML 및 Handlebars.js 로 작성된 템플릿 예시
<!-- 블록 컨테이너(Block Container) 영역 --> <div> <!-- 템플릿의 HTML은 블록 컨테이너 안에 그려져요. --> <h1>Hello Block Maker!</h1> <p>블록 메이커에 대한 설명이에요.</p> </div>
HTML
복사
작성된 템플릿이 웹사이트에 그려진 예시
블록의 기본이 되는 HTML 템플릿을 입력할 수 있어요.
작성한 HTML 템플릿은 자동으로 블록 컨테이너 내에 그려(Render)져요.
일반적인 HTML 문법과 다르게 추가로 Handlebars.js 문법을 지원해요.
Handlebars.js 문법으로 컨텍스트(Context) 값에 접근해서 동적인 HTML 구성에 활용할 수 있어요.
컨텍스트(Context) 값으로 동적인 HTML을 구성하지 않는다면, Handlebars.js 문법 없이 기본적인 HTML 코드만 입력하여 사용해도 괜찮아요.

블록 컨테이너

입력한 블록 템플릿을 감싸고 내부에 실제로 그리게 되는 HTML DOM 컨테이너에요.
블록 컨테이너는 하나의 블록당 1개만 존재하고, 작성한 HTML 템플릿의 부모(Parent) 컨테이너로 볼 수 있어요.
<script> 태그 내에서 bm.container 문법을 통해서 블록 컨테이너의 DOM 객체에 접근하여 활용할 수 있어요.

<script> 태그

<script> 태그 사용 시 주의 사항
Beta(베타) 기간에는 <script> 태그의 문법적 제약이 거의 없지만, 추후 특정 문법을 사용하는 경우 제약될 수 있어요.
외부 라이브러리(jQuery 등)를 사용하는 경우 공통 코드를 설정하여 <script> 태그 내에서 활용할 수 있지만, 꼭 필요한 경우가 아니라면 사이트의 속도 저하의 원인이 될 수 있으니 순수 JavaScript(Vanilla JavaScript) 사용을 지향해요.
<script> const container = bm.container; const context = bm.context; container.addEventListener('click', e => { e.preventDefault(); if (e.target.matches('h1')) { // <h1> 태그를 클릭시 사용자가 에디터에 설정한 메세지를 출력 alert(context.property.myAlertMessage); } }, true); </script>
HTML
복사
블록에서 접근 가능한 bm 변수와 스크립트 예시
<script> 태그 내에 JavaScript 코드를 작성해서 블록의 동작을 제어할 수 있어요.
작성한 <script> 코드는 <template><style> 이 그려진 뒤에 실행돼요.
그 외 <script> 태그 내 문법 패턴에 대한 내용은 <script> 태그 사용 — Good vs. Bad 내용도 함께 참고해 주세요.

bm

<script> 태그 내에서 bm 이라는 변수에 접근할 수 있고, bm 을 통해 해당 블록과 관련된 정보에 접근할 수 있어요.
bm 변수는 웹사이트에 삽입된 블록별로 격리되어 있어요.

bm.context

컨텍스트(Context) 객체에 접근해 블록의 기능이나 UI 구성에 활용할 수 있어요.
<script> 태그에서 컨텍스트(Context) 객체를 활용한 블록 제작 시에는 bm.onContextChange에디터 내 프리뷰(Preview) 지원 내용을 함께 참고해 주세요.

bm.container

블록 컨테이너의 DOM 객체에요.
일반적으로 DOM 이벤트(마우스 클릭 등)를 걸거나 블록 컨테이너 내 HTML을 찾는(Query) 용도로 사용해요.

bm.onContextChange

컨텍스트(Context) 객체의 변화가 생긴 경우 실행되는 콜백 함수를 정의할 수 있는 공간이에요.
bm.onContextChange 문법의 특이 사항
현재에는 제작하시게 되는 블록의 <script> 태그에서 컨텍스트(Context) 객체를 활용한 경우에 에디터 내 프리뷰(Preview) 지원을 자연스럽게 하는 경우에만 사용돼요.
bm.onContextChange 문법은 추후 다른 상황의 컨텍스트(Context) 변화 감지 시에도 실행되게 스펙이 확장될 예정이에요.

<script> 태그 사용 — Good vs. Bad

<!-- Good --> <script> // bm, bm.context 와 별도로 필요한 변수를 관리하고 사용 let myCounter = 0; bm.container.addEventListener('click', e => { e.preventDefault(); myCounter = myCounter + 1; }); </script> <!-- Bad --> <script> // bm.context에 변수를 할당하고 사용 bm.context.myCounter = 0; bm.container.addEventListener('click', e => { e.preventDefault(); bm.context.myCounter = bm.context.myCounter + 1; }); </script>
HTML
복사
bmbm.context 객체 내부의 값을 JavaScript 코드를 통해 직접 수정하지 말아 주세요.
추후bm 혹은 bm.context 를 코드에서 더 활용할 수 있는 문법을 추가 제공할 예정이어서, bm 혹은 bm.context 를 직접 수정하면 추후 예기치 않은 사이드 이펙트가 발생할 수 있어요.
<!-- Good --> <script> bm.container.innerHTML = '<h1>안녕하세요!</h1>'; // 블록 컨테이너에 DOM 이벤트를 위임하고 분기 bm.container.addEventListener('click', e => { e.preventDefault(); if (e.target.matches('h1')) { alert('<h1> 태그가 클릭되었어요.'); } }, true); // 1초 뒤 <h1> 태그를 새로 생성 setTimeout(() => { bm.container.innerHTML = '<h1>☺️클릭하면 창이 떠요!</h1>'; }, 1000); </script> <!-- Bad --> <script> bm.container.innerHTML = '<h1>안녕하세요!</h1>'; // 블록 컨테이너에 그려진 HTML 요소에 직접 DOM 이벤트를 바인딩 const h1 = bm.container.querySelector('h1'); h1.addEventListener('click', e => { e.preventDefault(); alert('<h1> 태그가 클릭되었어요.'); }); // 1초 뒤 <h1> 태그를 새로 생성 setTimeout(() => { bm.container.innerHTML = '<h1>😢클릭해도 창이 안떠요...</h1>'; }, 1000); </script>
HTML
복사
UI 클릭 등 DOM에 이벤트를 거는(Binding) 경우, 상위 컨테이너인 블록 컨테이너(bm.container)에 이벤트를 걸고 콜백 함수(Callback)에서 분기 처리하는 패턴이 좋아요.
블록 컨테이너 내부의 HTML 구조나 내용물이 바뀌는 상황에도 DOM 이벤트를 다시 걸어줄 필요가 없어요.
제작하는 블록에서 <script> 태그를 활용해 UI를 동적으로 수정하는 경우에도 상위 컨테이너인 블록 컨테이너를 활용하는 방식이 사이드 이펙트가 덜 발생해요.
에디터 내 프리뷰(Preview) 지원 시 자연스러운 동작에 도움이 돼요.

에디터 내 프리뷰(Preview) 지원

<style> h1 { /* 사용자가 블록의 설정 값(property.myColor)을 에디터에서 변경하면 프리뷰에 자동 반영돼요. */ color: {{property.myColor}}; } </style> <template> <!-- 사용자가 블록의 설정 값(property.myHelloPhrase)을 에디터에서 변경하면 프리뷰에 자동 반영돼요. --> <h1>{{property.myHelloPhrase}} 블록 메이커!</h1> <p></p> </template> <script> const container = bm.container; const context = bm.context; const p = container.querySelector('p'); // 처음 한 번은 반영되지만, 사용자가 블록의 설정 값(property.myContents)을 에디터에서 변경해도 자동 반영되지 않아요. p.innerHTML = context.property.myContents; </script>
HTML
복사
사용자가 설정할 수 있는 블록은 사용자가 에디터에서 블록을 삽입한 뒤, 블록이 정의한 설정 값(컨텍스트(Context) 객체의 property)들을 패널을 통해서 설정하는 과정을 거치게 돼요.
사용자가 에디터에서 블록을 설정하게 되면, 사용자는 설정한 값들이 블록에 바로 반영되어 프리뷰에 나오기를 기대해요.

에디터 프리뷰 내 태그별 특징

<template> 태그와 <style> 태그에서 사용 중인 컨텍스트(Context) 객체의 property 값들은 에디터에서 자동으로 변경을 감지하고 반영하여 에디터 프리뷰에서 바로 확인할 수 있어요.
<script> 태그도 <template> , <style> 태그와 동일하게 제일 처음에는 <script> 태그가 동작하면서 프리뷰에 반영돼요.
다만 <script> 태그는 <template> , <style> 태그와는 다르게, 별도의 문법 처리를 해주지 않으면 사용자가 블록의 설정값을 변경하였을 때 자동으로 프리뷰에 반영하지 않아요.
자세한 내용은 <script> 태그에서 프리뷰 지원하기 내용을 함께 참고해 주세요.
... <script> const container = bm.container; const context = bm.context; const p = container.querySelector('p'); // 최초 실행시 설정 값(property.myContents)을 반영 p.innerHTML = context.property.myContents; // 이후 사용자가 블록의 설정 값(property.myContents)을 변경한 경우 반영 처리 bm.onContextChange = () => { const p = container.querySelector('p'); p.innerHTML = context.property.myContents; }; </script>
HTML
복사

<script> 태그에서 프리뷰 지원하기

사용자가 블록이 정의한 설정 값(컨텍스트(Context) 객체의 property)들을 설정하여 property 값에 변화가 생기면, 블록 메이커는 컨텍스트(Context) 객체에 변화가 생겼다고 판단하고 bm.onContextChange에 정의한 함수를 실행해요.
bm.onContextChange에 콜백(Callback) 함수를 정의하고, property 값의 변화가 발생한 경우 블록의 UI와 동작에 반영하는 코드를 작성하면 프리뷰에서도 잘 반영되는 블록을 제작할 수 있어요.
bm.onContextChange 문법의 특이 사항
현재에는 제작하시게 되는 블록의 <script> 태그에서 컨텍스트(Context) 객체를 활용한 경우에 에디터 내 프리뷰(Preview) 지원을 자연스럽게 하는 경우에만 사용돼요.
bm.onContextChange 문법은 추후 다른 상황의 컨텍스트(Context) 변화 감지 시에도 실행되게 스펙이 확장될 예정이에요.

Handlebars.js 문법

<style>, <template> 태그에서는 일반적인 HTML/CSS와 다르게 Handlebars.js 문법 일부를 지원해요.
Handlebars.js 문법을 활용하면 <style>, <template> 태그 내에서 {{…}} 문법으로 컨텍스트(Context) 객체의 값에 접근하고 활용해서 사용자가 설정할 수 있는 블록을 제작할 수 있어요.
단순히 컨텍스트(Context) 객체에 접근하는 것뿐만 아니라, <style>, <template> 태그 내에서 간단한 로직을 구성할 수도 있어요.
{{property.mySetting}} {{property.myNested.mySetting}}
HTML
복사

{{…}} 문법

{{…}} 문법을 통해서 컨텍스트(Context) 객체의 값에 접근할 수 있어요.
. 으로 구분해서 중첩(Nested)된 값들에 접근할 수 있어요.
<style> {{#if property.showWelcome}} p { color: green; } {{/if}} </style> <template> {{#if property.showWelcome}} <p>만나서 반가워요!</p> {{else}} <p>인사는 생략할게요...</p> {{/if}} </template>
HTML
복사

{{#if}} {{else}} 문법 (+{{#unless}})

{{#if}} {{else}} 구문으로 아주 간단한 분기 처리를 할 수 있어요.
{{#if}} 가 있으면 {{/if}} 로 항상 닫혀야 해요.
{{else}} 구문은 필요한 경우에만 중간에 끼워서 사용할 수 있어요.
{{#if}} 구문에서는 falseundefinednull""0[] 값들은 모두 거짓 값(Falsy)으로 취급돼요.
아직은 {{#if}} 구문에서 비교 연산자(동일성 비교, 부등호 비교 등)를 지원하지 않고 있어요.
{{#if}} 와 비슷하지만 논리 연산이 반대인 문법으로 {{#unless}} 도 있어요.