ブログ

基本ブロックを超えて:WordPressの機能を強化するカスタムGutenbergブロックの作成

WordPressブロックエディターの可能性を最大限に引き出すために、独自のカスタムGutenbergブロックの作成方法を学びましょう。このガイドでは、サイトの機能とデザインを拡張するための実践的なステップ、コード例、ベストプラクティスを提供します。

まとめ

WordPressのブロックエディター、Gutenbergは、モジュラーブロックシステムでコンテンツ作成に革命をもたらしました。コアブロックは汎用性を提供しますが、カスタムブロックは独自の機能とブランディングに不可欠です。この記事では、ブロックの登録、属性、レンダリングなどの基本的な概念をカバーしながら、独自のGutenbergブロックを開発するプロセスをガイドします。実践的な例を探り、コードの整理とセキュリティのベストプラクティスについて議論し、カスタムブロックがWordPressのアーキテクチャとフックとどのように統合されるかを強調します。カスタムブロック開発をマスターすることで、WordPressサイトの機能とユーザーエクスペリエンスを大幅に向上させることができます。

基本ブロックを超えて:WordPressの機能を強化するカスタムGutenbergブロックの作成

WordPress 5.0でのGutenbergブロックエディターの登場は、コンテンツの作成と管理の方法に大きな変化をもたらしました。クラシックエディターの線形アプローチから移行し、Gutenbergは「ブロック」と呼ばれる個別のコンポーネントでコンテンツを構築するモジュラーシステムを導入しました。デフォルトのブロックセットは幅広い一般的なニーズをカバーしていますが、多くのウェブサイトでは、すぐに利用できるもの以上の独自の機能、特定のデザイン要素、または統合が必要です。ここでカスタムGutenbergブロック開発が登場し、WordPressの機能を拡張し、プロジェクトの要求に正確に合わせるための強力な方法を提供します。

カスタムブロックを開発することで、エディター向けのコンテンツ作成を合理化し、ブランドの一貫性を確保し、エディターインターフェース内で直接複雑な機能を実装できる再利用可能なコンポーネントを作成できます。このガイドでは、基本概念の理解から、堅牢で保守性の高いカスタムブロックのためのベストプラクティスの実装まで、プロセスを順を追って説明します。

ブロックエディターのアーキテクチャの理解

開発に入る前に、GutenbergとそのブロックがWordPressエコシステム内でどのように機能するかを把握することが重要です。WordPress自体は、モジュラーなPHPおよびMySQLアーキテクチャ上に構築されています。テーマはプレゼンテーションを制御し、プラグインは機能を追加します。コアWordPress機能であるGutenbergは、この構造にシームレスに統合されます。動的なブラウザ内編集エクスペリエンスのためにJavaScript(主にReact)を活用し、PHPはサーバーサイドの登録とレンダリングを処理します。

カスタムブロックは、基本的にWordPressに登録されるJavaScriptコンポーネントです。ユーザーが投稿またはページにカスタムブロックを追加すると、Gutenbergはその設定(属性)をデータベースに保存します。フロントエンドで投稿をレンダリングする際、WordPressはPHPを使用してこの設定を解釈し、適切なHTMLを出力します。これは、同じJavaScriptコンポーネントまたは個別のPHPテンプレートを利用することがよくあります。

カスタムブロックのコアコンポーネント

すべてのカスタムGutenbergブロックは、その中心にいくつかの主要な部分で構成されています。

  1. 登録: これは、WordPressに新しいブロックについて知らせるプロセスです。ブロックの名前、タイトル、アイコン、その他のメタデータを定義します。これは主にJavaScriptのregisterBlockType関数を使用して行われます。
  2. 属性: これらは、ブロックに関連付けられたデータフィールドです。ブロックの特定のインスタンス(例:テキストコンテンツ、画像URL、色の選択)に対してユーザーが変更できる設定またはプロパティと考えてください。属性は、ブロックのJavaScript登録で定義されます。
  3. 編集機能: このJavaScript関数は、Gutenbergエディター内でブロックがどのように表示され、どのように機能するかを定義します。コンテンツ作成者がブロックの設定に使用するインタラクティブなUIを構築する場所です。
  4. 保存機能: このJavaScript関数は、データベースに保存され、ウェブサイトのフロントエンドでレンダリングされる静的なHTMLマークアップを定義します。ブロックの属性の現在の状態を反映する必要があります。

ステップバイステップ:最初のカスタムブロックの作成

見出しとボタンを持つ「行動喚起」(CTA)を表示するシンプルなカスタムブロックを作成してみましょう。この例では、ブロックの登録と編集の基本的なJavaScriptの側面に焦点を当て、基本的なWordPress開発環境がセットアップされていることを前提とします。

前提条件:

  • ローカルWordPress開発環境。
  • JavaScript、React、PHPの基本的な理解。
  • アセットコンパイルのためにNode.jsとnpm(またはyarn)がインストールされていること。

1. プロジェクトセットアップ:

