WordPressを使ったサイト制作や運用の中で、「記事ごとに独自の画像を管理したい」「カテゴリーごとにアイコン画像を設定したい」といった要望は少なくありません。特にクライアント案件や自社メディア運営では、標準のアイキャッチ画像や本文への直接挿入では限界があり、もっと柔軟に画像を扱いたいと感じる瞬間があるはずです。しかし実際に「カスタムフィールドで画像をアップロードできるようにする方法」を調べると、情報が断片的だったり、プラグイン前提の解説が多かったりして、なかなかスムーズに導入できないのが現状です。
そこで本記事では、「WordPressのカスタムフィールドに画像アップロード機能を追加し、自在に管理・表示する方法」を、プラグイン不要のコード例を中心に丁寧に解説します。functions.phpへの記述から、wp.media()
APIを使った管理画面の拡張、複数画像のアップロードや並び替え、さらにはSEOやパフォーマンスを意識した最適化まで網羅的にご紹介します。
この記事を読めば、初めてカスタムフィールドで画像を扱う方でも、クライアント案件や自社サイトでそのまま応用できる実践的な知識が身につきます。
WordPressのカスタマイズ力を一段と高め、より柔軟なサイト構築を実現したい方にとって、実務レベルで役立つ内容を凝縮しています。
WordPressカスタムフィールドで画像アップロード機能を実装する基本
WordPressでブログやウェブサイトを制作していると、標準の投稿エディタだけでは実現できない複雑な要件に直面することがよくあります。その一つが「投稿ごとに決まった形式で画像を管理・表示したい」というニーズです。
例えば、製品紹介サイトで商品画像をギャラリー形式で表示したい、ポートフォリオサイトで制作実績の画像を登録したいといった場合、カスタムフィールドが非常に役立ちます。カスタムフィールドを使えば、投稿本文とは別に画像アップロード専用の項目を設けることができ、運用がぐっと効率的になります。
本記事では、WordPressのカスタムフィールドを使って画像アップロード機能を自作する方法を、具体的なコードを交えながら徹底的に解説します。プラグインに頼らず、PHPとWordPressの標準機能を活用することで、より柔軟で軽量なサイト構築を目指しましょう。
カスタムフィールドで画像アップロード機能を作る基本手順
WordPressでカスタムフィールドを使って画像アップロード機能を作るには、主に以下の3つのステップが必要です。
1.管理画面にカスタムフィールドの入力欄を追加する:
投稿編集画面に、画像アップロードボタンや画像プレビューを表示するための入力欄(メタボックス)を追加します。この入力欄は、add_meta_box()
関数を使って作成するのが一般的です。
2.wp.media()
APIで画像選択・アップロード機能を実装する:
追加した入力欄の「画像を選択」ボタンなどをクリックした際に、WordPress標準のメディアライブラリを開くためのJavaScriptコードを記述します。これにはwp.media()
APIが非常に便利です。
3.アップロードした画像のデータを保存・取得する:
ユーザーが選択した画像の情報を、投稿のメタデータとしてデータベースに保存します。そして、サイトの表示側(フロントエンド)でその画像データを取得し、HTMLに出力します。
これから、これらの手順を具体的なPHPとJavaScriptのコードを見ながら解説していきます。
wp.media() APIでJavaScript画像選択機能を追加する手順
WordPressのカスタムフィールドで画像を選択・アップロードする際のUI(ユーザーインターフェース)は、wp.media()
APIを使って実装するのが一般的です。このAPIは、WordPressのメディアライブラリを呼び出し、画像を選択・アップロード・削除といった一連の操作を簡単に行えるようにしてくれます。
まず、投稿編集画面に画像アップロード用の入力欄とボタンを追加します。functions.php
に以下のコードを追加してください。
<?php
/**
* 投稿編集画面に画像アップロード用のメタボックスを追加
*/
function my_custom_image_meta_box() {
add_meta_box(
'my_custom_image_uploader', // メタボックスのID
'カスタム画像', // メタボックスのタイトル
'my_custom_image_callback', // メタボックスのコンテンツを表示するコールバック関数
'post', // 対象の投稿タイプ(例: 'post', 'page'など)
'normal', // 表示位置
'high' // 優先度
);
}
add_action('add_meta_boxes', 'my_custom_image_meta_box');
/**
* メタボックスのコンテンツ(HTML)
*/
function my_custom_image_callback($post) {
// 投稿に保存されている画像IDを取得
$image_id = get_post_meta($post->ID, '_my_custom_image_id', true);
$image_url = wp_get_attachment_url($image_id);
?>
<div id="custom-image-container">
<input type="hidden" name="my_custom_image_id" id="my_custom_image_id" value="<?php echo esc_attr($image_id); ?>" />
<img id="custom-image-preview" src="<?php echo esc_url($image_url); ?>" style="max-width: 250px; height: auto;" />
<button id="upload-custom-image-button" class="button">画像を選択</button>
<button id="remove-custom-image-button" class="button button-secondary">画像を削除</button>
</div>
<?php
}
?>

