Costruzione HTML personalizzata per sub-menu in Custom Nav Walker

19 mag 2014, 13:02:30
Visualizzazioni: 17.6K
Voti: 1

Ho configurato il mio Custom Nav Walker e funziona bene con gli elementi del menu principale, visualizzandoli come desidero.

Tuttavia, lo stesso HTML viene applicato anche agli elementi sub-menu, cosa che non voglio.

Sto cercando di ottenere per il sub-menu il seguente stile:

<ul>
    <li>
        <h2 class="dropdown-text">Blog 1</h2>
    </li>
    <li>
        <h2 class="dropdown-text">Blog 2</h2>
    </li>
    <li>
        <h2 class="dropdown-text">Blog 3</h2>
    </li>
    <li>
        <h2 class="dropdown-text">Blog 4</h2>
    </li>
</ul>

Ecco la struttura HTML completa per la navigazione:

<div class="postit-surround">
<a href="#">
    <div class="postit">
        <div class="pin">
            <img src="<?php echo get_template_directory_uri(); ?>/assets/drawing-pin.png">
        </div>
        <div class="postit-title">
            <h1 class="nav-title-text">Products</h1>
        </div>
        <div class="corner-peel">
            <img src="<?php echo get_template_directory_uri(); ?>/assets/corner-flick-cyan.png">
        </div>
    </div>
</a>
<div class="navigation-dropdown">
    <ul>
        <li>
            <h2 class="dropdown-text">Products 1</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 2</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 3</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 4</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 5</h2>
        </li>
    </ul>
</div>
</div>

Ecco la chiamata HTML per wp_nav_menu:

<div class="navigation-container">
<?php 

$walker = new my_nav_walker;
wp_nav_menu( array( 'theme_location' => 'header-menu', 'menu' => 'ul', 'menu_class' => 'navigation', 'menu_id' => '', 'walker' => $walker ) ); 

?>
</div>

Ecco la struttura per il mio Custom Walker HTML: (NOTA: Sono nuovo in questo, quindi sarà disordinato...)

class my_nav_walker extends Walker {
       function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

            $direct = get_template_directory_uri();

            $item_output = $args->before;
            $item_output .= '<div class="postit-surround">';
            $item_output .= '<a'. $attributes .'>';
            /** Questo filtro è documentato in wp-includes/post-template.php */

            $item_output .= '<div class="postit">
                                    <div class="pin">';
            $item_output .= '<img src="' . $direct . '/assets/drawing-pin.png">
                                    </div>
                                    <div class="postit-title">
                                            <h1 class="nav-title-text">';
            $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;

            $item_output .= '</h1>
                            </div>
                                    <div class="corner-peel">
                                            <img src="' . $direct . '/assets/corner-flick-green.png">
                                    </div>
                            </div>';
            $item_output .= '</a>';
            $item_output .= '</div>';
            $item_output .= $args->after;

        }    

} // Walker_Nav_Menu

Ecco il CSS se serve: Link PasteBin

Non sono sicuro di aver fatto correttamente la struttura per ottenere lo stile separato che desidero.

Cosa mi consiglieresti?

Ci sono alternative?

Critiche costruttive sul codice? (Non essere troppo duro! :P)

EDIT -----:

Ho fatto ulteriori ricerche per capire meglio il codice php, e ora capisco dove inizia la definizione dell'inizio e della fine del sub-menu (con start_lvl e end_lvl), ma ancora non capisco come separare quale codice va ai pannelli di navigazione principale e quale va ai rispettivi sub-menu.

Questo è ciò che voglio ottenere con la visualizzazione della navigazione: http://jsfiddle.net/TPD5L/

15
Commenti

"Critiche costruttive sul codice?". Ben detto. ;)

Pieter Goosen Pieter Goosen
19 mag 2014 13:10:26

@PieterGoosen Grazie :) Anche io rabbrividisco davanti al codice, chissà cosa pensa la maggior parte delle persone che lo vede!

Mallander Mallander
19 mag 2014 13:13:59

qual è il metodo che stai sovrascrivendo? e non credo tu abbia bisogno di un custom walker, puoi ottenere lo stesso risultato usando la funzione wp_nav_menu con gli argomenti appropriati, per favore posta il codice completo includendo i nomi dei metodi del tuo custom walker

