Come mostrare il sottomenu utilizzando solo wp_nav_menu()
Sto usando questo codice per mostrare i sottomenu delle pagine personalizzate quando ci si trova nella pagina genitore. Tuttavia, questo codice mostra anche una pagina genitore in una pagina che non ha sottomenu, che vorrei nascondere. In pratica, vorrei utilizzare questo codice solo se ci troviamo in una pagina che ha sottopagine,
class Selective_Walker extends Walker_Nav_Menu
{
function walk( $elements, $max_depth) {
$args = array_slice(func_get_args(), 2);
$output = '';
if ($max_depth < -1) //parametro non valido
return $output;
if (empty($elements)) //niente da percorrere
return $output;
$id_field = $this->db_fields['id'];
$parent_field = $this->db_fields['parent'];
// visualizzazione piatta
if ( -1 == $max_depth ) {
$empty_array = array();
foreach ( $elements as $e )
$this->display_element( $e, $empty_array, 1, 0, $args, $output );
return $output;
}
/*
* necessario visualizzare in ordine gerarchico
* separare gli elementi in due contenitori: elementi di primo livello ed elementi figli
* children_elements è un array bidimensionale, es.
* children_elements[10][] contiene tutti i sotto-elementi il cui genitore è 10.
*/
$top_level_elements = array();
$children_elements = array();
foreach ( $elements as $e) {
if ( 0 == $e->$parent_field )
$top_level_elements[] = $e;
else
$children_elements[ $e->$parent_field ][] = $e;
}
/*
* quando nessuno degli elementi è di primo livello
* assumere che il primo deve essere la radice dei sotto-elementi
*/
if ( empty($top_level_elements) ) {
$first = array_slice( $elements, 0, 1 );
$root = $first[0];
$top_level_elements = array();
$children_elements = array();
foreach ( $elements as $e) {
if ( $root->$parent_field == $e->$parent_field )
$top_level_elements[] = $e;
else
$children_elements[ $e->$parent_field ][] = $e;
}
}
$current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' ); //aggiunto da continent7
foreach ( $top_level_elements as $e ){ //modificato da continent7
// scendere solo nell'albero corrente
$descend_test = array_intersect( $current_element_markers, $e->classes );
if ( !empty( $descend_test ) )
$this->display_element( $e, $children_elements, 2, 0, $args, $output );
}
/*
* se stiamo visualizzando tutti i livelli, e children_elements rimanenti non è vuoto,
* allora abbiamo orfani, che dovrebbero essere visualizzati comunque
*/
/* rimosso da continent7
if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
$empty_array = array();
foreach ( $children_elements as $orphans )
foreach( $orphans as $op )
$this->display_element( $op, $empty_array, 1, 0, $args, $output );
}
*/
return $output;
}
}
nel template usando:
wp_nav_menu(
array(
'theme_location'=>'primary',
'walker'=>new Selective_Walker()
)
);
Ho avuto questo stesso problema molte volte in passato con WordPress. In altri CMS che ho utilizzato, i menu avevano sempre un'opzione per lo start_depth che rendeva molto semplice implementare un menu secondario o terziario (menu diviso).
WordPress non include questa funzione; e molte delle soluzioni trovate online utilizzano wp_list_pages che ignora completamente la gerarchia del gestore dei menu.
Dopo aver provato diversi walker e widget, ho finalmente deciso di scrivere il mio plugin che include l'opzione start_depth.
Si utilizza in questo modo:
wp_nav_menu(array('theme_location' => 'primary_navigation', 'start_depth' => 1));
Per chi fosse interessato, è disponibile gratuitamente sul repository dei plugin di WordPress: https://wordpress.org/plugins/wp-nav-plus/

Ho creato un plugin gratuito che risolve questo problema!
https://wordpress.org/plugins/wp-nav-menu-extended/
Questo plugin estende la funzione nativa wp_nav_menu e aggiunge opzioni aggiuntive:
- level : (integer) (richiesto per il funzionamento del plugin) Il livello del menu di navigazione da mostrare. Se non viene passato il parametro child_of, mostra tutti gli elementi di questo livello
- child_of : (string|integer) (opzionale) Il titolo o l'ID dell'elemento genitore nel menu di cui mostrare i figli diretti
Esempio di utilizzo:
$defaults = array( 'theme_location' => 'main_menu', 'level' => 2, 'child_of' => 'Chi Siamo', );
wp_nav_menu( $defaults );
