WordPress プラグインなしでカスタム投稿のカスタムフィールドにメディアを追加する方法Contents Management System

WordPress プラグインなしでカスタム投稿のカスタムフィールドにメディアを追加する方法

WordPress

フロントエンドエンジニアのかみーゆです。
みなさん、WordPressはお好きですか?
今回はプラグインを使わずにカスタムフィールドで画像を登録する方法のご紹介です。
投稿画面から便利にかんたんに複数の画像登録したくて探していたらJavaScript APIが使えることを知りました。
メディアを呼び出せるとリッチに画像をカスタムフィールドで登録できる機能を実装できます。

実例:商品登録などのカスタム投稿にスライドショーを追加

普通の投稿(ブログ記事以外)で投稿の種類を増やせるのがWordPressの便利なところですよね?
今回は商品という投稿を作って、いくつか画像を登録して投稿ごとに商品のスライドショーを作らなければなりませんでした。

プラグイン・カスタムフィールドアドバンスを利用すればカンタンなんでしょうけど「テーマをインストールした瞬間から設定なしで使える」状態を目指したかったので、カスタマイズすることになりました。

wpcustom02.png

私が実際に実装したカスタムした内容に限りなく近い状態での実装方法をご紹介します。

カスタム投稿を新規で作成

function.phpなどにcreate_post_typeという関数を作って、新たにカスタム投稿を追加します。

add_action()は特定のアクションに対して指定した関数をフックさせる関数です。

この場合 init なのでプラグインなどの初期化のタイミングに実行されます。

今回はあくまで「カスタムフィールドにメディア(画像登録)を追加する方法」のご紹介なので、詳しい説明は割愛します。

add_action( 'init', 'create_post_type' );
    
function create_post_type() {
    $supports = array(
        'title',
        'editor',
        'author',
        'revisions',
    );
    
    register_post_type(
        'products', // カスタム投稿名
        array(
            'label' => '商品', // 管理画面の左メニューに表示されるテキスト
            'public' => true,
            'show_ui' => true,
            'show_in_menu' => true,
            'capability_type' => 'post',
            'rewrite' => true,
            'query_var' => false,
            'exclude_from_search' => false,
            'show_in_rest' => true,
            'rest_base' => 'products',
            'has_archive' => true, // アーカイブを有効にするか否か
            'menu_position' => 5, // 管理画面上でどこに配置するか今回の場合は「投稿」の下に配置
            'supports' => $supports // 投稿画面でどのmoduleを使うか的な設定
        )
    );
}

フックのタイミングは以下を参考にすると良いです。

プラグイン API/アクションフック一覧

カスタム投稿の編集画面にメタボックスの追加

add_meta_box()を使って登録エリアを作ります。

引数はこちらを参考にしてください。

関数リファレンス/add meta box

add_action( 'admin_menu', 'add_custom_fields' );
    
function add_custom_fields() {
    add_meta_box(
        'product_sectionid', //id(必須)
        '商品画像の登録',//title(必須)
        'product_custom_fields',//コールバック(必須)
        'products'//投稿の種類(必須、post、pageなど)
        'advanced',// 編集画面セクションが表示される部分(オプション)
        'default',//優先順位
    );
}

product_custom_fields関数内に実際登録させる内容コードを書きます。
以下のような感じで出力されます。

wpcustom01.png

今回は画像名と画像を3つまで登録できるようにしてみます。

実際のデータはフォームタグをhiddenで仕込んでおき、JSで動的に値を格納できるようにしておきます。

function product_custom_fields() {
    $product_image_name = array();
    $product_image = arra();
  
    // 3画像の格納
    for ( $i=0; $i < 3; $i++ ) {
        $product_image_name[] = get_post_meta( $post->ID, 'product-image-name_'.$i, true );
        $product_image[] = get_post_meta( $post->ID, 'product-image_'.$i, true );
    }    //登録画面に出力
?>
    <table class="form-table">
        <?php for ( $i=0; $i < 3; $i++ ):?>
            <tr class="form-field">
                <th scope="row">画像名<?php echo $i+ 1?></th>
                <td><input type="text" name="product-image-name_<?php echo $i?>" value="<?php echo esc_html($product_image_name[$i] ? $product_image_name[$i] : '')?>"></td>
            </tr>
            <tr class="form-field">
                <th scope="row">商品</th>
                <td>
                    <input type="hidden" id="product-image_<?php echo $i; ?>" name="product-image_<?php echo $i; ?>" value="<?php echo $product_image[$i] ? $product_image[$i] : '' ?>">
                    <div id="image-wrapper_<?php echo $i?>">
                    <?php if ( $product_image[$i] ) {
                        $product_thumb = wp_get_attachment_image_src ( $product_image[$i], 'thumbnail' );
                        ?>
                        <img src="<?php echo $product_thumb[0] ?>" width="<?php echo $product_thumb[1]; ?>" height="<?php echo $product_thumb[2]; ?>" class="custom_media_image">
                    <?php } ?>
                    </div>
                    <p><input type="button" class="button button-secondary media_button" name="media_button" value="追加" id="media-button_<?php echo $i?>" />
                    <input type="button" class="button button-secondary media_remove" name="media_remove" value="削除" id="media-remove_<?php echo $i?>"/></p>
                </td>
            </tr>
        <?php endfor;?>
    </table>
<?php
}

