Easy Carousel

Displays posts and products in a customizable carousel.

Display estimated delivery date
PHP
/**
 * Snippet Name:     Advanced Carousel
 * Snippet Author:   coding-bunny.com
 * Description:      Displays posts and products in a customizable carousel.
 * Version:          1.1.0
 * 
 * USAGE EXAMPLES:
 * 
 * Basic usage:
 * [posts_carousel]
 * 
 * Show 8 posts with thumbnails, titles, excerpts, date and author:
 * [posts_carousel post_type="post" posts_per_page="8" show_thumbnail="true" show_title="true" show_excerpt="true" show_date="true" show_author="true"]
 * 
 * AVAILABLE PARAMETERS:
 * - posts_per_page: Number of posts to display (default: 6)
 * - post_type: Post type to query (default: 'post')
 * - category: Filter by category slug
 * - tag: Filter by tag slug
 * - taxonomy: Custom taxonomy name
 * - term: Custom taxonomy term slug
 * - autoplay: Enable autoplay (true/false, default: false)
 * - show_thumbnail: Show featured image (true/false, default: true)
 * - show_title: Show post title (true/false, default: true)
 * - show_excerpt: Show post excerpt (true/false, default: false)
 * - show_date: Show publication date (true/false, default: false)
 * - show_author: Show author with link to author archive (true/false, default: false)
 * - show_taxonomies: Show post taxonomies (true/false, default: false)
 * - show_taxonomies_type: Type of taxonomies to show 'categories' or 'tags' (default: 'categories')
 * - excerpt_length: Number of words in excerpt (default: 20)
 * - orderby: Sort posts by 'date', 'title', 'menu_order', 'rand' (default: 'date')
 * - order: Sort direction 'ASC' or 'DESC' (default: 'DESC')
 * - slides_per_view: Number of slides visible per row on desktop (default: 3, range: 1-6)
 * - image_aspect_ratio: Image aspect ratio format '1:1', '2:3', '3:2', '4:3', '3:4', '16:9', '9:16' (default: '3:2')
 * - equal_heights: Enable equal heights for all post cards (true/false, default: true)
 * 
 * WOOCOMMERCE-SPECIFIC PARAMETERS:
 * - show_price: Show product price (true/false, default: false)
 * - show_stock: Show stock status (true/false, default: false)
 * - show_rating: Show star rating (true/false, default: false)
 * - show_add_to_cart: Show add to cart button (true/false, default: false)
 * - show_sale_badge: Show sale badge for discounted products (true/false, default: false)
 * - show_sku: Show product SKU (true/false, default: false)
 */

function cbacs_register_swiper_assets() {
    wp_register_style('swiper-css', 'https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css', [], null);
    wp_register_script('swiper-js', 'https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js', [], null, true);
}
add_action('wp_enqueue_scripts', 'cbacs_register_swiper_assets');

function cbacs_enqueue_swiper_assets($content) {
    if (has_shortcode($content, 'posts_carousel')) {
        wp_enqueue_style('swiper-css');
        wp_enqueue_script('swiper-js');
    }
    return $content;
}
add_filter('the_content', 'cbacs_enqueue_swiper_assets');

function cbacs_aspect_ratio($aspect_ratio_string) {
    $allowed_ratios = [
        '1:1' => 100,       // Square
        '2:3' => 150,       // Portrait (2:3)
        '3:2' => 66.67,     // Landscape (3:2) - Default
        '4:3' => 75,        // Standard (4:3)
        '3:4' => 133.33,    // Portrait (3:4)
        '16:9' => 56.25,    // Widescreen (16:9)
        '9:16' => 177.78,   // Mobile/Story format (9:16)
    ];
    
    return isset($allowed_ratios[$aspect_ratio_string]) ? $allowed_ratios[$aspect_ratio_string] : $allowed_ratios['3:2'];
}

