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 >
<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 >
<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 >'; the_post_thumbnail(); echo '</div>'; } ?>
<div >
<h2 ><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 >
<?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
CodePudding user response:
<?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.
CodePudding user response:
Some suggestions:
- Connect taxonomy
podcast_category
to custom post typepodcast
- 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>