get_categories per custom post type con una tassonomia personalizzata allegata

3 mar 2011, 11:32:14
Visualizzazioni: 21.6K
Voti: 8

Fondamentalmente ho un custom post type 'products' che ha due tassonomie collegate... la normale 'category' e una tassonomia personalizzata chiamata 'brands'.

Ho una pagina che è specifica per il 'brand'. In questa pagina vorrei elencare tutte le 'categorie' che hanno un 'prodotto' al loro interno con un termine del 'brand' della pagina in cui mi trovo.

Ad esempio, mettiamo che mi trovo nella pagina "Nike". Voglio che elenchi tutte le categorie che hanno un 'prodotto' al loro interno con il 'brand' "Nike" associato.

Il mio pensiero iniziale è di utilizzare get_categories ma non c'è modo di definire una tassonomia specifica o un 'brand'?

// Ottieni le categorie ordinate per nome, profondità 1 e includi anche le categorie vuote
$categories = get_categories('orderby=name&depth=1&hide_empty=0&child_of='.$cat);

Qualcuno ha già fatto qualcosa di simile o conosce un modo per interrogare direttamente il database per ottenere i risultati richiesti?

Ogni aiuto è molto apprezzato, Grazie

0
Tutte le risposte alla domanda 3
2

Se vuoi elencare tutte le categorie disponibili per un custom post type, questo snippet potrebbe esserti utile.

Basta usare la funzione standard get_categories() e passare gli $args relativi alla tassonomia che hai registrato per il tuo CPT. Quindi, se hai definito la tua tassonomia in questo modo:

register_taxonomy( 'the_taxonomy_named_in_your_CPT' );

Allora potresti mostrare la tassonomia agli utenti front end tramite:

$args = array( 
    'taxonomy'     => 'the_taxonomy_named_in_your_CPT',
    'orderby'      => 'name',
    'show_count'   => 1,
    'pad_counts'   => 1, 
    'hierarchical' => 1,
    'echo'         => 0
);

$allthecats = get_categories( $args );
echo ( '<pre>' );
print_r( $allthecats );
echo ( '</pre>' );

Vedrai un oggetto che ti aiuterà nel tuo percorso.

28 gen 2016 16:06:44
Commenti

Dopo ore e un mal di testa, questa soluzione ha funzionato come necessario. Grazie!! Non c'è una buona documentazione sulla stampa delle categorie dei post type.

Rodrigo Zuluaga Rodrigo Zuluaga
8 lug 2020 01:08:00

Per tutti coloro che si chiedono perché le categorie potrebbero ancora non apparire: get_categories() restituisce solo le categorie che hanno almeno un post assegnato, altrimenti restituirà semplicemente un array vuoto.

mfru mfru
3 mag 2022 13:08:16
8

Ciao @daveaspi:

Quello che vuoi fare è comune ma non gestito bene nel core di WordPress. Probabilmente ci sono modi per farlo senza SQL personalizzato, ma non credo che scalerebbero bene per un gran numero di articoli. Di seguito trovi una funzione che ho scritto chiamata get_cross_referenced_terms() che otterrà ciò che desideri, completa di un esempio su come usarla.

Il seguente codice può essere posizionato nella root del tuo sito WordPress in un file test.php per vederlo funzionare. Puoi poi copiare la funzione get_cross_referenced_terms() nel file functions.php del tuo tema o in un file .php di un plugin su cui stai lavorando:

<?php 

  include('wp-load.php');

  $nike = get_term_by('slug','nike','brand'); // Questo serve solo come esempio

  $terms = get_cross_referenced_terms(array(
    'post_type'        => 'product',
    'related_taxonomy' => 'brand',
    'term_id'          => $nike->term_id,
  ));
  foreach($terms as $term) {
    echo "<p>{$term->name}</p>";
  }

function get_cross_referenced_terms($args) {
  global $wpdb;
  $args = wp_parse_args($args,array(
    'post_type'        => 'post',
    'taxonomy'         => 'category',
    'related_taxonomy' => 'post_tag',
    'term_id'          => 0,
  ));
  extract($args);
  $sql = <<<SQL
SELECT DISTINCT
  {$wpdb->terms}.*,
  COUNT(*) AS post_count
FROM
  {$wpdb->terms}
  INNER JOIN {$wpdb->term_taxonomy} ON {$wpdb->terms}.term_id={$wpdb->term_taxonomy}.term_id
  INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_taxonomy}.term_taxonomy_id={$wpdb->term_relationships}.term_taxonomy_id
  INNER JOIN {$wpdb->posts} ON {$wpdb->term_relationships}.object_id={$wpdb->posts}.ID
  INNER JOIN {$wpdb->term_relationships} related_relationship ON {$wpdb->posts}.ID=related_relationship.object_id
  INNER JOIN {$wpdb->term_taxonomy} related_term_taxonomy ON related_relationship.term_taxonomy_id=related_term_taxonomy.term_taxonomy_id
  INNER JOIN {$wpdb->terms} related_terms ON related_term_taxonomy.term_id=related_terms.term_id
