Come creare un blogroll di post ordinati per categorie e sottocategorie?
Vorrei un aiuto per visualizzare tutti i post del mio sito web in un blogroll ordinato per categorie e sottocategorie.
Il risultato HTML che vorrei ottenere sarebbe qualcosa del genere:
<div id="content">
<div id="category1">
<ul id="posts">
<li>post1</li>
<li>post2</li>
<li>post3</li>
</ul><!-- #posts -->
</div><!-- #category1 -->
<div id="category2">
<div id="sub-category1">
<ul id="posts">
<li>post4</li>
<li>post5</li>
<li>post6</li>
</ul><!-- #posts -->
</div><!-- #sub-category1 -->
<div id="sub-category2">
<ul id="posts">
<li>post7</li>
<li>post8</li>
<li>post9</li>
</ul><!-- #posts -->
</div><!-- #sub-category2 -->
</div><!-- #category2 -->
</div><!-- #content -->
La struttura dei file che ho previsto sarebbe qualcosa del genere:
custom-category.php
//questo file estrarrà le categorie, le ordinerà e creerà i div contenitori per #category e #sub-category e chiamerà le informazioni dei post dal suo loop/query con get_template_part( 'content', get_post_format() );
content.php
//questo file ordinerà ul#posts e tutte le informazioni che potrei voler aggiungere riguardo al post stesso
Al momento i problemi principali che ho sono che non so davvero da dove iniziare a cercare per provare a capirlo da solo. Continuo a guardare il file category.php
predefinito e sento che non gli assomiglierà per niente.
Ho provato a guardare i plugin ma alcuni ordinano solo le categorie nelle barre laterali, altri permettono di creare campi personalizzati per le categorie ma le recensioni dicono che non si possono richiamare quei valori. Ho provato la funzione wp_list_categories(); per provare a iniziare da qualche parte, ma non elenca nemmeno le sottocategorie.
Ho letto di creare le proprie query_posts();
o get_posts();
ma non so davvero da dove iniziare con quelle.
Dal momento che questa non è una singola domanda, vorrei cercare di evidenziare le domande per chiarezza, ma sentitevi liberi di aggiungere altre informazioni che ritenete possano risolvere il problema, perché potrei fare le domande sbagliate xD
1- Come inizio "il Loop" per ottenere le categorie/sottocategorie?
2- Come ordino le categorie e mantengo le sottocategorie annidate?
3- Come mi assicuro che i post finiscano nei div giusti? Nel caso WordPress faccia qualcosa di strano.
Grazie per l'aiuto.
--- Aggiornamento ---
Ho cercato su internet provando a trovare soluzioni e sto iniziando ad arrivare da qualche parte, ma non ancora del tutto. Questo è quello che ho finora:
<?php
// ottiene tutte le categorie dal database
$args1 = array(
'orderby' => 'ID',
'order' => 'ASC',
'hierarchical' => true,
);
$cats = get_categories( $args1 );
// ciclo attraverso le categorie
foreach ($cats as $cat) {
// imposta l'ID della categoria
$cat_id= $cat->term_id;
// Crea un'intestazione per la categoria
echo "<h2>".$cat->name."</h2><p>".$cat->term_id."</p>";
// crea una query wordpress personalizzata
$args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// inizia il loop wordpress!
if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php // crea il nostro link ora che il post è configurato ?>
<a href="<?php the_permalink();?>"><?php the_title(); ?></a>
<?php echo '<hr/>'; ?>
<?php endwhile; endif; // terminato il nostro loop wordpress. Ricomincerà per ogni categoria ?>
<?php } // terminato il foreach ?>
Ho trovato questo codice su questo sito web. Mostra tutte le categorie e mette i post sotto di esse, ma replica i post per la categoria genitore così:
<h2>Category1</h2><p>2</p>
<a href="http://localhost/wordpress/2013/05/06/test0/">test0</a>
<hr>
<h2>Category2</h2><p>3</p>
<a href="http://localhost/wordpress/2013/05/15/test2/">test2</a>
<hr>
<a href="http://localhost/wordpress/2013/05/14/test1/">test1</a>
<hr>
<h2>Sub-category1</h2><p>4</p>
<a href="http://localhost/wordpress/2013/05/14/test1/">test1</a>
<hr>
<h2>Sub-category2</h2><p>5</p>
<a href="http://localhost/wordpress/2013/05/15/test2/">test2</a>
<hr>
Come potete vedere i post test1 e test2 vengono visualizzati in Category2 e questo non è esattamente quello che volevo, come descritto nella domanda iniziale (HTML risultante).
Credo di dover aggiungere una condizione per verificare se la categoria corrente ha figli e in caso affermativo passare alle categorie figlie, altrimenti popolarla. Ma sto ancora cercando di capire come farlo. Non sono ancora arrivato al punto in cui mi sento abbastanza sicuro da iniziare a provare a implementare i div che intendo avere nell'HTML finale ma ho la sensazione che avrò un problema anche con quello. A questo punto sto fondamentalmente cercando di imparare un po' di più su questa "roba dei loop" finché non ottengo un risultato decente che mi permetta di capire il tutto.
Sono a conoscenza di questi 2 link A e B ma sono ancora principiante e non riesco ancora ad arrivarci, quindi sto fondamentalmente lavorando con codice che vedo funzionare e cercherò di migliorarlo man mano che vado avanti.
--- Aggiornamento ---
Questo sembra mostrare i post nell'ordine corretto e senza ripeterli per le categorie genitore.
<?php
// ottiene tutte le categorie dal database
$args1 = array(
'orderby' => 'ID',
'order' => 'ASC',
'hierarchical' => true
);
$cats = get_categories( $args1 );
// ciclo attraverso le categorie
foreach ($cats as $cat) {
$cat_id= $cat->term_id;// imposta l'ID della categoria
$cat_name= $cat->name;// imposta il nome della categoria
$parent= $cat->category_parent;// imposta il genitore della categoria
$cat_child= get_term_children( $cat_id, 'category' ); //la funzione che avevo get_category_children(); era deprecata... l'ho corretta
$has_child=bool; //
if( empty($cat_child)) { $has_child= false; }
else { $has_child= true; }
if ( $parent == 0 && $has_child == true ) { //è genitore && ha figli -> mostra titolo
echo "<h2>".$cat_name."</h2>";
echo '<hr/>'; }
elseif ( $parent == 0 && $has_child == false ) { //è genitore && non ha figli -> loop dei post
echo "<h2>".$cat_name."</h2>";
// crea una query wordpress personalizzata
$args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// inizia il loop wordpress!
if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_title(); ?>
<?php echo '<hr/>'; ?>
<?php endwhile; endif; }
else { //è figlio -> loop dei post
echo "<h2>".$cat_name."</h2>";
// crea una query wordpress personalizzata
$args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// inizia il loop wordpress!
if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_title(); ?>
<?php echo '<hr/>'; ?>
<?php endwhile; endif; // terminato il nostro loop wordpress. Ricomincerà per ogni categoria ?>
<?php }} // terminato il foreach ?>
Ho diviso questo in 3 condizioni: è genitore e ha figli
, è genitore ma non ha figli
e è figlio
. La funzione che mi ha permesso di arrivare qui è get_category_children();
.
Leggendo il codice ora mi fa pensare che avrei potuto semplicemente controllare se $cat_child
era vuoto direttamente nelle istruzioni if/elseif principali, evitando il giro di $has_child
.

