お問い合わせ

EditorsKitのリンク機能が使えない、動かなかったので別のプラグインを拡張してみた

  • URLをコピーしました!

カラムブロックやグループ、カバーブロックなどにリンク機能を付けるEditorsKitというプラグインがあります。

SWELLを使っているとそれらの機能がテーマに組み込まれているので、EditorsKitを使ったことは無かったのですが、Arkhe Blocksの無料版と組み合わせると便利なのでは?と思ってEditorsKitを導入してみました。

EditorsKitをインストールして有効化しても、カラムブロックやグループ、カバーブロックのツールバーにリンクのアイコンが表示されることはありませんでした。

この記事は、EditorsKitのリンク機能を期待してインストールしたのに、ツールバーにリンクが表示されなくて困っている人に向けて、別のプラグインの紹介とその機能拡張の方法をまとめた内容になっています。

EditorsKitのリンク機能が使えない、動かなかった

なんで?と思ったのですが、『EditrsKit 使えない』というキーワードで検索すると、Wordpress6.6.1ぐらいから使えないという人が多いようでした。

試しにArkheから別のテーマに切り替えると、Arkhe Blocksを有効化している状態のままでも、EditorsKitのツールバー拡張が正しく動作することが確認できました。

そうなると、テーマやプラグインなどの組み合わせでブロックのツールバーを拡張しているものと相性が悪いのかな?という感じになり、一般に言われているようなWordPressのバージョン自体に問題があるわけではなさそうです。もちろん、Wordpressのバージョンアップの影響はあると思いますが。

EditorsKitのフォーラムでも同じような問題点の報告が上がっていますが、プラグイン作者からの返信はなく、現時点ではArkhe+Arkhe Blocksの組み合わせでEditrsKitは動かないという結論になりました。

EditorsKit以外の選択肢

Arkhe Blocks proを購入すればいいように思いますが、有料のArkheのフォーラムに書き込んでも作者からの返信がほとんどないので、購入するのはリスクがあります。

ゴリゴリHTMLを書けばいいのですが、後から他の人が修正することを考えると、ユーザーフレンドリーではないので、別の方法を探しました。

同じような問題を抱えている人が自分でプラグインを開発していることを知りました。

とても素晴らしいです。

でも、対象は『カバーブロック』のみでした。

私は、『グループ』や『カラム』にリンクを付けたいので、そのプラグインを拡張することにしました。

プラグインはとてもシンプルな構造で、他のブロックにもリンクを付けるのはできそうでした。

カラムとグループにリンクを付けるように拡張してみる

プラグインは3つのファイルから構成されているのですが、修正が必須なのはphpとjsファイルのみです。

custom-cover-link/custom-cover-link.php
custom-cover-link/custom-cover-link.js

これらのファイルの内容を以下の内容で置き換えれば拡張完了です。

オリジナルのプラグインは、リンク一度付けると後から削除できなかったので、削除ボンタンも付けました。

<?php
/*
Plugin Name: Custom Cover Link
Description: Extends the core Cover block to add a custom link.
Version: 1.0
Author: calcs
*/

function enqueue_custom_block_editor_assets() {
    wp_enqueue_script(
        'custom-cover-link',
        plugin_dir_url(__FILE__) . 'custom-cover-link.js',
        array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-block-editor'),
        filemtime(plugin_dir_path(__FILE__) . 'custom-cover-link.js'),
        true
    );
    wp_enqueue_style(
        'custom-cover-link-style',
        plugin_dir_url(__FILE__) . 'custom-cover-link.css',
        array(),
        filemtime(plugin_dir_path(__FILE__) . 'custom-cover-link.css')
    );
}
add_action('enqueue_block_editor_assets', 'enqueue_custom_block_editor_assets');

function enqueue_custom_block_frontend_assets() {
    wp_enqueue_style(
        'custom-cover-link-style',
        plugin_dir_url(__FILE__) . 'custom-cover-link.css',
        array(),
        filemtime(plugin_dir_path(__FILE__) . 'custom-cover-link.css')
    );
}
add_action('wp_enqueue_scripts', 'enqueue_custom_block_frontend_assets');

