Amazonで商品を見る セール会場へ

WordPress│管理画面にカスタムフィールドの一覧・編集機能を作成する方法

カスタムフィールドでデータを一覧する、または入力する際にまとめてやってしまいたいことがあります。

例えば有料記事の価格なのですが、管理画面に専用メニューを作ると時短になります。

WordPress管理画面に作成した有料記事の価格一覧や編集専用メニューの画面例。

本記事ではその作り方を紹介いたします。

ちなみにいろいろな技術記事を書いていますので、よかったら見てくださいませ。

目次

著者

WEB制作をしているデジタルノマド
WordPressのカスタマイズが好きで、色々と自作しています。

WordPressのカスタマイズに困ったらご相談ください!

WordPressの管理画面にカスタムフィールドの一覧・編集機能を作成する方法

まずはカスタムフィールドを用意しましょう。

今回は価格(price)というカスタムフィールドを作成します。

いつもであればACFかSCFのプラグインでカスタムフィールドを作成するのですが、一つであればfunctions.phpで書いてしまいます。

カスタムフィールドの作成

functions.phpに下記のコードを挿入します。

エラーが怖い人はCode Snippetsのプラグインを入れて、そこからコードを挿入しましょう。

// 投稿画面にカスタムフィールドエリアを追加
add_action('admin_menu', function () {
  add_meta_box(
    'custom_price_box',
    '価格',
    'render_custom_price_field',
    'post',
    'side',
    'default'
  );
});

// 入力欄の出力
function render_custom_price_field($post)
{
  wp_nonce_field('save_custom_price', 'custom_price_nonce');
  $price = get_post_meta($post->ID, 'price', true);
  echo '<label for="price">価格(円)</label>';
  echo '<input type="number" id="price" name="price" value="' . esc_attr($price) . '" style="width:100%;" />';
}

// 保存処理
add_action('save_post', function ($post_id) {
  if (!isset($_POST['custom_price_nonce']) || !wp_verify_nonce($_POST['custom_price_nonce'], 'save_custom_price')) return;
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
  if (isset($_POST['price'])) {
    update_post_meta($post_id, 'price', sanitize_text_field($_POST['price']));
  }
});

カスタムフィールドの表示場所

コードにsideと設定した場合はサイドバーにカスタムフィールドが設置されます。

カスタムフィールドの表示場所をサイドバーに設定した際の配置例。

逆にnomalとした場合は編集記事下にカスタムフィールドが設置されます。

カスタムフィールドの表示場所を編集記事下に設定した際の配置例。

専用管理画面の作成

下記のコードをfunctions.phpに記載するだけです。

エラーが怖い人はCode Snippetsのプラグインを入れて、そこからコードを挿入しましょう。

一応、記事が多い場合を想定してカテゴリーとタグの絞り込みもつけておきました。

以下のコードです。

名称は好きに変更しましょう。

このコードをベースにAIで書き換えてもよいでしょう。

add_action('admin_menu', function () {
    add_menu_page(
        '価格一覧',
        '価格一覧',
        'manage_options',
        'custom-price-list',
        'render_custom_price_list',
        'dashicons-money-alt',
        20
    );
});

