[워드프레스] 23. 블록 : 구텐베르크 블록의 구조 이해하기

워드프레스 해부 23편 - 구텐베르크 블록의 구조 이해하기

작성자

카테고리:

* 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

(워드프레스 해부 ㉓) 블록

지금 이 글도 블록으로 만들어졌다. 문단 하나, 코드 하나, 이미지 하나가 다 블록이다. 구텐베르크(블록 편집기)의 콘텐츠는 결국 블록 마크업으로 저장된다. 그 구조를 열어보자.

블록은 HTML 주석으로 감싸인다. <!-- wp:paragraph --> 처럼. 이 주석 안에 블록 종류와 속성(JSON)이 담기고, 그 아래 실제 HTML이 온다. 즉 저장된 글은 블록 주석 + HTML의 반복이다. 참고로 이 시리즈 글들을 나는 전부 이 블록 마크업을 직접 만들어 REST로 올렸다.

<!-- wp:paragraph -->
<p>이건 문단 블록이다.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">이건 제목 블록(속성 level:3)</h3>
<!-- /wp:heading -->

직접 해보기

# 저장된 글의 블록 구조를 눈으로 보기 (raw 콘텐츠)
$ wp post get 123 --field=content
# → <!-- wp:paragraph --> ... 블록 주석이 그대로 보인다

✅ 확인 — 아무 글이나 wp post get [ID] --field=content로 원본을 보면, 겉보기엔 평범한 글이 사실 <!-- wp:... --> 주석으로 구조화돼 있는 게 보인다. 이게 블록 편집기가 콘텐츠를 다루는 방식이다.

block.json — 블록의 신분증

블록 하나는 block.json으로 자신을 소개한다. 이름·속성·에디터 스크립트·렌더 방식이 전부 여기 담긴다. 워드프레스 7.0부터는 apiVersion 3이 기준인데, 이건 편집기가 iframe 안에서 돌 때 블록 스타일이 제대로 격리되도록 보장한다.

{
  "apiVersion": 3,
  "name": "cozlab/notice",
  "title": "안내 박스",
  "category": "widgets",
  "attributes": { "message": { "type": "string" } },
  "editorScript": "file:./index.js",
  "render": "file:./render.php"
}

edit와 save — 블록의 두 얼굴

정적 블록은 자바스크립트로 edit와 save 두 함수를 정의한다. edit는 편집 화면에서 보이는 모습이고, save는 글에 실제로 저장되는 HTML이다. 앞에서 본 블록 주석 아래의 마크업이 바로 이 save가 만든 결과물이다.

정적 블록 vs 동적 블록

저장 방식에서 둘이 갈린다. 정적 블록은 save()가 만든 HTML을 글에 그대로 박아둔다. 문단·이미지처럼 한 번 쓰면 바뀌지 않는 건 이걸로 충분하다. 동적 블록은 save를 비우고 속성만 저장한 뒤, 프런트에서 render.php(또는 render_callback)가 매번 PHP로 그려낸다. ‘최근 글 5개’처럼 볼 때마다 최신이어야 하는 건 동적이어야 한다.

정적 블록동적 블록
저장되는 것완성된 HTML속성(설정값)만
렌더 시점저장된 그대로매 요청 시 PHP로
예문단·이미지·버튼최근 글·조회수·목록

최소 블록 한 벌 — 등록부터 화면까지

개념을 이었으니 실제로 도는 최소 블록 한 벌을 보자. 알림 상자 블록이라 치면, 파일 두 개면 된다.

// block.json — 신분증
{ "apiVersion": 3, "name": "cozlab/notice", "title": "알림 상자",
  "category": "text", "editorScript": "file:./index.js" }

// index.js — 편집 화면과 저장 결과
registerBlockType( 'cozlab/notice', {
    edit: () => <div className="notice">
        <RichText tagName="p" ... /></div>,   // 편집기에서 보일 모습
    save: ( { attributes } ) => <div className="notice">
        <RichText.Content value={ attributes.text } /></div>,
} );

// PHP 쪽 등록은 한 줄 — block.json을 가리키기만 한다
register_block_type( __DIR__ . '/build' );

이걸 활성화하면 ① 삽입기에 ‘알림 상자’가 뜨고 ② 삽입해 글을 저장하면 본문에 <!-- wp:cozlab/notice --><div class="notice">…</div><!-- /wp:cozlab/notice -->가 박히고 ③ 프런트에 그 HTML이 그대로 나온다 — 맨 위에서 뜯어본 ‘블록 주석 + HTML’ 구조가 내 블록으로 재현되는 것이다. 실무에선 JSX 빌드가 필요하니 아래 스캐폴딩으로 시작하는 게 편하다.

블록 만들기 — 손으로 짜지 말고 스캐폴딩

이 파일들을 처음부터 손으로 만들 필요는 없다. 공식 도구가 뼈대를 통째로 만들어준다. 명령 한 줄이면 block.json, edit/save, 빌드 설정까지 갖춘 폴더가 생기고, 거기서 내용만 채우면 된다.

npx @wordpress/create-block cozlab-notice

정리하면 블록은 ‘block.json이 소개하고, edit가 편집 화면을, save나 render.php가 최종 출력을 맡는’ 구조다. 숏코드가 하던 ‘동적 조각 심기’를, 블록은 시각적 편집과 함께 현대적으로 해내는 셈이다.

블록을 이해했으니, 다음은 관리자 화면에 내 설정 페이지를 붙이는 Settings API다.

자주 묻는 질문 (FAQ)

구텐베르크 블록은 어떻게 이루어지나요?

block.json으로 메타데이터를 정의하고, edit(편집 화면)·save(저장 결과) 또는 서버 렌더로 구성됩니다.

정적 블록과 동적 블록은 뭐가 다른가요?

정적 블록은 저장된 HTML을 그대로 쓰고, 동적 블록은 렌더 시점에 PHP로 매번 생성합니다(예: 최신 글 목록).

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다