I’m using a CMS Collection List with over 150 items, and I’d like to display them in a custom grid pattern that follows this repeating structure:
[ A ] [ A ] [ B ]
[ C ] [ D ] [ D ]
[ E ] [ E ] [ F ]
[ G ] [ H ] [ H ]
[ I ] [ I ] [ J ] etc
Each row has 3 items, but some items are visually repeated in the layout (like A appearing twice in the first row).
If there’s a clean solution, maybe via advanced CSS or conditional visibility. I’d love to learn how. I am using finsweet cms filters that’s why attributes imported from the cms doesn’t work.
The 150 items isn’t a problem if you’re using FS CMS Filter, just use FS CMS Load and pagination as well.
But visually repeated items?
Since you’re wanting to use Finsweet CMS Filter you’d probably be best off actually creating duplicate rows in the CMS. That ensures filtering will work, and that you can control the repetition.
Another possible approach is to e.g. add a field to the CMS indicating the repetition count, e.g. 1, 2, 3… Then create a second collection list identical to the first, but filtered to show only items that have 2+ reptition. Then a third identical list, filtered to show only 3+
In the end you’ll have a single-rep item once, 2-rep items twice, 3 rep items 3 times.
Then use FS CMS Combine to merge those list together.
You might have some issues getting Combine to work with Load and Filter but IIRC they’re fully compatible.
You’d likely need FS CMS Sort as well to force the items to be adjacent.
You already have the CMS list working. Now let’s inject a script that clones items in the desired pattern.
Custom JS Script (for your Webflow project)
Paste this in the Page Settings > Before tag on your “Products Listing” page:
<script>
document.addEventListener("DOMContentLoaded", function () {
const items = Array.from(document.querySelectorAll(".all-products_component .w-dyn-item"));
const wrapper = document.querySelector(".all-products_component");
wrapper.innerHTML = ""; // Clear current CMS layout
for (let i = 0; i < items.length; i += 5) {
const group = [];
if (items[i]) {
group.push(items[i].cloneNode(true)); // A
group.push(items[i].cloneNode(true)); // A again
}
if (items[i + 1]) group.push(items[i + 1].cloneNode(true)); // B
if (items[i + 2]) group.push(items[i + 2].cloneNode(true)); // C
if (items[i + 3]) group.push(items[i + 3].cloneNode(true)); // D
if (items[i + 3]) group.push(items[i + 3].cloneNode(true)); // D again
if (items[i + 4]) {
group.push(items[i + 4].cloneNode(true)); // E
group.push(items[i + 4].cloneNode(true)); // E again
}
if (items[i + 5]) group.push(items[i + 5].cloneNode(true)); // F
group.forEach((item) => wrapper.appendChild(item));
}
});
</script>