次に、このHTMLのボタンにメディアライブラリの機能を紐づけるJavaScriptを記述します。WordPress管理画面でJavaScriptを読み込むには、wp_enqueue_script()
関数を使用します。
<?php
/**
* メディアアップローダーのJavaScriptを読み込む
*/
function my_custom_image_scripts($hook) {
if ('post.php' != $hook && 'post-new.php' != $hook) {
return;
}
wp_enqueue_media();
wp_enqueue_script('my-custom-image-js', get_theme_file_uri() . '/js/custom-image-uploader.js', array('jquery'), '1.0', true);
}
add_action('admin_enqueue_scripts', 'my_custom_image_scripts');
?>
上記のコードでは、テーマディレクトリ内のjs/custom-image-uploader.js
というファイルを読み込むように設定しています。このcustom-image-uploader.js
の中身は以下のようになります。
jQuery(function($) {
var custom_uploader;
$('#upload-custom-image-button').click(function(e) {
e.preventDefault();
// メディアアップローダーのインスタンスがなければ作成
if (custom_uploader) {
custom_uploader.open();
return;
}
custom_uploader = wp.media({
title: '画像を選択してください',
button: {
text: 'この画像を使用'
},
multiple: false // 複数画像の選択を許可しない
});
// 画像が選択された時の処理
custom_uploader.on('select', function() {
var attachment = custom_uploader.state().get('selection').first().toJSON();
$('#my_custom_image_id').val(attachment.id);
$('#custom-image-preview').attr('src', attachment.url);
});
custom_uploader.open();
});
// 画像削除ボタンの処理
$('#remove-custom-image-button').click(function(e) {
e.preventDefault();
$('#my_custom_image_id').val('');
$('#custom-image-preview').attr('src', '');
});
});
このJavaScriptコードにより、「画像を選択」ボタンが押されたときにメディアライブラリが開き、ユーザーが選択した画像のIDとURLを取得して、隠しフィールドとプレビュー画像に反映させることができます。

get_post_meta()でアップロード画像を取得・表示する具体例
管理画面で画像IDを保存したら、次はサイトの表示側でその画像を取得して表示させる必要があります。この際に使うのが、WordPressの標準関数get_post_meta()
です。
get_post_meta()
は、特定の投稿のカスタムフィールドの値を取得するために使用されます。第一引数に投稿ID、第二引数にカスタムフィールドのキー(先ほどの例では_my_custom_image_id
)、第三引数に真偽値(true
にすると単一の値、false
にすると配列として取得)を指定します。
functions.php
に以下の保存処理のコードを追加してください。
<?php
/**
* 投稿が保存されたときにメタデータを保存
*/
function save_my_custom_image_meta_box($post_id) {
// セキュリティチェック
if (!isset($_POST['my_custom_image_id'])) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
// データの保存
$image_id = intval($_POST['my_custom_image_id']);
if (!empty($image_id)) {
update_post_meta($post_id, '_my_custom_image_id', $image_id);
} else {
delete_post_meta($post_id, '_my_custom_image_id');
}
}
add_action('save_post', 'save_my_custom_image_meta_box');
?>
このコードは、投稿が保存されたときに隠しフィールドmy_custom_image_id
の値をデータベースに保存します。

