Description: adding blog page to another page without using Summary Block
#1. First, use this code to Page Header Injection (page where you want to place Blog Page)
<!-- @tuanphan - Blog page to another page -->
<style>
.blog-basic-grid.preFade {
opacity: 0;
}
.blog-basic-grid.fadeIn {
opacity: 1;
transition: opacity 0.5s ease;
}
.load-more-btn {
display: block;
margin: 40px auto;
padding: 12px 30px;
background: #000;
color: #fff;
border: none;
cursor: pointer;
font-size: 1rem;
transition: background 0.3s ease;
}
.load-more-btn:hover {
background: #333;
}
.load-more-btn:disabled {
background: #ccc;
cursor: not-allowed;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector('[data-showcase-blog]');
if (!container) return;
const BLOG_URL = container.getAttribute('data-showcase-blog');
if (!BLOG_URL) return;
const CATEGORY = container.getAttribute('data-category');
const LIMIT = parseInt(container.getAttribute('data-limit')) || 40;
const LOAD_MORE = container.getAttribute('data-load-more') === 'true';
let allItems = [];
let displayedCount = 0;
let blogWrapper = null;
const ITEMS_PER_LOAD = 10;
// Fetch HTML structure từ blog page
fetch(BLOG_URL).then(response => response.text()).then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const originalWrapper = doc.querySelector('.blog-basic-grid.collection-content-wrapper');
if (!originalWrapper) return;
// Clone wrapper và xóa hết nội dung bên trong
blogWrapper = document.createElement('div');
blogWrapper.className = originalWrapper.className;
blogWrapper.classList.add('preFade');
// Copy data attributes
Array.from(originalWrapper.attributes).forEach(attr => {
if (attr.name.startsWith('data-')) {
blogWrapper.setAttribute(attr.name, attr.value);
}
});
// Fetch all blog data
fetchAllBlogPages(BLOG_URL);
});
async function fetchAllBlogPages(baseUrl, offset = null) {
const url = offset ? `${baseUrl}?offset=${offset}&format=json` : `${baseUrl}?format=json`;
try {
const response = await fetch(url);
const data = await response.json();
let items = data.items || [];
if (CATEGORY) {
items = items.filter(item => {
const categories = item.categories || [];
return categories.some(cat => cat.toLowerCase().includes(CATEGORY.toLowerCase()));
});
}
allItems = allItems.concat(items);
if (data.pagination && data.pagination.nextPage && data.pagination.nextPageUrl) {
const nextOffset = data.pagination.nextPageOffset;
await fetchAllBlogPages(baseUrl, nextOffset);
} else {
// Hoàn thành fetch, bắt đầu render
allItems = allItems.slice(0, LIMIT);
initializeDisplay();
}
} catch (error) {
console.error('Error fetching blog data:', error);
}
}
function initializeDisplay() {
// Thêm wrapper vào container trước
container.innerHTML = '';
container.appendChild(blogWrapper);
if (LOAD_MORE) {
const initialItems = allItems.slice(0, ITEMS_PER_LOAD);
renderItems(initialItems);
displayedCount = initialItems.length;
if (displayedCount < allItems.length) {
createLoadMoreButton();
}
} else {
renderItems(allItems);
displayedCount = allItems.length;
}
setTimeout(() => {
blogWrapper.classList.remove('preFade');
blogWrapper.classList.add('fadeIn');
}, 100);
}
function renderItems(itemsToRender) {
itemsToRender.forEach(item => {
const article = createBlogArticle(item);
blogWrapper.appendChild(article);
});
}
function createBlogArticle(item) {
const article = document.createElement('article');
article.className = 'blog-basic-grid--container entry blog-item is-loaded';
// Image wrapper div
const imageOuterDiv = document.createElement('div');
const imageLink = document.createElement('a');
imageLink.href = item.fullUrl;
imageLink.className = 'image-wrapper';
imageLink.setAttribute('data-animation-role', 'image');
const img = document.createElement('img');
img.setAttribute('data-src', item.assetUrl);
img.setAttribute('data-image', item.assetUrl);
img.setAttribute('data-image-dimensions', item.originalSize || '1280x853');
img.setAttribute('data-image-focal-point', '0.5,0.5');
img.alt = item.title;
img.setAttribute('data-load', 'false');
img.src = item.assetUrl;
img.className = 'image';
img.style.cssText = 'display:block;position: absolute; height: 100%; width: 100%; object-fit: cover; object-position: 50% 50%;';
img.loading = 'lazy';
img.decoding = 'async';
img.setAttribute('data-loader', 'sqs');
imageLink.appendChild(img);
imageOuterDiv.appendChild(imageLink);
// Spacer
const spacer = document.createElement('div');
spacer.className = 'blog-article-spacer';
// Text content
const textDiv = document.createElement('div');
textDiv.className = 'blog-basic-grid--text';
// Meta section
const metaSection = createMetaSection(item);
// Title
const title = document.createElement('h1');
title.className = 'blog-title';
const titleLink = document.createElement('a');
titleLink.href = item.fullUrl;
titleLink.textContent = item.title;
// Nếu có sourceUrl thì thêm passthrough-link
if (item.sourceUrl) {
titleLink.className = 'passthrough-link';
titleLink.setAttribute('target', '_blank');
titleLink.setAttribute('rel', 'noopener');
titleLink.setAttribute('data-no-animation', '');
}
title.appendChild(titleLink);
// Excerpt
const excerpt = document.createElement('div');
excerpt.className = 'blog-excerpt';
if (item.excerpt) {
const excerptWrapper = document.createElement('div');
excerptWrapper.className = 'blog-excerpt-wrapper';
excerptWrapper.innerHTML = item.excerpt;
excerpt.appendChild(excerptWrapper);
}
// Read more link
const readMore = document.createElement('a');
readMore.className = 'blog-more-link passthrough-link';
readMore.href = item.sourceUrl || item.fullUrl;
readMore.setAttribute('data-animation-role', 'content');
readMore.textContent = 'Read More';
if (item.sourceUrl) {
readMore.setAttribute('target', '_blank');
readMore.setAttribute('rel', 'noopener');
}
textDiv.appendChild(metaSection);
textDiv.appendChild(title);
textDiv.appendChild(excerpt);
textDiv.appendChild(readMore);
article.appendChild(imageOuterDiv);
article.appendChild(spacer);
article.appendChild(textDiv);
return article;
}
function createMetaSection(item) {
const metaSection = document.createElement('div');
metaSection.className = 'blog-meta-section';
const metaPrimary = document.createElement('span');
metaPrimary.className = 'blog-meta-primary';
// Categories
if (item.categories && item.categories.length > 0) {
const categoriesSpan = document.createElement('span');
categoriesSpan.className = 'blog-categories-list';
item.categories.forEach((cat, index) => {
const catLink = document.createElement('a');
catLink.href = `${BLOG_URL}/category/${cat}`;
catLink.className = 'blog-categories';
catLink.textContent = cat;
categoriesSpan.appendChild(catLink);
if (index < item.categories.length - 1) {
const comma = document.createElement('span');
comma.className = 'blog-categories--comma';
comma.textContent = ', ';
categoriesSpan.appendChild(comma);
}
});
metaPrimary.appendChild(categoriesSpan);
}
// Author
if (item.author) {
const authorSpan = document.createElement('span');
authorSpan.className = 'blog-author';
authorSpan.textContent = item.author.displayName;
metaPrimary.appendChild(authorSpan);
}
// Date
const date = new Date(item.publishOn);
const dateTime = document.createElement('time');
dateTime.className = 'blog-date';
dateTime.setAttribute('pubdate', '');
dateTime.setAttribute('data-animation-role', 'date');
dateTime.textContent = date.toLocaleDateString('en-US', {month: 'numeric', day: 'numeric', year: '2-digit'});
metaPrimary.appendChild(dateTime);
const delimiter = document.createElement('span');
delimiter.className = 'blog-meta-delimiter';
// Meta secondary (duplicate for responsive)
const metaSecondary = metaPrimary.cloneNode(true);
metaSecondary.className = 'blog-meta-secondary';
metaSection.appendChild(metaPrimary);
metaSection.appendChild(delimiter);
metaSection.appendChild(metaSecondary);
return metaSection;
}
function showMoreItems() {
const itemsToShow = allItems.slice(displayedCount, displayedCount + ITEMS_PER_LOAD);
renderItems(itemsToShow);
displayedCount += itemsToShow.length;
if (displayedCount >= allItems.length) {
const btn = container.querySelector('.load-more-btn');
if (btn) btn.remove();
}
}
function createLoadMoreButton() {
const btn = document.createElement('button');
btn.className = 'load-more-btn';
btn.textContent = 'Load More';
btn.onclick = showMoreItems;
container.appendChild(btn);
}
});
</script>

#2. Next, edit page > Add a Code Block with this syntax
<div data-showcase-blog="/blog-01" data-category data-limit="40" data-load-more="true"></div>

#3. Update Blog Page URL Slug