function render_custom_price_list()
{
    // カテゴリーとタグの取得
    $categories = get_terms(['taxonomy' => 'category', 'hide_empty' => false]);
    $tags = get_terms(['taxonomy' => 'post_tag', 'hide_empty' => false]);

    // 選択されたID
    $selected_cat = isset($_GET['cat_id']) ? intval($_GET['cat_id']) : 0;
    $selected_tag = isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0;

    // 投稿を取得
    $args = [
        'post_type' => 'post',
        'posts_per_page' => 100,
        'post_status' => 'publish',
        'tax_query' => [],
    ];

    if ($selected_cat) {
        $args['tax_query'][] = [
            'taxonomy' => 'category',
            'field' => 'term_id',
            'terms' => $selected_cat,
        ];
    }

    if ($selected_tag) {
        $args['tax_query'][] = [
            'taxonomy' => 'post_tag',
            'field' => 'term_id',
            'terms' => $selected_tag,
        ];
    }

    if (count($args['tax_query']) > 1) {
        $args['tax_query']['relation'] = 'AND'; // 両方一致した投稿に限定
    }

    $posts = get_posts($args);

    // 保存処理
    if (isset($_POST['custom_price_save']) && isset($_POST['price']) && is_array($_POST['price'])) {
        foreach ($_POST['price'] as $post_id => $price) {
            update_post_meta($post_id, 'price', sanitize_text_field($price));
        }
        echo '<div class="updated"><p>価格を保存しました。</p></div>';
    }

    echo '<div class="wrap">';
    echo '<h1>投稿の価格一覧</h1>';

    // ▼絞り込みフォーム(カテゴリ + タグ)
    echo '<form method="get" style="margin-bottom: 1em;">';
    echo '<input type="hidden" name="page" value="custom-price-list">';

    echo '<label for="cat_id">カテゴリー:</label>';
    echo '<select name="cat_id" id="cat_id">';
    echo '<option value="0">すべて</option>';
    foreach ($categories as $cat) {
        $selected = selected($selected_cat, $cat->term_id, false);
        echo "<option value='{$cat->term_id}' {$selected}>{$cat->name}</option>";
    }
    echo '</select> ';

    echo '<label for="tag_id">タグ:</label>';
    echo '<select name="tag_id" id="tag_id">';
    echo '<option value="0">すべて</option>';
    foreach ($tags as $tag) {
        $selected = selected($selected_tag, $tag->term_id, false);
        echo "<option value='{$tag->term_id}' {$selected}>{$tag->name}</option>";
    }
    echo '</select> ';

    echo '<button type="submit" class="button">絞り込み</button>';
    echo '</form>';

    // ▼価格編集テーブル
    echo '<form method="post">';
    echo '<table class="widefat fixed striped">';
    echo '<thead><tr><th style="max-width:400px;width:400px;">記事タイトル</th><th>価格</th></tr></thead><tbody>';

    foreach ($posts as $post) {
        $price = get_post_meta($post->ID, 'price', true);
        echo '<tr>';
        echo '<td style="max-width:400px;width:400px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">';
        echo '<a href="' . get_edit_post_link($post->ID) . '">' . esc_html($post->post_title) . '</a>';
        echo '</td>';
        echo '<td><input type="number" name="price[' . $post->ID . ']" value="' . esc_attr($price) . '" /></td>';
        echo '</tr>';
    }

    echo '</tbody></table>';
    submit_button('価格を保存する', 'primary', 'custom_price_save');
    echo '</form>';
    echo '</div>';
}

以上です。

あとは管理画面から確認しましょう。

コード追加後に管理画面から確認できるカスタムフィールド一覧・編集機能の表示例。

シンプル版

絞り込みなしのシンプル版も作成しました。

絞り込み機能を省いたシンプル版のカスタムフィールド一覧・編集画面例。
add_action('admin_menu', function () {
    add_menu_page(
        '価格一覧',
        '価格一覧',
        'manage_options',
        'custom-price-list',
        'render_custom_price_list',
        'dashicons-money-alt',
        20
    );
});

function render_custom_price_list()
{
    // 投稿を取得(100件まで表示)
    $posts = get_posts([
        'post_type' => 'post',
        'posts_per_page' => 100,
        'post_status' => 'publish',
    ]);

    // 保存処理
    if (isset($_POST['custom_price_save']) && isset($_POST['price']) && is_array($_POST['price'])) {
        foreach ($_POST['price'] as $post_id => $price) {
            update_post_meta($post_id, 'price', sanitize_text_field($price));
        }
        echo '<div class="updated"><p>価格を保存しました。</p></div>';
    }

    echo '<div class="wrap">';
    echo '<h1>投稿の価格一覧</h1>';
    echo '<form method="post">';
    echo '<table class="widefat fixed striped">';
    echo '<thead><tr><th>記事タイトル</th><th>価格</th></tr></thead><tbody>';

    foreach ($posts as $post) {
        $price = get_post_meta($post->ID, 'price', true);
        echo '<tr>';
        echo '<td><a href="' . get_edit_post_link($post->ID) . '">' . esc_html($post->post_title) . '</a></td>';
        echo '<td><input type="number" name="price[' . $post->ID . ']" value="' . esc_attr($price) . '" /></td>';
        echo '</tr>';
    }

    echo '</tbody></table>';
    submit_button('価格を保存する', 'primary', 'custom_price_save');
    echo '</form>';
    echo '</div>';
}

この記事で紹介しているコードは、GitHubのMOTOKI-LLC/WAZA-codeにもまとめています。

  • URLをコピーしました!

実装を任せたい方へ

WordPressのカスタマイズ代行

ブロックの追加、テーマの改修、管理画面の調整など、記事で紹介している内容の実装を承ります。1時間 ¥8,000〜(税込)。

WAZAの有料記事のサブスクリプションも開始しました。

サービス

Service

WordPressサイトのカスタマイズのサービスに関心がありましたら、ぜひ詳細をご覧ください。

目次