EDIT: Up to date code, only thing left to fix is the subcategory query.

I'm struggling to get my portfolio page's filter to work. I have quite a good knowledge of WordPress and cannot seem to...


  • Create a filter with only the categories that are a subcategory of a specified category.

  • Use the selected option from the sub-category filter to Ajax the relevant posts for the chosen filter into view.

So onto the relevant code:

My portfolio page that successfully pulls the posts from the my portfolio category:

<div class="portfolio-filters">

    $filtercategory = get_template_directory() . "/template-parts/category-filter.php";


<div class="portfolio-pieces">

    <div class="portfolio-pieces-inner">

        <div id="response">

            $args = array(
                'post_type' => 'post',
                'post_status' => 'publish',
                'category_name' => 'portfolio',
                'posts_per_page' => '-1',
                'orderby' => 'post_date',
                'order' => 'DESC'
            ); ?>

            <?php $the_query = new WP_Query( $args ); ?>

            <?php while ($the_query -> have_posts()) : $the_query -> the_post(); ?>

                <div class="portfolio-piece" <?php if(has_post_thumbnail()) : ?>style="background-image: url(<?php echo get_the_post_thumbnail_url(); ?>);"<?php endif; ?>>
                    <a href="<?php the_permalink(); ?>" class="box-link" target="_blank"></a>

                    <div class="portfolio-piece-hover">


                    <div class="portfolio-piece-inner">
                        <h4><?php the_title(); ?></h4>





In the snippet above, I call my filter file. Create the response area and load in the complete list of portfolio pieces.

My Category Filter file looks like this:

<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
        $args = array(
            'taxonomy' => 'category',
            'category_name' => 'portfolio-category',
            'orderby' => 'name',
            'order' => 'DESC',
            'parent' => 0
        if( $terms = get_terms( $args ) ) :
            echo '<select name="categoryfilter"><option>Select category...</option>';
        foreach ( $terms as $term ) :
            echo '<option value="' . $term->term_id . '">' . $term->name . '</option>';
            echo '</select>';

    <button>Apply filters</button>
    <input type="hidden" name="action" value="customfilter">

    jQuery(function($) {
            var filter = $('#filter');
                data:filter.serialize(), // form data
                type:filter.attr('method'), // POST
                    filter.find('button').text('Applying Filters...');
                    filter.find('button').text('Apply filters');
            return false;

Where the above snippet is 'attempting' to create a form with an action that points to the admin-ajax.php file in my wp-admin folder (it is there).

Then loops through my get_terms args to present the sub-categories I wish into a drop down list, with an apply button.

The last snippet handles it all. Changing the buttons text depending on its state and gives my response div as the return place.

My functions file is like this:

/* Filter Post Results */
function catfilter_filter_function(){
    $args = array(
        'orderby' => 'date', // we will sort posts by date
        'order' => $_POST['date'] // ASC or DESC

    // for taxonomies / categories
    if( isset( $_POST['categoryfilter'] ) )
        $args['tax_query'] = array(
                'taxonomy' => 'category',
                'field' => 'id',
                'terms' => $_POST['categoryfilter']

    $query = new WP_Query( $args );

    if( $query->have_posts() ) :
        while( $query->have_posts() ): $query->the_post();

            echo "<div class=\"portfolio-piece\" style=\"background-image: url(" . get_the_post_thumbnail_url() . ");\">";

                echo "<a href=\"" . the_permalink() . "\" class=\"box-link\" target=\"_blank\"></a>";

                echo "<div class=\"portfolio-piece-hover\">";

                echo "</div>";

                echo "<div class=\"portfolio-piece-inner\">";

                    echo "<h4>" . the_title() . "</h4>";

                echo "</div>";

            echo "</div>";

    else :
        echo 'No posts found';

add_action('wp_ajax_customfilter', 'catfilter_filter_function');
add_action('wp_ajax_nopriv_customfilter', 'catfilter_filter_function');
/* END Filter Post Results */

The functions file script works, will pull the posts stated in the filter through.

Can someone please help me narrow down my category filter to only have the relevant sub-categories in it? - They are sub-categories of the 'Portfolio Categories' category that has the slug 'portfolio-category'

I am able to show the complete list of categories, or just the base parent categories, not the sub categories...

My categories are set up like this:

— Portfolio Piece

— — Portfolio Category

— — — Automation

— — — Design

— — — Digital

— — — Exhibitions

— — — PR / Social

— — — Strategy

— — — Tech Insights

— — Sector

— — — Construction

— — — Manufacturing

— — — Oil & Gas

— — — Science

I have had no joke 50+ attempts at different articles and cannot for the life of me narrow this list down.

So massive thanks in advance!

  • So essentially you want the lowest-level category of a post? Mar 1, 2019 at 15:48
  • 2
    You may want to have a look at get_term_children(). That will return an array of term's children from which you can fetch the one you need.
    – freejack
    Mar 1, 2019 at 17:51
  • So to clarify, does the post belong to the sub-sub-category you're trying to get the slug of? in other words, what's the relation between a queried post and this 3rd-level category?
    – Taruc
    Mar 1, 2019 at 22:44
  • Hi all, thanks for having a look over my question. Welcome to another week... I will update my question to extrapolate a little further on my situation. Mar 4, 2019 at 9:45

1 Answer 1


You are able to specify the parent for which the get_terms should iterate through by using:

parent => cat_ID

Where cat_ID is the ID of the category.

You can find out the category ID by hovering over the link to the category in the category list, then checking the URL you will be directed to in the link note in the bottom left of your browser.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.