Filtrare get_categories() per termine di tassonomia in WordPress

1 dic 2010, 09:36:30
Visualizzazioni: 18.1K
Voti: 2

Voglio mostrare una categoria solo se un post (personalizzato) è in quella categoria E la regione = $name per quel post.

Esempio: ho un post personalizzato (tipo "business") chiamato "Mamma Mia" nella sottocategoria: "pizzerie" (e nella categoria genitore "cibo"), e nella regione "Rotterdam" (tassonomia personalizzata: "region", termine di tassonomia: "rotterdam").

=> visualizzare la categoria "pizzerie" (e la categoria genitore "cibo")

Il problema è che non ho idea di come realizzarlo. Gradirei qualsiasi aiuto per risolvere questo puzzle.

<?php 

// $filter = array('region'=>$name); 

$categories = get_categories(); 
foreach ($categories as $cat) 
{ 
    if($cat->parent < 1) 
    { 
    $cat_name = $cat->cat_name; 
    $catid = get_cat_ID( $cat_name ); 
    echo $cat_name. '<br/>'; 

    $args=array( 
      'orderby' => 'name', 
      'order' => 'ASC', 
      'child_of' => $catid 
      ); 
    $categories=get_categories($args); 
      foreach($categories as $category) {  
        echo '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "Visualizza tutti i post in %s" ), $category->name ) . '" ' . '>' . $category->name.'</a><br/>'; 
        }  

    } 
} 

// print_r($categories);  


?>
3
Commenti

Quindi vuoi elencare i termini della categoria a cui sono assegnati business che sono anche assegnati a uno specifico regione?

Rarst Rarst
6 dic 2010 15:04:01

@Henk, puoi spiegare un po' meglio dove vorresti farlo? Su una pagina di singolo articolo? Su un archivio tassonomico? Su un archivio di categoria?

TheDeadMedic TheDeadMedic
6 dic 2010 15:30:44

Penso che possiamo generalizzare questo a una ricerca a faccette. C'è un plugin con questo nome, ma sembra che non si possano combinare multiple tassonomie. Poiché questo è molto interessante, ho aggiunto la ricompensa.

Jan Fabry Jan Fabry
6 dic 2010 16:47:49
Tutte le risposte alla domanda 8
1

l'intenzione è mostrare un elenco di categorie, ma solo quelle categorie che hanno post in cui la tassonomia personalizzata "region" è impostata su Rotterdam

Questo viene fatto nel plugin Query Multiple Taxonomies:

http://plugins.trac.wordpress.org/browser/query-multiple-taxonomies/trunk/core.php?rev=308185#L10

8 dic 2010 08:20:26
Commenti

E più specificamente, nel suo widget di navigazione a discesa. Ottimo! Ora questo dovrebbe solo essere esteso per mostrare anche le categorie genitore: se un post è associato a Pizzerie lo vedo anche quando navigo in Cibo, ma Cibo non viene mostrato nel widget se il post non è esplicitamente associato ad esso.

Jan Fabry Jan Fabry
8 dic 2010 09:27:25
3

Idea generale - eseguire una query per un insieme specifico di post, raccogliere tutte le loro categorie, filtrarle e lasciare che la funzione le organizzi.

Codice generico:

$posts = get_posts(array(
    'tag' => 'linux'
));

$categories = array();

foreach( $posts as $post ) {

    $cats = get_the_category($post->ID);

    foreach($cats as $c)
        $categories[] = $c->term_id;
}

$categories = array_unique($categories);
sort($categories);
$categories = implode(',', $categories);

$result = get_categories(array(
    'include' => $categories
));

I problemi sono - per quanto ricordo, query decenti per tassonomie multiple arriveranno solo in WP 3.1 e questo potrebbe diventare molto intensivo, quindi richiederà caching (probabilmente per ogni region).

6 dic 2010 15:22:21
Commenti

Come influisce il parametro include sui risultati gerarchici? Se ci sono alcuni post in Pizzerie, ma nessuno direttamente collegato al suo genitore Cibo, verrà visualizzato Cibo? Oppure i post vengono automaticamente collegati anche alle categorie genitore?

