skip to Main Content

I have a custom post type for podcasts but I can’t get the category filter to work. I created custom Taxonomies called Podcast Categories. When I click on one of the categories they all still show. Each podcast added has a different category. I can not figure out how to make it work so any help would be so appreciated!!

This is my functions.php file –

//Podcasts
function podcast_custom_post_type () {
    $labels = array (
        'name' => 'Podcasts',
        'singular_name' => 'Podcast',
        'add_new' => 'Add New Podcast',
        'all_items' => 'All Podcasts',
        'add_new_item' => 'Add A Podcast',
        'edit_item' => 'Edit Podcast',
        'new_item' => 'New Podcast',
        'view_item' => 'View Podcast',
        'parent_item_colon' => 'Parent Item',
        'rewrite' => array( 'slug' => 'podcast' )
    );
    $args = array(
        'labels' => $labels,
        'public' => true,
        'show_in_rest' => true,
        'has_archive' => true,
        'publicly_queryable' => true,
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'hierarchical' => false,
        'menu_icon' => 'dashicons-admin-users',
        'supports' => array(
            'title',
            'editor',
            'excerpt',
            'thumbnail',
            'custom-fields',
            'revisions',
            'page-attributes'
        ),
    //'taxonomies' => array('category', 'post_tag'),
    'menu_position' => 10,
    'exclude_from_search' => false
    );
register_post_type('podcast', $args);
}
add_action('init', 'podcast_custom_post_type');

function podcast_custom_taxonomies() {

    $labels = array(
        'name' => 'Podcast Categories',
        'singular_name' => 'Podcast Category',
        'search_items' => 'Search Podcast Categories',
        'all_items' => 'All Podcast Category',
        'parent_item' => 'Parent Podcast Category',
        'parent_item_colon' => 'Parent Podcast Category:',
        'edit_item' => 'Edit Podcast Category',
        'update_item' => 'Update Podcast Category',
        'add_new_item' => 'Add New Podcast Category',
        'new_item_name' => 'New Podcast Category',
        'menu_name' => 'Podcast Categories'
    );

    $args = array(
        'hierarchical' => true,
        'labels' => $labels,
        'show_ui' => true,
        'show_admin_column' => true,
        'query_var' => true,
        'rewrite' => array( 'slug' => 'podcast_category' )
    );

    register_taxonomy('podcast_category', array('podcast'), $args);
}
add_action( 'init' , 'podcast_custom_taxonomies' );



add_action('pre_get_posts', 'altering_podcast_archive_query', 99);
function altering_podcast_archive_query($query)
{
    if (
        is_post_type_archive('podcast') 
        && 
        get_query_var('orderby')
       ) 
    {
        $tax_query = array(
            array(
                'taxonomy' => 'podcast_category',
                'field' => 'slug',
                'terms' => sanitize_text_field(get_query_var('orderby')),
            )
        );
        $query->set('tax_query', $tax_query);
    };
};

And this is my theme page I created –

<?php
    /*Template Name: News & Media */
    get_header();
?>

<div class="singlewidth">
<div id="primary">

<form method='GET'>
  <select name='orderby' id='orderby'>
    <?php
    $terms = get_terms([
      'taxonomy' => 'podcast_category',
      'hide_empty' => 'false'
    ]);
    foreach ($terms as $term) :
    ?>

      <option value='<?php echo $term->slug; ?>' <?php echo selected(sanitize_text_field($_GET['orderby']), $term->slug); ?>><?php echo $term->name; ?></option>

    <?php endforeach; ?>
  </select>
  <button type='submit'>Filter</button>
</form>

<div class="podcasts">



<ul>


 <?php
    query_posts(array(
       'post_type' => 'podcast'
    )); ?>
    <?php
    while (have_posts()) : the_post(); ?>
   



<li>
 <?php if ( has_post_thumbnail() ) { /* loades the post's featured thumbnail, requires WordPress 3.0+ */ echo '<div class="featured-thumb clearfix">'; the_post_thumbnail(); echo '</div>'; } ?>


<div class="podcasttext">
<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'azurebasic' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>


<?php if( get_field('podcast_text') ): ?>
    <?php the_field('podcast_text'); ?>
<?php endif; ?>
</div>

<div class="podcastplayer">
<?php if( get_field('add_podcast') ): ?>
    <?php the_field('add_podcast'); ?>
<?php endif; ?>
</div>

</li>

<?php 
endwhile; 
?>

</ul>

</div>
</div>
</div>

<?php  get_footer();  ?>

this is the webpage it’s on –
https://baptist.tfm-dev.com/resources/news-resources

2