function cbacs_posts_carousel_shortcode($atts) {
    $atts = shortcode_atts([
        'posts_per_page'     => 6,
        'post_type'          => 'post',
        'category'           => '',
        'tag'                => '',
        'taxonomy'           => '',
        'term'               => '',
        'autoplay'           => 'false',
        'show_thumbnail'     => 'true',
        'show_title'         => 'true',
        'show_excerpt'       => 'false',
        'show_date'          => 'false',
        'show_author'        => 'false',
        'show_taxonomies'    => 'false',
        'show_taxonomies_type' => 'categories',
        'excerpt_length'     => 20,
        'orderby'            => 'date',
        'order'              => 'DESC',
        'slides_per_view'    => 3,
        'image_aspect_ratio' => '3:2',
        'equal_heights'      => 'true',
        
        // WooCommerce parameters
        'show_price'         => 'false',
        'show_stock'         => 'false',
        'show_rating'        => 'false',
        'show_add_to_cart'   => 'false',
        'show_sale_badge'    => 'false',
        'show_sku'           => 'false',
    ], $atts, 'posts_carousel');

    $post_type = sanitize_key($atts['post_type']);
    $category  = sanitize_title($atts['category']);
    $tag       = sanitize_title($atts['tag']);
    $taxonomy  = sanitize_key($atts['taxonomy']);
    $term      = sanitize_title($atts['term']);
    $autoplay  = filter_var($atts['autoplay'], FILTER_VALIDATE_BOOLEAN);
    $show_thumbnail = filter_var($atts['show_thumbnail'], FILTER_VALIDATE_BOOLEAN);
    $show_title = filter_var($atts['show_title'], FILTER_VALIDATE_BOOLEAN);
    $show_excerpt = filter_var($atts['show_excerpt'], FILTER_VALIDATE_BOOLEAN);
    $show_date = filter_var($atts['show_date'], FILTER_VALIDATE_BOOLEAN);
    $show_author = filter_var($atts['show_author'], FILTER_VALIDATE_BOOLEAN);
    $show_taxonomies = filter_var($atts['show_taxonomies'], FILTER_VALIDATE_BOOLEAN);
    $show_taxonomies_type = sanitize_text_field($atts['show_taxonomies_type']);
    $excerpt_length = intval($atts['excerpt_length']);
    $orderby = sanitize_key($atts['orderby']);
    $order = strtoupper(sanitize_key($atts['order'])) === 'ASC' ? 'ASC' : 'DESC';
    
    $slides_per_view = intval($atts['slides_per_view']);
    if ($slides_per_view < 1) $slides_per_view = 1;
    if ($slides_per_view > 6) $slides_per_view = 6;   
    $image_aspect_ratio = sanitize_text_field($atts['image_aspect_ratio']);
    $padding_bottom = cbacs_aspect_ratio($image_aspect_ratio);
    $equal_heights = filter_var($atts['equal_heights'], FILTER_VALIDATE_BOOLEAN);
    $show_price = filter_var($atts['show_price'], FILTER_VALIDATE_BOOLEAN);
    $show_stock = filter_var($atts['show_stock'], FILTER_VALIDATE_BOOLEAN);
    $show_rating = filter_var($atts['show_rating'], FILTER_VALIDATE_BOOLEAN);
    $show_add_to_cart = filter_var($atts['show_add_to_cart'], FILTER_VALIDATE_BOOLEAN);
    $show_sale_badge = filter_var($atts['show_sale_badge'], FILTER_VALIDATE_BOOLEAN);
    $show_sku = filter_var($atts['show_sku'], FILTER_VALIDATE_BOOLEAN);

    $is_woocommerce_active = class_exists('WooCommerce');
    $is_product_query = ($post_type === 'product' && $is_woocommerce_active);

    $args = [
        'post_type'      => $post_type,
        'posts_per_page' => intval($atts['posts_per_page']),
        'post_status'    => 'publish',
        'orderby'        => $orderby,
        'order'          => $order,
    ];

    $tax_query = [];

    if (!empty($category)) {
        if ($is_product_query) {
            $tax_query[] = [
                'taxonomy' => 'product_cat',
                'field'    => 'slug',
                'terms'    => $category,
            ];
        } else {
            $tax_query[] = [
                'taxonomy' => 'category',
                'field'    => 'slug',
                'terms'    => $category,
            ];
        }
    }

    if (!empty($tag)) {
        if ($is_product_query) {
            $tax_query[] = [
                'taxonomy' => 'product_tag',
                'field'    => 'slug',
                'terms'    => $tag,
            ];
        } else {
            $tax_query[] = [
                'taxonomy' => 'post_tag',
                'field'    => 'slug',
                'terms'    => $tag,
            ];
        }
    }

    if (!empty($taxonomy) && !empty($term)) {
        $tax_query[] = [
            'taxonomy' => $taxonomy,
            'field'    => 'slug',
            'terms'    => $term,
        ];
    }

    if (!empty($tax_query)) {
        $args['tax_query'] = $tax_query;
    }

    $query = new WP_Query($args);
    ob_start();

    if ($query->have_posts()) :
        $uid = uniqid('swiper_');
        ?>

        <div class="swiper <?php echo esc_attr($uid); ?>" data-equal-heights="<?php echo $equal_heights ? 'true' : 'false'; ?>">
            <div class="swiper-wrapper">
                <?php while ($query->have_posts()) : $query->the_post(); 
                    $product = $is_product_query ? wc_get_product(get_the_ID()) : null;
                ?>
                    <div class="swiper-slide">
                        <div class="post-slide <?php echo $is_product_query ? 'product-slide' : ''; ?>">
                            
                            <?php if ($show_thumbnail && has_post_thumbnail()) : ?>
                                <div class="post-thumbnail" data-aspect-ratio="<?php echo esc_attr($image_aspect_ratio); ?>">
                                    <?php if ($show_sale_badge && $is_product_query && $product && $product->is_on_sale()) : ?>
                                        <div class="sale-badge">
                                            <?php esc_html_e('Sale!', 'woocommerce'); ?>
                                        </div>
                                    <?php endif; ?>
                                    <a href="<?php the_permalink(); ?>">
                                        <div class="image-container">
                                            <?php the_post_thumbnail('large'); ?>
                                        </div>
                                    </a>
                                </div>
                            <?php endif; ?>

                            <?php if ($show_taxonomies) : ?>
                                <div class="<?php echo $is_product_query ? 'product-taxonomies' : 'post-taxonomies'; ?>">
                                    <?php
                                    if ($show_taxonomies_type === 'categories') {
                                        if ($is_product_query) {
                                            $categories = get_the_terms(get_the_ID(), 'product_cat');
                                            if ($categories && !is_wp_error($categories)) {
                                                $cat_names = array();
                                                foreach ($categories as $category) {
                                                    $cat_names[] = '<a href="' . esc_url(get_term_link($category)) . '">' . esc_html($category->name) . '</a>';
                                                }
                                                echo implode(' ', $cat_names);
                                            }
                                        } else {
                                            $categories = get_the_category();
                                            if ($categories && !is_wp_error($categories)) {
                                                $cat_names = array();
                                                foreach ($categories as $category) {
                                                    $cat_names[] = '<a href="' . esc_url(get_category_link($category->term_id)) . '">' . esc_html($category->name) . '</a>';
                                                }
                                                echo implode(' ', $cat_names);
                                            }
                                        }
                                    } elseif ($show_taxonomies_type === 'tags') {
                                        if ($is_product_query) {
                                            $tags = get_the_terms(get_the_ID(), 'product_tag');
                                            if ($tags && !is_wp_error($tags)) {
                                                $tag_names = array();
                                                foreach ($tags as $tag) {
                                                    $tag_names[] = '<a href="' . esc_url(get_term_link($tag)) . '">' . esc_html($tag->name) . '</a>';
                                                }
                                                echo implode(', ', $tag_names);
                                            }
                                        } else {
                                            $tags = get_the_tags();
                                            if ($tags && !is_wp_error($tags)) {
                                                $tag_names = array();
                                                foreach ($tags as $tag) {
                                                    $tag_names[] = '<a href="' . esc_url(get_tag_link($tag->term_id)) . '">' . esc_html($tag->name) . '</a>';
                                                }
                                                echo implode(', ', $tag_names);
                                            }
                                        }
                                    }
                                    ?>
                                </div>
                            <?php endif; ?>

                            <div class="post-content">
                                <?php if ($show_title) : ?>
                                    <h3 class="post-title">
                                        <a href="<?php the_permalink(); ?>"><?php echo esc_html(get_the_title()); ?></a>
                                    </h3>
                                <?php endif; ?>

                                <?php if ($show_rating && $is_product_query && $product && $product->get_average_rating()) : ?>
                                    <div class="product-rating">
                                        <?php
                                        $rating = $product->get_average_rating();
                                        $review_count = $product->get_review_count();
                                        echo wc_get_rating_html($rating);
                                        if ($review_count > 0) {
                                            echo '<span class="review-count">(' . sprintf(_n('%s review', '%s reviews', $review_count, 'woocommerce'), $review_count) . ')</span>';
                                        }
                                        ?>
                                    </div>
                                <?php endif; ?>

                                <?php if ($show_excerpt && !$is_product_query) : ?>
                                    <div class="post-excerpt">
                                        <?php
                                        $excerpt = get_the_excerpt();
                                        if (strlen($excerpt) > $excerpt_length) {
                                            $excerpt = wp_trim_words($excerpt, $excerpt_length, '...');
                                        }
                                        echo esc_html($excerpt);
                                        ?>
                                    </div>
                                <?php elseif ($show_excerpt && $is_product_query && $product) : ?>
                                    <div class="product-excerpt">
                                        <?php
                                        $description = $product->get_short_description();
                                        if (!empty($description)) {
                                            if (strlen($description) > $excerpt_length * 7) { // Rough word count estimation
                                                $description = wp_trim_words($description, $excerpt_length, '...');
                                            }
                                            echo wp_kses_post($description);
                                        }
                                        ?>
                                    </div>
                                <?php endif; ?>

                                <?php if ($show_price && $is_product_query && $product) : ?>
                                    <div class="product-price">
                                        <?php echo $product->get_price_html(); ?>
                                    </div>
                                <?php endif; ?>

                                <?php if ($show_stock && $is_product_query && $product) : ?>
                                    <div class="product-stock">
                                        <?php
                                        $stock_status = $product->get_stock_status();
                                        $stock_quantity = $product->get_stock_quantity();
                                        
                                        if ($stock_status === 'instock') {
                                            echo '<span class="stock in-stock"><span class="dashicons dashicons-yes-alt"></span>' . esc_html__('In Stock', 'woocommerce');
                                            if ($stock_quantity && $product->managing_stock()) {
                                                echo ' (' . esc_html($stock_quantity) . ' ' . esc_html__('available', 'woocommerce') . ')';
                                            }
                                            echo '</span>';
                                        } elseif ($stock_status === 'outofstock') {
                                            echo '<span class="stock out-of-stock"><span class="dashicons dashicons-dismiss"></span>' . esc_html__('Out of Stock', 'woocommerce') . '</span>';
                                        } elseif ($stock_status === 'onbackorder') {
                                            echo '<span class="stock on-backorder"><span class="dashicons dashicons-clock"></span>' . esc_html__('On Backorder', 'woocommerce') . '</span>';
                                        }
                                        ?>
                                    </div>
                                <?php endif; ?>

                                <?php if ($show_sku && $is_product_query && $product && $product->get_sku()) : ?>
                                    <div class="product-sku">
                                        <span class="sku-label"><?php esc_html_e('SKU:', 'woocommerce'); ?></span>
                                        <span class="sku"><?php echo esc_html($product->get_sku()); ?></span>
                                    </div>
                                <?php endif; ?>

                                <?php if (($show_date || $show_author) && !$is_product_query) : ?>
                                    <div class="post-meta">
                                        <?php if ($show_date) : ?>
                                            <span class="post-date">
                                                <span class="dashicons dashicons-calendar-alt"></span>
                                                <?php echo get_the_date(); ?>
                                            </span>
                                        <?php endif; ?>

                                        <?php if ($show_author) : ?>
                                            <span class="post-author">
                                                <span class="dashicons dashicons-admin-users"></span>
                                                <a href="<?php echo esc_url(get_author_posts_url(get_the_author_meta('ID'))); ?>" title="<?php echo esc_attr(sprintf(__('View all posts by %s', 'text-domain'), get_the_author())); ?>">
                                                    <?php echo get_the_author(); ?>
                                                </a>
                                            </span>
                                        <?php endif; ?>
                                    </div>
                                <?php endif; ?>

                                <?php if ($show_add_to_cart && $is_product_query && $product) : ?>
                                    <div class="product-add-to-cart">
                                        <?php
                                        if ($product->get_type() === 'simple') {
                                            woocommerce_template_loop_add_to_cart();
                                        } else {
                                            echo '<a href="' . esc_url($product->get_permalink()) . '" class="button product-type-' . esc_attr($product->get_type()) . '">' . esc_html__('Select Options', 'woocommerce') . '</a>';
                                        }
                                        ?>
                                    </div>
                                <?php endif; ?>
                            </div>
                        </div>
                    </div>
                <?php endwhile; ?>
            </div>

            <div class="swiper-button-next">
                <span class="dashicons dashicons-arrow-right-alt2"></span>
            </div>
            <div class="swiper-button-prev">
                <span class="dashicons dashicons-arrow-left-alt2"></span>
            </div>
        </div>

        <style>
        .<?php echo esc_attr($uid); ?> {
            position: relative;
            width: 100% !important;
            max-width: none !important;
        }

        .<?php echo esc_attr($uid); ?> .swiper-slide .post-slide {
            background: #ffffff;
            border: 1px solid #e1e5e9;
            border-radius: 10px;
            overflow: hidden;
            transition: all 0.3s ease;
            height: 100%;
            display: flex;
            flex-direction: column;
        }

        .<?php echo esc_attr($uid); ?> .swiper-slide .post-slide:hover {
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
            transform: translateY(-2px);
        }

        .<?php echo esc_attr($uid); ?> .post-thumbnail {
            width: 100%;
            overflow: hidden;
            position: relative;
        }

        .<?php echo esc_attr($uid); ?> .post-thumbnail .image-container {
            width: 100%;
            height: 0;
            padding-bottom: <?php echo esc_attr($padding_bottom); ?>%;
            position: relative;
            overflow: hidden;
        }

        .<?php echo esc_attr($uid); ?> .post-thumbnail .image-container img {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.3s ease;
        }

        .<?php echo esc_attr($uid); ?> .post-thumbnail:hover .image-container img {
            transform: scale(1.05);
        }

        .<?php echo esc_attr($uid); ?> .sale-badge {
            position: absolute;
            top: 10px;
            left: 10px;
            background: #ff4444;
            color: white;
            padding: 5px 10px;
            border-radius: 15px;
            font-size: 12px;
            font-weight: bold;
            z-index: 2;
        }

        .<?php echo esc_attr($uid); ?> .post-taxonomies {
            padding: 15px 15px 0 15px;
            font-size: 12px;
            line-height: 1.4;
            background: #ffffff;
        }

        .<?php echo esc_attr($uid); ?> .post-taxonomies a {
            color: #ffffff;
            background: #2370b0;
            padding: 5px;
            border-radius: 3px;
            text-decoration: none;
            transition: background 0.3s ease;
        }

        .<?php echo esc_attr($uid); ?> .post-taxonomies a:hover {
            background: #1d6197;
            text-decoration: none;
        }

        .<?php echo esc_attr($uid); ?> .product-taxonomies {
            padding: 15px 15px 0 15px;
            font-size: 12px;
            line-height: 1.4;
            background: #ffffff;
        }

        .<?php echo esc_attr($uid); ?> .product-taxonomies a {
            color: #000000;
            border-radius: 3px;
            text-decoration: none;
            transition: background 0.3s ease;
        }

        .<?php echo esc_attr($uid); ?> .product-taxonomies a:hover {
            color: #2370b0;
            text-decoration: none;
        }

        .<?php echo esc_attr($uid); ?> .post-content {
            padding: 15px;
            flex-grow: 1;
            display: flex;
            flex-direction: column;
        }

        .<?php echo esc_attr($uid); ?> .post-title {
            margin: 0;
            font-size: 16px;
            line-height: 1.4;
        }

        .<?php echo esc_attr($uid); ?> .post-title a {
            color: #333;
            text-decoration: none;
            transition: color 0.3s ease;
        }

        .<?php echo esc_attr($uid); ?> .post-title a:hover {
            color: #0073aa;
        }

        .<?php echo esc_attr($uid); ?> .product-rating {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .<?php echo esc_attr($uid); ?> .product-rating .star-rating {
            font-size: 14px;
        }

        .<?php echo esc_attr($uid); ?> .product-rating .review-count {
            font-size: 12px;
            color: #666;
        }

        .<?php echo esc_attr($uid); ?> .post-excerpt,
        .<?php echo esc_attr($uid); ?> .product-excerpt {
            color: #666;
            font-size: 14px;
            line-height: 1.5;
            margin-bottom: 15px;
        }

        .<?php echo esc_attr($uid); ?> .product-price {
            font-size: 18px;
            font-weight: bold;
            margin-bottom: 10px;
        }

        .<?php echo esc_attr($uid); ?> .product-price .price {
            color: #333;
        }

        .<?php echo esc_attr($uid); ?> .product-price .price del {
            color: #999;
            text-decoration: line-through;
            font-weight: normal;
        }

        .<?php echo esc_attr($uid); ?> .product-price .price ins {
            color: #77a464;
            text-decoration: none;
        }

        .<?php echo esc_attr($uid); ?> .product-stock {
            margin-bottom: 10px;
            font-size: 12px;
        }

        .<?php echo esc_attr($uid); ?> .product-stock .stock {
            display: flex;
            align-items: center;
            gap: 5px;
        }

        .<?php echo esc_attr($uid); ?> .product-stock .in-stock {
            color: #77a464;
        }

        .<?php echo esc_attr($uid); ?> .product-stock .out-of-stock {
            color: #ff4444;
        }

        .<?php echo esc_attr($uid); ?> .product-stock .on-backorder {
            color: #ffba00;
        }

        .<?php echo esc_attr($uid); ?> .product-stock .dashicons {
            font-size: 14px;
            width: 14px;
            height: 14px;
        }

        .<?php echo esc_attr($uid); ?> .product-sku {
            font-size: 11px;
            color: #999;
            margin-bottom: 10px;
        }

        .<?php echo esc_attr($uid); ?> .product-sku .sku-label {
            font-weight: bold;
        }

        .<?php echo esc_attr($uid); ?> .post-meta {
            margin-top: auto;
            padding-top: 10px;
            border-top: 1px solid #f0f0f0;
            font-size: 12px;
            color: #999;
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
        }

        .<?php echo esc_attr($uid); ?> .post-meta span {
            display: flex;
            align-items: center;
            gap: 5px;
        }

        .<?php echo esc_attr($uid); ?> .post-meta .dashicons {
            font-size: 14px;
            width: 14px;
            height: 14px;
        }

        .<?php echo esc_attr($uid); ?> .post-author a {
            color: #999;
            text-decoration: none;
            transition: color 0.3s ease;
        }

        .<?php echo esc_attr($uid); ?> .post-author a:hover {
            color: #0073aa;
            text-decoration: underline;
        }

        .<?php echo esc_attr($uid); ?> .product-add-to-cart {
            margin-top: auto;
            padding-top: 15px;
        }

        .<?php echo esc_attr($uid); ?> .product-add-to-cart .added_to_cart {
            display: none;
        }

        .<?php echo esc_attr($uid); ?> .swiper-button-next,
        .<?php echo esc_attr($uid); ?> .swiper-button-prev {
            width: 35px;
            height: 35px;
            background: rgba(0, 0, 0, 0.8);
            border-radius: 50%;
            opacity: 0;
            visibility: hidden;
            transition: all 0.3s ease;
            margin-top: -17.5px;
            color: transparent;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .<?php echo esc_attr($uid); ?> .swiper-button-next:after,
        .<?php echo esc_attr($uid); ?> .swiper-button-prev:after {
            display: none;
        }

        .<?php echo esc_attr($uid); ?> .swiper-button-next .dashicons,
        .<?php echo esc_attr($uid); ?> .swiper-button-prev .dashicons {
            color: #ffffff;
            font-size: 16px;
            width: 16px;
            height: 16px;
        }

        .<?php echo esc_attr($uid); ?>:hover .swiper-button-next,
        .<?php echo esc_attr($uid); ?>:hover .swiper-button-prev {
            opacity: 1;
            visibility: visible;
        }

        .<?php echo esc_attr($uid); ?> .swiper-button-next:hover,
        .<?php echo esc_attr($uid); ?> .swiper-button-prev:hover {
            background: rgba(0, 0, 0, 1);
            transform: scale(1.1);
        }

        .<?php echo esc_attr($uid); ?> .swiper-button-next {
            right: 10px;
        }

        .<?php echo esc_attr($uid); ?> .swiper-button-prev {
            left: 10px;
        }

        @media (max-width: 768px) {
            .<?php echo esc_attr($uid); ?> .post-title {
                font-size: 14px;
            }
            
            .<?php echo esc_attr($uid); ?> .post-content {
                padding: 12px;
            }

            .<?php echo esc_attr($uid); ?> .post-taxonomies,
            .<?php echo esc_attr($uid); ?> .product-taxonomies {
                padding: 8px 12px;
                font-size: 11px;
            }

            .<?php echo esc_attr($uid); ?> .swiper-button-next,
            .<?php echo esc_attr($uid); ?> .swiper-button-prev {
                width: 30px;
                height: 30px;
                margin-top: -15px;
            }

            .<?php echo esc_attr($uid); ?> .swiper-button-next .dashicons,
            .<?php echo esc_attr($uid); ?> .swiper-button-prev .dashicons {
                font-size: 14px;
                width: 14px;
                height: 14px;
            }

            .<?php echo esc_attr($uid); ?> .product-price {
                font-size: 16px;
            }
        }

        @media (max-width: 480px) {
            .<?php echo esc_attr($uid); ?> .post-meta {
                flex-direction: column;
                gap: 8px;
            }

            .<?php echo esc_attr($uid); ?> .swiper-button-next,
            .<?php echo esc_attr($uid); ?> .swiper-button-prev {
                opacity: 1;
                visibility: visible;
                background: rgba(0, 0, 0, 0.6);
            }

            .<?php echo esc_attr($uid); ?> .product-rating {
                flex-direction: column;
                align-items: flex-start;
                gap: 5px;
            }

            .<?php echo esc_attr($uid); ?> .post-taxonomies,
            .<?php echo esc_attr($uid); ?> .product-taxonomies {
                padding: 6px 10px;
                font-size: 10px;
            }
        }
        </style>

        <?php
        $js = "
        document.addEventListener('DOMContentLoaded', function () {
            
            // Function to equalize heights
            function equalizeHeights(swiperElement) {
                const slides = swiperElement.querySelectorAll('.swiper-slide .post-slide');
                let maxHeight = 0;
                
                // Reset heights first
                slides.forEach(slide => {
                    slide.style.height = 'auto';
                });
                
                // Find maximum height
                slides.forEach(slide => {
                    const height = slide.offsetHeight;
                    if (height > maxHeight) {
                        maxHeight = height;
                    }
                });
                
                // Apply maximum height to all slides
                slides.forEach(slide => {
                    slide.style.height = maxHeight + 'px';
                });
            }
            
            // Initialize Swiper
            const swiperElement = document.querySelector('." . esc_js($uid) . "');
            const enableEqualHeights = swiperElement.dataset.equalHeights === 'true';
            
            const swiper = new Swiper('." . esc_js($uid) . "', {
                slidesPerView: " . $slides_per_view . ",
                spaceBetween: 30,
                loop: true,
                autoHeight: false,
                navigation: {
                    nextEl: '." . esc_js($uid) . " .swiper-button-next',
                    prevEl: '." . esc_js($uid) . " .swiper-button-prev'
                },
                " . ($autoplay ? "autoplay: { delay: 3000, disableOnInteraction: false }," : "") . "
                breakpoints: {
                    320: { 
                        slidesPerView: 1, 
                        spaceBetween: 15 
                    },
                    768: { 
                        slidesPerView: " . min($slides_per_view, 2) . ", 
                        spaceBetween: 20 
                    },
                    1024: { 
                        slidesPerView: " . $slides_per_view . ", 
                        spaceBetween: 30 
                    }
                },
                on: {
                    init: function() {
                        if (enableEqualHeights) {
                            // Small delay to ensure images are loaded
                            setTimeout(() => {
                                equalizeHeights(swiperElement);
                            }, 100);
                        }
                    }
                }
            });
            
            // Re-equalize heights on window resize
            if (enableEqualHeights) {
                let resizeTimer;
                window.addEventListener('resize', function() {
                    clearTimeout(resizeTimer);
                    resizeTimer = setTimeout(() => {
                        equalizeHeights(swiperElement);
                    }, 250);
                });
                
                // Re-equalize when images finish loading
                const images = swiperElement.querySelectorAll('img');
                let loadedImages = 0;
                
                if (images.length > 0) {
                    images.forEach(img => {
                        if (img.complete) {
                            loadedImages++;
                        } else {
                            img.addEventListener('load', () => {
                                loadedImages++;
                                if (loadedImages === images.length) {
                                    equalizeHeights(swiperElement);
                                }
                            });
                        }
                    });
                    
                    if (loadedImages === images.length) {
                        equalizeHeights(swiperElement);
                    }
                }
            }
        });
        ";

        wp_add_inline_script('swiper-js', $js);
        wp_reset_postdata();
    else :
        echo '<p>' . esc_html__('No posts found.', 'text-domain') . '</p>';
    endif;

    return ob_get_clean();
}
add_shortcode('posts_carousel', 'cbacs_posts_carousel_shortcode');

How To Implement This Solution?

Leave a Reply

Your email address will not be published. Required fields are marked *

My Agile Privacy
This site uses technical and profiling cookies. You can accept, decline or customize cookies by pressing the desired buttons. By closing this policy you will continue without accepting.

Need help?

Choose one of the following options:

Powered by CodingBunny