MortalViews MortalViews
19 mag 2014 14:47:47

@MortalViews Domanda modificata per includere il CODICE COMPLETO del Custom Walker e la chiamata HTML wp_nav_menu.

Mallander Mallander
19 mag 2014 14:55:27

Ciao, quando estendi la classe genitore, non è necessario includere alcun metodo che non stai sovrascrivendo. Controlla: l'esempio generale http://codex.wordpress.org/Class_Reference/Walker

MortalViews MortalViews
19 mag 2014 15:00:34

@MortalViews Potresti approfondire? Non capisco molto di questo :)

Mallander Mallander
19 mag 2014 15:02:03

dai un'occhiata all'Esempio del Menu Generale @ http://codex.wordpress.org/Class_Reference/Walker e anche http://codex.wordpress.org/Function_Reference/wp_nav_menu

MortalViews MortalViews
19 mag 2014 15:02:50

Grazie per questo, ma non capisco come questo mi permetta di separare l'HTML per gli elementi di livello superiore e il sottomenu.

Mallander Mallander
19 mag 2014 15:06:09

com'è la struttura del tuo menu? è così? <ul><li><a>Servizi</a><ul clas='submenu'><li><a>Caccia al Lupo</a></li><li><a>Caccia al Cavallo</a></li></ul></li></ul> cioè: Elemento Menu Principale->elementi del sottomenu

MortalViews MortalViews
19 mag 2014 15:22:51

Lo aggiungerò alla domanda

Mallander Mallander
19 mag 2014 15:27:26

@MortalViews Aggiunto.

Mallander Mallander
19 mag 2014 15:36:30

Per favore dai un'occhiata al Walker originale e rimuovi tutti i metodi dal tuo walker che sono uguali all'originale. Quando fai extend hai una sorta di relazione genitore/figlio. Non devi duplicare i metodi che esistono nel genitore a meno che non voglia cambiarli. Una volta fatto questo, darò un'altra occhiata. C'è troppo codice non necessario così com'è.

s_ha_dum s_ha_dum
19 mag 2014 15:51:56

@s_ha_dum Va meglio così? Ho semplicemente rimosso tutto ciò che non era necessario per la generazione della struttura HTML.

Mallander Mallander
19 mag 2014 15:55:54

Meglio, ma hai rimosso troppo. Devi comunque mantenere le definizioni dei metodi per i metodi che stai utilizzando-- la parte function start_el(...).

s_ha_dum s_ha_dum
19 mag 2014 16:00:08

@s_ha_dum Ecco fatto, ora dovrebbe andare bene. Anche se, quando ho questo sul mio sito in localhost, ottengo: pastebin

Mallander Mallander
19 mag 2014 16:04:44
Mostra i restanti 10 commenti
Tutte le risposte alla domanda 1
8

Soluzione: Copia e incolla il codice qui sotto nella tua funzione. e poi nel template usa

my_nav_menu($menu_location);

//inserisci questo nelle tue funzioni

class MY_Menu_Walker_Ext extends Walker {

    var $tree_type = array('post_type', 'taxonomy', 'custom');
    var $db_fields = array('parent' => 'menu_item_parent', 'id' => 'db_id');

    function start_el(&$output, $object, $depth = 0, $args = array(), $current_object_id = 0) {
        $output .="<li><h2 class='dropdown-text'>{$object->title}</h2>";
    }

    function end_el(&$output, $object, $depth = 0, $args = array()) {
        $output.='</li>';
    }

}

class my_custom_menu {

    public $menu;
    public $menuItems;
    public $parents;
    public $walker;

    public function __construct($menu_location) {
        $this->setMenu($menu_location);
        $this->getMenuItems();
        $this->getParents();

        $this->walker = new MY_Menu_Walker_Ext();
    }

    public function drawMenu() {

    }

    public function setMenu($menu_location) {

        $this->menu = $this->getMenuByLocation($menu_location);
    }

    protected function getMenuByLocation($menu_location) {
        $locations = get_nav_menu_locations();

        $menu = null;
        if ($locations && isset($locations[$menu_location])) {
            $menu = wp_get_nav_menu_object($locations[$menu_location]);
        }

        return $menu;
    }

    public function get() {

    }

