Sync blog page with carousel (current week)

To sync Blog Page with Carousel, and show blog items belong current week only, you can do these.

#1. First, add a People Carousel

#2. Remember to enable Section Title

#3. Click Content > Title

#4. Enter syntax, use format: #blog-url=enter-blog-page-url-here#

In my example, blog page url is /subscription-rituals

so we will enter: #blog-url=/subscription-rituals#

#5. Add some carousel items

#6. Use this code to Page Header Injection

<script>
class BlogCarouselSync {
    constructor(options) {
        this.config = options;
        this.carouselSection = this.config.target;
        this.carouselSection.dataset.blogSync = "loading";
        this.blogData = [];
        this.carouselItems = this.carouselSection.querySelectorAll("li.user-items-list-carousel__slide");
        this.carouselContainer = this.carouselSection.querySelector("ul.user-items-list-carousel__slides");
        this.blogUrl = this.extractBlogUrl();
        this.initialize();
    }

    extractBlogUrl() {
        const titleElement = this.carouselSection.querySelector(".list-section-title p");
        if (!titleElement) return null;
        const titleText = titleElement.textContent;
        const match = titleText.match(/#blog-url=([^#]+)#/);
        return match ? match[1] : null;
    }

    getCurrentWeekRange() {
        const now = new Date();
        const currentDay = now.getDay();
        const startOfWeek = new Date(now);
        startOfWeek.setDate(now.getDate() - currentDay);
        startOfWeek.setHours(0, 0, 0, 0);
        
        const endOfWeek = new Date(startOfWeek);
        endOfWeek.setDate(startOfWeek.getDate() + 6);
        endOfWeek.setHours(23, 59, 59, 999);
        
        return { start: startOfWeek, end: endOfWeek };
    }

    isCurrentWeek(publishDate) {
        const { start, end } = this.getCurrentWeekRange();
        const pubDate = new Date(publishDate);
        return pubDate >= start && pubDate <= end;
    }

    async initialize() {
        try {
            if (!this.blogUrl) {
                console.error("Blog URL not found in section title");
                this.carouselSection.dataset.blogSync = "error";
                return;
            }

            this.blogData = await this.fetchBlogData();
            console.log("Fetched current week blog data:", this.blogData.length);
            
            if (this.blogData.length === 0) {
                console.log("No blog posts from current week found");
                this.carouselSection.dataset.blogSync = "no-current-week-posts";
                return;
            }

            this.adjustCarouselItems();
            this.populateCarouselItems();
            this.carouselSection.dataset.blogSync = "complete";
            console.log("Blog carousel sync completed with", this.blogData.length, "current week items");
        } catch (error) {
            console.error("Blog Carousel Sync failed:", error);
            this.carouselSection.dataset.blogSync = "error";
        }
    }

    async fetchBlogData() {
        try {
            const response = await fetch(`${this.blogUrl}?format=json`);
            if (!response.ok) {
                throw new Error(`Blog request failed: ${response.status}`);
            }
            const jsonData = await response.json();
            return this.parseBlogData(jsonData);
        } catch (error) {
            console.error("Error loading blog data:", error);
            throw error;
        }
    }

    parseBlogData(jsonData) {
        const data = [];
        if (!jsonData.items || !Array.isArray(jsonData.items)) return data;

        const first10Items = jsonData.items.slice(0, 10);
        console.log("Processing first 10 blog items...");

        first10Items.forEach((item, index) => {
            if (item.title && item.title.trim()) {
                const publishDate = item.publishOn || item.addedOn;
                
                if (publishDate && this.isCurrentWeek(publishDate)) {
                    let imageUrl = '';
                    if (item.assetUrl) {
                        imageUrl = item.assetUrl;
                    } else if (item.featuredImage && item.featuredImage.assetUrl) {
                        imageUrl = item.featuredImage.assetUrl;
                    }

                    const excerpt = item.excerpt || '';
                    const blogItemUrl = `${this.blogUrl}/${item.urlId}`;
                    
                    data.push({
                        title: item.title,
                        description: excerpt,
                        imageUrl: imageUrl,
                        buttonUrl: blogItemUrl,
                        publishDate: new Date(publishDate)
                    });
                    
                    console.log(`Added current week blog item ${data.length}:`, {
                        title: item.title,
                        publishDate: new Date(publishDate).toLocaleDateString()
                    });
                } else {
                    console.log(`Skipped blog item ${index} - not from current week:`, {
                        title: item.title,
                        publishDate: publishDate ? new Date(publishDate).toLocaleDateString() : 'No date'
                    });
                }
            } else {
                console.log(`Skipped blog item ${index} - no title:`, item);
            }
        });

        console.log("Final current week blog data array length:", data.length);
        return data;
    }

    adjustCarouselItems() {
        this.carouselItems = this.carouselSection.querySelectorAll("li.user-items-list-carousel__slide");
        
        while (this.carouselItems.length < this.blogData.length) {
            console.log("Creating new carousel item...");
            const newItem = this.createNewCarouselItem();
            this.carouselContainer.appendChild(newItem);
            this.carouselItems = this.carouselSection.querySelectorAll("li.user-items-list-carousel__slide");
        }

        if (this.carouselItems.length > this.blogData.length) {
            console.log("Hiding excess carousel items");
            for (let i = this.blogData.length; i < this.carouselItems.length; i++) {
                this.carouselItems[i].style.display = "none";
            }
        }
    }

    createNewCarouselItem() {
        const itemTemplate = `
            <li class="user-items-list-carousel__slide list-item" data-is-card-enabled="false">
                <div class="user-items-list-carousel__media-container" style="margin-bottom: 4%; width: 100%;">
                    <div class="user-items-list-carousel__media-inner preFade fadeIn" data-media-aspect-ratio="4:3" data-animation-role="image">
                        <img data-image-focal-point="0.5,0.5" alt="" class="user-items-list-carousel__media" data-load="false" data-mode="cover" data-use-advanced-positioning="true" style="width: 100%; height: 100%; object-fit: cover;">
                    </div>
                </div>
                <div class="list-item-content">
                    <div class="list-item-content__text-wrapper">
                        <h2 class="list-item-content__title preFade fadeIn" style="max-width: 100%;"></h2>
                        <div class="list-item-content__description" style="margin-top: 1%; max-width: 100%;">
                            <p class="preFade fadeIn" style="white-space: pre-wrap;"></p>
                        </div>
                        <div class="list-item-content__button-container preFade fadeIn" style="margin-top: 2%;">
                            <a class="list-item-content__button sqs-block-button-element sqs-block-button-element--medium sqs-button-element--primary" href="#">
                                Read More
                            </a>
                        </div>
                    </div>
                </div>
            </li>
        `;
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = itemTemplate;
        return tempDiv.firstElementChild;
    }

    populateCarouselItems() {
        console.log("Populating", this.blogData.length, "carousel items with current week blog data");
        
        for (let index = 0; index < this.blogData.length; index++) {
            if (!this.carouselItems[index]) {
                console.log("No carousel item for index", index);
                continue;
            }

            const carouselItem = this.carouselItems[index];
            carouselItem.style.opacity = "1";
            
            const { title: itemTitle, description: itemDescription, imageUrl: itemImage, buttonUrl: itemLink, publishDate } = this.blogData[index];

            let titleElement = carouselItem.querySelector(".list-item-content__title");
            let descriptionElement = carouselItem.querySelector(".list-item-content__description p");
            let imageElement = carouselItem.querySelector("img");
            let buttonElement = carouselItem.querySelector(".list-item-content__button");
            let dateElement = carouselItem.querySelector(".list-item-date");

            if (!dateElement) {
                const mediaContainer = carouselItem.querySelector(".user-items-list-carousel__media-container");
                if (mediaContainer) {
                    mediaContainer.style.position = "relative";
                    const dateSpan = document.createElement("span");
                    dateSpan.className = "list-item-date";
                    dateSpan.style.cssText = "position: absolute; top: 0px; left: 0px; background: rgba(0,0,0,0.7); color: white; padding: 4px 8px; border-radius: 0px; font-size: 12px;";
                    mediaContainer.appendChild(dateSpan);
                    dateElement = dateSpan;
                }
            }

            if (dateElement && publishDate) {
                const formattedDate = publishDate.toLocaleDateString();
                dateElement.textContent = formattedDate;
                console.log("Updated date for item", index, ":", formattedDate);
            }

            if (titleElement) {
                if (this.config.linkTitle && itemLink && itemLink !== '#') {
                    titleElement.innerHTML = `<a href="${itemLink}">${itemTitle}</a>`;
                } else {
                    titleElement.innerHTML = `<span>${itemTitle}</span>`;
                }
                console.log("Updated title for item", index);
            }

            if (descriptionElement && itemDescription) {
                descriptionElement.innerHTML = itemDescription;
                console.log("Updated description for item", index);
            }

            if (imageElement && itemImage) {
                imageElement.src = itemImage;
                imageElement.setAttribute('data-src', itemImage);
                imageElement.setAttribute('data-image', itemImage);
                imageElement.alt = itemTitle;
                console.log("Updated image for item", index);
            }

            if (buttonElement) {
                buttonElement.textContent = "Read More";
                if (itemLink && itemLink !== '#') {
                    buttonElement.href = itemLink;
                } else {
                    buttonElement.href = "#";
                }
                console.log("Updated button for item", index);
            }
        }

        window.dispatchEvent(new Event("resize"));
    }

    refreshData() {
        this.initialize();
    }
}

(function() {
    const initBlogCarouselSync = () => {
        const carouselSections = document.querySelectorAll(".user-items-list-carousel");
        
        carouselSections.forEach(section => {
            if (section.dataset.blogSync) return;
            
            const target = section.closest(".page-section");
            const titleElement = target ? target.querySelector(".list-section-title p") : null;
            
            if (!titleElement || !titleElement.textContent.includes("#blog-url=")) {
                return;
            }

            const config = {
                target: target,
                linkTitle: true,
                linkImage: false
            };

            if (config.target) {
                config.target.BlogCarouselSync = new BlogCarouselSync(config);
            } else {
                section.dataset.blogSync = "no-target";
            }
        });
    };

    window.blogCarouselSync = {
        init: initBlogCarouselSync,
        refreshAll: () => {
            const carouselSections = document.querySelectorAll(".user-items-list-carousel");
            carouselSections.forEach(section => {
                const target = section.closest(".page-section");
                if (target && target.BlogCarouselSync) {
                    target.BlogCarouselSync.refreshData();
                }
            });
        }
    };

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initBlogCarouselSync);
    } else {
        initBlogCarouselSync();
    }

    setInterval(() => {
        window.blogCarouselSync.refreshAll();
    }, 6 * 60 * 60 * 1000);
})();
</script>
<style>
div.list-section-title {
    display: none !important;
}
   .slides .preFade {
      opacity: 1 !important;
  }
</style>

#7. Result like this

Buy me a coffee