カスタムブロックは通常、プラグインの一部として開発されます。新しいプラグインファイル(例:my-custom-blocks/my-custom-blocks.php)とブロック用のJavaScriptファイル(例:src/index.js)を作成します。また、JavaScriptをコンパイルするためのビルドプロセスも必要になります。一般的なアプローチは@wordpress/scriptsを使用することです。これにより、コンパイルの処理が容易になります。

プラグインのルートディレクトリにpackage.jsonファイルを作成します。

{
  "name": "my-custom-blocks",
  "version": "1.0.0",
  "description": "A plugin for custom Gutenberg blocks.",
  "main": "index.js",
  "scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start"
  },
  "keywords": ["wordpress", "gutenberg", "block"],
  "author": "Your Name",
  "license": "GPL-2.0-or-later",
  "devDependencies": {
    "@wordpress/scripts": "^26.0.0" 
  }
}

依存関係をインストールします:npm install

2. ブロックの登録(JavaScript):

src/index.jsファイルで、@wordpress/blocksパッケージからregisterBlockTypeを使用します。

import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';

// エディター用のコンポーネントをインポート
import { Edit } from './edit';
import { Save } from './save';

registerBlockType( 'my-custom-blocks/cta', {
    title: __( 'Call to Action', 'my-custom-blocks' ),
    icon: 'megaphone',
    category: 'widgets',
    attributes: {
        headline: {
            type: 'string',
            default: '',
        },
        buttonText: {
            type: 'string',
            default: 'Learn More',
        },
        buttonUrl: {
            type: 'string',
            default: '#',
        },
    },
    edit: Edit,
    save: Save,
} );

3. エディターインターフェースの定義(src/edit.js):

このコンポーネントは、エディター内でブロックがどのように表示され、機能するかを処理します。

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, TextControl } from '@wordpress/components';

export const Edit = ( { attributes, setAttributes } ) => {
    const blockProps = useBlockProps();

    const onChangeHeadline = ( newHeadline ) => {
        setAttributes( { headline: newHeadline } );
    };

    const onChangeButtonText = ( newButtonText ) => {
        setAttributes( { buttonText: newButtonText } );
    };

    const onChangeButtonUrl = ( newButtonUrl ) => {
        setAttributes( { buttonUrl: newButtonUrl } );
    };

    return (
        <>
            <InspectorControls>
                <PanelBody title={ __( 'Button Settings', 'my-custom-blocks' ) }>
                    <TextControl
                        label={ __( 'Button Text', 'my-custom-blocks' ) }
                        value={ attributes.buttonText }
                        onChange={ onChangeButtonText }
                    />
                    <TextControl
                        label={ __( 'Button URL', 'my-custom-blocks' ) }
                        value={ attributes.buttonUrl }
                        onChange={ onChangeButtonUrl }
                    />
                </PanelBody>
            </InspectorControls>
            <div { ...blockProps }>
                <RichText
                    tagName="h3"
                    placeholder={ __( 'Enter your headline here...', 'my-custom-blocks' ) }
                    value={ attributes.headline }
                    onChange={ onChangeHeadline }
                    allowedFormats={ [ 'core/bold', 'core/italic' ] }
                />
                <a href={ attributes.buttonUrl } className="wp-element-button">
                    { attributes.buttonText }
                </a>
            </div>
        </>
    );
};

4. 保存機能の定義(src/save.js):

この関数は、フロントエンドのHTML出力を決定します。

import { useBlockProps, RichText } from '@wordpress/block-editor';

export const Save = ( { attributes } ) => {
    const blockProps = useBlockProps.save();

    return (
        <div { ...blockProps }>
            <RichText.Content
                tagName="h3"
                value={ attributes.headline }
            />
            <a href={ attributes.buttonUrl } className="wp-element-button">
                { attributes.buttonText }
            </a>
        </div>
    );
};

5. ブロックスクリプトのエンキュー(PHP):

メインのプラグインファイル(my-custom-blocks.php)で、コンパイルされたJavaScriptファイルを登録してエンキューする必要があります。

<?php
/**
 * Plugin Name: My Custom Blocks
 * Description: Adds custom Gutenberg blocks.
 * Version: 1.0
 * Author: Your Name
 */

function my_custom_blocks_register_block() {
    // Automatically loads the block.json file and enqueues the script.
    register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'my_custom_blocks_register_block' );
?>

6. アセットのビルド:

プラグインディレクトリでnpm run buildを実行します。これにより、JavaScriptがbuildフォルダにコンパイルされます。

これで、WordPressでプラグインをアクティブ化します。「行動喚起」ブロックがエディターで利用可能になるはずです!

カスタムブロック開発のベストプラクティス

