Come creare un menu con tutte le sottocategorie?
Questo dipende dal tipo di menu a cui ti riferisci:
1)
Se stai parlando di "menu personalizzati" (presenti nel backend sotto Design -> Menu) puoi fare quanto segue:
Crea una nuova funzione con l'hook di azione
add_category
all'interno di questa funzione, puoi creare un nuovo post del tipo elemento del menu, che viene aggiunto correttamente al tuo menu
ogni volta che viene pubblicata una nuova categoria, l'elemento del menu viene ora aggiunto
dovresti anche agganciarti alla cancellazione delle categorie, per mantenere il tuo menu aggiornato
2)
Potresti fare molto più facilmente senza un menu WordPress:
- basta scrivere una funzione per elencare le tue categorie (o usare la funzione predefinita
wp_list_categories
) - se questo non è sufficiente, scrivi una personalizzata che (magari in modo ricorsivo) legge le tue categorie dal database
Per l'opzione 1, è richiesta una certa conoscenza di WordPress per il codice.

Preferisco utilizzare wp_list_categories
. Ecco il codice che ho usato nel mio ultimo progetto:
<?php wp_list_categories('orderby=ID&exclude=3,10,1,16,38&title_li=<span class="sidebar_heading d_shadow">' . __('Categorie') . '</span>'); ?>
Otterrai un elenco di tutte le tue categorie e sottocategorie.

Dopo molte ricerche ho trovato una soluzione affidabile e utile, questa classe funziona bene:
class EntexAutoSubmenu {
/**
* Costruttore
*/
function __construct(){
add_action('created_category', array($this, 'on_publish_category'));
}
/**
* Quando viene pubblicata una nuova categoria figlia, aggiungila al menu personalizzato appropriato.
*/
function on_publish_category($cat_id){
// Il tema supporta i menu personalizzati?
if (!current_theme_supports('menus')) return;
// La tassonomia pubblicata ha un genitore?
$cat = get_category($cat_id);
if (!$cat->category_parent) return;
$all_menus = get_terms('nav_menu', array('hide_empty' => true));
// Scorri tutti i menu per trovare il genitore della pagina
foreach ($all_menus as $menu) {
$menu_parent = NULL;
$menu_items = wp_get_nav_menu_items($menu->term_id, array('post_status' => 'publish,draft'));
if (!is_array($menu_items)) continue;
foreach ($menu_items as $menu_item){
// L'elemento è già nel menu?
if ($menu_item->object_id == $cat_id) continue 2;
if ($menu_item->object_id == $cat->category_parent) $menu_parent = $menu_item;
}
// Aggiungi nuovo elemento
if ($menu_parent) {
wp_update_nav_menu_item($menu->term_id, 0, array(
'menu-item-object-id' => $cat_id,
'menu-item-object' => $cat->taxonomy,
'menu-item-parent-id' => $menu_parent->ID,
'menu-item-type' => 'taxonomy',
'menu-item-status' => 'publish'
));
}
}
}
}
$auto_submenu = new EntexAutoSubmenu();

Un'altra alternativa potrebbe essere utilizzare List Custom Taxonomy Widget, potrebbe funzionare nel tuo caso d'uso (se non hai intenzione di utilizzare WP nav_menu).

Ho codificato il mio per uno dei miei clienti
<div class="menu">
<ul id="MenuBar1" class="MenuBarHorizontal">
<li><a <?PHP if( count($_GET) == 0 ){ echo 'class="-current"';} ?> href="<?php echo esc_url( home_url( '/' ) ); ?>">home</a></li>
<?php
$category_ids = get_all_category_ids();
sort($category_ids);
foreach($category_ids as $cat_id) {
$cat_name = get_cat_name($cat_id);
echo '<li><a href="' . get_category_link( $cat_id ) . '">' . $cat_name . '</a>';
$args = array( 'numberposts' => -1, 'offset'=> 0, 'cat' => $cat_id, 'orderby' => 'ID', 'order' => 'ASCE' );
echo '<ul>';
/* La seconda Query (senza variabile globale) */
$query2 = new WP_Query( $args );
// Il secondo Loop
while( $query2->have_posts() ):
$query2->next_post();
echo '<li><a href="' . get_permalink( $query2->post->ID ) . '">' . get_the_title( $query2->post->ID ) . '</a></li>';
endwhile;
// Ripristina la Query originale e i dati del Post
wp_reset_query();
wp_reset_postdata();
echo '</ul>';
echo '</li>';
}
?>
</ul>
</div>