続いて、画像の表示処理をテーマファイルに記述します。例えば、single.php
(投稿の詳細ページ)に表示したい場合は、以下のコードを記述します。
<?php
// 現在の投稿のカスタムフィールドから画像IDを取得
$image_id = get_post_meta(get_the_ID(), '_my_custom_image_id', true);
if ($image_id) {
// 画像IDを使って、任意のサイズの画像HTMLを取得
echo wp_get_attachment_image($image_id, 'large');
} else {
// 画像がない場合は、デフォルト画像を表示
echo '<img src="' . get_template_directory_uri() . '/images/default.png" alt="デフォルト画像" />';
}
?>
上記のコードでは、wp_get_attachment_image()
関数を使って、画像IDからHTMLタグを生成しています。'large'
はWordPressに標準で用意されている画像サイズです。これにより、投稿に設定されたカスタム画像が簡単に表示されます。
実際の表示( 個別投稿ページ)

複数画像の管理・表示テクニック
単一の画像だけでなく、複数の画像をカスタムフィールドで管理したいというニーズも多いでしょう。例えば、商品ギャラリーやポートフォリオのようなケースです。この場合も、WordPressの標準機能を使って実装することが可能です。
カスタムフィールドで複数画像アップロードを可能にする実装例
単一の画像アップロードの仕組みを応用することで、複数の画像を管理する仕組みを作ることができます。基本的な考え方は、複数の画像IDを配列としてデータベースに保存することです。
先ほどのコードを修正し、multiple: true
に設定することでメディアライブラリで複数画像を選択できるようにし、_my_custom_image_ids
というキーで複数の画像IDを保存するように変更します。
my_custom_image_callback()
関数を以下のように修正します。
<?php
/**
* メタボックスのコンテンツ(HTML)
*/
function my_custom_image_callback($post) {
$image_ids = get_post_meta($post->ID, '_my_custom_image_ids', true);
if (!is_array($image_ids)) {
$image_ids = [];
}
?>
<div id="custom-multi-image-container">
<input type="hidden" name="my_custom_image_ids" id="my_custom_image_ids" value="<?php echo esc_attr(implode(',', $image_ids)); ?>" />
<div id="image-gallery-preview">
<?php foreach ($image_ids as $image_id) : ?>
<?php echo wp_get_attachment_image($image_id, 'thumbnail', false, ['data-id' => $image_id]); ?>
<?php endforeach; ?>
</div>
<button id="upload-multi-image-button" class="button">画像を選択</button>
<button id="clear-multi-image-button" class="button button-secondary">全て削除</button>
</div>
<?php
}
JavaScriptのコードも同様に修正が必要です。複数選択を許可し、選択された画像IDをカンマ区切りの文字列としてinput
にセットするようにします。
jQuery(function($) {
var custom_uploader;
$('#upload-multi-image-button').click(function(e) {
e.preventDefault();
if (custom_uploader) {
custom_uploader.open();
return;
}
custom_uploader = wp.media({
title: '画像を選択してください',
button: {
text: 'この画像を使用'
},
multiple: true // 複数画像の選択を許可
});
custom_uploader.on('select', function() {
var selection = custom_uploader.state().get('selection');
var imageIds = [];
var galleryHtml = '';
selection.each(function(attachment) {
imageIds.push(attachment.id);
galleryHtml += '<img src="' + attachment.attributes.url + '" data-id="' + attachment.id + '" style="max-width: 150px; height: auto;" />';
});
$('#my_custom_image_ids').val(imageIds.join(','));
$('#image-gallery-preview').html(galleryHtml);
});
custom_uploader.open();
});
$('#clear-multi-image-button').click(function(e) {
e.preventDefault();
$('#my_custom_image_ids').val('');
$('#image-gallery-preview').html('');
});
});
最後に、PHPの保存処理と表示処理も複数画像に対応させます。
<?php
/**
* 複数画像を保存
*/
function save_my_custom_multi_image_meta_box($post_id) {
if (!isset($_POST['my_custom_image_ids'])) {
return;
}
// ... セキュリティチェックは省略 ...
$image_ids_str = sanitize_text_field($_POST['my_custom_image_ids']);
$image_ids = explode(',', $image_ids_str);
update_post_meta($post_id, '_my_custom_image_ids', $image_ids);
}
add_action('save_post', 'save_my_custom_multi_image_meta_box');
/**
* 複数画像を表示
*/
$image_ids = get_post_meta(get_the_ID(), '_my_custom_image_ids', true);
if (is_array($image_ids)) {
foreach ($image_ids as $image_id) {
echo wp_get_attachment_image($image_id, 'medium');
}
}
?>
実際の表示



