Sync Blog Page with Slideshow

Description: sync Blog Page with Slideshow and add slideshow to other pages

To turn Blog Page to Slideshow and add it to other pages, like this.

#1. First, find Blog Page URL

In my example, it is: /blog-01

#2. Add a Slideshow Section

Choose Banner Slideshow

#3. Enable these options

#4. Click Content > Title

#5. Enter Blog Page URL, use this format

#blog-url=/blog-01#

#6. Add this code to Page Header Injection (page where you use Slideshow)

<style>
div.list-section-title {
    display: none !important;
}
   .slides .preFade {
  	opacity: 1 !important;
  }
</style>

#7. Use this code to Code Injection > Footer

#membership

<script>class BlogSlideshowSync{constructor(options){this.config=options;this.slideshowSection=this.config.target;this.slideshowSection.dataset.blogSync="loading";this.blogData=[];this.slideItems=this.slideshowSection.querySelectorAll("li.slide.list-item");this.slideContainer=this.slideshowSection.querySelector("ul.slides");this.blogUrl=this.extractBlogUrl();this.initialize()}
extractBlogUrl(){const titleElement=this.slideshowSection.querySelector(".list-section-title p");if(!titleElement)return null;const titleText=titleElement.textContent;const match=titleText.match(/#blog-url=([^#]+)#/);return match?match[1]:null}
async initialize(){try{if(!this.blogUrl){console.error("Blog URL not found in section title");this.slideshowSection.dataset.blogSync="error";return}
this.blogData=await this.fetchBlogData();console.log("Fetched blog data:",this.blogData.length);console.log("Current slide items:",this.slideItems.length);while(this.slideItems.length<this.blogData.length){console.log("Creating new slide...");const newSlide=this.createNewSlide();this.slideContainer.appendChild(newSlide);this.slideItems=this.slideshowSection.querySelectorAll("li.slide.list-item");console.log("Total slides now:",this.slideItems.length)}
if(this.slideItems.length>this.blogData.length){console.warn("Too many slide items, removing excess");while(this.slideItems.length>this.blogData.length){this.slideItems[this.slideItems.length-1].remove();this.slideItems=this.slideshowSection.querySelectorAll("li.slide.list-item")}}
this.createSlideTemplate();this.populateSlideItems();this.slideshowSection.dataset.blogSync="complete";console.log("Blog sync completed with",this.slideItems.length,"items")}catch(error){console.error("Blog Slideshow Sync failed:",error);this.slideshowSection.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;jsonData.items.forEach((item,index)=>{if(item.title&&item.title.trim()){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});console.log(`Added blog item ${data.length}:`,data[data.length-1])}else{console.log(`Skipped blog item ${index} - no title:`,item)}});console.log("Final blog data array length:",data.length);return data}
createNewSlide(){const slideTemplate=`
            <li class="slide list-item" data-is-card-enabled="false">
                <div class="slide-media-container">
                    <img class="list-slideshow-image" data-load="false" style="display:block;object-position: 50% 50%;" loading="lazy" decoding="async" data-loader="sqs">
                </div>
                <div class="slide-content list-item-card-background" style="width: 500px; max-width: 100%;">
                    <h2 class="list-item-content__title preFade"></h2>
                    <div class="list-item-content__description" style="margin-top: 10px;">
                        <p class="preFade" style="white-space: pre-wrap;"></p>
                    </div>
                    <div class="list-item-content__button-container preFade" style="margin-top: 10px;" data-animation-role="button">
                        <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>
            </li>
        `;const tempDiv=document.createElement('div');tempDiv.innerHTML=slideTemplate;return tempDiv.firstElementChild}
createSlideTemplate(){if(this.slideItems.length>0){const templateHTML=this.slideItems[0].innerHTML;this.slideItems.forEach(item=>{item.innerHTML=templateHTML})}}
populateSlideItems(){console.log("Populating",this.slideItems.length,"items with",this.blogData.length,"blog data");this.slideItems=this.slideshowSection.querySelectorAll("li.slide.list-item");console.log("Refreshed slide items count:",this.slideItems.length);for(let index=0;index<this.blogData.length;index++){if(!this.slideItems[index]){console.log("No slide item for index",index);continue}
console.log("Processing blog data",index,":",this.blogData[index].title);const slideItem=this.slideItems[index];const{title:itemTitle,description:itemDescription,imageUrl:itemImage,buttonUrl:itemLink}=this.blogData[index];let titleElement=slideItem.querySelector(".list-item-content__title");let descriptionElement=slideItem.querySelector(".list-item-content__description p");let imageElement=slideItem.querySelector("img");let buttonElement=slideItem.querySelector(".list-item-content__button");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){let newImage=imageElement.cloneNode(!0);newImage.src=itemImage;newImage.setAttribute('data-src',itemImage);newImage.setAttribute('data-image',itemImage);newImage.srcset="";newImage.alt=itemTitle;imageElement.parentElement.appendChild(newImage);imageElement.style.display="none";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()}
setupEventHandlers(){window.addEventListener("DOMContentLoaded",()=>{this.populateSlideItems()});window.addEventListener("load",()=>{this.populateSlideItems()})}}(function(){const initBlogSlideshowSync=()=>{const slideshowSections=document.querySelectorAll(".user-items-list-banner-slideshow");slideshowSections.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:!0,linkImage:!1};if(config.target){config.target.BlogSlideshowSync=new BlogSlideshowSync(config)}else{section.dataset.blogSync="no-target"}})};window.blogSlideshowSync={init:initBlogSlideshowSync,refreshAll:()=>{const slideshowSections=document.querySelectorAll(".user-items-list-banner-slideshow");slideshowSections.forEach(section=>{const target=section.closest(".page-section");if(target&&target.BlogSlideshowSync){target.BlogSlideshowSync.refreshData()}})}};if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',initBlogSlideshowSync)}else{initBlogSlideshowSync()}
setInterval(()=>{window.blogSlideshowSync.refreshAll()},6*60*60*1000)})();</script>

Buy me a coffee