カスタムフィールドをプラグインなしで自作する(2)

カスタムフィールドをプラグインなしで自作する(2)
LaraによるPixabayからの画像

2025.02.14(更新日:2025.02.16)

「画像アップロード」をカスタムフィールドで設置したい需要は多いと思う。その際Wordpressのメディアアップローダを使用出来るようにしたい。流れ的には前回の(1)と同じだが、メディアアップローダを使用するため追加コードが必要になる。

画像アップロードのカスタムフィールドを作成するには

基本的な流れは(1)で行ったものと同じ。ただしWordpress標準のメディアアップローダを使用するためには、加えるものが必要になる。

  1. 「add_meta_box」を使い表示する投稿等を指定する
  2. 「wp_enqueue_media」「メディアアップローダを処理するJSファイル」を読み込ませる
  3. メタボックスのHTMLを処理する
  4. メディアアップローダを処理するJS(jQuery)を組み込む
  5. メタボックスの値を保存処理するコード

カスタムフィールドのレイアウトを整えたければ2番目で合わせて読み込む処理を行う。上記は外部ファイルを使用する場合だが、JSとCSSの記述は面倒であれば3番目のメタボックスのHTML内に書く方法もあり。

画像アップロードのカスタムフィールドのコード解説

「add_meta_box」を使い表示する投稿等を指定する

// メタボックスを追加
function add_custom_image_uploader_meta_box() {
    add_meta_box(
        'custom_image_meta_box', // メタボックスID
        '画像アップローダ', // タイトル
        'render_custom_image_uploader_meta_box', // コールバック関数
        'post', // 投稿タイプ(例:'post', 'page')
        'side', // 表示場所('normal', 'side', 'advanced')
        'low' // 優先順位('high', 'core', 'default', 'low')
    );
}
add_action('add_meta_boxes', 'add_custom_image_uploader_meta_box');

「wp_enqueue_media」「メディアアップローダを処理するJSファイル」を読み込ませる

function custom_image_uploader_scripts($hook) {
    if ('post.php' === $hook || 'post-new.php' === $hook) {
        wp_enqueue_media(); // メディアライブラリ用のスクリプト
        wp_enqueue_script(
            'custom-image-uploader',
            get_template_directory_uri() . '/custom-image-uploader.js', //JSファイルの指定。ディレクトリは各自変更すること
            array('jquery'),
            null,
            true
        );
    }
}
add_action('admin_enqueue_scripts', 'custom_image_uploader_scripts');

もし特定の投稿タイプのみで使用したければ、上記コードに「global $post」で「$post->post_type」を追加し分岐させれば良い。

メタボックスのHTMLを処理する

function render_custom_image_uploader_meta_box($post) {
  // 現在の画像IDを取得
  $image_id = get_post_meta($post->ID, 'custom_image_id', true);
  $image_url = $image_id ? wp_get_attachment_image_url($image_id, 'thumbnail') : '';
  // セキュリティ用の非公開フィールド
  wp_nonce_field('custom_image_nonce', 'custom_image_nonce_field');

  echo '<div class="postbox">';
  echo '<div id="custom-image-wrapper">';
  if ($image_url){
    echo '<img src="' . esc_url($image_url) . '">';
  }
  echo '</div>';
  echo '<p>';
  echo '<button type="button" class="button" id="custom-image-upload-button">';
  if ($image_url){
    echo '画像を変更';
  } else {
    echo '画像を追加';
  }
  echo '</button>';
  if ($image_url){
    echo '<button type="button" class="button" id="custom-image-remove-button">画像を削除</button>';
  }
  echo '</p>';
  echo '<input type="hidden" id="custom-image-id" name="custom_image_id" value="' . esc_attr($image_id) . '">';
  echo '</div>';
}

JSで使用するセレクタもあるので、名称変更の際はJSファイルにも反映すること。

メディアアップローダを処理するJS(jQuery)を組み込む

以下の内容を custom-image-uploader.js としてテーマディレクトリに保存。これはJSファイルなので間違えないこと!

jQuery(document).ready(function ($) {
  var mediaUploader;

  $('#custom-image-upload-button').on('click', function (e) {
    e.preventDefault();

    if (mediaUploader) {
      mediaUploader.open();
      return;
    }

    mediaUploader = wp.media({
      title: '画像を選択',
      button: {
        text: '画像を選択'
      },
      multiple: false
    });

    mediaUploader.on('select', function () {
      var attachment = mediaUploader.state().get('selection').first().toJSON();
      $('#custom-image-id').val(attachment.id);
      $('#custom-image-wrapper').html('<img src="' + attachment.sizes.thumbnail.url + '" style="max-width: 100%; height: auto;" />');
      $('#custom-image-remove-button').show();
    });

    mediaUploader.open();
  });

  $('#custom-image-remove-button').on('click', function (e) {
    e.preventDefault();
    $('#custom-image-id').val('');
    $('#custom-image-wrapper').html('');
    $(this).hide();
  });
});

メタボックスの値を保存処理するコード

function save_custom_image_meta_box_data($post_id) {
  // セキュリティチェック
  if (!isset($_POST['custom_image_nonce_field']) || !wp_verify_nonce($_POST['custom_image_nonce_field'], 'custom_image_nonce')) {
    return;
  }

  // 自動保存時は処理をスキップ
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    return;
  }

  // 権限のチェック(必要であれば)
  if (!current_user_can('edit_post', $post_id)) {
    return;
  }

  // 画像IDを保存
  if (isset($_POST['custom_image_id'])) {
    update_post_meta($post_id, 'custom_image_id', sanitize_text_field($_POST['custom_image_id']));
  }
}
add_action('save_post', 'save_custom_image_meta_box_data');

複数のフィールド設置たい場合は、単純に追加するフィールドのコードを付け足してあげればいい。