カスタムブロックの開発は、機能させるだけでなく、それ以上のものです。ベストプラクティスに従うことで、ブロックが安全で、パフォーマンスが高く、アクセスしやすく、保守可能であることを保証できます。

  • 名前空間: 常にブロックに一意の名前空間を使用してください(例:my-custom-blocks/cta)。これにより、他のブロックとの競合を防ぎます。registerBlockType関数がこれを処理します。
  • コードの整理: JavaScriptとPHPのコードをクリーンで整理された状態に保ちます。複雑なブロックの場合は、JavaScriptを小さく再利用可能なコンポーネントに分割することを検討してください。
  • セキュリティ:
    • サニタイズ: データベースにデータを保存する際(特にユーザー生成コンテンツ)、常にサニタイズしてください。WordPressはsanitize_text_fieldesc_urlなどの関数を提供します。
    • エスケープ: ブラウザにデータを出力する際、クロスサイトスクリプティング(XSS)攻撃を防ぐために常にエスケープしてください。esc_htmlesc_attresc_urlなどの関数を使用します。
    • ノンス: ブロックに関連するAJAXリクエストまたはフォーム送信には、リクエストが正当なWordPressソースから送信されたことを確認するためにノンスを使用します。
  • 国際化(i18n): JavaScriptのすべてのユーザー向け文字列には、__()および_x()関数(@wordpress/i18nから)を使用します。これにより、ブロックが翻訳可能になります。
  • アクセシビリティ: すべての人がブロックを使用できるようにしてください。セマンティックHTMLを使用し、必要に応じてARIA属性を提供し、スクリーンリーダーでテストします。
  • パフォーマンス:
    • 遅延読み込み: 重いアセットや複雑なデータを読み込むブロックの場合は、遅延読み込み技術の実装を検討してください。
    • 効率的なレンダリング: save関数とサーバーサイドレンダリングを可能な限り効率的に最適化します。
    • アセットのエンキュー: ブロックに必要なスクリプトとスタイルのみをエンキューします。ブロック固有のアセットにはenqueue_block_styleおよびenqueue_block_script_handleを使用します。
  • モジュール性と拡張性: PHP内でWordPressフック(アクションとフィルター)を使用して、他のプラグインやテーマがブロックの動作や出力を変更できるようにします。
  • block.json: より複雑なブロックの場合は、block.jsonファイルを使用してブロックのメタデータ、依存関係、スタイル、スクリプトハンドルを宣言します。これはブロック開発の最新の標準であり、アセット管理を簡素化します。

WordPressアーキテクチャとの統合

カスタムブロックは孤立したエンティティではありません。WordPressのコアアーキテクチャと深く統合されています。

  • フック: プラグインでPHPアクションとフィルターを使用して、ブロックの登録を変更したり、条件付きでカスタムスタイルやスクリプトを追加したり、コアブロックのレンダリングされた出力を変更したりできます。たとえば、block_type_metadata_settingsフィルターを使用して、登録済みブロックの設定を変更できます。
  • テーマ統合: ブロックベースのテーマとフルサイト編集(FSE)は、ブロックに大きく依存しています。カスタムブロックはFSEテンプレートにシームレスに適合するように設計でき、ユーザーは一貫したブロックベースのワークフローを使用してサイト全体を構築できます。
  • プラグイン相互運用性: カスタムブロックは他のプラグインと相互作用できます。たとえば、カスタム製品ブロックはeコマコマースプラグインからデータを取得したり、カスタムギャラリーブロックは特定のメディアライブラリプラグインと統合したりできます。

高度な概念と考慮事項

  • サーバーサイドレンダリング(SSR): 動的なデータやサーバーで処理するのが最適な複雑なロジックを必要とするブロックの場合、サーバーサイドレンダリングを実装できます。これには、ブロックを登録する際にPHPでrender_callback関数を定義することが含まれます。
  • 動的ブロック: SSRを使用するブロックは、動的ブロックと呼ばれることがよくあります。データベースに静的なHTMLを保存せず、属性のみを保存し、render_callbackがページロードごとにHTMLを生成します。
  • ブロックスタイル: エディター内でユーザーが選択できるブロックのカスタムスタイルを定義できます。
  • ブロックバリエーション: 基本ブロックのバリエーションを作成して、異なるデフォルト設定または外観を持つ事前設定済みのバージョンを提供します。
  • エディターとフロントエンドの違い: edit関数とsave関数が異なるシナリオを処理する必要がある場合があることに注意してください。edit関数はインタラクティブなエディターエクスペリエンス用であり、save関数は静的なHTML出力用です。場合によっては、動的なフロントエンドレンダリング用に個別のrender_callbackが必要になることがあります。

結論

カスタムGutenbergブロック開発は、WordPressウェブサイトのカスタマイズと機能の新しいレベルを解き放つ強力なスキルです。登録、属性、編集、保存機能といったコアコンポーネントを理解し、セキュリティ、パフォーマンス、アクセシビリティのベストプラクティスに従うことで、堅牢で再利用可能でユーザーフレンドリーなブロックを作成できます。クライアント向けのカスタムプラグインを構築する場合でも、自身のサイトを強化する場合でも、カスタムブロックをマスターすることは、WordPress開発能力を大幅に向上させ、標準的な提供を超えて真にユニークなデジタルエクスペリエンスを作成できるようになります。

Sources (5)