WordPress メタボックスでメディアライブラリ呼出し
概要
「WordPress メタボックスでファイルアップロード」の続き。記事編集ページに、メディアライブラリを使ってファイルアップロードする機能を追加する処理の説明。
サンプルコードは以下。
https://github.com/kztomita/wordpress-plugin-sample-metabox
全体の説明は「WordPress メタボックス追加サンプルコード」を参照。
メディアライブラリを使ったアップロードを行うメタボックスの説明
sample-metabox-admin-media.phpの説明。
sample-metabox-admin-media.phpは図1に示すメタボックスを追加する。「ファイル選択」をクリックすると、図2のメディアライブラリが開き、ファイルをアップロード/選択すると、図1のテキストボックスに選択したファイルのURLが設定される。
処理はメタボックスの表示処理、保存処理とメディアライブラリ関連処理の三つに分かれる。
図1 sample-metabox-admin-media.phpが追加するメタボックス
図2 メディアライブラリ
メタボックス表示処理
function sample_metabox_add_media() { wp_nonce_field('sample_metabox', 'sample_metabox_media_nonce'); $id = get_the_ID(); $post_meta = get_post_meta($id, SAMPLE_METABOX_METAKEY_MEDIA, true); $value = $post_meta ? $post_meta['url'] : ''; $value_esc = esc_url($value); $name = SAMPLE_METABOX_NAME_MEDIA; $link_id = SAMPLE_METABOX_ID_ADD_MEDIA; echo <<<END_OF_TEXT <p><input type="text" name="{$name}" id="{$name}" value="{$value_esc}" style="width:90%;" /></p> <p><a href="javascript:void(0);" id="{$link_id}" class="button">ファイル選択</a></p> END_OF_TEXT; } function sample_metabox_add_meta_boxes_media() { add_meta_box('id_sample_metabox_media', 'メディアライブラリを使ったファイルのアップロードと選択', 'sample_metabox_add_media', 'post', 'normal', 'high'); } add_action('add_meta_boxes', 'sample_metabox_add_meta_boxes_media'); function sample_metabox_enqueue_scripts($hook) { if ($hook == 'post.php' || $hook == 'post-new.php') { $url = plugins_url('js/media_upload.js', __FILE__); wp_enqueue_script('media_upload', $url); } } add_action('admin_enqueue_scripts', 'sample_metabox_enqueue_scripts');
メタボックスの表示処理はチェックボックスのものとほぼ同じ。メディアライブラリのオープン処理と、画像選択時のURL取得処理でJavaScriptが必要になるため、admin_enqueue_scriptsアクションでjs/media_upload.jsを読み込むように指定している。
保存処理
function sample_metabox_save_media($post_id) { if (!isset($_POST['sample_metabox_media_nonce'])) { return; } if (!wp_verify_nonce($_POST['sample_metabox_media_nonce'], 'sample_metabox')) { return; } if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } /* 権限チェック */ if (isset($_POST['post_type']) && 'page' == $_POST['post_type']) { if (!current_user_can('edit_page', $post_id)) { return; } } else { if (!current_user_can('edit_post', $post_id)) { return; } } $url = isset($_POST[SAMPLE_METABOX_NAME_MEDIA]) && is_string($_POST[SAMPLE_METABOX_NAME_MEDIA]) ? esc_url_raw($_POST[SAMPLE_METABOX_NAME_MEDIA]) : ''; if($url !== ''){ $post_meta = array('url' => $url); update_post_meta($post_id, SAMPLE_METABOX_METAKEY_MEDIA, $post_meta); } else { delete_post_meta($post_id, SAMPLE_METABOX_METAKEY_MEDIA); } } /* * save_post_{$post_type}のactionを使用 * 全post_typeを対象にするなら、save_post actionを使用 */ add_action('save_post_post', 'sample_metabox_save_media');
お決まりのnonce、自動保存、権限チェックを行った後は、URLが格納されているテキストボックスの内容をpost_metaに保存しているだけ。ファイルのアップロード自体はメディアライブラリで行うため、保存処理は簡単なものになっている。
メディアライブラリ関連処理(media_upload.js)
jQuery(document).ready(function () { // // media modalの処理 // // カスタムしたmedia modalの作成 function createCustomMedia() { var media = wp.media({ title: 'ファイルアップロード', library: {type: ''}, frame: 'select', button: {text: '選択'}, multiple: false }); return media; } var customMedia; jQuery('#sample_metabox_add_media').click(function (event) { event.preventDefault(); if (customMedia) { customMedia.open(); return; } customMedia = createCustomMedia(); customMedia.on('select', function() { var attachment = customMedia.state().get('selection').first().toJSON(); jQuery('#sample_metabox_media_url').val(attachment.url); }); customMedia.open(); }); });
メディアライブラリはwp.mediaを使って制御する。wp.mediaは、オブジェクトを生成する際のコンストラクタに渡す引数で、色々カスタマイズができる。wp.mediaオブジェクトを生成したあとはselectイベントのハンドラを定義して、ファイル選択時にURLをテキストボックスに設定するようにしている。以上でメディアライブラリの設定は終わりで、media.open()を呼び出せば、メディアライブラリが開く。
メディアライブラリで画像のみを対象にしたいなら、コンストラクタに渡す引数でlibrary.typeを'images'にすればよい。
メディアライブラリでファイルアップロードを実装する例として、'media-upload.php?type=image&TB_iframe=true'をThickBoxで開く例がよく紹介されているが、この方法では、選択ファイルのURLを横取りするためにsend_to_editor()関数を書き換える必要があり、複雑になる。実際、send_to_editor()を壊したままで、通常の記事内への画像挿入が出来なくなってしっている例もみられる。後、media-upload.phpで開かれるメディアライブラリは項目が多くて使い辛い。wp.mediaを使う方が、選択時の処理はselectイベントできれいに記述できるし、メディアライブラリ自体のカスタマイズもコンストラクタのパラメータでできるため、おすすめだ。