WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am writing a plugin which creates a custom post type and two associated custom taxonomies. The custom post type list/archive page should be filterable by terms in one or both taxonomies i.e not just a filter by one taxonomy term. The filters should be displayed as two separate tag clouds.

Does anyone have experience of implementing this functionality and can recommend any suitable plugins?

share|improve this question

You don't really need a pre-built plugin for this or you may create your own slim plugin. This is how I'd tackle the problem:

  1. You need the app to remember an already selected filter and pass all filter values every time you change your selection.
  2. Therefore your safest bet is to build a form with as many <select> boxes as the taxonomies you want to filter.
  3. You will populate those boxes with all your terms and then hide the form. The <option> values will be equal to the term's slugs.
  4. You will then generate a standard term cloud using wp_tag_cloud and hook it to the hidden <select> filters using JavaScript.
  5. Every time you click on the link in the cloud, you will change the appropriate <select> box filter and submit the form.
  6. When the form is submitted, you will fetch the filter settings from $_GET and query and filter the posts using new WP_Query.
  7. You will display the queried posts. Easy!

Following is an example implementation. You can list as many taxonomies you want. Make sure you have jQuery loaded before trying to use it:

    // List all taxonomies you want to bind
    $taxonomies = array( 'genre', 'writer' );

    // Creates the supplementary $genres_list, $writers_list, ... taxonomies holding all their terms
    foreach( $taxonomies as $taxonomy )
        ${$taxonomy . 's_list'} = get_terms( $taxonomy, array() );

<!-- Create the hidden <select>s that will filter our data -->
<form method="GET" id="filter-manager">

    <?php foreach( $taxonomies as $taxonomy ): ?>
        <select id="<?= $taxonomy ?>_filter" name="<?= $taxonomy ?>_filter">
            <option value="">(none)</option>
        <?php foreach( ${$taxonomy . 's_list'} as $taxonomy_object ): ?>
            <?php $selected = ( isset( $_GET[$taxonomy . '_filter'] ) && $_GET[$taxonomy . '_filter'] === $taxonomy_object->slug ) ? ' selected="selected"' : ''; ?>
            <option value="<?= $taxonomy_object->slug ?>"<?= $selected ?>><?= $taxonomy_object->name ?></option>
        <?php endforeach; ?>
    <?php endforeach; ?>


    // Display the tag clouds for all taxonomies
    foreach( $taxonomies as $taxonomy ) {
        $cloud = wp_tag_cloud( array( 'taxonomy' => $taxonomy, 'echo' => false ) );

        // Add the taxonomy data to each link
        $cloud = preg_replace( '~>([^<]+)<~U', ' data-taxonomy="' . $taxonomy . '">$1<', $cloud );

        echo $cloud;


    (function($) {
        // Hide the filter manager
        $form = $('#filter-manager');
        $form.find('select').on('change', function() {

        // Pass the cloud clicks to the appropriate filter manager
        $('a[class*="tag-link"]').on('click', function(e) {
            var taxonomy = $(this).data('taxonomy');
            var $link = $(this);
            $form.find('select#' + taxonomy + '_filter option').filter( function() {
                return ( $(this).text() == $link.text() );
            }).prop('selected', true);
            $form.find('select#' + taxonomy + '_filter option').trigger('change');



    // Construct WP_Query args, change as you see fit
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => -1

    // Creates the WP_Query that filters only the posts we want
    foreach( $taxonomies as $taxonomy )
        if ( isset( $_GET[$taxonomy . '_filter'] ) and (bool) $_GET[$taxonomy . '_filter'] === true )
            $args = array_merge( $args, array( $taxonomy => $_GET[$taxonomy . '_filter'] ) );

    $filtered_posts = new WP_Query( $args );

    // List filtered posts
    while( $filtered_posts->have_posts() ): $filtered_posts->the_post();
    <div class="post">
            echo '<h2>' . get_the_title() . '</h2>';
share|improve this answer
Oh, right. Thanks! – Dero Oct 19 '13 at 15:28

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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