- 実践 WordPress ホーム
- 投稿タイプ管理
WordPress でプラグインを使わず繰り返しカスタムフィールドを自作する方法
WordPress でプラグインを使わずに繰り返しカスタムフィールド(ポストメタ)を自作する方法を紹介します。
ここでは繰り返し(複数の値の保存)ができるカスタムフィールドを扱います。 単一の値のパターンは次のページを参照ください。
Note
ここではすべての値を wp_postmeta
テーブルの 1 つのレコードに格納するパターンをご紹介します。
この方法で追加したカスタムフィールドは投稿の検索には使えないのでご注意ください。
繰り返しカスタムフィールド追加後のイメージは次のとおりです。
今回はデモとして「ラベル」「 URL 」という 2 つのフィールドを持つカスタムフィールドを繰り返せる形を作ります。
やるべきことは大きく 3 つあります。
- カスタムフィールドを定義する:
init
アクション - 投稿編集ページに入力フィールドを追加する:
add_meta_boxes
アクション - 投稿の保存時にカスタムフィールドの値を更新する:
save_post
アクション
確認時のバージョン
- WordPress
6.6.1
WordPress で繰り返しカスタムフィールドを作成する方法
カスタムフィールドの作成はプラグインとテーマのどちらでもできますが、今回はプラグインを使って行います。
wp-content/plugins
以下に custom-field-related-pages
というディレクトリを作成してその中にファイルを作成します。
wp-content/plugins
┗ custom-field-related-pages
┣ custom-field-related-pages.php
┗ custom-field-related-pages.js
まずプラグインのメインファイルを作成します。
custom-field-related-pages.php
:
1. カスタムフィールドを定義する
init
アクションと関数 register_post_meta()
を使ってカスタムフィールドを定義します。
custom-field-related-pages.php
:
add_action ( 'init', function () {
// カスタムフィールド `related_pages` を登録する:
register_post_meta( 'post', 'related_pages', [
'type' => 'array',
'single' => true,
'default' => [],
] );
} );
2. 投稿編集ページに入力フィールドを追加する
次に add_meta_boxes
アクションを使って投稿編集ページに入力フィールドを追加します。
custom-field-related-pages.php
:
add_action( 'add_meta_boxes', function () {
// 「関連ページ」のメタボックスを追加する:
add_meta_box(
'related_pages', // ID
'関連ページ', // 表示タイトル
'slug_display_meta_box', // コールバック
'post', // 対象スクリーン
'normal', // コンテキスト(表示位置)
);
} );
/**
* メタボックス related_pages の表示用コールバック
*/
function slug_display_meta_box($post) {
$related_pages = get_post_meta( $post->ID, 'related_pages', true );
wp_nonce_field( basename(__FILE__), 'related_pages' );
// テーブルヘッダー:
?>
<div id="custom-field-related-pages">
<table class="table" width="100%">
<thead>
<tr>
<th width="40%">ラベル</th>
<th width="40%">URL</th>
<th width="20%"></th>
</tr>
</thead>
<tbody>
<?php
// テーブルボディ:
// 保存された値がある場合
if ( ! empty($related_pages) ) {
foreach ($related_pages as $field) {
?>
<tr>
<td><input type="text" name="label[]" value="<?php echo esc_attr($field['label']); ?>" /></td>
<td><input type="text" name="url[]" value="<?php echo esc_attr($field['url']); ?>" /></td>
<td><a class="button remove-row" href="#">削除</a></td>
</tr>
<?php
}
} else {
// 保存された値が無い場合
?>
<tr>
<td><input type="text" name="label[]" /></td>
<td><input type="text" name="url[]" /></td>
<td><a class="button remove-row" href="#">削除</a></td>
</tr>
<?php
}
// 追加用の非表示行:
?>
<tr class="empty-row screen-reader-text">
<td><input type="text" name="label[]" /></td>
<td><input type="text" name="url[]" /></td>
<td><a class="button remove-row" href="#">削除</a></td>
</tr>
</tbody>
</table>
<?php // 追加用ボタン: ?>
<p><a id="add-row" class="button" href="#">行を追加</a></p>
</div>
<?php
// 「削除」と「行を追加」ボタンを機能させる JavaScript コードを追加:
wp_enqueue_script(
'custom-field-related-pages',
plugin_dir_url( __FILE__ ) . '/custom-field-related-pages.js',
['jquery'],
'0.1.0',
true
);
}
ページに追加する JavaScript のスクリプトを作成します。
custom-field-related-pages.js
:
jQuery(document).ready(($) => {
const $parent =$('#custom-field-related-pages');
const $table = $parent.find('table');
// 「行を追加」ボタンがクリックされたら新たな行を追加する:
$parent.find('#add-row').on('click', () => {
const $row = $('.empty-row').clone(true);
$row.removeClass('empty-row screen-reader-text');
$row.insertBefore($table.find('tbody>tr:last'));
return false;
});
// 「削除」ボタンがクリックされたら行を削除する:
$table.on('click', '.remove-row', (event) => {
$(event.target).parents('tr').remove();
return false;
});
});
3. 投稿の保存時にカスタムフィールドの値を更新する
最後に、 save_post
アクションを使って投稿の保存時にカスタムフィールドの値を更新する処理を追加します。
add_action( 'save_post', function ($post_id) {
// nonce チェックを行う:
$nonce_key = 'related_pages';
if ( ! isset($_POST[$nonce_key]) ||
! wp_verify_nonce($_POST[$nonce_key], basename( __FILE__ ) )) {
return;
}
// 自動保存では処理を行わない:
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// ユーザーが編集権限を持たない場合は処理を行わない:
$post_type = $_POST['post_type'];
if (!current_user_can('edit_' . $post_type, $post_id)) {
return;
}
// 保存処理を行う:
$labels = $_POST['label'];
$urls = $_POST['url'];
$count = count($labels);
$new = [];
foreach (range(0, count($labels) - 1) as $i) {
if ($labels[$i] != '') {
$new[$i] = [
'label' => stripslashes(strip_tags($labels[$i])),
'url' => stripslashes(strip_tags($urls[$i])),
];
}
}
$old = get_post_meta($post_id, 'related_pages', true);
if (!empty($new) && $new != $old) {
update_post_meta($post_id, 'related_pages', $new);
} else if (empty($new) && $old) {
delete_post_meta($post_id, 'related_pages', $old);
}
} );
ここまでできたら完了です。
プラグインを有効化して投稿編集ページを開いてください。 投稿編集ページを開くとカスタムフィールドが追加できることが確認できるはずです。
新規作成時は次のように表示されます。
要素を追加します。
さらに追加して投稿を保存します。
編集ページを開き直すと、保存した値が格納されて表示され、値が正しく保存されていることが確認できます。
以上です。
まとめ
繰り返しカスタムフィールドを追加するには次の 3 つのことをする必要があります。
それぞれ init
アクション、 add_meta_boxes
アクション、 save_post
アクションを使用します。
- カスタムフィールドを定義する:
init
アクション - 投稿編集ページに入力フィールドを追加する:
add_meta_boxes
アクション - 投稿の保存時にカスタムフィールドの値を更新する:
save_post
アクション
繰り返しのカスタムフィールドは実装が複雑になりがちですが、今回のようにシンプルな形であればプラグインなしでも比較的シンプルなコードで実装ができます。 ぜひ参考にしてみてください。
サンプルコード
GitHub に置きました。 試したい方は使ってみてください。