Gutenberg InnerBlocks로 훌륭한 WordPress 편집 경험을 만들고 시간을 절약하십시오

게시 됨: 2023-02-12

자신을 반복하지 마십시오

개발자에게 게으름은 미덕이 될 수 있습니다. 잘 만들어진 재사용 가능한 구성 요소는 시간을 절약하고 효율적인 재사용 및 일관성을 허용합니다. 일관성은 일상적으로 웹 사이트를 사용하는 사람들에게 친숙함과 지식을 낳기 때문에 WordPress에서 편집 경험을 만드는 데 적합합니다.

WordPress는 이제 단순히 "The Editor"로 알려진 Gutenberg 블록 편집기의 출시로 많은 소음을 냈습니다. 콘텐츠 편집, 초안 작성 및 게시의 경우 이전 WYSIWYG보다 훨씬 우수한 탁월한 경험을 제공합니다. 개발자로서 저는 고객에게 최고의 편집 경험을 제공하고 핵심 기능을 활용하고 싶고 바퀴를 재발명하고 싶지 않습니다. 운 좋게도 WordPress를 사용하면 사용자 지정 블록으로 이러한 모든 작업을 수행할 수 있습니다.

InnerBlocks 입력

InnerBlocks는 WordPress 편집기의 훌륭한 기능입니다. 개발자는 단락, 머리글 및 버튼과 같은 핵심 블록을 사용하여 클라이언트를 위한 일관된 경험을 만들 수 있습니다. 텍스트 섹션을 다시 작성하고 필드를 다시 선언하는 대신 클라이언트는 익숙해지는 경험을 얻습니다. 동일한 블록 편집 및 결합. 클라이언트를 위해 구축해야 할 수 있는 블록을 살펴보고 InnerBlocks가 이를 달성하는 데 어떻게 도움이 되는지 알아봅시다.

InnerBlocks로 블록 만들기

헤드라인, 단락 및 버튼 링크가 있는 클릭 유도 문안 블록의 예
그림: Call to Action 블록의 예. 여기에는 헤드라인, 단락 및 일부 버튼 링크가 포함됩니다.

이 블록을 살펴보고 어떻게 만들 수 있는지 생각해 봅시다. 블록을 만들 때 사용하는 일반적인 도구는 ACF(Advanced Custom Fields)입니다. ACF Pro는 사용자 정의 블록 지원을 추가하여 개발자가 편집기 및 프런트 엔드용 PHP에서 블록을 작성할 수 있도록 합니다. 또한 많은 WordPress 개발자에게 친숙한 패러다임인 사용자 지정 필드를 사용할 수 있습니다. ACF는 InnerBlocks를 지원합니다. 즉, 사용자 지정 블록을 만들 수 있지만 해당 제목, 단락 또는 버튼에 대한 사용자 지정 코드를 작성할 필요조차 없습니다.

ACF 블록을 사용하면 코어 블록을 활용하여 이 블록에 표시되는 모든 텍스트에 대해 훌륭한 편집 환경을 만들 수 있습니다. 또 다른 가능한 옵션은 블록 패턴을 사용하는 것이지만 환상적인 WordPress 경험의 개발자 및 큐레이터로서 사용자 지정 블록을 생성하면 원하는 목표를 달성할 수 있습니다.

블록 등록 코드

