Recently we were tasked with creating a new site for the marketing agency Media Frenzy with CloudCanvas, we decided to use the Divi theme to make the site. We wanted to allow users to filter through posts the same way you can with the portfolio module but after some searching, we realised there was no custom module to do this. So we created the function ourselves and thought we would share with anyone else who wants to achieve the same effect with Divi.

See it in action: www.mediafrenzyglobal.com/news

Getting started

Before we jump in I’ll explain a few drawbacks. You will need to have posts and categories, this effect is really only suitable for a few categories. The other drawback is that you can’t use this with pagination, so you will have to display all the posts from your selected categories on the page. This works perfectly if you are filtering a small number of posts from a few different categories.

 

The Modules

You will need to create a page using the Divi Builder, on your page all you will need is a blog and code module. Within the blog module select the categories you want to display and select to display full width, you need to display full width and Divi uses a column effect layout to display posts in a masonry grid and because the posts are in columns they can’t be filtered within a single parent element. Don’t worry we will add our own CSS later to make the posts appear in a grid layout again.

Filter Posts with Divi blog module

Filter Posts with Divi blog module

Select just the categories you want to display, we have entered the number of posts as an infinite value of ‘-1’ to display all posts from the selected categories.

Filter Posts with Divi blog module
Add the following CSS ID to the blog module “filterposts”, you can also add the class if you want to achieve the same styles as in our sample.

We can start working on our filter buttons now within a code module, these buttons are very simple and you just need to create a button for each category you want to filter plus one extra to display all posts again.

This is what your buttons should look like, these are from our sample in the link above. You will need to change data-filter=”.category-articles” to reflect your category, this is simply the class added to each post in the loop and it will be ‘category-CATSLUG’ so just find your category slug and add it to the data-filter and also change the text of your button.

<button class="filter-btn" data-filter="all">Show All</button>
<button class="filter-btn" data-filter=".category-articles">Articles</button>
<button class="filter-btn" data-filter=".category-press-releases">Press Releases</button>

You need to then insert these buttons in a code module as shown below.

Filter Posts with Divi blog module

 

Adding Scripts

Now you have finished with Divi, the rest we will have to make the ‘old fashioned way’ with some functions and scripts.

To make the filter function work we are using the jQuery plugin MixItUP. You can enqueue this script using our function below in a child theme or even better with a plugin, we suggest the My Custom Functions plugin. Feel free to load the script from the CloudCanvas CDN or download the MixItUp script from the link above and host yourself. We have also enqueued a Google hosted jQuery library, you can remove this if you have already done this or don’t want to use Google jQuery.

function adamhaworth_assets_scripts() {   
    // Google jQuery
    wp_deregister_script('jquery');
    wp_register_script('jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js', false, '1.12.4');
    wp_enqueue_script('jquery'); 
    
    if ( is_page('news') ) {
        wp_enqueue_script('mixitup_js', 'https://cdn.cloudcanvas.website/wp-content/cc-assets/js/mixitup.min.js', true, '2.1.11');
    }
}
add_action( 'wp_enqueue_scripts', 'adamhaworth_assets_scripts', 15);

You will notice that the function is conditional so it only loads on the news page. You can either remove the conditional ‘if’ statement and enqueue on all pages or you can change the slug to the page you want to have the filter function display on.

Now the jQuery plugin is enqueued we need to add the options to make the plugin work with our setup. These are the options required to display the filter, we have placed these in a PHP function and enqueued them using this function to display in the footer of the site. Again this is a conditional script so you can remove the conditional statement or add your page slug again.

function adamhaworth_filter_script() {
	if( is_page('news') ) {
		?> 
		<?php ?>
    <script type="text/javascript">
        $(window).load(function(){
            $('#filterposts').mixItUp({
                animation: {
                    effects: 'fade',
                    duration: 700
                },
                selectors: {
                	target: '.et_pb_post',
               	 	filter: '.filter-btn'
                },
                callbacks: {
                    onMixEnd: function(state) {
                        console.log(state)
                    }
                }
            });
        })
    </script>
		<?php ?>
	    <?php
	}
}
add_action('wp_footer', 'adamhaworth_filter_script', 99);

The Styles All that you need to do now is add some styles to make the posts appear in a grid again. To add the styles activate Jetpack and enable the CSS module, we can then use SCSS within the CSS editor in customizer. Its important that you enable SCSS within the Jetpack CSS editor if you are going to copy and paste our styles. If you want to convert the SCSS to CSS for use on your site you can convert it here: www.sassmeister.com.

