logo

WordPressのブロックエディタ用ブログカードを作ってみた。

作ったもの

リポジトリ

動画Demo
※vimeoに遷移します。

導入方法

1、リポジトリからデータをクローンする。

2、以下のコマンドを打つ。

npm ci
npm run plugin-zip

3、生成されたzipファイルを解凍し、wp-content/pluginsに入れる。

4、WordPressの管理画面からプラグイン一覧ページへ行き、blog-cardを有効化する。

ソースコード解説

今回作成したブログカードのソースコードを解説します。
※解説を見る前にブロック作成のチュートリアルをしていただくことをお勧めします。

1、メタデータの取得方法について

URLの入力欄がonChangeした時にメタ取得のAPIを叩いています。
メタ取得用のAPIはblog-card.phpにて、定義しています。

    const fetchMeta = (newUrl) => {
        setAttributes({ url: newUrl || "" });
        //URLが無効の場合は処理を中断
        if (!newUrl || !URL.canParse(newUrl)) {
            return;
        }
        fetch(apiUrl, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({ url: newUrl }),
        })
            .then(response => {
                if (!response.ok) {
                    throw new Error('ネットワークエラーが発生しました');
                }
                return response.json();
            })
            .then(data => {
                console.log(data)
                setAttributes({
                    title: data.title || "",
                    description: data.description || "",
                    og_image: data.image || "",
                });
            })
            .catch(error => {
                console.error('エラー:', error);
                alert('データの取得中にエラーが発生しました。');
            })

    };
    return (
        <>
            <InspectorControls>
                <PanelBody title={__('Meta', 'blog-card')}>
                    <TextControl
                        label={__(
                            'URL',
                            'blog-card'
                        )}
                        value={url}
                        onChange={(value) => {
                            setAttributes({
                                url: value,
                            })
                            fetchMeta(value)
                        }
                        }
                    />
===========
略

function add_rest_original_endpoint()
{
	//エンドポイントを登録
	register_rest_route('wp/custom', '/meta/', array(
		'methods' => 'POST',
		//エンドポイントにアクセスした際に実行される関数
		'callback' => 'get_meta',
		'permission_callback' => function () {
			return true;
		}
	));
}
add_action('rest_api_init', 'add_rest_original_endpoint');

function get_meta($request)
{
	$args = json_decode($request->get_body(), true);
	$url = filter_var($args['url'], FILTER_VALIDATE_URL);

	if (!$url) {
		return new WP_Error('invalid_url', '無効なURLです', array('status' => 400));
	}

	$html = @file_get_contents($url);
	if ($html === false) {
		return new WP_Error('fetch_error', 'URLからデータを取得できませんでした', array('status' => 500));
	}

	$html = mb_convert_encoding($html, "utf-8", "auto");

	$doc = new DOMDocument();
	@$doc->loadHTML($html);
	$xpath = new DOMXPath($doc);

	$return = array();
	$metas = $xpath->query("//meta[@property='og:title' or @property='og:description' or @property='og:image']");
	foreach ($metas as $meta) {
		$property = $meta->getAttribute('property');
		$content = $meta->getAttribute('content');
		$return[str_replace('og:', '', $property)] = trim($content);
	}

	return new WP_REST_Response($return, 200);
}

2、CSSが可変する箇所について


ボーダーやフォントなど、管理画面側で変更したいCSSに関しては、block.jsonのattributesで定義して、HTMLに直接スタイルを当てる形で渡しています。
その変数を、setAttributesで変更することで、可変することが可能です。

const { fontColor, backgroundColor, borderColor, borderWidth, borderRadius, newTab, url, title, description, og_image } = attributes;
======================
略
======================                   
                                    <RangeControl
                        label='Border width'
                        onChange={(number) => { setAttributes({ borderWidth: number }); }}
                        value={borderWidth}
                        min={0}
                    />
                    <RangeControl
                        label='Border radius'
                        onChange={(number) => { setAttributes({ borderRadius: number }); }}
                        value={borderRadius}
                        min={0}
                    />
                </PanelBody>

            </InspectorControls>
            <div {...useBlockProps()}>
                <a href={url || "/"} target={newTab ? '_blank' : '_self'} className='blogCard' onClick={preventClick} style={{ color: fontColor, backgroundColor: backgroundColor, borderColor: borderColor, borderWidth: borderWidth + 'px', borderRadius: borderRadius + 'px' }}>
                    <div className='blogCard__thumbnail'>
                        <img className='' src={og_image} alt='' />
                    </div>
                    <dl className='blogCard__text'>
                        <dt className='blogCard__text-title'>{title}</dt>
                        <dd className='blogCard__text-description'>
                            {description}
                        </dd>
                    </dl>
                </a>
            </div>
==============
略

3、カラーパレットやレンジコントロールについて


複雑な実装は不要で、ワードプレス側がコンポーネントを用意してくれています。

ColorPalette

RangeControl

まとめ

最近リリースしたホームページでカスタムブロックを作成しました。

https://umisodate.com/

最近リリースしたホームページでカスタムブロックを作成しました。Reactを使ってサクサクとUIを作成でき、APIも手軽に構築できるため、開発体験が非常にスムーズでした。試作品として作成したブログカードは、内部記事の参照やレイアウト変更が可能なようにアップデートを進めていく予定です。