0

I have built an isotope portfolio Wordpress theme which so far is working perfectly:

Anything posted in the custom post type 'portfolio' shows on the homepage and is filterable by the 'portfolio-category' taxonomy using the Isotope JQuery plugin.

So far so good.

However, I wish to make a small improvement.

I only want FEATURED portfolio items to show on the homepage. For example, only portfolio items with the taxonomy classification of 'featured'. This part I have achieved easily with a custom query (see code snippet below).

The problem I am having is displaying the filterable buttons. I don't want a filterable button to say 'Featured' (defies the point), nor do I want any taxonomies to appear which aren't applicable to any of the featured items (because if clicked, all the portfolio items being displayed will disappear).

Here is my current query to show the portfolio items. No problems here:

<?php
// Query the portfolio posts 
$args = array(
    'post_type' => 'portfolio',
    'portfolio-category' => 'featured',
    'posts_per_page' => -1 );
$loop = new WP_Query( $args );
  while ( $loop->have_posts() ) : $loop->the_post(); 
?>
<!-- PORTFOLIO ITEM -->
<?php endwhile; ?>

And here is the code I have currently which outputs the filterable taxonomies. This is what needs addressing.

<?php
    $terms = get_terms('portfolio-category');
    $count = count($terms);
    echo '<li class="filtering"><a href="#" title="" data-filter="*" class="button-primary">All</a></li>';
        if ( $count > 0 ){
            foreach ( $terms as $term ) {
                $termname = strtolower($term->name);
                $termname = str_replace(' ', '-', $termname);
                echo '<li class="filtering"><a href="#" title="" data-filter=".'.$termname.'">'.$term->name.'</a></li>';
            }
        }
?>

Many thanks!

2 Answers 2

1

You can just get the terms from the current query. To achieve this you can use wp_get_object_terms(), but it expects IDs, which we can extract by using wp_list_pluck() on the query objects posts property. It seems like you only need the names, which we can extract again with wp_list_pluck() from the result wp_get_object_terms() returns. Last but not least, the array returned might have duplicates, so we make it unique with array_unique(). In summary this would look somewhat along the lines of the following:

$args = array(
    'post_type'          => 'portfolio',
    'portfolio-category' => 'featured',
    'posts_per_page'     => -1 
);
$loop = new WP_Query( $args );

$loop_posts     = $loop->posts;
$loop_posts_ids = wp_list_pluck( $loop_posts, 'ID' );

$loop_term_objects          = wp_get_object_terms( $loop_posts_ids, 'portfolio-category' );
$loop_term_names_not_unique = wp_list_pluck( $loop_term_objects, 'name' );
$loop_term_names_unique     = array_unique( $loop_term_names_not_unique );

From there you can build your filter buttons for that specific query. Just remove the featured term from the array or skip the output for it in your foreach loop to not have it shown.


Edit:

Below some code for testing, or to be more exact, proof of concept for the method. It will return the term names on the post type post archive aka »Page for Posts« and single views of posts of the post type post - otherwise, on other pages, it returns empty. You can put this into your functions.php - you need PHP 5.3++, because of the anonymous function.

add_action( 'shutdown', function () {
    global $wp_query;
    echo '<pre>';
    foreach (
        array_unique(
            wp_list_pluck(
                wp_get_object_terms(
                    wp_list_pluck(
                        $wp_query->posts,
                        'ID'
                    ),
                    'category'
                ),
                'name'
            )
        ) as $term_name
    ) {
        print_r( $term_name . '<br>' );
    }
    echo '</pre>';
});
2
  • Thanks for the comprehensive reply. My PHP is a little rusty but foreach ( $loop_term_names_unique as $term ) { // ECHO SOMETHING WITH .$TERM. } Returns an error (the dreaded blank page)
    – J-C
    Aug 23, 2015 at 11:29
  • The code I've posted works - I'm 99.99% certain. I'm guessing you have an other - non related - PHP syntax problem. You should enable debugging to get a hold of what the problem is. I'm adding some test-code for a proof of concept to the answer. @J-C Aug 23, 2015 at 12:55
1

@ialocin many many thanks. I have got it to work. Here is my full code based on yours:

<?php
$args = array(
    'post_type'          => 'portfolio',
    'portfolio-category' => 'featured',
    'posts_per_page'     => -1 
);
$loop = new WP_Query( $args ); 
$loop_posts     = $loop->posts;
$loop_posts_ids = wp_list_pluck( $loop_posts, 'ID' );
$loop_term_objects          = wp_get_object_terms( $loop_posts_ids, 'portfolio-category' );
$loop_term_names_not_unique = wp_list_pluck( $loop_term_objects, 'name' );
$loop_term_names_unique     = array_unique( $loop_term_names_not_unique );

echo '<li class="filtering"><a href="#" title="" data-filter="*" class="button-primary">All</a></li>';

// start loop
            foreach ( $loop_term_names_unique as $term ) {
                $termfilter = strtolower($term);
                $termfilter = str_replace(' ', '-', $termfilter);
                echo '<li class="filtering"><a href="#" title="" data-filter=".'.$termfilter.'">'.$term.'</a></li>';
            }
// end loop  


?>

All I need to figure out now is removing "featured" from the array so that portfolio-category itself doesn't appear as a filterable item.

Huge thanks.

2
  • My pleasure! Put if ( $term == 'featured' ) { continue; } after the foreach line to skip in case of that term. Aug 23, 2015 at 14:00
  • You the man! That did the trick, although it is case sensitive so have changed to Featured (as that's how it is spelt in my taxonomy. Brilliant stuff! Many thanks.
    – J-C
    Aug 23, 2015 at 14:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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