Ok, dopo molte ricerche ho creato un codice che fa esattamente ciò che ho chiesto. Tuttavia non credo che questo codice sia elegante/efficiente/riutilizzabile in alcun modo. Lo pubblico semplicemente perché esegue ciò che mi aspettavo. Apprezzerei una risposta che mi indirizzi verso il modo "migliore" di programmare in modo da poter imparare, quindi non segnerò la mia domanda come risolta per circa una settimana per attendere qualche soluzione di codifica migliore.
Questo è il risultato a cui sono arrivato:
<?php
$isOdd = true; // imposta un booleano per determinare l'ID del div genitore per il CSS
$args1 = array(
'orderby' => 'ID',
'order' => 'ASC',
'hierarchical' => true
);
$cats = get_categories( $args1 ); // ottiene tutte le categorie dal database
// ciclo attraverso le categorie
foreach ($cats as $cat) {
$cat_id= $cat->term_id;// imposta l'ID della categoria
$cat_name= $cat->name;// imposta il nome della categoria
$parent= $cat->category_parent;// imposta il genitore della categoria
$cat_child= get_term_children( $cat_id, 'category' ); // restituisce una stringa con le categorie figlie dalla tassonomia
$has_child=bool; // crea una variabile che permette di verificare se una categoria ha figli
if( empty($cat_child)) { $has_child= false; }
else { $has_child= true; }
if ( $parent == 0 && $has_child == false ) { //è genitore && nessun figlio -> ciclo i post
echo "<div class=\"parent-wrap\" id=\"". ( $isOdd ? 'odd' : 'even') . "\">";
echo "<h2>".$cat_name."</h2>";
echo "<div class=\"post-wrap\">";
echo "<ul class=\"post-list\">";
echo "<li class=\"back-button\"><</li>";
// crea una query personalizzata di WordPress
$args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// inizia il loop di WordPress!
if (have_posts()) : while (have_posts()) : the_post();
get_template_part( 'content', get_post_format() ); //ottiene il template del post da content.php
endwhile; endif;
echo "<li class=\"front-button\">></li>";
echo "</ul><!-- .post-list -->";
echo "</div><!-- .post-wrap -->";
echo "</div><!-- .parent-wrap -->";
$isOdd = !$isOdd;
}
elseif ( $parent == 0 && $has_child == true ) { //è genitore && ha figli -> titolo del post
echo "<div class=\"parent-wrap\" id=\"". ( $isOdd ? 'odd' : 'even') . "\">";
echo "<h2>".$cat_name."</h2>";
// ciclo attraverso le categorie NEL STATEMENT ELSEIF
foreach ($cats as $cat) {
$cat_id_new= $cat->term_id;// imposta il nuovo ID della categoria
$cat_name_new= $cat->name;// imposta il nuovo nome della categoria
$parent_new= $cat->category_parent;// imposta il nuovo genitore della categoria
$cat_child_new= get_term_children( $cat_id_new, 'category' ); // restituisce una stringa con le categorie figlie dalla tassonomia
$has_child_new=bool; // crea una nuova variabile che permette di verificare se una categoria ha figli
if( empty($cat_child_new)) { $has_child_new= false; }
else { $has_child_new= true; }
if ($parent_new != 0 && $has_child_new == false && cat_is_ancestor_of($cat_id, $cat_id_new) ) { //è figlio -> ciclo i post
echo "<div class=\"child-wrap\">";
echo "<h3>".$cat_name_new."</h3>";
echo "<div class=\"post-wrap\">";
echo "<ul class=\"post-list\">";
echo "<li class=\"back-button\"><</li>";
// crea una query personalizzata di WordPress
$args2 = 'cat=' . $cat_id_new . '&orderby=date&order=DESC&post_per_page=-1';
query_posts( $args2 );
// inizia il loop di WordPress!
if (have_posts()) : while (have_posts()) : the_post();
get_template_part( 'content', get_post_format() ); //ottiene il template del post da content.php
endwhile;
endif; // completato il nostro loop di WordPress. Ricomincerà per ogni categoria
echo "<li class=\"front-button\">></li>";
echo "</ul><!-- .post-list -->";
echo "</div><!-- .post-wrap -->";
echo "</div><!-- .child-wrap -->";
} // chiudi if ($parent_new != 0...
} // chiudi foreach in elseif
echo "</div><!-- .parent-wrap -->";
$isOdd = !$isOdd;
} // chiudi if ($parent == 0...
} // chiudi il primo statement foreach ?>
Penso che alcune cose in questo codice potrebbero essere organizzate meglio se venissero create delle funzioni e poi riutilizzate nel codice e sto ancora valutando di sostituire query_posts();
con get_posts();
o pre_get_posts();
.