Jan Fabry Jan Fabry
6 dic 2010 16:24:36

@Jan Fabry ho testato, se viene passato solo l'id della categoria figlia a get_categories() allora la categoria genitore non viene recuperata. :( Quindi un altro passaggio sarebbe quello di scorrere le categorie e ottenere i genitori. Un disastro ancora più grande.

Rarst Rarst
6 dic 2010 16:34:06

Penso che dovremmo guardare nella direzione di una query SQL personalizzata, unendo più tabelle di tassonomia. E caching, certamente.

Jan Fabry Jan Fabry
6 dic 2010 16:41:17
0

Sulla versione di WordPress che sto utilizzando, ovvero la versione 3.1.2. Se aggiungi 'taxonomy' => 'taxonomy_term' all'array degli argomenti, dovrebbe funzionare. Quindi ecco una modifica al tuo codice originale per includere la tassonomia nell'array. Non so però il nome della tassonomia che stai cercando di utilizzare o meno:

<?php 

// $filter = array('region'=>$name); 

$categories = get_categories(); 
foreach ($categories as $cat) 
{ 
    if($cat->parent < 1) 
    { 
    $cat_name = $cat->cat_name; 
    $catid = get_cat_ID( $cat_name ); 
    echo $cat_name. '<br/>'; 

    $args=array( 
      'taxonomy' => 'taxonomy_term', 
      'orderby' => 'name', 
      'order' => 'ASC', 
      'child_of' => $catid 
      ); 
    $categories=get_categories($args); 
      foreach($categories as $category) {  
        echo '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "Visualizza tutti i post in %s" ), $category->name ) . '" ' . '>' . $category->name.'</a><br/>'; 
        }  

    } 
} 

// print_r($categories);  
?>
31 mag 2011 17:50:16
0

Ho adattato la risposta di @rarst sopra menzionata per utilizzare 3 tassonomie personalizzate. Voglio solo visualizzare i termini che sono associati a uno o più post nel loop.

Ecco la mia funzione che ho aggiunto a functions.php:

function dv_setup_sidebar_cats() {
    global $wp_query;

    $designers = array();
    $sizes     = array();
    $colors    = array();

    foreach( $wp_query->posts as $post ) {

        $des   = get_the_terms($post->ID, 'designer');
        $siz   = get_the_terms($post->ID, 'size');
        $col   = get_the_terms($post->ID, 'color');    

        foreach($des as $d) {
            $designers[] = $d->term_id;
        }

        foreach($siz as $s) {
            $sizes[] = $s->term_id;
        }

        foreach($col as $c) {
            $colors[] = $c->term_id;
        }

    }

    if ( !empty($designers) ) {
        $designers = array_unique($designers);
        sort($designers);
        $designers = implode(',', $designers);

        $dresult   = get_categories(array(
            'include'  => $designers,
            'taxonomy' => 'designer'
        ));
    }

    if ( !empty($sizes) ) {
        $sizes = array_unique($sizes);
        sort($sizes);
        $sizes = implode(',', $sizes);

        $sresult   = get_categories(array(
            'include'  => $sizes,
            'taxonomy' => 'size'
        ));
    } 

    if ( !empty($colors) ) {
        $colors = array_unique($colors);
        sort($colors);
        $colors = implode(',', $colors);

        $cresult   = get_categories(array(
            'include'  => $colors,
            'taxonomy' => 'color'
        ));
    }

    $return = array(
        'size'     => $sresult,
        'color'    => $cresult,
        'designer' => $dresult
    );


    return $return;

}

Spero che questo possa aiutare qualcun altro.

-J

10 mag 2012 20:37:20
3

Perdonami se mi è sfuggito qualcosa, ma non sarebbe semplice come:

if (is_object_in_term($post->ID, 'region', 'rotterdam'))
    the_category(); // mostra le categorie associate al post corrente

