Construcción HTML personalizada para submenús en Custom Nav Walker
Tengo mi Custom Nav Walker configurado y funciona bien con los elementos del menú principal, mostrándolos como quiero.
Sin embargo, el mismo HTML se está aplicando a los elementos sub-menu
lo cual no es lo que deseo.
Estoy tratando de que el sub-menu
tenga el siguiente estilo:
<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>
Aquí está la estructura HTML para la navegación completa:
<div class="postit-surround">
<a href="#">
<div class="postit">
<div class="pin">
<img src="<?php echo get_template_directory_uri(); ?>/assets/drawing-pin.png" alt="Pin decorativo" title="Pin decorativo">
</div>
<div class="postit-title">
<h1 class="nav-title-text">Productos</h1>
</div>
<div class="corner-peel">
<img src="<?php echo get_template_directory_uri(); ?>/assets/corner-flick-cyan.png" alt="Esquina doblada" title="Esquina doblada">
</div>
</div>
</a>
<div class="navigation-dropdown">
<ul>
<li>
<h2 class="dropdown-text">Productos 1</h2>
</li>
<li>
<h2 class="dropdown-text">Productos 2</h2>
</li>
<li>
<h2 class="dropdown-text">Productos 3</h2>
</li>
<li>
<h2 class="dropdown-text">Productos 4</h2>
</li>
<li>
<h2 class="dropdown-text">Productos 5</h2>
</li>
</ul>
</div>
</div>
Aquí está la llamada HTML para 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>
Aquí está la construcción para mi Custom Walker HTML: (NOTA: Soy nuevo en esto, así que será un poco desordenado...)
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 .'>';
/* Este filtro está documentado en wp-includes/post-template.php */
$item_output .= '<div class="postit">
<div class="pin">';
$item_output .= '<img src="' . $direct . '/assets/drawing-pin.png" alt="Pin decorativo" title="Pin decorativo">
</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" alt="Esquina doblada" title="Esquina doblada">
</div>
</div>';
$item_output .= '</a>';
$item_output .= '</div>';
$item_output .= $args->after;
}
} // Walker_Nav_Menu
Aquí está el CSS si es necesario: Enlace a PasteBin
No estoy seguro si estoy haciendo la construcción correctamente para obtener el estilo separado que quiero.
¿Qué me recomendarías?
¿Hay alguna alternativa?
¿Crítica constructiva sobre el código? (¡No seas muy duro! :P)
EDITADO -----:
He investigado más para entender el código php, y ahora me doy cuenta de dónde comienza la definición del inicio y fin del sub-menu (Con start_lvl y end_lvl), pero todavía no entiendo cómo separar qué código va a los paneles de navegación principales y cuál va a sus respectivos sub-menús.
Esto es lo que busco con la visualización de la navegación: http://jsfiddle.net/TPD5L/

Solución: Copia y pega el siguiente código en tu función. y luego en la plantilla usa
my_nav_menu($menu_location);
//coloca esto en tus funciones
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="Icono de chincheta" title="Chincheta decorativa">
</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="Esquina despegada" title="Efecto de esquina despegada">
</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();
}

Gracias, eso funciona bien por sí solo, sin embargo, me cuesta ver cómo integrarlo con mi Walker de nivel superior para obtener la estructura general indicada en la pregunta.

Reemplaza tu clase my_nav_walker con esta. Y en la plantilla donde quieras mostrar el menú de navegación, copia y pega el código de la segunda sección. Nota: la salida incluirá también el div contenedor.

No estoy seguro de que estés entendiendo lo que busco con la navegación (he sido muy poco claro en mi pregunta, lo siento por eso) Mira este fiddle: http://jsfiddle.net/TPD5L/

ok, el html para la parte del 'postit' debería incluirse en la plantilla. <div post it>< el código del post it></> Aquí llama al menú de navegación </div>

NO deberías intentar obtener todo el html desde wp_nav_menu. usa wp_nav_menu solo para la parte del 'menú'. el resto debería incluirse en el código de la plantilla, ¿me entiendes?

¿Entonces en lugar de usar wp_nav_menu para obtener los elementos del menú de primer nivel, simplemente lo usas para obtener los elementos hijos?

continuemos esta discusión en el chat