function add_block_link($block_content, $block) {
    // カバーブロックの場合
    if ('core/cover' === $block['blockName'] && isset($block['attrs']['link'])) {
        $link = $block['attrs']['link'];
        if (!empty($link)) {
            $block_content = '<a href="' . esc_url($link) . '" class="cover-link">' . $block_content . '</a>';
        }
    }

    // グループブロックの場合
    if ('core/group' === $block['blockName'] && isset($block['attrs']['link'])) {
        $link = $block['attrs']['link'];
        if (!empty($link)) {
            $block_content = '<a href="' . esc_url($link) . '" class="group-link">' . $block_content . '</a>';
        }
    }

    // カラムブロックの場合
    if ('core/column' === $block['blockName'] && isset($block['attrs']['link'])) {
        $link = $block['attrs']['link'];
        if (!empty($link)) {
            $block_content = '<a href="' . esc_url($link) . '" class="column-link">' . $block_content . '</a>';
        }
    }

    return $block_content;
}
add_filter('render_block', 'add_block_link', 10, 2);
(function(wp) {
    const { registerBlockType } = wp.blocks;
    const { createHigherOrderComponent } = wp.compose;
    const { InspectorControls, __experimentalLinkControl } = wp.blockEditor;
    const { PanelBody, ToolbarButton, Popover, Button } = wp.components;
    const { Fragment, useState, createElement } = wp.element;

    // リンク機能を拡張する共通の関数
    const withCustomLink = (BlockEdit, blockType) => {
        return (props) => {
            if (props.name !== blockType) {
                return createElement(BlockEdit, props);
            }

            const { attributes: { link }, setAttributes } = props;
            const [isLinkPickerOpen, setIsLinkPickerOpen] = useState(false);

            const openLinkPicker = () => setIsLinkPickerOpen(true);
            const closeLinkPicker = () => setIsLinkPickerOpen(false);

            const removeLink = () => {
                setAttributes({ link: '' }); // リンクを空に設定
            };

            return createElement(
                Fragment,
                null,
                createElement(BlockEdit, props),
                createElement(
                    InspectorControls,
                    null,
                    createElement(
                        PanelBody,
                        { title: 'リンク設定' },
                        createElement(
                            ToolbarButton,
                            {
                                icon: 'admin-links',
                                label: 'リンクを編集',
                                onClick: openLinkPicker,
                            }
                        ),
                        isLinkPickerOpen && createElement(
                            Popover,
                            { position: "middle center", onClose: closeLinkPicker },
                            createElement(
                                __experimentalLinkControl,
                                {
                                    value: { url: link },
                                    onChange: (value) => setAttributes({ link: value.url }),
                                }
                            )
                        ),
                        link && createElement(
                            Button,
                            {
                                isDestructive: true,
                                onClick: removeLink,
                            },
                            'リンクを削除'
                        )
                    )
                )
            );
        };
    };

    // カバーブロックの拡張
    const withCustomCoverLink = createHigherOrderComponent(
        (BlockEdit) => withCustomLink(BlockEdit, 'core/cover'), 
        'withCustomCoverLink'
    );

    // グループブロックの拡張
    const withCustomGroupLink = createHigherOrderComponent(
        (BlockEdit) => withCustomLink(BlockEdit, 'core/group'), 
        'withCustomGroupLink'
    );

    // カラムブロックの拡張
    const withCustomColumnLink = createHigherOrderComponent(
        (BlockEdit) => withCustomLink(BlockEdit, 'core/column'), 
        'withCustomColumnLink'
    );

    // フィルターフックに追加
    wp.hooks.addFilter(
        'editor.BlockEdit',
        'custom/with-custom-cover-link',
        withCustomCoverLink
    );

    wp.hooks.addFilter(
        'editor.BlockEdit',
        'custom/with-custom-group-link',
        withCustomGroupLink
    );

    wp.hooks.addFilter(
        'editor.BlockEdit',
        'custom/with-custom-column-link',
        withCustomColumnLink
    );

    // ブロック保存の修正
    const withCustomSave = (element, blockType, attributes) => {
        if (blockType.name !== 'core/cover' && blockType.name !== 'core/group' && blockType.name !== 'core/column') {
            return element;
        }

        const { link } = attributes;

        if (!link) {
            return element;
        }

        const className = blockType.name === 'core/cover' ? 'cover-link' : blockType.name === 'core/group' ? 'group-link' : 'column-link';

        return createElement(
            'a',
            { href: link, className: className },
            element
        );
    };

    wp.hooks.addFilter(
        'blocks.getSaveElement',
        'custom/with-custom-save',
        withCustomSave
    );
})(window.wp);

CSSについては、人それぞれだと思いますので、適宜直して頂ければと思います。

まとめ

ブロックエディタ周りの機能を使っているので将来的に問題が起きる可能性も無くもないですが、ツールバーではなく、ブロック設定のパネルにリンク機能が追加されるので、影響を受けにくいのではないかと思っています。

他の人にもシェアしてね
  • URLをコピーしました!
  • URLをコピーしました!
コメントを閉じる

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

クリックできる目次
  • URLをコピーしました!