Nell'amministrazione, stai assegnando il post sia a 'pizzerie' che a 'cibo' (selezionando entrambe le caselle), o solo a 'pizzerie'?

Se quest'ultimo, the_category() non mostrerà 'Cibo' di default, quindi dovrai recuperare la gerarchia delle categorie manualmente.

6 dic 2010 12:52:03
Commenti

No, l'intenzione è mostrare un elenco di categorie, ma solo quelle categorie che hanno post in cui la tassonomia personalizzata region è impostata su Rotterdam. Questa domanda è stata posta anche su SO, tra l'altro.

Jan Fabry Jan Fabry
6 dic 2010 13:28:48

A meno che non stia fraintendendo, questa sembra una risposta adeguata. Se Mamma Mia è una pizzeria a rotterdam, allora per definizione ci sono pizzerie a Rotterdam e la categoria dovrebbe essere visualizzata. Altrimenti non capisco come la categoria dovrebbe essere collegata alla regione.

Rarst Rarst
6 dic 2010 14:11:16

@Rarst: Il modo in cui ho interpretato la domanda è che l'elenco delle categorie non dovrebbe essere mostrato solo sulla pagina di un post, ma ad esempio su region/rotterdam/: per tutti i post che utilizzano questo termine di tassonomia personalizzata, restituiscimi un albero di tutte le categorie a cui sono collegati. L'OP utilizza get_categories(), che non è limitato alle categorie del post corrente.

Jan Fabry Jan Fabry
6 dic 2010 14:48:05
2

puoi ottenere le tassonomie per un custom post con una piccola funzione:

    function get_the_taxonomy( $taxonomy, $id = FALSE ) {
        global $post;

        $id = (int) $id;
        if ( !$id )
            $id = (int) $post->ID;

        $categories = get_object_term_cache( $id, $taxonomy );
        if ( FALSE === $categories ) {
            $categories = wp_get_object_terms( $id, $taxonomy );
            wp_cache_add($id, $categories, $taxonomy . '_relationships');
        }

        if ( !empty( $categories ) )
            usort( $categories, '_usort_terms_by_name' );
        else
            $categories = array();

        foreach ( (array) array_keys( $categories ) as $key ) {
            _make_cat_compat( $categories[$key] );
        }

        return $categories;
    }

Puoi anche utilizzare la funzione wp-core:

$taxonomys = get_the_term_list($id, YOUR_CUSTOM_POST_TYPE, '', ', ', '' );

e puoi verificare una tassonomia con is_tax(), vedi codex per questo conditional tag

Forse questo può aiutare, se ho capito bene il tuo problema. Scusa per il mio inglese non perfetto.

7 dic 2010 00:14:21
Commenti

Penso che Henk Jan voglia ottenere un elenco di categorie, indipendenti da un post corrente. Solo tutte le categorie che hanno post assegnati al termine personalizzato rotterdam.

Jan Fabry Jan Fabry
7 dic 2010 00:41:47

Grazie per il suggerimento; penso sia possibile utilizzare una query personalizzata con il termine personalizzato. Il post restituisce tutti i termini, e la query deve utilizzare tutti o il primo termine per elencare nel loop tutti i post relativi a questo termine. È anche possibile restituire tutte le categorie dei post in questa query.

bueltge bueltge
7 dic 2010 10:11:19
4

Grazie a tutti per l'aiuto - è davvero fantastico. Vorrei condividere con voi la soluzione a cui sono arrivato. So che non è la soluzione più intelligente. Lo svantaggio è che viene mostrata una categoria genitore per una regione, quando non ci sono post personalizzati associati ad essa per questa regione (ma c'è un post personalizzato associato per un'altra regione).

Sto utilizzando questo codice in una pagina di archivio tassonomia per le regioni.

