Verificare se un post è in una qualsiasi sottocategoria di una categoria genitore

21 lug 2014, 22:48:13
Visualizzazioni: 16.6K
Voti: 11

In un sito che sto sviluppando, ho la seguente struttura di categorie:

* film (genitore)
    * thriller (figlio)  
    * commedia (figlio)
    * dramma (figlio)

Il post corrente è nella categoria commedia. La funzione has_term con i seguenti parametri restituisce true:

has_term( 'commedia', 'category' )

Ma la stessa funzione con i seguenti parametri restituisce false:

has_term( 'film', 'category' )

La mia domanda è: esiste una funzione di WordPress per verificare se il post corrente è in una qualsiasi sottocategoria di una categoria genitore specifica? Se non esiste, come posso effettuare questo controllo?

Grazie in anticipo

0
Tutte le risposte alla domanda 3
1
19

Aggiungi il seguente codice al file functions.php del tuo tema:

/**
 * Verifica se una delle categorie assegnate a un articolo è discendente delle categorie target
 *
 * @param int|array $cats Le categorie target. Può essere un ID intero o un array di ID
 * @param int|object $_post L'articolo. Ometti per verificare l'articolo corrente nel Loop o nella query principale
 * @return bool True se almeno una delle categorie dell'articolo è discendente di una delle categorie target
 * @see get_term_by() Puoi ottenere una categoria per nome o slug, poi passare l'ID a questa funzione
 * @uses get_term_children() Passa $cats
 * @uses in_category() Passa $_post (può essere vuoto)
 * @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() accetta solo ID interi
            $descendants = get_term_children( (int) $cat, 'category' );
            if ( $descendants && in_category( $descendants, $_post ) )
                return true;
        }
        return false;
    }
}

Utilizza la funzione per verificare l'ID della categoria genitore, non il nome o lo slug. Ad esempio, se l'ID della categoria 'film' è 50:

if ( post_is_in_descendant_category( 50 ) ) {
    // fai qualcosa
}

Se non conosci l'ID della categoria 'film', puoi recuperarlo usando get_term_by() e passarlo a post_is_in_descendant_category():

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

if ( post_is_in_descendant_category( $category_to_check->term_id ) ) {
    // fai qualcosa
}
21 lug 2014 23:44:10
Commenti

Grazie. Questa dovrebbe essere una funzione integrata di WordPress.

David Rhoden David Rhoden
6 set 2020 22:07:17
3

Se vuoi supportare qualsiasi livello di annidamento, usa get_posts.

/**
 * Verifica se il post appartiene a una delle categorie o a una qualsiasi sottocategoria.
 * 
 * @param  int|string|array $category_ids (ID singolo di categoria) oppure (stringa separata da virgole o array di ID di categorie).
 * @param  int              $post_id      ID del post da verificare. Di default usa `get_the_ID()`.
 * @return bool true, se il post appartiene a una qualsiasi categoria o sottocategoria.
 */
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 ) );
}

Puoi espandere questa funzione in molti modi. Ad esempio, passare un array di ID post e filtrare alcuni oppure permettere di affinare la query.

22 set 2020 11:51:23
Commenti

risposta migliore in quanto controlla a qualsiasi profondità.

JJS JJS
9 ott 2021 23:55:48

sembra eccessivo

DrLightman DrLightman
13 ott 2022 12:13:21

Anche se può sembrare eccessivo, penso che questo approccio possa generare meno query SQL rispetto all'altra risposta

Matt Browne Matt Browne
13 set 2024 03:51:19
0

Aggiornamento per l'utilizzo di tassonomie personalizzate:

/**
 * Verifica se una delle categorie assegnate a un post è discendente delle categorie target
 *
 * @param int|array $cats Le categorie target. ID intero o array di ID interi
 * @param int|object $_post Il post. Ometti per verificare il post corrente nel Loop o nella query principale
 * @param string $target_cat Il nome della tassonomia da interrogare. Ometti per usare la tassonomia predefinita 'category' utilizzata per i post
 * @return bool True se almeno 1 delle categorie del post è discendente di una delle categorie target
 * @see get_term_by() Puoi ottenere una categoria per nome o slug, poi passare l'ID a questa funzione
 * @uses get_term_children() Passa $cats
 * @uses in_category() Passa $_post (può essere vuoto)
 * @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() accetta solo ID intero
      $descendants = get_term_children((int) $cat, $target_cat);
      if($descendants && has_term($descendants, $target_cat, $_post)) {
        return true;
      }
    }
    return false;
  }
}

Contesto

in_category utilizza has_category che a sua volta chiama has_term( $category, 'category', $post ) con la tassonomia hard-coded 'category'.

Usando direttamente has_term() possiamo verificare una tassonomia personalizzata come product_cat (WooCommerce) o qualsiasi altra tassonomia.

La funzione usa category come predefinito quindi può essere usata come sostituto diretto.

Utilizzo

Chiama la funzione in questo modo:

if(post_is_in_descendant_category($category_to_check->term_id, $post, 'product_cat')) {
  // fai qualcosa
}
15 nov 2022 13:01:28