WPのメディアアップローダを自作フォームに組み込む
WPのダッシュボード内では多機能で安定して動作する「メディア・アップローダ」があるが、これをオリジナルで作ったフォーム(フロント・バックを問わず)で流用できないかという話。
もちろんできる。
基本は必要なスクリプトを読み込み、jQueryを1行書けばアップローダは立ち上がる。
しかし多くの場合、アップロードされたファイルの画像ファイルやpost_idを獲得してフォームに埋め込む処理が必要なので、その部分のスクリプトも記述する。
フォーム部分
input type=”file”タグなどは必要ない。反応するボタンがあればそれでいい。
だが、ほとんどの場合アップロードしたファイルのIDなどを記録するためのhiddenフィールド、およびアップロードした画像をプレビューするためのdivも合わせて必要になる。
<form method='post'> <div class="image-upload-wrap"> <div class='image-preview-wrapper'> <img id='image-preview-1' src='' height='100'> </div> <input id="upload_image_button-1" type="button" class="button upload_image_button" value="画像1アップロード" /> <input type='hidden' name='image1' id='image_attachment_id-1' value='' /> </div> <input type="submit" name="submit_image_selector" value="Save" class="button-primary"> </form> |
スクリプト(ライブラリ)の読み込み
ここが実に簡単でwp_enqueue_media()という関数を、’wp_enqueue_scripts’などのフックに掛けておけば良い。テーマのfunctions.phpに書いておけば良いだろう。
function my_media_script(){ wp_enqueue_media(); } add_action( 'wp_enqueue_scripts', 'my_media_script' ); |
メインのスクリプト
メインのスクリプトは以下。enqueueするなり直に入れるなりして動作させる。
function media_selector_print_scripts() { $my_saved_attachment_post_id = get_option( 'media_selector_attachment_id', 0 ); ?><script type='text/javascript'> jQuery( document ).ready( function( $ ) { // Uploading files var file_frame; var wp_media_post_id = wp.media.model.settings.post.id; // Store the old id var set_to_post_id = <?php echo $my_saved_attachment_post_id; ?>; // Set this jQuery('.upload_image_button').on('click', function( event ){ event.preventDefault(); // If the media frame already exists, reopen it. btn_id = $(this).attr('id'); btn_no = btn_id.replace('upload_image_button-' , ''); if ( file_frame ) { // Set the post ID to what we want //file_frame.uploader.uploader.param( 'post_id', set_to_post_id ); // Open frame file_frame.open(); return; } else { // Set the wp.media post id so the uploader grabs the ID we want when initialised //wp.media.model.settings.post.id = set_to_post_id; } // Create the media frame. file_frame = wp.media.frames.file_frame = wp.media({ title: 'Select a image to upload', button: { text: 'Use this image', }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. file_frame.on( 'select', function() { // We set multiple to false so only get one image from the uploader attachment = file_frame.state().get('selection').first().toJSON(); // Do something with attachment.id and/or attachment.url here $( '#image-preview-'+btn_no ).attr( 'src', attachment.sizes.thumbnail.url ).css( 'width', 100 ); $( '#image_attachment_id-'+btn_no ).val( attachment.id ); // Restore the main post ID //wp.media.model.settings.post.id = wp_media_post_id; }); // Finally, open the modal file_frame.open(); }); // Restore the main ID when the add media button is pressed jQuery( 'a.add_media' ).on( 'click', function() { //wp.media.model.settings.post.id = wp_media_post_id; }); }); </script><?php } |
以上で、アップローダが立ち上がり、画像を選択するとhiddenに画像のIDが入るので、これをフォームの処理部にて保存するようにすれば良い。
ちなみに今回のコードは1フォームにつき1箇所でしか使えないが、メインのスクリプトを少しいじれば複数個でも対応できるはずだ。いずれ機会があれば紹介したい。
#UPDATE
上記のコードは複数箇所設置可能なものにアレンジした。
#UPDATE2
上記のコードは添付ファイルの処理が含まれ、固定ページでの実装など添付を目的としない場合アップロード権限エラーが発生した。よってpostIDを紐付ける部分をすべてコメントアウトした。
#追記
この実装の場合アップローダと一緒にメディアのタブが開き、アップされている全ユーザーの画像が出てきてしまう。それで支障がある場合、以下のプラグインが利用できるようだ。
restrict media library access
#UPDATE3
このままだと、投稿画面に追加されるサムネール画像が元画像になってしまって無駄に重くなるので、
attachment.urlを
attachment.sizes.thumbnail.url
に変更。