Gutenberg InnerBlocks ile Harika Bir WordPress Düzenleme Deneyimi Yaratın ve Zamandan Kazanın

Yayınlanan: 2023-02-12

Kendinizi Tekrar Etmeyin

Geliştiriciler için tembellik bir erdem olabilir. İyi yapılmış, yeniden kullanılabilir bir bileşen zamandan tasarruf sağlar ve verimli yeniden kullanım ve tutarlılık sağlar. Tutarlılık, bir web sitesini günlük olarak kullananlar için aşinalık ve bilgi sağladığından, bu, WordPress'te düzenleme deneyimleri oluşturmaya uygundur.

WordPress, artık basitçe "Editör" olarak bilinen Gutenberg blok düzenleyicisinin piyasaya sürülmesiyle çok ses getirdi. İçerik düzenleme, taslak oluşturma ve yayınlama için eski WYSIWYG'lerden çok daha iyi, mükemmel bir deneyim sağlar. Bir geliştirici olarak müşterilerim için en iyi düzenleme deneyimini sağlamak istiyorum, temel işlevlerden yararlanmak istiyorum ve tekerleği yeniden icat etmek istemiyorum. Neyse ki, WordPress tüm bunları özel bloklarla yapmamıza izin veriyor.

InnerBlocks'a girin

InnerBlocks, WordPress düzenleyicisinde harika bir özelliktir. Geliştiriciler, bir müşteri için tutarlı bir deneyim oluşturmak üzere paragraf, başlıklar ve düğmeler gibi temel blokları kullanabilir. Müşteri, metin bölümlerini yeniden yazmak ve alanları yeniden ilan etmek yerine aşina oldukları bir deneyim elde eder; aynı blokları düzenleme ve birleştirme. Bir müşteri için oluşturmamız gerekebilecek bir bloğa bir göz atalım ve InnerBlocks'un bunu başarmamıza nasıl yardımcı olabileceğini görelim.

InnerBlocks ile Blok Oluşturma

Başlık, paragraf ve düğme bağlantıları içeren örnek bir Harekete Geçirici Mesaj Bloğu
Şekil: örnek bir Harekete Geçirici Mesaj Bloğu. Buna bir başlık, paragraf ve bazı düğme bağlantıları dahildir.

Bu bloğu inceleyelim ve onu nasıl inşa edebileceğimizi düşünelim. Blok oluştururken ulaştığımız yaygın bir araç, Gelişmiş Özel Alanlardır (ACF). ACF Pro, geliştiricilerin düzenleyici ve kullanıcı arabirimi için PHP'de bloklar yazmasına izin veren özel blok desteği ekler. Ayrıca, birçok WordPress geliştiricisinin aşina olduğu bir paradigma olan özel alanları kullanmamıza izin verir. ACF, InnerBlocks'u destekler, yani özel bir blok oluşturabiliriz, ancak o başlık, paragraf veya düğmeler için özel kod yazmamıza bile gerek kalmaz.

ACF Blokları ile, bu blokta gördüğümüz tüm metinler için harika bir düzenleme deneyimi oluşturmak üzere çekirdek bloklardan yararlanabiliriz. Başka bir potansiyel seçenek blok kalıplarını kullanmak olabilir, ancak harika bir WordPress deneyiminin geliştiricileri ve küratörleri olarak, özel bir blok oluşturmak istenen hedefe ulaşır.

Blok Kayıt Kodu

İşte özel ACF bloğumuzu kaydetme kodu. acf_register_block_type işlevini kullanma hakkında daha fazlasını buradan okuyun.

 <?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. ), ) ); } );

Kodu parçalayalım. Bloğumuzu kaydetmek için acf_register_block_type işlevini kullanıyoruz ve bloğumuzu tanımlayan ve işlevselliği açıp kapatan bir dizi argüman geçiriyoruz.

  • Bloğumuza benzersiz bir ad, okunabilir bir başlık ve açıklama eklemek için önerilen prosedürü takip ettiğimize dikkat edin. Daha sonra blok için PHP şablonumuzu kuracağımız bir işleme şablonuna işaret ediyoruz. Blok Yerleştiricide bloğumuzun gruplanmasını istediğimiz bir kategori de ekledik.
  • Bloğun yerleştiricide aranmasını kolaylaştırmak için aranabilir anahtar kelimelerimiz var.
  • Bir HTML çapası ayarlama gibi işlevleri etkinleştirmek için bir 'destek' dizisi ekledik ve bu blok her zaman sayfanın ortasında duracağı için hizalamayı kapattık.
  • Destek dizisi, InnerBlocks büyüsünü açtığımız yerdir! 'jsx'in true olarak ayarlanması ACF'ye bloğumuzun içinde React jsx şablon oluşturmayı destekleyeceğimizi söyler.

