WordPressでタグリストを表示するGutenbergブロックを開発した

WordPressのブロックエディタ(Gutenberg)用のカスタムブロックを開発することで、記事の機能性を高められます。今回は、記事に関連付けられたタグを効率的にリスト表示するブロックプラグインの開発手順を紹介します。シンプルかつ保守性の高い実装方法で、使いやすいタグ表示機能を実現します。

タグリストブロックの役割と特徴

タグリスト機能は、ブログやWebサイトでよく活用される機能です。記事に付けられたタグを一覧表示することで、関連コンテンツへの誘導や記事の内容把握を助けます。これをブロック化することで、記事編集時にも実際の表示をプレビューしながら作業できるようになります。

このブロックの主な特徴は以下の通りです:

  1. 複数の記事(2つ以上)に関連付けられているタグのみ表示
  2. タグは記事数の多い順に自動ソート
  3. ハッシュタグ形式(#タグ名)で表示
  4. 各タグの記事数も併せて表示(例:#タグ名(5))

プラグイン開発の基本構成

まずは基本的なディレクトリ構造を作りましょう。ファイルを適切に分けることで、後々のメンテナンスがしやすくなります。

tag-list-block/
│
├── tag-list-block.php        // メインのプラグインファイル
└── tag-list-block.js         // ブロックエディタ用のJavaScript
Code language: PHP (php)

この構成は、PHPとJavaScriptを分離することで、それぞれの役割を明確にしています。PHPファイルはサーバーサイドの処理を、JavaScriptファイルはエディタでの表示や操作を担当します。

プラグインのPHP部分の実装

まず、メインとなるPHPファイル(tag-list-block.php)を作成します。

<?php
/**
 * Plugin Name: タグリストブロック
 * Description: 記事のタグをリスト表示するためのブロック
 * Version: 1.0.0
 * Author: chiilabo
 * Author URI: https://app.chiilabo.jp
 */

// 直接アクセスを防止
if (!defined('ABSPATH')) {
    exit;
}

// ブロックを登録
function register_tag_list_block() {
    wp_register_script(
        'tag-list-block-editor',
        plugins_url('tag-list-block.js', __FILE__),
        array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-data'),
        filemtime(plugin_dir_path(__FILE__) . 'tag-list-block.js')
    );

    register_block_type('tag-list-block/tag-list', array(
        'editor_script' => 'tag-list-block-editor',
        'render_callback' => 'render_tag_list_block'
    ));
}
add_action('init', 'register_tag_list_block');

// ブロックのレンダリング関数(サーバーサイド)
function render_tag_list_block($attributes) {
    $posttags = get_the_tags();
    if (!$posttags) return '';

    $link_counts = array();
    foreach ($posttags as $tag) {
        if ($tag->count > 1) { // 記事数が1より大きい場合のみ表示
            $link = get_tag_link($tag->term_id);
            if (is_wp_error($link)) return '';
            $link_counts[] = array(
                'count' => $tag->count,
                'link' => '<a class="tag-link tag-link-' . $tag->term_id . ' border-element" href="' . esc_url($link) . '">#' . $tag->name . '(' . $tag->count . ')' . '</a>'
            );
        }
    }

    if (empty($link_counts)) return ''; // 表示するタグがない場合は終了

    usort($link_counts, function ($a, $b) {
        // 記事数の降順にソート
        return $b['count'] - $a['count'];
    });

    $tag_links = array_map(function ($tag) {
        return $tag['link'];
    }, $link_counts);

    $before = '<div class="wp-block-tag-list-block-tag-list">';
    $after = '</div>';
    $sep = ' ';

    return $before . join($sep, $tag_links) . $after;
}
Code language: HTML, XML (xml)

PHPファイルの役割を詳しく見ていきましょう。

プラグイン情報

まず、プラグインの基本情報を定義します。これによって、WordPressの管理画面でプラグインとして認識されます。

/**
 * Plugin Name: タグリストブロック
 * Description: 記事のタグをリスト表示するためのブロック
 * Version: 1.0.0
 * Author: chiilabo
 * Author URI: https://app.chiilabo.jp
 */
Code language: JSON / JSON with Comments (json)

セキュリティ対策

直接アクセスを防止するため、ABSPATHが定義されているかをチェックします。これはWordPressのセキュリティ対策の基本です。

// 直接アクセスを防止
if (!defined('ABSPATH')) {
    exit;
}
Code language: PHP (php)

ブロック登録とスクリプト追加

register_tag_list_block関数では、エディタ用のJavaScriptファイルを登録し、ブロックタイプを定義しています。render_callbackパラメータで、実際の表示内容を生成する関数を指定しています。

function register_tag_list_block() {
    // JavaScriptを登録
    wp_register_script(
        'tag-list-block-editor',
        plugins_url('tag-list-block.js', __FILE__),
        array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-data'),
        filemtime(plugin_dir_path(__FILE__) . 'tag-list-block.js')
    );

    // ブロックタイプを登録
    register_block_type('tag-list-block/tag-list', array(
        'editor_script' => 'tag-list-block-editor',
        'render_callback' => 'render_tag_list_block'
    ));
}
add_action('init', 'register_tag_list_block');
Code language: PHP (php)

ここでは、外部のJavaScriptファイル(tag-list-block.js)を読み込み、Gutenbergエディタで利用できるようにしています。

サーバーサイドレンダリング関数

render_tag_list_block関数が、タグリストの実際の表示内容を生成します。この関数では次のような処理を行っています:

  1. 現在の記事に関連付けられたタグを取得
  2. 記事数が2以上のタグだけをフィルタリング
  3. 記事数が多い順にタグをソート
  4. タグごとにリンク付きのHTML要素を生成
  5. すべてのタグ要素を結合して最終的なHTMLを返す

これによって、複数の記事で使われているタグだけが、人気順(記事数順)で表示されるようになります。

JavaScript部分の実装

次に、ブロックエディタでの表示や操作を担当するJavaScriptファイル(tag-list-block.js)を作成します。

(function() {
    var __ = wp.i18n.__;
    var registerBlockType = wp.blocks.registerBlockType;
    var ServerSideRender = wp.serverSideRender;
    var Placeholder = wp.components.Placeholder;
    var Spinner = wp.components.Spinner;

    registerBlockType('tag-list-block/tag-list', {
        title: __('タグリスト'),
        icon: 'tag',
        category: 'widgets',
        keywords: [__('タグ'), __('リスト'), __('ハッシュタグ')],
        
        edit: function(props) {
            return wp.element.createElement(
                'div',
                { className: props.className },
                wp.element.createElement(
                    ServerSideRender,
                    {
                        block: 'tag-list-block/tag-list',
                        attributes: props.attributes,
                    }
                )
            );
        },
        
        save: function() {
            // サーバーサイドレンダリングを使用するため空を返す
            return null;
        },
    });
})();
Code language: JavaScript (javascript)

このJavaScriptファイルの役割を詳しく見ていきましょう。

WordPressコンポーネントの取得

まず、WordPressが提供する各種APIやコンポーネントを取得しています。

var __ = wp.i18n.__;
var registerBlockType = wp.blocks.registerBlockType;
var ServerSideRender = wp.serverSideRender;
var Placeholder = wp.components.Placeholder;
var Spinner = wp.components.Spinner;
Code language: JavaScript (javascript)

ブロックの登録

registerBlockType関数を使って、ブロックを登録しています。ここでは、ブロックのタイトルやアイコン、カテゴリなどの基本情報を設定しています。

registerBlockType('tag-list-block/tag-list', {
    title: __('タグリスト'),
    icon: 'tag',
    category: 'widgets',
    keywords: [__('タグ'), __('リスト'), __('ハッシュタグ')],
    // ...
});
Code language: JavaScript (javascript)

エディタでの表示

edit関数では、エディタ内での表示内容を定義しています。ここでは、ServerSideRenderコンポーネントを使って、PHPのrender_tag_list_block関数の出力結果をエディタ内に表示しています。

edit: function(props) {
    return wp.element.createElement(
        'div',
        { className: props.className },
        wp.element.createElement(
            ServerSideRender,
            {
                block: 'tag-list-block/tag-list',
                attributes: props.attributes,
            }
        )
    );
},
Code language: JavaScript (javascript)

フロントエンド表示の処理

save関数は、サーバーサイドレンダリングを使用するため、空を返しています。実際の表示内容は、PHPのrender_tag_list_block関数が生成します。

save: function() {
    // サーバーサイドレンダリングを使用するため空を返す
    return null;
},
Code language: JavaScript (javascript)

サーバーサイドレンダリングの利点

このプラグインでは「サーバーサイドレンダリング(SSR)」を採用しています。具体的には、JavaScriptのsave関数がnullを返し、PHPのrender_callback関数でHTMLを生成する方式です。

これには以下のような利点があります:

  1. 常に最新のデータを表示できる:表示時に毎回PHPが実行されるため、タグの情報が更新されてもすぐに反映されます
  2. SEO対策になる:JavaScriptに依存せず、HTMLとして出力されるためSEOに有利です
  3. パフォーマンスの向上:クライアント側での処理が減り、特に大量のブロックがある場合に効果的です

図書館で例えるなら、本の内容をコピーして持ち歩くのではなく、必要なときに図書館で最新版を参照するようなものです。少し手間はかかりますが、常に最新の情報が得られます。

プラグインの使い方

完成したプラグインは、以下の手順で使用できます:

  1. プラグインのフォルダ(tag-list-block)をWordPressのwp-content/plugins/ディレクトリにアップロード
  2. WordPressの管理画面からプラグインを有効化
  3. 記事編集画面で「+」ボタンをクリックしてブロックを追加
  4. 「タグリスト」を検索して選択

ブロックが追加されると、現在の記事に関連付けられたタグが自動的にリスト表示されます。特に設定は不要で、すぐに使い始められます。

実装のポイント

このプラグインの実装で特に注目したのは以下の点です:

  1. 条件付きフィルタリング:記事数が1より多いタグのみを表示することで、関連性の高いタグだけを表示しています
  2. ソート機能:記事数の多い順にソートすることで、人気のあるタグを優先表示しています
  3. ファイル分離:PHPとJavaScriptを別ファイルに分けることで、コードの保守性を高めています
  4. サーバーサイドレンダリング:最新データを常に表示できる方式を採用しています

これらの工夫により、使いやすく、実用的な機能を持つブロックとなっています。

まとめ

WordPressのGutenbergブロックプラグイン開発は、基本的なPHPとJavaScriptの知識があれば取り組むことができます。今回作成したタグリストブロックは、サーバーサイドレンダリングを活用し、最新のタグ情報を常に表示できる実用的なコンポーネントとなりました。

ファイルを適切に分離することで、コードの保守性も高まります。PHPとJavaScriptの役割を明確に分けることで、それぞれの言語の強みを生かした実装が可能になります。ブロックエディタの機能を活用し、サイトの使いやすさを向上させるプラグイン開発に挑戦してみてください。