/**
 * Filter Posts
 */
#filterposts {
	.category-articles {
			background-color: #F26827;
		
			h2.entry-title {
				color: #ffffff;
			}
	
		.post-content {
					p {
						color: rgba(255, 255, 255, 0.78) !important;
					}
				
					a {
						color: #fff;
						background: rgba(242, 106, 43, 0.7);
					}
		}
	}
	
	.category-articles:before {
			content: "Article";
			background: #fff;
			color: #f26827;
	}
	
	.category-press-releases {
			background-color: #fff;
		
			h2.entry-title {
				color: #f26827;
			}
	
		.post-content {
					p {
						color: #f26827 !important;
					}
				
					a {
						color: #222;
						background: rgba(255, 255, 255, 0.7);
					}
		}
	}
	
	.category-press-releases:before {
			content: "Press Release";
			background: #f26827;
			color: #fff;
	}
}

#filterposts .category-articles:after {
    box-shadow: inset 0px -58px 39px -34px #f26827;
}

#filterposts .category-press-releases:after {
    box-shadow: inset 0px -58px 39px -34px #fff;
}

#filterposts {
	position: relative;
}

#filterposts .et_pb_post:before {
    position: absolute;
    top: 0;
    left: 0;
    border-radius: 0 0 5px 0;
    padding: 7px 21px;
    font-size: 12px;
    font-weight: 600;
}

#filterposts .et_pb_post:after {
    content: "";
    position: absolute;
    z-index: 100;
    width: 100%;
    height: 50px;
    left: 0;
    bottom: 0;
    border-radius: 4px;
}

#filterposts .et_pb_post {
    border: 1px solid #eee;
    display: none;
    border-radius: 4px;
    padding: 20px;
    margin: 2%;
    float: left;
    width: 46%;
    height: 250px;
    position: relative;
    overflow: hidden;

		.post-content {
			a {
				position: absolute;
				bottom: 0;
				left: 0;
				z-index: 100;
				width: 100%;
				height: 100%;
				text-align: center;
				padding: 119px 0;
				top: 0;
				text-transform: capitalize;
				font-family: 'Montserrat', Helvetica, Arial, Lucida, sans-serif;
				font-weight: bold;
				font-size: 20px;
				opacity: 0;
				transition: all .2s;
			}
		}

		&:hover {
		.post-content {
			a {
				opacity: 1;
			}
		}
		}
}

#filter-buttons {
    display: block;
    text-align: center;
    width: 96%;
    border: 1px solid #f3f3f3;
    background: #fff;
    border-radius: 4px;
    margin: 0 2%;
	
	button {
    border: none;
    cursor: pointer;
    display: inline-block;
    padding: 25px 17px;
    margin: 0 8px;
    font-size: 16px;
    background: transparent;
    font-weight: 700;
    color: #666;
    font-family: 'Lato', Helvetica, Arial, Lucida, sans-serif;
    transition: all .2s;
		
		&:hover {
			    border-bottom: 1px solid #81ab40;
		}
	}

	.filter-btn.active {
			border-bottom: 2px solid #f26827 !important;
	}
}

@media screen and (max-width: 980px) {
	#filterposts .et_pb_post {
			width: 100%;
			height: auto;
			float: none;
	
			h2.entry-title {
				font-style: 18px !important;
			}

			.post-content {
				a {
					position: relative;
					width: auto;
					background: transparent;
					opacity: 1;
					padding: 0;
					display: inline-block;
					font-size: 13px;
				}
			}
	}

	#filterposts .et_pb_post:after {
		display: none;
	}
}

You will notice we have added some before and after pseudo styles to add labels, you can remove these if you like. You will have to adjust this CSS to match your color and font choices.

If you want to achieve a similar effect with different colors for each category you can follow this snippet of CSS to get started.

/**
 * Blog
 */
.blog-orange-bg {
	.et_pb_blog_grid .et_pb_post {
			border-radius: 4px;
			border-color: #F26827 !important;
			background-color: #F26827 !important;
		
			h2.entry-title {
					color: #efefef;
			}
	
			.post-content {
				p {
					color: rgba(255, 255, 255, 0.78) !important;
				}
			
				a {
						color: #ffffff;
				}
			}
	}
}

I hope you found this useful, please share and comment below.

Pin It on Pinterest