0

I have a custom post type product with custom taxonomy web_cat and I have set a custom field expiration_date to each of the posts of this type. I'm using that field in a pre_get_posts to hide posts that expired like this:

function rt_webinar_pre_query_two($query){
   if ( ! is_admin() && $query->is_main_query() && $query->query_vars['post_type'] == 'product' ) {
    $today = date('Ymd'); // Today's date
        $query->set( 'meta_key', 'event_date' );
        $query->set( 'orderby', 'meta_value' );
        $query->set( 'order', 'ASC');
        $query->set( 'meta_query', array(
            array(
                'key'     => 'expiration_date',
                'compare' => '>=',
                'value'   => date('Ymd'),
                'type'    => 'numeric',
            )
        ) );
   }
}
add_action( 'pre_get_posts', 'rt_webinar_pre_query_two' );

This filters my posts on my archive page correctly.

I want a list of all terms as links to the tax archives.

I created that link list with this function:

function list_webinar_categories() {
    $webcats = get_terms( array(
        'taxonomy' => 'web_cat',
        'hide_empty' => true,
        'parent' => 0
    ) );
    if ( !empty($webcats) ) {
        $catlist = '<ul>';
        foreach ($webcats as $webcat) {
            $catlist .= '<li><a href="'.esc_url( get_term_link( $webcat ) ).'">'.$webcat->name.'</a></li>';
        }
        $catlist .= '</ul>';
        return $catlist;
    }
}
add_shortcode ('webinar-categories', 'list_webinar_categories');

The problem is that this function is not being filtered by my pre_get_posts. So it will create a list of categories but will not hide empty categories based on my expiration date. This results in a direct 404 page if that term has all expired posts or a tax page that has links that go to 404 pages. Is there any way to apply the expiration_date exclusion to get_terms? (something along the lines of if_empty)

I thought about adding

    'meta_query' => array(
        array(
           'key'       => 'expiration_date',
           'value'     => date('Ymd'),
           'compare'   => '>='
        )),

But that would only check if the terms have the expiration date.

I also tried adding a 2nd pre_get_posts:

function rt_webinar_pre_query_three($query){
   if ( ! is_admin() && $query->is_main_query() && $query->is_tax() && $query->query_vars['taxonomy'] == 'web_cat') {
    $today = date('Ymd'); // Today's date
        $query->set( 'meta_key', 'event_date' );
        $query->set( 'orderby', 'meta_value' );
        $query->set( 'order', 'ASC');
        $query->set( 'meta_query', array(
            array(
                'key'     => 'expiration_date',
                'compare' => '>=',
                'value'   => date('Ymd'),
                'type'    => 'numeric',
            )
        ) );
   }
}
add_action( 'pre_get_posts', 'rt_webinar_pre_query_three' );

However no changes to the terms archives.

1 Answer 1

0

If you want to output a list of terms that are assigned to the posts in the current query, you could use something like this in your template:

global $wp_query;
$terms = [];
foreach ( $wp_query->get_posts() as $item ) {
    $item_terms = wp_get_post_terms( $item->ID, 'web_cat' );
    $terms[]    = $item_terms;
}
$unique = array_unique( array_merge(...$terms), SORT_REGULAR );
foreach ( $unique as $t ) {
    var_dump( $t->term_id);
}
1
  • No, this is going to be in the sidebar and fully separate from posts
    – rudtek
    Nov 23, 2022 at 16:37

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.