WordPressブロック開発 投稿の更新日をサイドパネルに表示する(ブロックなし)

投稿の更新日がある場合にサイドパネルにその日付を表示するプラグインを作ります。ブロックは作成しません。

雛形のインストール

プラグイン名は「My Updated Date At Sidepanel」とした。

npx @wordpress/create-block@latest my-updated-date-at-sidepanel

プラグインの構造

  • my-updated-date-at-sidepanel
    • build
    • node_modules
    • src
      • block.json
      • my-updated-date-at-sidepanel.js
    • my-updated-date-at-sidepanel.php
    • package.json
    • and more ..

package.jsonの編集

ビルドコマンドを修正し、メインスクリプトとしてmy-updated-date-at-sidepanel.jsを指定する。

{
	"scripts": {
		"build": "wp-scripts build ./src/my-updated-date-at-sidepanel.js",
		"start": "wp-scripts start ./src/my-updated-date-at-sidepanel.js"
	},
}

メインスクリプトをエンキューする

<?php

/**
 * Plugin Name:       My Updated Date At Sidepanel
 * Description:       Example block scaffolded with Create Block tool.
 * Version:           0.1.0
 * Requires at least: 6.7
 * Requires PHP:      7.4
 * Author:            The WordPress Contributors
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       my-updated-date-at-sidepanel
 *
 * @package CreateBlock
 */


namespace CreateBlock;

add_action('enqueue_block_editor_assets', __NAMESPACE__ . '\enqueue_files');

function enqueue_files() {
	$file = plugin_dir_path(__FILE__) . '/build/my-updated-date-at-sidepanel.asset.php';

	if (file_exists($file)) {
		$assets = include $file;
		wp_enqueue_script(
			'my-updated-date-at-sidepanel',
			plugin_dir_url(__FILE__) . 'build/my-updated-date-at-sidepanel.js',
			$assets['dependencies'],
			$assets['version'],
			true
		);
	}
}

my-updated-date-at-sidepanel.js

import { Flex, FlexItem } from "@wordpress/components";
import { registerPlugin } from "@wordpress/plugins";
import { PluginPostStatusInfo } from "@wordpress/editor";
import { useSelect } from "@wordpress/data";
import { store as editorStore } from "@wordpress/editor";

const Render = () => {
	const modified = useSelect(
		(select) => select(editorStore).getEditedPostAttribute("modified"),
		[],
	);
	return (
		<PluginPostStatusInfo>
			<Flex className="editor-post-panel__row">
				<FlexItem className="editor-post-panel__row-label">更新日時</FlexItem>
				<FlexItem className="editor-post-panel__row-control">
					<span className="components-button editor-post-discussion__panel-toggle is-compact">
						{modified ? new Date(modified).toLocaleString() : "読み込み中..."}
					</span>
				</FlexItem>
			</Flex>
		</PluginPostStatusInfo>
	);
};

registerPlugin("my-updated-date-at-sidepanel", {
	render: Render,
});

完成図

投稿が公開されている場合のみ更新日時を表示するカスタマイズ

編集画面を開いた段階で更新日時がセットされてしまい、投稿を公開していないのに更新日時が表示されるのは不自然である。そのため、投稿が公開されている場合のみ更新日時を表示するようにカスタマイズする。

import { Flex, FlexItem } from "@wordpress/components";
import { registerPlugin } from "@wordpress/plugins";
import { PluginPostStatusInfo } from "@wordpress/editor";
import { useSelect } from "@wordpress/data";
import { store as editorStore } from "@wordpress/editor";

const Render = () => {
	const { modified, status } = useSelect((select) => {
		const post = select(editorStore);
		return {
			modified: post.getEditedPostAttribute("modified"),
			status: post.getEditedPostAttribute("status"),
		};
	}, []);

	if (status !== "publish") return null;

	return (
		<PluginPostStatusInfo>
			<Flex className="editor-post-panel__row">
				<FlexItem className="editor-post-panel__row-label">更新日時</FlexItem>
				<FlexItem className="editor-post-panel__row-control">
					<span className="components-button editor-post-discussion__panel-toggle is-compact">
						{modified ? new Date(modified).toLocaleString("ja-JP") : ""}
					</span>
				</FlexItem>
			</Flex>
		</PluginPostStatusInfo>
	);
};

registerPlugin("my-updated-date-at-sidepanel", {
	render: Render,
});

コードの解説をする。

const { modified, status } = useSelect((select) => {
  • useSelect は、WordPress が提供するデータ取得用の React フックである。
  • select 関数を用いて、エディターの内部状態(ストア)から必要な情報を取得する。
  • オブジェクトの分割代入によって、取得した modifiedstatus の値を個別の変数として取り出している。
    const post = select(editorStore);
  • select(editorStore) により、WordPress の「投稿編集ストア」から現在編集中の投稿データを取得できる。
  • editorStore@wordpress/editor に含まれるストアで、編集中の投稿に関する状態が集約されている。
    return {
        modified: post.getEditedPostAttribute('modified'),
        status: post.getEditedPostAttribute('status'),
    };
  • getEditedPostAttribute() は、現在編集中の投稿における特定の属性(メタ情報)を取得するメソッドである。
  • 'modified' は、投稿が最後に保存された日時(ISO 形式)を表す。
  • 'status' は、投稿の現在の状態(例:'draft', 'publish', 'pending' など)を表す。

return の有無の違いは「アロー関数の省略記法」によるもの。返す値が「1つの値だけ」の場合は省略できる。

const modified = useSelect(
  (select) => select(editorStore).getEditedPostAttribute("modified"),
  []
);
// 同じ意味
const modified = useSelect(
  (select) => {
    return select(editorStore).getEditedPostAttribute("modified");
  },
  []
);

返す値が「オブジェクト全体」の場合。

ストアからのデータ取得の他にもconst post = select(editorStore);と書いて、関数の中で複数の処理をしている場合、returnが必要になる。

const { modified, status } = useSelect(
    (select) => ({
        modified: select(editorStore).getEditedPostAttribute("modified"),
        status: select(editorStore).getEditedPostAttribute("status"),
    }),
    [],
);


const { modified, status } = useSelect(
    (select) => {
        const post = select(editorStore);
        return {
            modified: post.getEditedPostAttribute("modified"),
            status: post.getEditedPostAttribute("status"),
        };
    },
    []
);