标签: 产品画廊

  • 纯代码为WordPress自定义文章类型【产品】添加产品画廊

    纯代码为WordPress自定义文章类型【产品】添加产品画廊

    原来使用ACF插件,后面觉得就使用一个插件就为了实现这一个小功能觉得有点浪费插件性能,因此,改成使用纯代码来原生添加画廊。

    展示效果图:

    代码如下:

    产品画廊前端输出代码

    function display_custom_meta_gallery() {
        // 获取特色图像 URL
        $featured_image_id = get_post_thumbnail_id();
        $featured_image_url = $featured_image_id ? wp_get_attachment_image_url($featured_image_id, 'full') : '';
        // 获取自定义元框中的画廊字段数据 (存储的是图片的URL)
        $gallery = get_post_meta(get_the_ID(), '_custom_gallery', true);
        // 如果画廊不存在或者为空,并且没有特色图,则返回空
        if (!$gallery && !$featured_image_url) {
            return '';
        }
        $output = '<div class="custom-gallery-container">';
        // 主图
        $main_image_url = $featured_image_url ? $featured_image_url : $gallery[0]; // 使用画廊中的第一张图片作为主图
        $output .= '<div class="custom-main-image">';
        $output .= '<a id="main-image-link" href="' . esc_url($main_image_url) . '" data-fancybox="gallery">';
        $output .= '<img id="main-image" src="' . esc_url($main_image_url) . '" alt="Main Image">';
        $output .= '</a>';
        $output .= '</div>';
        // 只有在画廊存在时,才输出缩略图
        if ($gallery) {
            $output .= '<div class="custom-thumbnails-container">';
            $output .= '<div class="swiper-container custom-thumbnails">';
            $output .= '<div class="swiper-wrapper">';
            // 如果有特色图像,先输出特色图像的缩略图
            if ($featured_image_url) {
                $thumbnail_url = wp_get_attachment_image_url($featured_image_id, 'thumbnail');
                $output .= '<div class="swiper-slide custom-thumbnail">';
                $output .= '<a href="' . esc_url($featured_image_url) . '" data-fancybox="gallery" data-main-image="' . esc_url($featured_image_url) . '">';
                $output .= '<img src="' . esc_url($thumbnail_url) . '" alt="Thumbnail Image">';
                $output .= '</a>';
                $output .= '</div>';
            }
            // 输出自定义元框画廊的缩略图
            foreach ($gallery as $image_url) {
                $output .= '<div class="swiper-slide custom-thumbnail">';
                $output .= '<a href="' . esc_url($image_url) . '" data-fancybox="gallery" data-main-image="' . esc_url($image_url) . '">';
                $output .= '<img src="' . esc_url($image_url) . '" alt="Thumbnail Image">';
                $output .= '</a>';
                $output .= '</div>';
            }
            $output .= '</div>'; // swiper-wrapper
            $output .= '</div>'; // swiper-container
            // 左右滑动箭头放到缩略图区域
            $output .= '<div class="swiper-button-next custom-swiper-next"></div>';
            $output .= '<div class="swiper-button-prev custom-swiper-prev"></div>';
            $output .= '</div>'; // custom-thumbnails-container
        }
        $output .= '</div>'; // custom-gallery-container
        return $output;
    }
    // 注册短代码
    add_shortcode('custom_gallery', 'display_custom_meta_gallery');
    // 加载 FancyBox 和 Swiper 的样式与脚本,仅在自定义文章类型为 product 时
    function enqueue_fancybox_swiper_scripts() {
        // 检查当前文章类型是否为 product
        if (is_singular('product')) {
            // FancyBox
            wp_enqueue_style('fancybox-style', 'https://cdn.jsdelivr.net/npm/@fancyapps/ui@4.0/dist/fancybox.css');
            wp_enqueue_script('fancybox-script', 'https://cdn.jsdelivr.net/npm/@fancyapps/ui@4.0/dist/fancybox.umd.js', array('jquery'), null, true);
            
            // Swiper
            wp_enqueue_style('swiper-style', 'https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css');
            wp_enqueue_script('swiper-script', 'https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js', array('jquery'), null, true);
            // 自定义初始化脚本,确保 FancyBox 和 Swiper 正确工作
            wp_add_inline_script('swiper-script', "
                document.addEventListener('DOMContentLoaded', function() {
                    // 初始化 FancyBox
                    Fancybox.bind('[data-fancybox=\"gallery\"]', {});
                    // 初始化 Swiper 幻灯片
                    var swiper = new Swiper('.swiper-container', {
                        slidesPerView: 4,  // 每次显示4张缩略图
                        spaceBetween: 5,  // 缩略图之间的间距
                        navigation: {
                            nextEl: '.custom-swiper-next',
                            prevEl: '.custom-swiper-prev',
                        },
                        loop: false,
                        watchOverflow: true,  // 当缩略图不足时隐藏导航按钮
                    });
                    // 当用户点击缩略图时,更新主图和 FancyBox 链接
                    const thumbnails = document.querySelectorAll('.custom-thumbnail a');
                    const mainImage = document.getElementById('main-image');
                    const mainImageLink = document.getElementById('main-image-link');
                    thumbnails.forEach(thumbnail => {
                        thumbnail.addEventListener('click', function(event) {
                            event.preventDefault();  // 阻止默认的<a>点击行为
                            const newImageUrl = this.getAttribute('data-main-image');
                            const newImageHref = this.getAttribute('href');
                            
                            // 更新主图的 src 和 FancyBox 链接
                            mainImage.setAttribute('src', newImageUrl);
                            mainImageLink.setAttribute('href', newImageHref);
                        });
                    });
                });
            ");
        }
    }
    add_action('wp_enqueue_scripts', 'enqueue_fancybox_swiper_scripts');

    画廊后台代码

    function custom_gallery_meta_box() {
        add_meta_box(
            'custom_gallery',
            'Custom Gallery',
            'custom_gallery_meta_box_callback',
            'product', // 仅作用于 'product'
            'normal',
            'high'
        );
    }
    add_action('add_meta_boxes', 'custom_gallery_meta_box');
    function custom_gallery_meta_box_callback($post) {
        wp_nonce_field(basename(__FILE__), 'custom_gallery_nonce');
        $gallery_data = get_post_meta($post->ID, '_custom_gallery', true);
        ?>
        <div id="custom-gallery-wrapper">
            <ul id="custom-gallery-list">
                <?php
                if (!empty($gallery_data)) {
                    foreach ($gallery_data as $image_url) {
                        echo '<li><img src="' . esc_url($image_url) . '"><input type="hidden" name="custom_gallery_images[]" value="' . esc_url($image_url) . '"><a href="#" class="remove-image">Remove</a></li>';
                    }
                }
                ?>
            </ul>
            <input type="button" class="button button-secondary" id="add-gallery-image" value="Add Gallery Image">
        </div>
        <style>
            #custom-gallery-wrapper ul {
                list-style-type: none;
                margin: 0;
                padding: 0;
            }
            #custom-gallery-wrapper ul li {
                display: inline-block;
                margin-right: 5px;
                position: relative;
            }
            #custom-gallery-wrapper ul li img {
                display: block;
            }
            #custom-gallery-wrapper ul li .remove-image {
                position: absolute;
                top: 5px;
                right: 5px;
                color: red;
                cursor: pointer;
            }
        </style>
        <script>
            jQuery(document).ready(function($) {
                var frame;
                $('#add-gallery-image').on('click', function(e) {
                    e.preventDefault();
                    if (frame) {
                        frame.open();
                        return;
                    }
                    frame = wp.media({
                        title: 'Select Images',
                        button: {
                            text: 'Add to Gallery',
                        },
                        multiple: true
                    });
                    frame.on('select', function() {
                        var attachments = frame.state().get('selection').toArray();
                        attachments.forEach(function(attachment) {
                            var image_url = attachment.attributes.url;
                            $('#custom-gallery-list').append('<li><img src="' + image_url + '" width="150" height="150"><input type="hidden" name="custom_gallery_images[]" value="' + image_url + '"><a href="#" class="remove-image">Remove</a></li>');
                        });
                    });
                    frame.open();
                });
                $(document).on('click', '.remove-image', function(e) {
                    e.preventDefault();
                    $(this).parent().remove();
                });
            });
        </script>
        <?php
    }
    function save_custom_gallery_meta_box($post_id) {
        if (!isset($_POST['custom_gallery_nonce']) || !wp_verify_nonce($_POST['custom_gallery_nonce'], basename(__FILE__))) {
            return $post_id;
        }
        if ('product' !== get_post_type($post_id)) {
            return $post_id;
        }
        if (!current_user_can('edit_post', $post_id)) {
            return $post_id;
        }
        if (isset($_POST['custom_gallery_images'])) {
            update_post_meta($post_id, '_custom_gallery', array_map('esc_url', $_POST['custom_gallery_images']));
        } else {
            delete_post_meta($post_id, '_custom_gallery');
        }
    }
    add_action('save_post', 'save_custom_gallery_meta_box');
    function enqueue_custom_gallery_scripts($hook) {
        global $post;
        if ($post->post_type == 'product') {
            wp_enqueue_media();
            wp_enqueue_script('jquery');
        }
    }
    add_action('admin_enqueue_scripts', 'enqueue_custom_gallery_scripts');