
How to win when Gen Z asks TikTok, not Google

Marketing Budget 2026: Your 90-day guide to getting it done

B2B content marketing trends not to miss in 2026

E-commerce category page best practices for SEO

How to build an email list for property management companies

How to run TikTok search ads

AI in e-commerce: Use cases and how to get started

10 data-driven digital PR ideas for Christmas 2025

How to identify customer digital touchpoints

10 lead generation strategies for home improvement businesses

B2B digital marketing trends to watch ahead of 2026
@import "../../resources/scss/util/variables";
@import "../../resources/scss/util/mixins";
@import "../../resources/scss/vendor/bootstrap/vendor/rfs";
.block-post-feed{
@include padding-top(rem-calc(60));
@include padding-bottom(rem-calc(60));
position: relative;
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
background-color: $white;
z-index: 10;
transition: opacity 0.25s ease-in-out;
pointer-events: none;
}
&__items{
display: grid;
gap: rem-calc(10);
grid-template-columns: 1fr;
@include margin-bottom(rem-calc(40));
@include bp($md) {
grid-template-columns: 1fr 1fr;
@include margin-bottom(rem-calc(60));
}
@include bp($lg) {
grid-template-columns: 1fr 1fr 1fr;
}
@include bp($xl) {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
}
.post-card{
overflow: hidden;
&:nth-child(2n){
--post-card-bg: var(--tertiary);
}
&--featured{
min-height: rem-calc(420);
transition: 0.3s ease-in all;
@include bp($md) {
grid-column: 1 / span 2;
}
.post-card__tags {
top: rem-calc(10);
left: rem-calc(10);
@include bp($md) {
top: rem-calc(16);
left: rem-calc(16);
}
}
.image-wrapper{
width: 100%;
height: 100%;
position: absolute !important;
top: 0;
left: 0;
}
@media (hover: hover) and (pointer: fine){
&:hover{
box-shadow: 0px 16px 34px 0px rgba(0, 0, 0, 0.25);
transform: translateY(-5px);
.image-wrapper{
&::after{
opacity: 1;
}
}
}
}
}
.image-wrapper{
opacity: 1;
transition: 0.3s ease opacity;
position: relative;
overflow: hidden;
&:after{
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
background-color: rgba(0,0,0,0.6);
transition: 0.3s all ease;
}
}
.image-wrapper-hover{
opacity: 0;
transition: 0.3s ease opacity;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
&:after{
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 1;
background-color: rgba(0,0,0,0.6);
transition: 0.3s all ease;
}
}
&__tags {
top: rem-calc(24);
left: rem-calc(24);
}
&--standard{
.post-card__tags {
top: 1.25rem;
left: 1.25rem;
}
@media (hover: hover) and (pointer: fine){
transition: 0.3s ease-in all;
&:hover{
box-shadow: 0px 16px 34px 0px rgba(0, 0, 0, 0.25);
transform: translateY(-5px);
}
}
}
}
&.loading {
&:before {
opacity: 0.75;
pointer-events: all;
}
&:after {
content: '';
position: absolute;
top: 20%;
left: calc(50% - 50px);
width: 100px;
height: 100px;
animation: spin 1s linear infinite;
border: 8px solid;
border-color: color-mix(in srgb, var(--primary) 10%, transparent);
border-top-color: var(--primary);
border-radius: 50%;
z-index: 20;
}
}
.sort-by-wrap{
width: 100%;
}
select[data-sort-by],
select[data-filter-by]{
border-radius: 60px;
border: 1px solid rgba(0,0,0,0.2);
width: 100%;
min-height: rem-calc(44);
background-size: rem-calc(8);
font-size: rem-calc(16);
cursor: pointer;
padding:rem-calc(10) rem-calc(40) rem-calc(10) rem-calc(20);
@include bp($md){
width: rem-calc(200);
}
@include bp($lg){
font-size: rem-calc(18);
}
}
.mobile-filter{
@include bp($lg){
display: none;
}
}
.filter-wrapper{
display: block;
position: relative;
border-radius: 60px;
border: 1px solid rgba(0,0,0,0.2);
display:none;
@include bp($lg){
max-width: 100%;
overflow-x: auto;
white-space: nowrap;
padding: 0 1px;
display:block;
&::-webkit-scrollbar {
height: 5px;
margin-top: 4px;
}
&::-webkit-scrollbar-track {
background: transparent;
margin: 10px 20px 0;
}
&::-webkit-scrollbar-thumb {
background: #bbb;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb:hover {
background: #999;
}
}
}
.filter-container{
display: none;
@include bp($lg){
display: inline-flex;
gap: 8px;
padding-right: 4px;
.filter{
border-radius: 60px;
font-size: rem-calc(18px);
line-height: 1.5;
background-color: $white;
@include padding(rem-calc(8 18));
text-decoration: none;
flex-shrink: 0;
margin-top: 4px;
margin-left: 4px;
&.active{
background-color: $grey-primary;
}
}
}
}
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
class PostFeedBlock {
/**
* Create and initialise objects of this class
* @param {HTMLElement} block
*/
constructor(block) {
this.block = block;
this.postsContainer = this.block.querySelector('.results');
this.countElement = this.block.querySelector('.post-feed-count');
this.sortBy = this.block.querySelector('select[data-sort-by]');
this.postType = this.block.dataset.postType;
this.featuredId = this.block.dataset.featured;
this.perPage = parseInt(this.block.dataset.perPage);
this.taxonomy = this.block.dataset.taxonomy;
this.filterCategory = false;
this.orderBy = this.block.dataset.orderby;
this.sortOrder = this.block.dataset.order;
this.currentPage = 1;
this.init();
}
init() {
this.setupPagination();
this.setupSorting();
this.setupFilters();
}
setupPagination() {
const pagination = this.block.querySelector('.pagination');
if (!pagination) {
return;
}
const paginationLinks = pagination.querySelectorAll('a');
paginationLinks.forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
// Get page
let page = link.innerText;
if (link.dataset.page) {
page = link.dataset.page;
}
if (!page) {
return;
}
if (page && page !== this.currentPage) {
this.currentPage = page;
this.fetchResults();
}
});
});
}
setupFilters() {
const filters = this.block.querySelectorAll('select[data-filter-by]');
const filtersLinks = this.block.querySelectorAll('.filter');
if (filters) {
filters.forEach(filter => {
filter.addEventListener('change', (e) => {
const filterValue = filter.value;
if (!filterValue || filterValue === 'all') {
this.filterCategory = false;
} else {
this.filterCategory = filterValue;
}
this.currentPage = 1;
this.fetchResults();
});
});
}
if (filtersLinks) {
filtersLinks.forEach(filterItem => {
filterItem.addEventListener('click', (e) => {
if(!filterItem.classList.contains('active')){
filtersLinks.forEach(fitem=>{
fitem.classList.remove('active');
});
}
const filterValue = filterItem.dataset.value;
filterItem.classList.add('active');
if (!filterValue || filterValue === 'all') {
this.filterCategory = false;
} else {
this.filterCategory = filterValue;
}
this.currentPage = 1;
this.fetchResults();
});
});
}
}
setupSorting() {
const sortSelect = this.sortBy;
if (!sortSelect) return;
sortSelect.addEventListener('change', () => {
const val = sortSelect.value;
if (!val) {
this.feedSorting = {};
} else {
const [orderby, order] = val.split('_');
this.orderBy=orderby;
this.sortOrder=order;
}
this.fetchResults();
});
}
async fetchResults() {
this.block.classList.add('loading');
try {
const formData = new FormData();
formData.append('action', 'load_post_feeds');
formData.append('nonce', postFeed.nonce);
formData.append('post_type', this.postType);
formData.append('posts_per_page', this.perPage);
formData.append('paged', this.currentPage);
formData.append('orderby', this.orderBy);
formData.append('order', this.sortOrder);
formData.append('origin',postFeed.baseURL);
formData.append('featured',this.featuredId);
// Add category filter if selected
if (this.filterCategory) {
formData.append('taxonomy', this.taxonomy);
formData.append('category', this.filterCategory);
}
const response = await fetch(postFeed.ajaxurl, {
method: 'POST',
credentials: 'same-origin',
body: formData,
});
const data = await response.json();
if (data.success) {
this.totalPages = data.data.total_pages;
this.updateResults(data.data);
this.updatePagination(data.data.pagination);
this.updateCount(data.data.found_posts);
} else {
this.updatePagination(false);
this.showError(data.data.message || 'Error loading posts');
}
} catch (error) {
this.showError('Error loading posts. Please try again.');
} finally {
this.block.classList.remove('loading');
}
}
updateResults(data){
if (!this.postsContainer) return;
this.postsContainer.innerHTML = data.results;
}
updateCount(count){
if (!this.countElement) return;
const countText = count === 1 ? 'Resource' : 'Resources';
this.countElement.textContent = `${count} ${countText}`;
}
updatePagination(pagination){
const paginationElem = this.block.querySelector('.pagination');
if (!paginationElem) {
return;
}
// if no pagination, remove pagination
if (!pagination) {
paginationElem.innerHTML = '';
return;
}
// replace pagination
paginationElem.outerHTML = pagination;
// Reregister events
this.setupPagination();
}
showError(message = 'Sorry, there was an error loading posts. Please try again.') {
if (!this.postsContainer) return;
this.postsContainer.innerHTML = `
${message}
`;
}
}
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.block-post-feed').forEach(block => new PostFeedBlock(block));
});
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "strategiq/post-feed",
"title": "Post Feed",
"description": "Example block to be used as a template",
"category": "strategiq",
"icon": "strategiq",
"acf": {
"mode": "preview",
"renderTemplate": "block-post-feed.php"
},
"supports": {
"anchor": true,
"align": false,
"color": {
"background": true,
"text": false,
"gradients": true
},
"spacing": {
"padding": [
"top",
"bottom"
],
"margin": [
"top",
"bottom"
]
}
},
"style": ["file:../../assets/css/post-feed/block-post-feed.css", "base-blog"],
"viewScript": ["post-feed"]
}