Per risolvere questo problema ho provato a creare un plugin che crea automaticamente una voce di menu per la categoria pubblicata sotto la sua categoria genitore se presente nel menu.
Idea per il plugin:
1. Nel codice, ho utilizzato l'hook di azione "created_$taxonomy".
2. Ho raccolto tutte le voci di menu (usando wp_get_nav_menu_items)
3. E ho inserito una condizione: se il genitore della categoria pubblicata è presente come voce di menu, allora viene creata una voce di menu come sottomenu della sua categoria genitore (usando wp_update_nav_menu_item)
<?php
/*
Plugin Name: Auto Category Submenu
Plugin URI:
Description: Crea una voce di menu quando una categoria viene pubblicata/creata se la sua categoria genitore è presente come voce di menu.
Version: 0.1
Author: Mayank Gupta/Ravinder Kumar
Author URI:
License: GPL2
*/
class AutoSubmenu {
/**
* Costruttore
*/
function __construct() {
add_action( 'created_category', array( &$this, 'on_publish_cat' ) );
}
/**
* Quando viene pubblicata una nuova pagina figlia, la aggiunge al menu personalizzato appropriato.
*/
function on_publish_cat( $cat_id ) {
$cat = get_category( $cat_id );
//ID del menu in cui la categoria genitore della sottocategoria è presente come voce di menu
$menu_ids = array(101,100);
//recupera tutte le voci di menu dal menu
foreach($menu_ids as $menu_id){
$menu_items[] = wp_get_nav_menu_items( $menu_id, array('post_status' => 'publish','post_type' => 'nav_menu_item','output' => ARRAY_A, ) );
}
foreach($menu_items as $menu_item){
$counter = 0 ;
echo'<!--';
print_r($menu_item);
echo'-->';
foreach($menu_item as $menu_term){
$menu_terms_id[] = $menu_term->object_id; //tutti gli ID delle voci di menu
}
}
//print_r($menu_terms_id); //test per gli elementi nel menu
foreach( $menu_terms_id as $menu_term ){
if( $cat->category_parent == $menu_term){
wp_update_nav_menu_item( $cat_id, 0, array(
'menu-item-object-id' => $cat_id,
'menu-item-object' => $cat->taxonomy,
'menu-item-parent-id' => $menu_term,
'menu-item-type' => 'category',
'menu-item-status' => 'publish'
) );
}else{
return;
}
}
}
}
$auto_submenu = new AutoSubmenu();
Nota: il plugin restituisce un errore (header già inviato) e la voce di menu non viene creata quando la categoria viene pubblicata. Questo potrebbe essere un altro argomento per il problema, ma lo inserisco qui perché potrebbe essere una soluzione se qualcuno mi indica dove sbaglio. Scusate se sto facendo qualcosa di sbagliato inserendolo qui

Sto utilizzando questo codice per mostrare tutte le categorie e sottocategorie come menu nel mio progetto.
$all_categories = get_categories( $args );
echo "<div class='container'>";
echo "<div class='productsubmenu'>";
echo "<ul>";
foreach ($all_categories as $cat)
{
if($cat->category_parent == 0)
{
$category_id = $cat->term_id;
$thumbnail_id = get_woocommerce_term_meta( $cat->term_id, 'thumbnail_id', true );
$image = wp_get_attachment_url( $thumbnail_id );
echo '<li class="parent '.$my.' "><a href="'.get_term_link( $cat ) . '">'.$cat->name.'</a>';
$args2 = array(
'taxonomy' => $taxonomy,
'child_of' => 0,
'parent' => $category_id,
'orderby' => $orderby,
'show_count' => $show_count,
'pad_counts' => $pad_counts,
'hierarchical' => $hierarchical,
'title_li' => $title,
'hide_empty' => $empty
);
$args = array(
'hierarchical' => 1,
'show_option_none' => '',
'hide_empty' => 0,
'parent' => $parent_cat_ID,
'taxonomy' => 'product_cat'
);
$subcats = get_categories($args2);
echo '<ul class="wooc_sclist">';
foreach ($subcats as $sc) {
}
$link = get_term_link( $sc->slug, $sc->taxonomy );
echo '<li class="'.$my.'" ><a href="'. $link .'">'.$sc->name.'</a></li>';
}
echo '</ul>';
echo "</li>";
}
else
{
}
}
echo "</ul>";
echo "</div>";
echo "</div>";

Le risposte di solito sono più che semplici blocchi di codice. Potresti per favore modificare la tua risposta e spiegare cosa stai facendo e perché?

questo è il mio approccio, funziona per le categorie di prodotti.
$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true,);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
if ($cat->parent == 0):
echo $cat->name;
foreach ($cats as $key => $cat2):
if ($cat2->parent == $cat->term_id):
echo $cat2->name;
foreach ($cats as $key => $cat3):
if ($cat3->parent == $cat2->term_id):
echo $cat3->name;
endif;
endforeach;
endif;
endforeach;
endif;
endforeach;