Bloğumuzda ihtiyacımız olan içeriği inceleyelim:

  • başlık
  • paragraf metni
  • Harekete geçmek için düğmeler!

Şimdi, normalde burada belirtildiği gibi alanları bloğumuza atardık. Ancak bu durumda, buna ihtiyacımız yok - tüm bunları başarmak için çekirdek bloklardan yararlanabiliriz. Örneğin, bloğun bir görüntü arka planına ihtiyacı varsa, bloğa bir ACF görüntü alanı eklemek bunu başarmanın harika bir yolu olabilir. Şimdilik InnerBlocks örneğimize bağlı kalalım ve şablona geçelim.

Blok Şablonu

İşte yeni bloğun şablonu. Blok kaydını blok şablonu konumuna yönlendirdiğinizden emin olun. Yaygın bir uygulama, bunları temadaki kısmi bir klasöre koymaktır.

 <?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>

Bu kodu parçalayalım.

  • Başlangıçta, ACF'nin blok rehberliğinde sağladığı, örneğin bir bağlantı ve özel sınıf adı için destek gibi genel bir blok şablonu şablonumuz var.
  • InnerBlocks bileşeni özellikleri alabilir. Bu şablonda üç tane kullanıyoruz.
    • İzin Verilen Bloklar: Düzenlemek için bir dizi izin verilen blok ekliyoruz. Yalnızca bu bloklar, özel bloğumuzun InnerBlocks alanında seçim için mevcut olacaktır.
    • Şablon: Bir blok dizisi iletebiliriz ve blokların editöre ilk yüklendiklerinde başlamaları için blok niteliklerini iletebiliriz.
      • Kullanıcılarımızı başarıya hazırlamak için blok özelliklerini iletebileceğimize dikkat edin. Başlık zaten 2. seviyeye ayarlanmıştır ve paragraf ortalanmıştır.
      • Not: Çekirdek bloklara JavaScript'te her zaman {eklenti}/blok adı olarak atıfta bulunulacaktır. Bizim durumumuzda çekirdek blokları kullanıyoruz, ancak özel bir ACF bloğu kullanmak isteseydiniz, blok adının önüne 'acf' yazardınız. Unutmayın, InnerBlocks kullanırken, bu bileşeni React kullanan WordPress Düzenleyiciye aktarıyoruz. Bu yüzden burada JS'de düşünüyoruz.
      • Başka bir not: çekirdek/düğme bloğunun InnerBlocks'u kullandığına dikkat edin! Aslında içinde iki çekirdek/düğme bloğu dizisinden geçiyoruz!
    • Şablon Kilitleme: templateLock, InnerBlocks bileşeninde ayarlanır. Bunu 'all' olarak ayarlarsak, şablonumuzda InnerBlocks'a sağlanan blokların hiçbiri taşınamaz veya kaldırılamaz. Bunu 'insert' olarak ayarlarsak, içindeki bloklar sadece hareket ettirilebilir, hiçbir blok kaldırılamaz ve yeni blok eklenemez. Bunu 'false' olarak ayarlarsak, InnerBlocks örneğinin kilidi açılır ve herhangi bir ana şablon kilidinden bağımsız olarak kilidi açılır (bununla ilgili daha fazla bilgi aşağıda). WordPress Blok Düzenleyici El Kitabında Blok Şablonları hakkında daha fazla bilgi edinin. Blok kilitleme hakkında daha fazla konuşacağız.

Yeni bir bloğumuz var! Tüm bunlardan ve biraz stilden sonra, elbette, örnek blok düzenleyicide şöyle görünür:

Başlık bloğunun seçili olduğu Harekete Geçirici Mesaj Bloğu.
Şekil: Düzenleyicideki Harekete Geçirici Mesaj Bloğu. Başlık bloğu seçilir.

Daha Derin Yerleştirme: Yuvalanmış InnerBlocks ile Deneyimi Daha da İyileştirme

Harika bir bloğumuz var ve bir WYSIWYG kurmamız, hatta şablonumuzda özel alanları işlememiz gerekmedi. Peki ya bu deneyimi müşteri için daha da ileriye götürmek ve ince ayar yapmak istersek? Diyelim ki başlığın her zaman mevcut olmasını sağlamamız için bir talep aldık, yani her zaman bir başlık bloğu var, ancak sonraki içerik esnektir ve hatta bir liste veya başka türde bir blok içerebilir. Amacımız, tutarlılığı korurken bu esnekliği elde etmektir.

InnerBlocks ile çalışırken bazı kuralları ele alalım:

  • Tek bir bloğun içinde yalnızca bir InnerBlock örneği olabilir.
  • InnerBlocks içindeki çoklu bloklar, kendi InnerBlocks bileşenlerini kullanabilir.
  • InnerBlocks, templateLock özelliği aracılığıyla kilitlenebilir, ancak iç içe geçmiş bir blok yapısı içinde daha derin olan InnerBlocks örneklerinin kilidi, templateLock false olarak ayarlanarak tekrar açılabilir.

Çözümlerden biri, InnerBlocks için sarmalayıcı görevi gören yeni bir blok oluşturmaktır. Bu bloğu ana blok şablonumuza dahil eder ve kilitleriz, ancak 'templateLock' öğesini false olarak ayarlayarak sarmalayıcı bloğumuzun kilidini açık bir şekilde açarız. Ayrıca, bloğumuz için bir ebeveyn ayarlayarak, bu özel sarmalayıcı bloğun yalnızca seçtiğimiz ebeveyn blok içinde mevcut olduğundan emin olmak isteyebiliriz. Bu alandaki birden fazla blok türünün editörlere listeler ve daha fazlasını sunmasına izin verirken, ana Harekete Geçirici Mesaj bloğunda yalnızca başlık, düğmeler ve sarmalayıcı bloğumuza izin verebiliriz.

Bireysel Blok Kilitleme

WordPress 5.9'daki yeni bir özellik, tek tek blokları bir şablonda kilitleme yeteneğidir. Bu, esnek ama tutarlı sorunumuza başka bir olası çözümdür.

Bazı bağımsız bloklar kilitliyken şablonumuz şöyle görünür:

 <?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>

Başlık ve düğme blokları artık taşınamaz veya kaldırılamaz. Şablon değişikliklerini almak için düzenleyiciyi yenilediğinizden, bloğu kaldırdığınızdan ve ardından tekrar eklediğinizden emin olun.

Bonus: Aynı Bloğu Yerel Olarak Oluşturmak

Yerinde bir oluşturma süreciniz olduğunda, React ile yerel WordPress blokları oluşturmak şaşırtıcı derecede kolaydır ve php'de bir blok şablon oluşturmaktan çok da farklı değildir. Bir blok geliştirme ortamı kurmak bu makalenin kapsamı dışındadır, ancak başlamanıza yardımcı olacak WordPress Blok Düzenleyici El Kitabı gibi bir dizi kaynak vardır. Özel blokları ekleyebildiğinizde, InnerBlocks kullanarak hızlı bir şekilde bloklar oluşturabilirsiniz.

İşte React'teki Harekete Geçirici Mesaj bloğumuz index.js'ye bir örnek. ACF'nin burada uygulandığı yukarıda tartıştığımız aynı stratejiyi göreceksiniz.

 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> ); }, });

Devam et ve inşa et!

Ek kaynaklar

  • Bill Erickson'ın InnerBlocks hakkındaki makalesi
  • Bill Erickson'ın Block Editor'daki makaleleri
  • ACF Blokları Kılavuzu
  • ACF Kayıt Blok Tipi Dokümantasyonu
  • WordPress Blok Düzenleyici El Kitabı
  • WordPress Block Editor El Kitabı: Bir Blok Eğitimi Oluşturun