JavaScript APIの呼び出し

管理画面でメディアのJavaScript APIを利用してメディアのポップアップを呼び出せるようにします。

wp_enqueue_media()が無茶便利でした!

関数リファレンス/wp enqueue media

add_action( 'admin_enqueue_scripts', add_api );
    
function add_api() {
    wp_enqueue_media();
}

JavaScript APIの調整

編集画面にJavaScript APIを使って画像追加、削除ボタンから動的に画像を操作できるよう管理画面のfooterにJavaScriptを追加します。

 画像が選択されたら、JSで仕込んでおいたimgタグを表示するようにJavaScriptを仕込んでおきます。これで見た目もきれい。

wpcustom03.png

add_action( 'admin_footer', array ( $this, 'add_script' ) );
    
public function add_script() {
?>
<script>
    jQuery(document).ready(
        function($) {
            let _custom_media = true,
            _orig_send_attachment = wp.media.editor.send.attachment;
    
            // 画像の登録
            $( '.media_button' ).each(function(index) {
                $(this).on("click", function(){
                    let send_attachment_bkp = wp.media.editor.send.attachment;
                    wp.media.editor.send.attachment = function(props, attachment){
                        if ( _custom_media ) {
                            $('#product-image_'+index).val(attachment.id);
                            $('#image-wrapper_'+index).html('<img class="custom_media_image" src="' + attachment.sizes.thumbnail.url + '" height="' + attachment.sizes.thumbnail.height + '" width="' + attachment.sizes.thumbnail.width + '">');
                        } else {
                            return _orig_send_attachment.apply( $(this).id, [props, attachment] );
                        }
                    }
                    wp.media.editor.open($(this));
                    return false;
                });
            });
        
            // 削除
            $( '.media_remove').each(function(index) {
                $(this).on("click", function(){
                    $('#product-image_'+index).val('');
                    $('#image-wrapper_' + index + ' .custom_media_image').remove();
                });
            });
        });
    </script>
<?php }
}

画像と画像名を保存

画像と画像名を保存できるようにします。

add_action( 'save_post', 'save_products' );
    
function save_products( $post_id ) {
    // 画像
    for ( $i=0; $i < 3; $i++ ) {
        if ( isset( $_POST['product-image-name_'.$i] ) ){
            update_post_meta( $post_id, 'product-image-name_'.$i, $_POST['product-image-name_'.$i] );
        } else {
            delete_post_meta($post_id, 'product-image-name_'.$i);
        }
        // 画像の保存
        if( isset( $_POST['product-image_' . $i] ) ) {
            update_post_meta( $post_id, 'product-image_' . $i, $_POST['product-image_' . $i] );
        } else {
            delete_post_meta( $post_id, 'product-image_'.$i );
        }
    }
}

プラグインなしで実装するメリット

ぶっちゃけWordPressってプラグインの方が安定してますしすべての機能を網羅していて痒いところに手が届きます。しかも無料です。

しかし「すべての機能」を網羅しているがゆえに不要な機能もたくさん付いています

 

私のカスタマイズするメリットは以下のような感じです。

  • サイトの軽量化プラグインを減らして不要なJSやCSSを抑え軽くすることができる
  • 余計な機能を減らすことでユーザーが迷わない

 

利用するのはお客さん。

ブログなのか、企業サイトなのかなどで何を強化するなどがまったく違ってきますのでニーズに合わせてカスタマイズするのがディベロッパーの使命かと思います^ ^。

まとめ

こんな感じで、画像がカスタム投稿でもリッチに登録できるようになりました!!

工夫したらカテゴリーなどのサムネ登録などでも応用できます。

みなさんのコーディングライフの一助となれば幸いです。

 

最後までお読みいただきありがとうございました。

 

関連記事もあわせてお読みください

Read More Blogs

Web制作に関する人気の記事

セブ島・海外移住に関する人気の記事

キャリアアップ・ライフスタイルに関する人気の記事

管理人について

IT戦士:かみーゆ

「銀ねこアトリエ」へようこそ!フロントエンドエンジニアのかみーゆです。

  • 日本でフロントエンドを中心に約10年Web制作
  • 2019年4月「MacBook Pro とスーツケースだけで生きていこう」と、セブ島に移住
  • セブ島に転職してエンジニア講師
  • オフショア開発担当者
  • 疲れたので辞めてプータロー
  • 人生の充電中でセブ島ライフを満喫(イマココ)

好きな人といるだけでパワースポット!今は大好きな仲間と消耗しない働き方をするために計画中。
13歳の頃から「好きなように生きて好きなように死ぬ」が人生のKPI。
「楽しいか」、「かっこいいか」でやることを判断・取捨択一しています。好きなものは肉とビール。

About Me