<?php
$categories = get_categories();
foreach ($categories as $cat)
{
    if($cat->parent < 1)
    {
        $cat_name = $cat->cat_name;                         
        $catid = get_cat_ID( $cat_name );

        echo '<div class="indexcolumn-top">';

        $img = $taxonomy_images_plugin->get_image_html( 'fullsize', $cat->term_taxonomy_id );
        if( !empty( $img ) )
            print $img;
        else 
            echo '<h2>' .$cat_name. '</h2>';

        $input = array();
        $args=array(
          'child_of' => $catid,
          'orderby' => 'name',
          'order' => 'ASC'
          );

        $categories = get_categories($args);
        foreach ($categories as $cat)
        {
            $cat_name = $cat->cat_name;
            $catid = get_cat_ID( $cat_name );

            $args = array(
                'post_status' => 'publish',
                'taxonomy_name' => 'region',
                'taxonomy_term' => $name,
            );
            $custom_posts = get_posts_by_taxonomy($args);
            if ($custom_posts):
                foreach ($custom_posts as $post):
                    setup_postdata($post);
                    $postcategory = get_the_category(); $postcat = $postcategory[0]->cat_name;
                    if ($postcat == $cat_name):
                        $category = get_the_category(); 
                        $input[] = $catid;
                    endif;
                endforeach;
            endif;
        }
        echo '<br/>';
        $output = array_unique($input);
        if (empty($output)):
            echo '<p>Nessuna azienda</p>';
            echo '</div>';
        else :
            echo '<ul class="port-box">';
            foreach ($output as $output) {
                $cat_name = get_cat_name($output);  
                echo '<li><a href="' . get_category_link($output) . '" title="' . sprintf( __( "Visualizza tutti i post in %s" ), $cat_name ) . '" ' . '>' . $cat_name .'</a></li>';                             
            }
            echo '</ul></div>';
        endif;
    }                                                   
}
?>
8 dic 2010 12:09:53
Commenti

Non credo sia un modo efficiente per farlo: fai molte query e non capisco il ciclo interno dei post: se un post viene trovato nella categoria corrente, probabilmente puoi semplicemente aggiungere quella categoria alla lista senza ciclare attraverso tutti i post?

Jan Fabry Jan Fabry
8 dic 2010 14:58:14

@Jan: So che non è la soluzione più intelligente. Però non capisco la tua osservazione sul ciclo interno dei post. Avrai bisogno del ciclo interno dei post per trovare una corrispondenza - oppure no. Oppure, puoi interrompere il ciclo in caso di corrispondenza? Ma come faresti allora?

Henk Jan Henk Jan
8 dic 2010 16:32:17

Non importa, pensavo che la tua funzione get_posts_by_taxonomy() selezionasse sia per tassonomia che per categoria. La domanda successiva è perché ripeti questa query più e più volte, invece di farla una volta e riutilizzare i risultati. E perché controlli solo la prima categoria? Se un'attività è sia in Pizzeria che in French Fries, ne verrà restituita solo una, quindi potresti perderne una alla fine.

Jan Fabry Jan Fabry
8 dic 2010 16:45:43

@Jan: OK. Sto controllando solo la prima categoria perché le mie attività possono essere in una sola categoria. Non capisco la tua prima domanda. Il codice if ($custom_posts): endif; può essere rimosso. Ma dovrai fare un loop per trovare una corrispondenza - oppure no. Cosa intendi con riutilizzo?

Henk Jan Henk Jan
8 dic 2010 17:20:20
0
<?php $cat_id = $_GET["cat"];?>     
      <li id="category-active"><a><?php if ($cat_id){echo get_the_category_by_id($li_id);}else{ echo "Categoria selezionata";}?></a></li>            <?php   $subcategories1 = wp_list_categories("title_li&child_of=$cat_id&hide_empty");
                wp_list_categories("title_li=&current_category="); ?>
                    </ul><?php ?>

grazie per il tuo aiuto.

ma penso non ci sia bisogno di foreach o qualsiasi loop, possiamo ottenere i figli di qualsiasi categoria usando questo semplice codice: prima $li_id ottiene l'ID della categoria corrente e lo passiamo dinamicamente a child_of=$cat_id e mostra i figli della categoria selezionata. Lo sto usando nella sidebar del mio sito.

18 gen 2011 18:58:37