다음은 사용자 지정 ACF 블록을 등록하는 코드입니다. acf_register_block_type 기능 사용에 대한 자세한 내용은 여기를 참조하세요.

 <?php /** * Template for registering an ACF powered custom block. * * More info: https://www.advancedcustomfields.com/resources/blocks/ */ /** * Register the block. */ add_action( 'acf/init', function() { /** * ACF block registration options here: https://www.advancedcustomfields.com/resources/acf_register_block_type/ */ acf_register_block_type( array( 'name' => 'call-to-action-demo', // JS will register as: acf/{block-name}. 'title' => __( 'Call to Action ACF Demo', 'locale' ), 'description' => __( 'A custom ACF Call to Action block.', 'locale' ), 'render_template' => 'partials/blocks/call-to-action-demo.php', // Change to block template. 'category' => 'design', // Category in the block inserter. 'keywords' => array( 'action', 'buttons', 'cta' ), // Searchable keywords. 'supports' => array( 'align' => false, // Disable support for align. 'anchor' => true, // Enable support for anchor. 'jsx' => true, // Enable support for JSX. 'mode' => false, // Disable ACF block edit/preview mode switching as we are only using InnerBlocks for editable content. ), ) ); } );

코드를 분해해 봅시다. 우리는 acf_register_block_type 함수를 사용하여 블록을 등록하고 블록을 정의하고 기능을 켜고 끄는 인수 배열을 전달하고 있습니다.

  • 사람이 읽을 수 있는 제목 및 설명뿐만 아니라 블록에 고유한 이름을 추가하는 권장 절차를 따르고 있습니다. 나중에 블록에 대한 PHP 템플릿을 설정할 렌더 템플릿을 가리킵니다. 또한 블록 삽입기에서 블록을 그룹화하려는 범주를 추가했습니다.
  • 삽입기에서 블록을 더 쉽게 검색할 수 있도록 검색 가능한 키워드가 있습니다.
  • HTML 앵커 설정과 같은 기능을 활성화하기 위해 'supports' 배열을 추가하고 이 블록이 항상 페이지 중앙에 위치하므로 정렬을 해제했습니다.
  • 배열을 지원하는 곳에서 InnerBlocks 마법을 켭니다! 'jsx'를 true로 설정하면 블록 내에서 React jsx 템플릿 렌더링을 지원할 것임을 ACF에 알립니다.

블록에 필요한 콘텐츠를 검토해 보겠습니다.

  • 표제
  • 단락 텍스트
  • 조치를 취하기 위한 버튼!

이제 일반적으로 여기에 설명된 대로 블록에 필드를 할당합니다. 하지만 이 경우에는 그럴 필요가 없습니다. 핵심 블록을 활용하여 이 모든 것을 달성할 수 있습니다. 예를 들어 블록에 이미지 배경이 필요한 경우 ACF 이미지 필드를 블록에 추가하는 것이 이를 달성하는 좋은 방법이 될 수 있습니다. 하지만 지금은 InnerBlocks 예제에 충실하고 템플릿으로 이동하겠습니다.

블록 템플릿

다음은 새 블록의 템플릿입니다. 블록 등록이 블록 템플릿 위치를 가리키도록 하십시오. 일반적인 방법은 이를 테마의 부분 폴더에 넣는 것입니다.

 <?php /** * ACF Call to Action example block template. * * More info: https://www.advancedcustomfields.com/resources/acf_register_block_type/ * * @param array $block The block settings and attributes. * @param string $content The block inner HTML (empty). * @param bool $is_preview True during AJAX preview. * @param (int|string) $post_id The post ID this block is saved to. * */ // Create id attribute allowing for custom "anchor" value. $block_ . $block['id']; if ( ! empty( $block['anchor'] ) ) { $block_id = $block['anchor']; } // Create class attribute allowing for custom "className" and "align" values. $class_name = 'acf-call-to-action-demo'; if ( ! empty( $block['className'] ) ) { $class_name .= ' ' . $block['className']; } if ( ! empty( $block['align'] ) ) { $class_name .= ' align' . $block['align']; } ?> <div class="<?php echo esc_html( $class_name ); ?>"> <div class="cta__inner"> <?php // Set up innerBlocks and provide a template. // Restrict InnerBlocks to allowed block list. $allowed_blocks = array( 'core/heading', 'core/paragraph', 'core/buttons' ); // Start InnerBlocks with a template. $template = array( array( 'core/heading', array( 'placeholder' => __( 'CTA Heading', 'locale' ), 'align' => 'center', 'level' => '2', ), ), array( 'core/paragraph', array( 'placeholder' => __( 'Add CTA text here', 'locale' ), 'align' => 'center', ), ), array( 'core/buttons', array( 'placeholder' => __( 'Add CTA buttons here', 'locale' ), 'align' => 'center', ), array( array( 'core/button', array( 'text' => __( 'Take action', 'locale' ), ), ), array( 'core/button', array( 'text' => __( 'Learn more', 'locale' ), ), ), ), ), ); // Echo out our JSX InnerBlocks compoennt for the editor. echo '<InnerBlocks allowedBlocks="' . esc_attr( wp_json_encode( $allowed_blocks ) ) . '" template="' . esc_attr( wp_json_encode( $template ) ) . '" templateLock="false" />'; ?> </div> </div>

이 코드를 분해해 봅시다.

  • 처음에는 앵커 및 사용자 지정 클래스 이름에 대한 지원과 같은 블록 지침에서 ACF가 제공하는 일반 블록 템플릿 상용구가 있습니다.
  • InnerBlocks 구성 요소는 속성을 받을 수 있습니다. 이 템플릿에서는 3개를 사용하고 있습니다.
    • 허용된 블록: 선별할 허용된 블록 배열을 추가합니다. 이 블록만 사용자 지정 블록의 InnerBlocks 공간 내에서 선택할 수 있습니다.
    • 템플릿: 블록 배열을 전달할 수 있으며 블록이 편집기에 처음 로드될 때 시작할 블록에 대한 블록 특성을 전달할 수 있습니다.
      • 블록 속성을 전달하여 사용자가 성공할 수 있도록 설정할 수 있습니다. 제목에는 이미 수준 2가 설정되어 있고 단락은 가운데에 있습니다.
      • 참고: 핵심 블록은 JavaScript에서 항상 {plugin}/blockname으로 참조됩니다. 우리의 경우 코어 블록을 사용하고 있지만 사용자 지정 ACF 블록을 사용하려면 블록 이름 앞에 'acf'를 씁니다. InnerBlocks를 사용할 때 React를 사용하는 WordPress Editor에 이 구성 요소를 전달한다는 점을 기억하십시오. 이것이 우리가 여기서 JS로 생각하는 이유입니다.
      • 또 다른 참고 사항: 코어/버튼 블록은 InnerBlocks 자체를 사용합니다! 우리는 실제로 내부에 두 개의 코어/버튼 블록 배열을 전달하고 있습니다!
    • 템플릿 잠금: 템플릿 잠금은 InnerBlocks 구성 요소에 설정됩니다. 'all'로 설정하면 InnerBlocks에 제공된 템플릿의 어떤 블록도 이동하거나 제거할 수 없습니다. '삽입'으로 설정하면 내부 블록은 이동만 가능하고 블록을 제거할 수 없으며 새 블록을 추가할 수 없습니다. 'false'로 설정하면 InnerBlocks 인스턴스가 잠금 해제되고 상위 템플릿 잠금에 관계없이 잠금 해제됩니다(자세한 내용은 아래 참조). WordPress 블록 편집기 핸드북에서 블록 템플릿에 대해 자세히 알아보세요. 블록 잠금에 대해 더 이야기하겠습니다.

새로운 블록이 있습니다! 물론 일부 스타일 지정과 함께 예제 블록은 편집기에서 다음과 같이 보입니다.

제목 블록이 선택된 클릭 유도 문안 블록.
그림: 편집기의 Call to Action 블록. 제목 블록이 선택됩니다.

더 깊은 중첩: 중첩된 InnerBlocks로 경험을 더욱 큐레이팅

훌륭한 블록이 있고 WYSIWYG를 설정하거나 템플릿에서 사용자 정의 필드를 처리할 필요가 없었습니다. 하지만 클라이언트를 위해 이 경험을 더욱 선별하고 미세 조정하려면 어떻게 해야 할까요? 제목이 항상 있는지 확인하라는 요청을 받았으므로 항상 제목 블록이 있지만 그 뒤의 내용은 유연하며 목록이나 다른 유형의 블록을 포함할 수도 있습니다. 우리의 목표는 일관성을 유지하면서 유연성을 달성하는 것입니다.

InnerBlocks로 작업할 때 몇 가지 규칙을 고려해 보겠습니다.

  • 단일 블록은 InnerBlock 인스턴스를 하나만 가질 수 있습니다.
  • InnerBlocks 내부의 여러 블록은 자체 InnerBlocks 구성 요소를 사용할 수 있습니다.
  • InnerBlocks는 templateLock 속성을 통해 잠글 수 있지만 중첩된 블록 구조 내 더 깊은 InnerBlocks 인스턴스는 templateLock을 false로 설정하여 다시 잠금 해제할 수 있습니다.

한 가지 해결책은 InnerBlocks의 래퍼 역할을 하는 새 블록을 만드는 것입니다. 부모 블록 템플릿에 해당 블록을 포함하고 잠그지만 'templateLock'을 false로 설정하여 래퍼 블록을 명시적으로 잠금 해제합니다. 또한 이 특수 래퍼 블록이 블록의 부모를 설정하여 선택한 부모 블록 내에서만 사용 가능하도록 할 수도 있습니다. 상위 Call to Action 블록의 제목, 버튼 및 래퍼 블록만 허용하면서 해당 공간 내에서 여러 블록 유형을 허용하여 편집자 목록 등을 제공할 수 있습니다.

개별 블록 잠금

WordPress 5.9의 새로운 기능은 템플릿의 개별 블록을 잠그는 기능입니다. 이것은 우리의 유연하면서도 일관된 문제에 대한 또 다른 가능한 해결책입니다.

일부 개별 블록이 잠겨 있는 템플릿은 다음과 같습니다.

 <?php /** * ACF Call to Action example block template. * * More info: https://www.advancedcustomfields.com/resources/acf_register_block_type/ * * @param array $block The block settings and attributes. * @param string $content The block inner HTML (empty). * @param bool $is_preview True during AJAX preview. * @param (int|string) $post_id The post ID this block is saved to. * */ // Create id attribute allowing for custom "anchor" value. $block_ . $block['id']; if ( ! empty( $block['anchor'] ) ) { $block_id = $block['anchor']; } // Create class attribute allowing for custom "className" and "align" values. $class_name = 'acf-call-to-action-demo'; if ( ! empty( $block['className'] ) ) { $class_name .= ' ' . $block['className']; } if ( ! empty( $block['align'] ) ) { $class_name .= ' align' . $block['align']; } ?> <div class="<?php echo esc_html( $class_name ); ?>"> <div class="cta__inner"> <?php // Set up innerBlocks and provide a template. // Restrict InnerBlocks to allowed block list. $allowed_blocks = array( 'core/heading', 'core/paragraph', 'core/buttons' ); // Start InnerBlocks with a template. $template = array( array( 'core/heading', array( 'placeholder' => __( 'Heading', 'locale' ), 'align' => 'center', 'level' => '2', 'lock' => array( 'move' => true, // Block may nto be moved. 'remove' => true, // Block may not be removed. ), ), ), array( 'core/paragraph', array( 'placeholder' => __( 'Add CTA text here', 'locale' ), 'align' => 'center', ), ), array( 'core/buttons', array( 'placeholder' => __( 'Add CTA buttons here', 'locale' ), 'align' => 'center', 'lock' => array( 'move' => true, // Block may not be moved. 'remove' => true, // Block may not be removed. ), ), array( array( 'core/button', array( 'text' => __( 'Take action', 'locale' ), ), ), array( 'core/button', array( 'text' => __( 'Learn more', 'locale' ), ), ), ), ), ); // Echo out our JSX InnerBlocks compoennt for the editor. echo '<InnerBlocks allowedBlocks="' . esc_attr( wp_json_encode( $allowed_blocks ) ) . '" template="' . esc_attr( wp_json_encode( $template ) ) . '" />'; ?> </div> </div>

제목 및 버튼 블록은 더 이상 이동하거나 제거할 수 없습니다. 편집기를 새로 고치고 블록을 제거한 다음 다시 추가하여 템플릿 변경 사항을 가져오십시오.

보너스: 기본적으로 동일한 블록 만들기

빌드 프로세스가 준비되면 React로 기본 WordPress 블록을 만드는 것은 놀라울 정도로 쉽고 php에서 블록을 템플릿으로 만드는 것과 크게 다르지 않습니다. 블록 개발 환경 설정은 이 문서의 범위를 벗어나지만 WordPress 블록 편집기 핸드북과 같이 시작하는 데 도움이 되는 많은 리소스가 있습니다. 사용자 지정 블록을 포함할 수 있게 되면 InnerBlocks를 사용하여 신속하게 블록을 구축할 수 있습니다.

다음은 React의 Call to Action 블록 index.js의 예입니다. 여기에 적용된 ACF로 위에서 논의한 것과 동일한 전략을 볼 수 있습니다.

 import { __ } from '@wordpress/i18n'; import { registerBlockType } from '@wordpress/blocks'; import { InnerBlocks } from '@wordpress/block-editor'; import { useBlockProps } from '@wordpress/block-editor'; /** * Block Name. * Create an example Call to Action Block * Uses InnerBlocks for editable content within. */ export const blockName = 'call-to-action'; /** * Block Config. * Set basic params for controlling the editor. */ export const BLOCK_CONFIG = { // Set up the block template. CTA_TEMPLATE: [ [ 'core/heading', { placeholder: __('CTA Headline', 'locale'), align: 'center', level: 2, lock: { move: true, remove: true, }, }, ], [ 'core/paragraph', { placeholder: 'Optional CTA text', align: 'center', lock: { move: true, }, }, ], [ 'core/buttons', { lock: { move: true, remove: true, }, className: 'is-content-justification-center', align: 'center', // __experimentalLayout - https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/buttons/block.json layout: { type: 'flex', justifyContent: 'center', }, }, [ [ 'core/button', { text: 'Apply now', lock: { move: true, remove: true, }, }, ], ['core/button', { text: 'Learn more' }], ], ], ], // Set up the allowed blocks. ALLOWED_BLOCKS: ['core/paragraph', 'core/heading', 'core/buttons'], }; // Register the block via WP func. Change 'myplugin' to your plugin or theme. registerBlockType(`myplugin/${blockName}`, { title: __('Call to Action', 'locale'), // Change 'locale' to your locale for internationalization. description: __( 'Call to action block with headline and buttons', 'locale' ), keywords: [__('call'), __('action'), __('cta')], category: 'design', supports: { anchor: true, defaultStylePicker: false, html: false, align: false, }, attributes: { anchor: { type: 'string', default: '', }, }, transforms: {}, variations: [], edit: (props) => { const blockProps = useBlockProps({ className: `wp-block-myplugin-${blockName}`, }); return ( <div {...blockProps}> <div className="cta__inner"> <div className="cta__inner-blocks-wrapper"> <InnerBlocks template={BLOCK_CONFIG.CTA_TEMPLATE} allowedBlocks={BLOCK_CONFIG.ALLOWED_BLOCKS} renderAppender={false} /> </div> </div> </div> ); }, save: () => { return ( <div> <div className="cta__inner"> <InnerBlocks.Content /> </div> </div> ); }, });

나가서 건설하십시오!

추가 리소스

  • InnerBlocks에 대한 Bill Erickson의 기사
  • 블록 편집기에 대한 Bill Erickson의 기사
  • ACF 블록 가이드
  • ACF 레지스터 블록 유형 문서
  • WordPress 블록 편집기 핸드북
  • WordPress 블록 편집기 핸드북: 블록 자습서 만들기