【WordPressブロック開発】カスタムフィールドの値を表示するシンプルなカスタムブロック

カスタムフィールドの値を取得して表示するシンプルなカスタムブロックを開発する。カスタムフィールドの値は内部的に「投稿メタ」として扱われる。

投稿メタブロック開発

テーマのfunctions.phpを編集

編集画面で投稿メタを複数取得できていない。meta_keyのcountryにJapanとAmericaという2つの値がある場合、投稿IDの若い方しか取得できていない。

meta_keyがcountryの値をすべて取得する場合、’single’ => false を指定する。

function myguten_register_post_meta() {
	register_post_meta('post', 'country', array(
		'single'       => false,
		'type'         => 'string',
		'show_in_rest' => true
	));
}
add_action('init', 'myguten_register_post_meta');

block.jsonを編集

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "create-block/my-post-meta",
	"version": "0.1.0",
	"title": "My Post Meta",
	"category": "widgets",
	"icon": "smiley",
	"description": "Example block scaffolded with Create Block tool.",
	"example": {},
	"supports": {
		"html": false
	},
	"usesContext": ["postId", "postType"],
	"textdomain": "my-post-meta",
	"editorScript": "file:./index.js",
	"style": "file:./style-index.css",
	"render": "file:./render.php"
}

edit.jsを編集

import { useBlockProps } from "@wordpress/block-editor";
import { useEntityProp } from "@wordpress/core-data";

export default function Edit({ context: { postType, postId } }) {
	const blockPlops = useBlockProps();

	const [metas] = useEntityProp("postType", postType, "meta");

	// 'country' メタが配列であると仮定
	const countryArray = metas["country"];

	return (
		<div {...blockPlops}>
			{Array.isArray(countryArray) &&
				countryArray.map((country, index) => (
					<p key={index}>{country}</p> // key を付けてユニークにする
				))}
		</div>
	);
}

render.phpを編集

<div <?php echo get_block_wrapper_attributes(); ?>>
	<?php
	$countries = get_post_meta(get_the_ID(), 'country', false);
	foreach ($countries as $counrty) {
	?>
		<p>meta:<?php echo $counrty; ?></p>
	<?php
	}
	?>
</div>

改良

meta_keyのcountryにJapanとAmericaという2つの値をすべて取得する。

function my_register_post_metas() {
	$meta_definitions = array(
		'color' => array(
			'single'       => false,
			'type'         => 'string',
			'show_in_rest' => true,
		),
		'country' => array(
			'single'       => false,
			'type'         => 'string',
			'show_in_rest' => true,
		),

	foreach ($meta_definitions as $meta_key => $args) {
		register_post_meta('post', $meta_key, $args);
	}
}
add_action('init', 'my_register_post_metas');

// 別解
function my_register_post_metas() {
	$meta_keys = array('color', 'country');

	foreach ($meta_keys as $meta_key) {
		register_post_meta('post', $meta_key, array(
			'single'       => false,
			'type'         => 'string',
			'show_in_rest' => true,
		));
	}
}
add_action('init', 'my_register_post_metas');
import { useBlockProps } from "@wordpress/block-editor";
import { useEntityProp } from "@wordpress/core-data";

export default function Edit({ context: { postType, postId } }) {
	const blockPlops = useBlockProps();

	const metaKey = "metaキー:";

	const [metas] = useEntityProp("postType", postType, "meta");

	const color = "color";
	const country = "country";

	const colorArray = metas[color];
	const countryArray = metas[country];

	return (
		<>
			<div {...blockPlops}>
				<h2>{metaKey + color}</h2>
				{Array.isArray(colorArray) && colorArray.length > 0 ? (
					colorArray.map((color, index) => (
						<p key={index}>{color}</p> // key を付けてユニークにする
					))
				) : (
					<p>{color}を設定してください。</p>
				)}
			</div>
			<div {...blockPlops}>
				<h2>{metaKey + country}</h2>
				{Array.isArray(countryArray) && countryArray.length > 0 ? (
					countryArray.map((country, index) => (
						<p key={index}>{country}</p> // key を付けてユニークにする
					))
				) : (
					<p>{country}を設定してください。</p>
				)}
			</div>
		</>
	);
}
<?php
$meta_key = "metaキー:";
$color = "color";
$colors = get_post_meta(get_the_ID(), $color, false);
$country = "country";
$countries = get_post_meta(get_the_ID(), $country, false);
?>

<div <?php echo get_block_wrapper_attributes(); ?>>
	<h2><?php echo $meta_key . esc_html($color) ?></h2>
	<?php if (!empty($colors)): ?>
		<?php foreach ($colors as $key => $val) : ?>
			<p><?php echo $val; ?></p>
		<?php endforeach; ?>
	<?php else: ?>
		<p><?php echo $color; ?>を設定してください。</p>
	<?php endif; ?>
</div>
<div <?php echo get_block_wrapper_attributes(); ?>>
	<h2><?php echo $meta_key . esc_html($country) ?></h2>
	<?php if (!empty($countries)): ?>
		<?php foreach ($countries as $key => $counrty) : ?>
			<p><?php echo $counrty; ?></p>
		<?php endforeach; ?>
	<?php else: ?>
		<p><?php echo $country; ?>を設定してください。</p>
	<?php endif; ?>
</div>

// 別解
<?php
$meta_key_prefix = "metaキー:";
$meta_fields = ['color', 'country'];

/**
 * メタ情報を表示する汎用関数
 */
if (!function_exists('render_meta_block')) {
	function render_meta_block($field, $meta_key_prefix) {
		$values = get_post_meta(get_the_ID(), $field, false);
		?>
		<div <?php echo get_block_wrapper_attributes(); ?>>
			<h2><?php echo esc_html($meta_key_prefix . $field); ?></h2>
			<?php if (!empty($values)): ?>
				<?php foreach ($values as $value): ?>
					<p><?php echo esc_html($value); ?></p>
				<?php endforeach; ?>
			<?php else: ?>
				<p><?php echo esc_html($field); ?>を設定してください。</p>
			<?php endif; ?>
		</div>
		<?php
	}
}

// 各メタフィールドに対して出力
foreach ($meta_fields as $field) {
	render_meta_block($field, $meta_key_prefix);
}
?>

表示確認