Answers


  1.  <?php
    
      // Query Arguments
      $args = array(
        //
        // your custom post type
        //
        'post_type' => 'podcast',
        //
        // your taxonomy info to filter
        //
        'tax_query' => array(
          array(
            //
            // your custom taxonomy
            //
            'taxonomy' => 'podcast_category',
            //
            // eg. we filter by slug
            //
            'field'    => 'slug',
            //
            // replace 'the-slug' with your target slugs to filter
            //
            'terms'    => array('the-slug'),  
          ),
        ),
      );
    
      query_posts($args);
    ?>
    

    That’s all, if I understand what you are asking.

    I am sure that there are hundreds of such posts to solve this.

    Login or Signup to reply.
  2. Some suggestions:

    • Connect taxonomy podcast_category to custom post type podcast
    • Change the select form field name for orderby (if possible)
    • Add (the newly named) orderby parameter to WP_Query for use as a filter
    • Avoid query_posts()

    Explanations and updated code samples are below.

    Connect taxonomy podcast_category to custom post type podcast

    WP Docs for register_post_type say that:

    any taxonomy connections should be registered via the $taxonomies argument

    When calling register_taxonomy() set the $object_type argument to null (see wordpress.stackexchange.com answer here), and use the 'taxonomies' property in the call to register_post_type() to connect the podcast_category taxonomy to the podcast custom post type. While there are other ways to accomplish the same thing, this approach is easy to understand.

    Code in the podcast_custom_taxonomies() function would need to change from this:

    
        register_taxonomy('podcast_category', array('podcast'), $args);
    }
    

    …to this…

    
        register_taxonomy('podcast_category', null, $args);
    }
    

    Code in the podcast_custom_post_type() function would need to change from this:

                'revisions',
                'page-attributes'
            ),
        //'taxonomies' => array('category', 'post_tag'),
        'menu_position' => 10,
        'exclude_from_search' => false
        );
    

    …to this…

                'revisions',
                'page-attributes'
            ),
        'taxonomies' => array('podcast_category', 'category', 'post_tag'),
        'menu_position' => 10,
        'exclude_from_search' => false
        );
    

    Change the select form field name for orderby (if possible)

    Using orderby as an argument in get_query_var() can cause problems. orderby is an existing WP_Query public query variable used to sort the list of posts. Your code seems to use orderby not as a sort key, but as a filter. When your code calls get_query_var('orderby') it is retrieving the existing WP_Query parameter value for orderby, not the value for orderby submitted by the HTML form.

    The HTML form select options are podcast categories used as a filter. To reduce confusion, I suggest changing the HTML form select tag name and ID to podcast_category_filter.


    Add (the newly named) orderby parameter to WP_Query for use as a filter

    Assuming orderby has been changed to podcast_category_filter, the get_query_var() function can be called to get the value submitted by the HTML form only after the field podcast_category_filter has been added to the list of WP_Query public query variables. Once added to the list, WordPress will know that when it sees podcast_category_filter in the URL (e.g. https://example.com/podcast?podcast_category_filter=sports), podcast_category_filter and its value should be added to WP_Query. The value for podcast_category_filter can then be retrieved using get_query_var('podcast_category_filter').

    To add podcast_category_filter to the list of WP_Query public query variables, use the query_vars filter hook in your theme or plugin:

    function myplugin_query_vars( $qvars ) {
        $qvars[] = 'podcast_category_filter';
        return $qvars;
    }
    add_filter( 'query_vars', 'myplugin_query_vars' );
    

    Avoid query_posts()

    Please note this warning from the WordPress Docs on the use of the query_posts() function:

    Note: This function will completely override the main query and isn’t intended for use by plugins or themes. Its overly-simplistic approach to modifying the main query can be problematic and should be avoided wherever possible. […] This must not be used within the WordPress Loop.

    WordPress suggests using the pre_get_posts action within WP_Query.

    To avoid query_posts() changes to your code could look like this:

    Delete this from your theme page:

    query_posts(array(
       'post_type' => 'podcast'
    )); ?>
    

    Update your pre_get_posts action hook to this:

    add_action('pre_get_posts', 'altering_podcast_archive_query', 99);
    function altering_podcast_archive_query($query)
    {
        // You may wish to put this line within an if-statement if there are
        // conditions under which the post_type should not be filtered.
        $query->set('post_type', 'podcast');
    
        if (
            is_post_type_archive('podcast') 
            && 
            get_query_var( 'podcast_category_filter' )
           ) 
        {
            $tax_query = array(
                array(
                    'taxonomy' => 'podcast_category',
                    'field' => 'slug',
                    'terms' => sanitize_text_field( get_query_var( 'podcast_category_filter' ) ),
                )
            );
            $query->set('tax_query', $tax_query);
        };
    };
    

    Alternative for creating form select HTML

    If you don’t need special class names or custom attributes in the select or option tags consider using wp_dropdown_categories():

    <?php
    $selected_category_slug = get_query_var( 'podcast_category_filter' );
    
    $args = array(
        'taxonomy'    => 'podcast_category',
        'selected'    => sanitize_text_field( $selected_category_slug ),
        'name'        => 'podcast_category_filter',
        'hide_empty'  => false,
        'value_field' => 'slug',
        'echo'        => false // Set to true to echo the HTML directly rather than save the HTML to a variable.
    );
    $select_category_html = wp_dropdown_categories( $args );
    ?>
    
    <form method='GET'>
        <?php echo $select_category_html ?>
        <button type='submit'>Filter</button>
    </form>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search