WHERE 1=1
  AND (related_term_taxonomy.taxonomy<>{$wpdb->term_taxonomy}.taxonomy OR related_terms.term_id<>{$wpdb->terms}.term_id)
  AND {$wpdb->posts}.post_type='%s'
  AND {$wpdb->term_taxonomy}.taxonomy='%s'
  AND related_term_taxonomy.taxonomy='%s'
  AND related_terms.term_id=%d
GROUP BY
  {$wpdb->terms}.term_id
SQL;
  $sql = $wpdb->prepare($sql,$post_type,$taxonomy,$related_taxonomy,$term_id);
  $terms = $wpdb->get_results($sql);
  return $terms;
}
3 mar 2011 12:51:28
Commenti

sì, è la query SQL di cui parlavo :)

Bainternet Bainternet
3 mar 2011 12:59:19

Ciao @MikeSchinkel, è esattamente ciò di cui avevo bisogno! Funziona alla perfezione. Grazie mille davvero!

daveaspinall daveaspinall
3 mar 2011 13:22:59

@Bainternet grazie mille anche per il tuo contributo :-)

daveaspinall daveaspinall
3 mar 2011 13:23:31

Una piccola domanda, c'è un modo per limitare la 'profondità' a 1? In modo da ottenere solo le categorie di primo livello? :-) Grazie ragazzi

daveaspinall daveaspinall
3 mar 2011 13:29:36

@daveaspi: Aggiungi AND {$wpdb->term_taxonomy}.parent=0 alla clausola where.

MikeSchinkel MikeSchinkel
3 mar 2011 13:38:20

@MikeSchinkel, @Bainternet ciao ragazzi, c'è un modo per aggiungere una variabile negli $args per definire sia la categoria che il brand? es. 'post_type' => 'post', 'taxonomy' => 'category', 'related_taxonomy' => 'post_tag', 'term_id' => 0, 'category_id' => $cat

daveaspinall daveaspinall
7 mar 2011 16:25:01

@davesapi - Sembra che questo dovrebbe essere una nuova domanda.

MikeSchinkel MikeSchinkel
8 mar 2011 01:52:13

@MikeSchinkel come dovremmo modificare la query SQL personalizzata in modo che restituisca i link alle categorie invece che solo i nomi? Grazie!

Ioannis Baltzakis Ioannis Baltzakis
28 set 2011 01:56:23
Mostra i restanti 3 commenti
4

Puoi scrivere una query SQL personalizzata oppure puoi interrogare il tuo post type per quel "brand" specifico, raccogliere le categorie e poi visualizzarle, qualcosa come:

//ottieni tutti i post di quel tipo per il brand specifico
$my_query = new WP_Query();
$my_query->query(array(
    'post_type' => 'products',
    'posts_per_page' => -1,
    'tax_query' => array(
        array(
            'taxonomy' => 'brand',
            'field' => 'slug',
            'terms' => $wp_query->query_vars['brand']
        )
    )
    ));
$my_cats = array(); 
if ($my_query->have_posts()){
//cicla su tutti i post e raccogli le categorie in un array
    while ($my_query->have_posts()){
        $my_query->the_post();
        foreach((get_the_category($post->ID)) as $category) {
            if (!in_array($category->cat_ID ,$my_cats)){
                $my_cats[] = $category->cat_ID;
            }
        } 
    }
}

e qui avrai la lista di tutti gli ID delle categorie nell'array $my_cats. Da cui puoi ottenere tutte le informazioni di cui hai bisogno

3 mar 2011 12:58:21
Commenti

Sì, molto più pulito e ottimo per un sito piccolo, ma per un gran numero di articoli potrebbe diventare davvero molto lento.

MikeSchinkel MikeSchinkel
3 mar 2011 13:09:04

@MikeSchinkel - sì, richiederebbe un po' di tempo su un sito dove ogni marca ha un sacco di prodotti, ma immagino che il mio "kong SQL fu" non sia forte come il tuo, maestro!

Bainternet Bainternet
3 mar 2011 13:11:41

Ah! Non è che l'ho imparato da un giorno all'altro! Ci sono voluti più di 20 anni di lavoro su SQL per arrivare qui. :)

MikeSchinkel MikeSchinkel
3 mar 2011 13:13:27

20+ dici, quindi mi mancano solo altri 15 per arrivarci.

Bainternet Bainternet
3 mar 2011 13:19:31