    public function getMenuItems() {
        if ($this->menuItems)
            return $this->menuItems;
        $this->menuItems = wp_get_nav_menu_items($this->menu);

        return $this->menuItems;
    }

    public function getParents() {
        if ($this->parents)
            return $this->parents;
        $parents = array();

        foreach ($this->menuItems as $item) {
            if ($item->menu_item_parent == 0) {
                array_push($parents, $item);
            }
        }

        $this->parents = $parents;
        return $this->parents;
    }

    public function getChild($parent_id) {

        $childs = array();


        foreach ($this->menuItems as $item) {
            if ($parent_id == $item->menu_item_parent) {
                $item->menu_item_parent = 0;

                array_push($childs, $item);
                foreach ($this->menuItems as $item1) {
                    if ($item->ID == $item1->menu_item_parent) {
                        array_push($childs, $item1);
                    }
                }
            }
        }

        return $childs;
    }

    public function draw() {
        echo "<div class='postit-surround'>";

        foreach ($this->parents as $item) {
            $this->displayParentHTML($item->title);
            $this->drawChildren($this->getChild($item->ID));
        }
        echo "</div>";
    }

    public function displayParentHTML($title) {
        ?>
        <a href="#">
            <div class="postit">
                <div class="pin">
                    <img src="<?php echo get_template_directory_uri(); ?>/assets/drawing-pin.png" alt="Spillo da disegno" title="Spillo da disegno">
                </div>
                <div class="postit-title">
                    <h1 class="nav-title-text"><?php echo $title ?></h1>
                </div>
                <div class="corner-peel">
                    <img src="<?php echo get_template_directory_uri(); ?>/assets/corner-flick-cyan.png" alt="Angolo staccato" title="Angolo staccato">
                </div>
            </div>
        </a>

        <?php
    }

    public function drawChildren($children) {
        $defaults = array('menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '',
            'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
            'depth' => 0, 'walker' => '', 'theme_location' => '');
        $args = array(
            'theme_location' => 'header-menu',
            'container' => 'div',
            'container_class' => 'navigation-dropdown',
            'items_wrap' => '<ul >%3$s</ul>',
            'depth' => 0,
        );
        $args = wp_parse_args($args, $defaults);

        echo "<div class='navigation-dropdown'><ul>";
        echo $this->walker->walk($children, 2, $args);
        echo "</ul></div>";
    }

}

function my_nav_menu($name = null) {
    $myMenu = new my_custom_menu($name);
    $myMenu->draw();
}
19 mag 2014 15:58:32
Commenti

Grazie, quello funziona bene da solo, però ho difficoltà a capire come integrarlo con il mio Walker di livello superiore per ottenere la struttura complessiva indicata nella domanda?

Mallander Mallander
19 mag 2014 16:20:19

non ti ho capito. non hai bisogno di un altro Walker di livello superiore.

MortalViews MortalViews
19 mag 2014 16:22:10

sostituisci la tua classe my_nav_walker con questa. e nel template dove vuoi visualizzare il menu di navigazione, copia e incolla il codice nella seconda sezione. nota: l'output includerà anche il div container

MortalViews MortalViews
19 mag 2014 16:23:24

Non sono sicuro che tu stia capendo cosa sto cercando con la navigazione (sono stato davvero poco chiaro nella mia domanda, scusa per questo) Guarda questo fiddle: http://jsfiddle.net/TPD5L/

Mallander Mallander
19 mag 2014 16:25:58

ok, l'html per la parte 'postit' dovrebbe essere incluso nel template. <div post it>< il codice post it></> Qui chiama il menu di navigazione </div>

MortalViews MortalViews
19 mag 2014 16:28:27

NON dovresti provare a ottenere l'intero html da wp_nav_menu. usa wp_nav_menu solo per la parte 'menu'. il resto dovrebbe essere incluso nel codice del template, mi capisci?

MortalViews MortalViews
19 mag 2014 16:29:56

Quindi, invece di usare wp_nav_menu per ottenere gli elementi del menu di primo livello, usalo solo per ottenere gli elementi figli?

Mallander Mallander
19 mag 2014 16:36:40

continuiamo questa discussione nella chat

MortalViews MortalViews
19 mag 2014 16:38:52
Mostra i restanti 3 commenti