Verifică dacă un post se află în orice subcategorie a unei categorii părinte

21 iul. 2014, 22:48:13
Vizualizări: 16.6K
Voturi: 11

Într-un site pe care îl dezvolt, am următoarea structură de categorii:

* filme (părinte)
    * thriller (copil)
    * comedie (copil)
    * dramă (copil)

Postul curent se află în categoria comedie. Funcția has_term cu următorii parametri returnează true:

has_term( 'comedie', 'category' )

Dar, aceeași funcție cu următorii parametri returnează false:

has_term( 'filme', 'category' )

Întrebarea mea este: există o funcție de bază pentru a verifica dacă postul curent se află în orice subcategorie a unei categorii părinte specifice? Dacă nu, cum pot face această verificare?

Mulțumesc anticipat

0
Toate răspunsurile la întrebare 3
1
19

Adăugați următoarele în functions.php al temei dumneavoastră:

/**
 * Testează dacă oricare dintre categoriile alocate unui post sunt descendente ale categoriilor țintă
 *
 * @param int|array $cats Categoriile țintă. ID-ul ca întreg sau un array de ID-uri întregi
 * @param int|object $_post Postul. Omiteți pentru a testa postul curent din Loop sau interogarea principală
 * @return bool True dacă cel puțin 1 dintre categoriile postului este descendentă a oricăreia dintre categoriile țintă
 * @see get_term_by() Puteți obține o categorie după nume sau slug, apoi trimiteți ID-ul către această funcție
 * @uses get_term_children() Trimite $cats
 * @uses in_category() Trimite $_post (poate fi gol)
 * @version 2.7
 * @link http://codex.wordpress.org/Function_Reference/in_category#Testing_if_a_post_is_in_a_descendant_category
 */
if ( ! function_exists( 'post_is_in_descendant_category' ) ) {
    function post_is_in_descendant_category( $cats, $_post = null ) {
        foreach ( (array) $cats as $cat ) {
            // get_term_children() acceptă doar ID-uri întregi
            $descendants = get_term_children( (int) $cat, 'category' );
            if ( $descendants && in_category( $descendants, $_post ) )
                return true;
        }
        return false;
    }
}

Utilizați funcția pentru a verifica ID-ul categoriei părinte, nu numele sau slug-ul. De exemplu, dacă ID-ul categoriei 'movies' este 50:

if ( post_is_in_descendant_category( 50 ) ) {
    // fă ceva
}

Dacă nu cunoașteți ID-ul categoriei 'movies', puteți obține ID-ul folosind get_term_by() și să-l trimiteți către post_is_in_descendant_category():

$category_to_check = get_term_by( 'name', 'movies', 'category' );

if ( post_is_in_descendant_category( $category_to_check->term_id ) ) {
    // fă ceva
}
21 iul. 2014 23:44:10
Comentarii

Mulțumesc. Aceasta ar trebui să fie o funcție încorporată în WordPress.

David Rhoden David Rhoden
6 sept. 2020 22:07:17
3

Dacă dorești orice adâncime de imbricare, folosește get_posts.

/**
 * Verifică dacă postarea se află într-una din categorii sau orice categorie copil. 
 * 
 * @param  int|string|array $category_ids (ID-ul unei singure categorii) sau (șir de caractere separat prin virgule sau array de ID-uri de categorii).
 * @param  int              $post_id      ID-ul postării de verificat. Implicit este `get_the_ID()`.
 * @return bool true, dacă postarea se află în orice categorie sau categorie copil.
 */
function is_post_in_category( $category_ids, $post_id = null ) {
    $args = array(
        'include'  => $post_id ?? get_the_ID(),
        'category' => $category_ids,
        'fields'   => 'ids',
    );
    return 0 < count( get_posts( $args ) );
}

Poți extinde această funcție în multe moduri. Poate să transmiți un array de ID-uri de postări și să filtrezi unele sau să permiți rafinarea interogării.

22 sept. 2020 11:51:23
Comentarii

răspuns mai bun deoarece verifică la orice adâncime.

JJS JJS
9 oct. 2021 23:55:48

aceasta pare exagerat

DrLightman DrLightman
13 oct. 2022 12:13:21

Deși poate părea exagerat, cred că acest lucru ar putea rezulta în mai puține interogări SQL decât celălalt răspuns

Matt Browne Matt Browne
13 sept. 2024 03:51:19
0

Actualizare pentru utilizarea taxonomiilor personalizate:

/**
 * Testează dacă oricare dintre categoriile alocate unui articol sunt descendente ale categoriilor țintă
 *
 * @param int|array $cats Categoriile țintă. ID-ul ca întreg sau un array de ID-uri întregi
 * @param int|object $_post Articolul. Lăsați necompletat pentru a testa articolul curent din Loop sau interogarea principală
 * @param string $target_cat Numele taxonomiei pentru care se face interogarea. Lăsați necompletat pentru a utiliza taxonomia implicită 'category' utilizată pentru articole
 * @return bool True dacă cel puțin 1 dintre categoriile articolului este un descendent al oricăreia dintre categoriile țintă
 * @see get_term_by() Puteți obține o categorie după nume sau slug, apoi transmiteți ID-ul acestei funcții
 * @uses get_term_children() Transmite $cats
 * @uses in_category() Transmite $_post (poate fi gol)
 * @version 2.7
 * @link https://developer.wordpress.org/reference/functions/in_category/#comment-4999
 */
if(!function_exists('post_is_in_descendant_category')) {
  function post_is_in_descendant_category($cats, $_post = null, $target_cat = 'category') {
    foreach((array) $cats as $cat) {
      // get_term_children() acceptă doar ID-uri întregi
      $descendants = get_term_children((int) $cat, $target_cat);
      if($descendants && has_term($descendants, $target_cat, $_post)) {
        return true;
      }
    }
    return false;
  }
}

Context

in_category utilizează has_category care la rândul său apelează has_term( $category, 'category', $post ) cu 'category' setat hard-codat ca taxonomie.

Folosirea directă a has_term() ne permite să verificăm o taxonomie personalizată precum product_cat (WooCommerce) sau orice altă taxonomie.

Funcția utilizează category ca valoare implicită, astfel încât aceasta poate fi utilizată ca înlocuitor direct.

Utilizare

Apelați funcția astfel:

if(post_is_in_descendant_category($category_to_check->term_id, $post, 'product_cat')) {
  // fă ceva
}
15 nov. 2022 13:01:28