Step 1: Add Meta Boxes for Each Field
Step 2: Display Each Meta Box
// Profile Image Meta Box function profile_image_box_callback($post) { $image_ids = get_post_meta($post->ID, 'profile_image_gallery', true); $image_ids = is_array($image_ids) ? $image_ids : []; wp_nonce_field('profile_image_box_nonce', 'profile_image_box_nonce_field'); ?> <div id="profile-image-gallery-wrapper"> <ul class="custom-images-list"> <?php foreach ($image_ids as $image_id) : ?> <li> <?php echo wp_get_attachment_image($image_id, 'thumbnail'); ?> <a href="#" class="custom-remove-image" data-image-id="<?php echo esc_attr($image_id); ?>">Remove</a> </li> <?php endforeach; ?> </ul> <input type="hidden" id="profile_image_gallery" name="profile_image_gallery" value="<?php echo implode(',', $image_ids); ?>"> <button type="button" class="button" id="profile_upload_images_button">Add Images</button> </div> <?php } // Similar code for biography and photo gallery callbacks...
Step 3: Enqueue JavaScript with Separate Handlers
jQuery(document).ready(function($) { function mediaUploaderHandler(buttonId, inputFieldId, galleryWrapperId) { var mediaUploader; $(buttonId).on('click', function(e) { e.preventDefault(); if (mediaUploader) { mediaUploader.open(); return; } mediaUploader = wp.media.frames.file_frame = wp.media({ title: 'Choose Images', button: { text: 'Add Images' }, multiple: true }); mediaUploader.on('select', function() { var attachments = mediaUploader.state().get('selection').map(function(attachment) { attachment = attachment.toJSON(); return attachment.id; }); var imageList = $(galleryWrapperId + ' .custom-images-list'); var imageField = $(inputFieldId); var currentImageIds = imageField.val().split(',').filter(Boolean); // Check if total number of images exceeds the limit (20) if (currentImageIds.length + attachments.length > 20) { alert('You can only upload a maximum of 20 images.'); return; } $.each(attachments, function(index, imageId) { if (!currentImageIds.includes(imageId.toString())) { currentImageIds.push(imageId); imageList.append('<li>' + wp.media.attachment(imageId).get('sizes').thumbnail.url + '<a href="#" class="custom-remove-image" data-image-id="' + imageId + '">Remove</a></li>'); } }); imageField.val(currentImageIds.join(',')); }); mediaUploader.open(); }); } // Initialize for each meta box mediaUploaderHandler('#profile_upload_images_button', '#profile_image_gallery', '#profile-image-gallery-wrapper'); mediaUploaderHandler('#biography_upload_images_button', '#biography_image_gallery', '#biography-image-gallery-wrapper'); mediaUploaderHandler('#photo_gallery_upload_images_button', '#photo_gallery', '#photo-gallery-wrapper'); // Remove image from the gallery $(document).on('click', '.custom-remove-image', function(e) { e.preventDefault(); var imageId = $(this).data('image-id'); var imageField = $(this).closest('.custom-image-box').find('input[type="hidden"]'); var currentImageIds = imageField.val().split(',').filter(Boolean); var newImageIds = currentImageIds.filter(function(id) { return id !== imageId.toString(); }); imageField.val(newImageIds.join(',')); $(this).closest('li').remove(); }); });
Step 4: Save the Meta Box Data for Each Field
function custom_save_meta_boxes($post_id) { // Profile Image Save if (isset($_POST['profile_image_box_nonce_field']) && wp_verify_nonce($_POST['profile_image_box_nonce_field'], 'profile_image_box_nonce')) { if (isset($_POST['profile_image_gallery'])) { $image_ids = array_map('intval', explode(',', $_POST['profile_image_gallery'])); if (count($image_ids) > 20) { $image_ids = array_slice($image_ids, 0, 20); } update_post_meta($post_id, 'profile_image_gallery', $image_ids); } else { delete_post_meta($post_id, 'profile_image_gallery'); } } // Biography Image Save if (isset($_POST['biography_image_box_nonce_field']) && wp_verify_nonce($_POST['biography_image_box_nonce_field'], 'biography_image_box_nonce')) { if (isset($_POST['biography_image_gallery'])) { $image_ids = array_map('intval', explode(',', $_POST['biography_image_gallery'])); if (count($image_ids) > 20) { $image_ids = array_slice($image_ids, 0, 20); } update_post_meta($post_id, 'biography_image_gallery', $image_ids); } else { delete_post_meta($post_id, 'biography_image_gallery'); } } // Photo Gallery Save if (isset($_POST['photo_gallery_box_nonce_field']) && wp_verify_nonce($_POST['photo_gallery_box_nonce_field'], 'photo_gallery_box_nonce')) { if (isset($_POST['photo_gallery'])) { $image_ids = array_map('intval', explode(',', $_POST['photo_gallery'])); if (count($image_ids) > 20) { $image_ids = array_slice($image_ids, 0, 20); } update_post_meta($post_id, 'photo_gallery', $image_ids); } else { delete_post_meta($post_id, 'photo_gallery'); } } } add_action('save_post', 'custom_save_meta_boxes');