phpwordpressarchiveshortcode

Customed shortcode shows same value to the whole post query loop (WordPress Archive page)


I created a shortcode using the code below and placed the shortcode in the post query loop, e.g. archive page. At the result, all the items in the query loop show 'bread' regardless to what category they are, e.g. cake and brownie also show 'bread'.

function display_class_category() {
    $target_categories = array( 'bread', 'cake', 'brownie' );
    if ( has_category( $target_categories ) ) {
        $categories = get_the_category( get_the_ID() );
        foreach ( $categories as $category ) {
            if ( in_array( $category->slug, $target_categories ) ) {
                $category_link = get_category_link( $category->term_id );
                return '<div class="link-cat"> <a href="' . esc_url( $category_link ) . '">' . esc_html( $category->name ) . '</a> </div>';
            }
        }
    }
    return '';
}
add_shortcode( 'class_category', 'display_class_category' );

Solution

  • Update:

    1. I tried the code on a new clean environment with clean wordpresss 6.8.3 installed and the result was exactly the same.
    2. Tried on 3 different themes: twenty twenty-four, twenty twenty-five, and astra, all gave the same result.
    3. Tried using ACF + ACF views (the latter generated shortcode to put anywhere you'd like) and the result was still the same.

    All above displayed only 'bread' instead of actual category ('bread', 'cake', or 'brownie') where each item belonged. So I assumed this should be something internal of wordpress about shortcode displaying in query loop.

    Anyway, I tried another way not using shortcode and this time it works:

    function filter_archive_categories( $terms, $post_id, $taxonomy ) {
        if ( $taxonomy !== 'category' || ( ! is_archive() && ! is_home() && ! is_front_page() && ! is_search() ) ) {
            return $terms;
        }
        $allowed_category_slugs = array( 'bread', 'cake', 'brownie' );
        $filtered_terms = array();
        if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
            foreach ( $terms as $term ) {
                if ( in_array( $term->slug, $allowed_category_slugs, true ) ) {
                    $filtered_terms[] = $term;
                }
            }
        }
        return $filtered_terms;
    }
    add_filter( 'get_the_terms', 'filter_archive_categories', 10, 3 );
    
    

    This time the result displays correctly. Thanks everyone so far. Hope this helps for those who may have the same problem.