The Filterable Projects module in Divi is great and we love using it for various projects, unfortunately, Divi didn’t make the Blog Module filterable out of the box. Luckily making the blog module filterable is possible and pretty easy to do, with just a little CSS knowledge and a basic understanding of HTML and PHP you can make a simple filterable blog module for Divi.

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

There are a few draw backs that I will go over first. The Filterable blog module that we will make won’t be pageable, it also won’t show the posts in the perfect date order. That said it’s perfect for filtering a few categories or latest posts from a few of your categories. You can also filter using tags.

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 wph_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') ) { // CHANGE PAGE SLUG OR REMOVE CONDITIONAL STATEMENT
wp_enqueue_script('mixitup_js', '//cdn.cloudcanvas.website/wp-content/assets/js/mixitup.min.js', true, '2.1.11'); // ENTER PATH TO FILE ON YOUR SERVER
}
}
add_action( 'wp_enqueue_scripts', 'wph_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 wph_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', 'wph_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;
}
#filterposts .category-articles h2.entry-title {
color: #ffffff;
}
#filterposts .category-articles .post-content p {
color: rgba(255, 255, 255, 0.78) !important;
}
#filterposts .category-articles .post-content a {
color: #fff;
background: rgba(242, 106, 43, 0.7);
}
#filterposts .category-articles:before {
content: "Article";
background: #fff;
color: #f26827;
}
#filterposts .category-press-releases {
background-color: #fff;
}
#filterposts .category-press-releases h2.entry-title {
color: #f26827;
}
#filterposts .category-press-releases .post-content p {
color: #f26827 !important;
}
#filterposts .category-press-releases .post-content a {
color: #222;
background: rgba(255, 255, 255, 0.7);
}
#filterposts .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;
}
#filterposts .et_pb_post .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;
}
#filterposts .et_pb_post: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%;
}
#filter-buttons 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;
}
#filter-buttons button:hover {
border-bottom: 1px solid #81ab40;
}
#filter-buttons .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;
}
#filterposts .et_pb_post h2.entry-title {
font-style: 18px !important;
}
#filterposts .et_pb_post .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 colour and font choices.

If you want to achieve a similar effect with different colours 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;
}
.blog-orange-bg .et_pb_blog_grid .et_pb_post h2.entry-title {
color: #efefef;
}
.blog-orange-bg .et_pb_blog_grid .et_pb_post .post-content p {
color: rgba(255, 255, 255, 0.78) !important;
}
.blog-orange-bg .et_pb_blog_grid .et_pb_post .post-content a {
color: #ffffff;
}

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

This is a repost of my article on adamhaworth.com.