一括アップロードした画像をギャラリーやスライダーで表示する方法
複数の画像をカスタムフィールドに登録できたら、次はそれをギャラリーやスライダーとして魅力的に見せる段階です。これは、WordPressの機能だけでなく、JavaScriptのライブラリと組み合わせるのが一般的です。
例えば、SlickやSwiper.jsといったライブラリを使えば、簡単にスライダーを実装できます。以下のPHPコードは、登録された画像をSlickスライダーに対応したHTML構造で出力する例です。

<?php
$image_ids = get_post_meta(get_the_ID(), '_my_custom_image_ids', true);
if (is_array($image_ids) && count($image_ids) > 0) :
?>
<div class="my-image-slider">
<?php foreach ($image_ids as $image_id) : ?>
<div>
<?php echo wp_get_attachment_image($image_id, 'large'); ?>
</div>
<?php endforeach; ?>
</div>
<script>
jQuery(document).ready(function($){
$('.my-image-slider').slick({
dots: true,
arrows: false,
infinite: true,
speed: 500,
fade: true,
cssEase: 'linear'
});
});
</script>
<?php endif; ?>
このコードでは、my-image-slider
というクラスを持つdiv
の中に各画像を出力し、その後にSlickライブラリの初期化コードを記述しています。Slickのライブラリ自体は別途読み込む必要があります。
ドラッグ&ドロップで画像順序を変更する管理画面UIの作り方
さらに高度なUIとして、管理画面で画像の順序をドラッグ&ドロップで自由に変更できるようにしたいという要望もあるでしょう。これはjQuery UIのSortable機能を使うことで実装可能です。
まず、WordPressの管理画面でjQuery UIを読み込むようにします。
wp_enqueue_script('jquery-ui-sortable');
次に、複数画像を表示しているdiv
(例: #image-gallery-preview
)に対して、Sortableを適用するJavaScriptを追加します。
jQuery(function($) {
// ... (画像アップロードのJavaScriptコードは省略) ...
// Sortableを適用
var galleryPreview = $('#image-gallery-preview');
galleryPreview.sortable({
update: function(event, ui) {
var newOrderIds = [];
galleryPreview.find('img').each(function() {
newOrderIds.push($(this).data('id'));
});
$('#my_custom_image_ids').val(newOrderIds.join(','));
}
});
});
このコードは、画像の並び替えが完了した際に、新しい順序で画像IDを再取得し、my_custom_image_ids
という隠しフィールドの値を更新します。これにより、保存ボタンを押したときに新しい順序がデータベースに反映されるようになります。
画像サイズ・最適化・エラー対策
カスタムフィールドでアップロードした画像を適切に表示するためには、サイズ管理や最適化、そして予期せぬエラーへの対策が不可欠です。
add_image_size()で独自のカスタムサイズを定義する方法
WordPressは、画像をアップロードする際に、自動的にいくつかの標準サイズ(thumbnail
, medium
, large
など)を生成します。しかし、特定のデザイン要件に合わせて独自のサイズが必要になることがよくあります。

