Jak sprawdzić, czy wpis należy do określonej taksonomii? (has_term, is_tax)
PL

Jak sprawdzić, czy wpis należy do określonej taksonomii? (has_term, is_tax)

5.00 /5 - (27 głosów )
Spis treści

Częstym zadaniem developera jest wyświetlenie elementu (np. bannera reklamowego) tylko jeśli wpis należy do konkretnej kategorii lub taksonomii (np. ‘Gatunek filmowy: Komedia’).

W WordPressie mamy do tego dwie główne funkcje, które często są mylone: is_tax() oraz has_term(). Różnica między nimi jest kluczowa dla działania twojego motywu.


1. is_tax() vs has_term() – Na czym polega różnica?

is_tax() – Kontekst Strony (Archive)

Używamy tego, aby sprawdzić, na jakiej stronie znajduje się użytkownik.

  • Czy użytkownik przegląda archiwum kategorii “Horrory”?
if ( is_tax( 'gatunek', 'horror' ) ) {
    echo 'Jesteś na liście horrorów!';
}

Funkcja ta zwróci false, jeśli jesteś na stronie pojedynczego wpisu (Single Post), nawet jeśli ten wpis jest horrorem!

has_term() – Kontekst Wpisu (Single)

Używamy tego, aby sprawdzić, co jest przypisane do danego wpisu.

  • Czy ten konkretny film jest “Horrorem”?
if ( has_term( 'horror', 'gatunek' ) ) {
    echo 'Ten wpis to horror.';
}

Tej funkcji używamy najczęściej wewnątrz pętli (The Loop) lub w pliku single.php.


2. Problem Hierarchii (Dzieci i Rodzice)

Największym wyzwaniem jest to, że has_term() sprawdza tylko dokładnie ten term, który podasz.

Załóżmy strukturę:

  • Filmy (Taksonomia: movie_genre)
    • Komedie (ID: 10)
      • Romantyczne (ID: 11)
      • Czarne komedie (ID: 12)

Jeśli masz wpis przypisany TYLKO do “Romantyczne”, to sprawdzenie:

has_term( 'komedie', 'movie_genre' ) 

zwróci FALSE. Dlaczego? Bo wpis technicznie nie ma zaznaczonego checkboxa “Komedie”, tylko “Romantyczne”.

Rozwiązanie: Funkcja sprawdzająca potomków

Aby sprawdzić, czy wpis należy do kategorii “Komedie” LUB dowolnej jej podkategorii, musimy napisać własną funkcję pomocniczą.

/**
 * Sprawdza czy wpis należy do terminu lub jego dzieci.
 *
 * @param int|string|array $term_id_or_slug ID lub Slug szukanego rodzica.
 * @param string $taxonomy Nazwa taksonomii.
 * @param int|null $post_id ID postu (opcjonalnie).
 * @return bool
 */
function wppoland_in_term_tree( $term_id_or_slug, $taxonomy, $post_id = null ) {
    $post_id = $post_id ? $post_id : get_the_ID();
    $term    = get_term_by( is_numeric($term_id_or_slug) ? 'id' : 'slug', $term_id_or_slug, $taxonomy );

    if ( ! $term ) {
        return false;
    }

    // 1. Sprawdź bezpośrednie przypisanie (najszybsze)
    if ( has_term( $term->term_id, $taxonomy, $post_id ) ) {
        return true;
    }

    // 2. Pobierz wszystkich potomków danego terma
    $children = get_term_children( $term->term_id, $taxonomy );
    
    if ( is_wp_error( $children ) || empty( $children ) ) {
        return false;
    }

    // 3. Sprawdź czy wpis ma któregokolwiek z potomków
    return has_term( $children, $taxonomy, $post_id );
}

Użycie:

// W pliku single.php
if ( wppoland_in_term_tree( 'komedie', 'movie_genre' ) ) {
    get_template_part( 'partials/banner-comedy' );
}

Teraz zadziała to zarówno dla “Komedii”, jak i “Komedii Romantycznych”.


3. Optymalizacja Wydajności

Funkcja get_term_children() wykonuje zapytanie do bazy danych. Jeśli używasz tego w pętli wyświetlającej 50 wpisów, robisz 50 dodatkowych zapytań SQL.

Jak to zoptymalizować? Jeśli twoja struktura kategorii zmienia się rzadko, możesz cache’ować wyniki ID dzieci w Transients API, ale w 2026 roku serwery są na tyle szybkie, że dla prostych struktur nie jest to konieczne, o ile nie masz tysięcy podkategorii.

Ważniejszą optymalizacją jest przekazywanie ID zamiast Sluga. WordPress i tak musi zamienić Slug na ID, więc podając od razu ID (np. 10), oszczędzasz jedno zapytanie.

// Szybciej (ID)
has_term( 10, 'movie_genre' );

// Wolniej (Slug -> musi poszukać ID)
has_term( 'komedie', 'movie_genre' );

Podsumowanie

  1. Używaj is_tax() tylko do sprawdzania, czy jesteś na stronie archiwum.
  2. Używaj has_term() do logicznego sprawdzania pojedynczych wpisów.
  3. Pamiętaj, że has_term nie dziedziczy – jeśli potrzebujesz logiki “kategoria i jej dzieci”, użyj customowej funkcji wppoland_in_term_tree.

To podstawa budowania dynamicznych motywów, które reagują na kontekst treści.