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');