Custom Gallery Metabox

Picture of Amitpal Singh
Amitpal Singh
September 24, 2021
				
					function custom_gallery_metabox() {
    add_meta_box(
        'custom_gallery_metabox',
        'Custom Gallery',
        'render_custom_gallery_metabox',
        'post',
        'normal',
        'high'
    );
}
add_action('add_meta_boxes', 'custom_gallery_metabox');

function render_custom_gallery_metabox($post) {
    // Retrieve saved image IDs
    $image_ids = get_post_meta($post->ID, '_custom_gallery', true) ?: [];
    ?>
    <style>
        #gallery-wrapper {
            margin-top: 10px;
        }
        #gallery-images {
            list-style: none;
            padding: 0;
            margin: 0;
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }
        .gallery-item {
            position: relative;
            width: 100px;
            height: 100px;
            border: 1px solid #ddd;
            overflow: hidden;
            border-radius: 4px;
            cursor: move;
        }
        .gallery-item img {
            width: 100%;
            height: auto;
        }
        .remove-image {
            position: absolute;
            top: 5px;
            right: 5px;
            background-color: #e74c3c;
            border: none;
            color: #fff;
            font-size: 12px;
            border-radius: 50%;
            cursor: pointer;
            padding: 2px 5px;
        }
    </style>

    <div id="gallery-wrapper">
        <ul id="gallery-images">
            <?php foreach ($image_ids as $image_id): ?>
                <li class="gallery-item" data-id="<?php echo esc_attr($image_id); ?>">
                    <?php echo wp_get_attachment_image($image_id, 'thumbnail'); ?>
                    <button type="button" class="remove-image">&times;</button>
                </li>
            <?php endforeach; ?>
        </ul>
        <button id="add-gallery-image" class="button">Add Images</button>
        <input type="hidden" name="custom_gallery" value="<?php echo esc_attr(implode(',', $image_ids)); ?>" id="custom-gallery-field">
    </div>

    <script>
        (function($) {
            $(document).ready(function() {
                var frame;

                // Make gallery sortable
                $('#gallery-images').sortable({
                    update: function() {
                        updateGalleryField();
                    }
                });

                // Open media frame to add images
                $('#add-gallery-image').on('click', function(e) {
                    e.preventDefault();
                    if (frame) frame.open();
                    frame = wp.media({
                        title: 'Select Images for Gallery',
                        button: { text: 'Add to Gallery' },
                        multiple: true
                    });

                    frame.on('select', function() {
                        var images = frame.state().get('selection').toJSON();
                        images.forEach(function(image) {
                            $('#gallery-images').append(
                                '<li class="gallery-item" data-id="' + image.id + '">' +
                                '<img decoding="async" src="' + image.sizes.thumbnail.url + '" />' +
                                '<button type="button" class="remove-image">&times;</button>' +
                                '</li>'
                            );
                        });
                        updateGalleryField();
                    });

                    frame.open();
                });

                // Remove image from gallery
                $('#gallery-images').on('click', '.remove-image', function() {
                    var imageId = $(this).closest('.gallery-item').data('id');

                    // Remove the image from the gallery
                    $(this).closest('.gallery-item').remove();
                    updateGalleryField();

                    // AJAX request to detach the image
                    $.post(ajaxurl, {
                        action: 'remove_gallery_attachment',
                        image_id: imageId,
                        post_id: <?php echo $post->ID; ?> // Pass the current post ID
                    });
                });

                // Update the hidden field with the order of image IDs
                function updateGalleryField() {
                    var imageIds = [];
                    $('#gallery-images .gallery-item').each(function() {
                        imageIds.push($(this).data('id'));
                    });
                    $('#custom-gallery-field').val(imageIds.join(','));
                }
            });
        })(jQuery);
    </script>
    <?php
}

function save_custom_gallery_metabox($post_id) {
    // Check if the custom_gallery field is set
    if (isset($_POST['custom_gallery'])) {
        $image_ids = array_filter(explode(',', $_POST['custom_gallery']));

        // Update the post meta to store image IDs in the correct order
        update_post_meta($post_id, '_custom_gallery', $image_ids);

        // Ensure each image is attached to this post
        foreach ($image_ids as $image_id) {
            // Only set attachment if it's not already attached to this post
            if (get_post_field('post_parent', $image_id) != $post_id) {
                // Update the post parent to attach the image to this post
                wp_update_post([
                    'ID' => $image_id,
                    'post_parent' => $post_id
                ]);
            }
        }
    }
}
add_action('save_post', 'save_custom_gallery_metabox');

function remove_gallery_attachment() {
    // Check for nonce and permissions if needed
    $image_id = intval($_POST['image_id']);
    $post_id = intval($_POST['post_id']);

    if ($image_id && $post_id) {
        // Update the attachment to remove it from the post
        wp_update_post([
            'ID' => $image_id,
            'post_parent' => 0 // Detach the image
        ]);
    }
    wp_die(); // This is required to properly terminate the AJAX request
}
add_action('wp_ajax_remove_gallery_attachment', 'remove_gallery_attachment');

// Display the custom gallery on the front end
$image_ids = get_post_meta(get_the_ID(), '_custom_gallery', true);
if ($image_ids) {
    echo '<div class="custom-gallery">';
    foreach ($image_ids as $image_id) {
        echo wp_get_attachment_image($image_id, 'large');
    }
    echo '</div>';
}
				
			

Share this post:

How to Attribute?

Lorem ipsum is typically a corrupted version of De finibus bonorum et malorum, a 1st-century BC text by the Roman statesman and philosopher Cicero.
for Example: Website, Social Media, Blogs, ebooks , newsletter, etc.
Lorem ipsum is typically a corrupted version of De finibus bonorum et malorum, a 1st-century BC text by the Roman statesman and philosopher Cicero.
Copied!

Got a Question? Check out our FAQ Section.

Your action, our appreciation

It encourage us to give you more valuable content on website.