この場合、functions.php
にadd_image_size()
関数を使って新しいカスタムサイズを定義することができます。
<?php
/**
* カスタム画像サイズを追加
*/
function my_custom_image_sizes() {
// 300px x 200px (トリミング)
add_image_size('portfolio-thumb', 300, 200, true);
// 幅768px (高さは比率を維持)
add_image_size('blog-main', 768, 9999);
}
add_action('after_setup_theme', 'my_custom_image_sizes');
?>
add_image_size()
の引数は、順にサイズ名、幅、高さ、トリミングの有無です。定義したサイズは、先ほどのwp_get_attachment_image()
関数で利用できます。
<?php
echo wp_get_attachment_image($image_id, 'portfolio-thumb');
?>
画像アップロード時の自動リサイズ・圧縮とalt・キャプションの取得方法
アップロードされる画像のファイルサイズが大きいと、サイトの表示速度が低下してしまいます。これを防ぐには、画像をアップロードしたときに自動でリサイズや圧縮を行うプラグイン(例:EWWW Image Optimizer)を導入するか、テーマ側で処理を実装する方法があります。

また、画像のalt
属性やキャプションは、SEOやアクセシビリティにとって非常に重要です。wp_get_attachment_image()
関数は、これらの情報も自動で取得してHTMLタグに含めてくれます。
<?php
// wp_get_attachment_image()は自動的にalt属性などを出力してくれる
echo wp_get_attachment_image($image_id, 'large');
?>
もし個別にalt
属性を取得したい場合は、get_post_meta()
を使って画像IDから直接取得することも可能です。
<?php
$alt_text = get_post_meta($image_id, '_wp_attachment_image_alt', true);
?>
アップロードエラー(HTTPエラー等)の原因と解決策
カスタムフィールドでの画像アップロード時に「HTTPエラー」などの問題が発生することがあります。これらの原因は多岐にわたりますが、多くはサーバーの設定やファイルの権限に関連しています。
主な原因と解決策:
- サーバーのファイルサイズ制限(
upload_max_filesize
):php.ini
でupload_max_filesize
やpost_max_size
の値を大きく設定してください。
- メモリ制限(
memory_limit
):- 大容量の画像をアップロードする際にメモリが不足することがあります。
memory_limit
の値を増やしてみてください。
- 大容量の画像をアップロードする際にメモリが不足することがあります。
- ファイル・ディレクトリのパーミッション:
wp-content/uploads
ディレクトリのパーミッションが適切でない(通常は755)場合、書き込みエラーが発生します。FTPソフトなどでパーミッションを確認・変更してください。
- プラグインの競合:
- 別のプラグインがメディアアップローダーに影響を与えている可能性があります。他のプラグインを一時的に無効にして原因を特定してください。
- SSL証明書の問題:
- SSL化しているサイトで、設定が不完全な場合、混合コンテンツエラー(httpとhttpsが混在)によりアップロードが失敗することがあります。
よくある質問(FAQ)
-
プラグイン(ACFなど)と自作コード、どちらが良いですか?
-
手軽さや開発スピードを優先するなら、ACF (Advanced Custom Fields)などの高機能なプラグインがおすすめです。特に複雑なフィールド(リピーター、柔軟なコンテンツなど)を扱う場合、プラグインの方がはるかに効率的です。
一方、自作コードは、軽量でサイトに不要な機能を入れないため、パフォーマンスを重視する場合に適しています。シンプルな画像アップロード機能だけで十分な場合や、将来的にテーマを他者に配布・販売することを考えている場合にも有効です。
-
アップロードした画像はどこに保存されますか?
-
WordPressの標準のメディアアップローダーを経由してアップロードされた画像は、
wp-content/uploads
ディレクトリに保存されます。カスタムフィールドからアップロードした場合も同様です。
-
カテゴリーやカスタムタクソノミーに画像を紐づけることはできますか?
-
可能です。
add_meta_box()
関数の投稿タイプをpost
ではなく、カスタムタクソノミーの編集画面に表示するようにフックを変えることで実装できます。これにより、特定のカテゴリーに代表画像を紐づけるといったことが可能になります。
まとめ
この記事では、WordPressのカスタムフィールドを使って画像アップロード機能を自作する方法について、基礎から応用までを解説しました。
自作コードでの実装は、プラグインに頼らない自由度の高いサイト構築を可能にし、あなたのWordPressスキルを一段階引き上げてくれます。本記事のコードを参考に、あなたのWordPressサイトに最適な画像管理機能を実装してみてください。