Cómo construir un Walker personalizado para menús en WordPress

En WordPress, los menús personalizados son una parte fundamental del desarrollo de temas avanzados. Si bien la función wp_nav_menu()es muy flexible, hay ocasiones en las que necesitas control total sobre el HTML que genera. Para esos casos, WordPress nos da la clase Walker_Nav_Menu, que podemos extender para crear un custom Walker.

¿Qué es un Walker en WordPress?

Un Walker es una clase que WordPress usa para recorrer estructuras jerárquicas (como menús o taxonomías anidadas) y generar el HTML correspondiente.

En el caso de los menús (wp_nav_menu()), WordPress utiliza la clase Walker_Nav_Menupara construir el HTML de los <ul>, <li>, submenús, etc.

Cuando necesitas cambiar esa estructura, puedes extender Walker_Nav_Menuy reescribir algunos de sus métodos para modificar la salida HTML.

 

¿Cuándo deberías usar un custom Walker?

Deberías crear un Walker personalizado cuando:

  • Necesitas agregar clases personalizadas a ciertos elementos.
  • Quieres cambiar por completo la estructura HTML de los <ul> y <li>.
  • Usás un framework CSS como Bootstrap o Tailwind y necesitás adaptarlo.
  • Querés incluir íconos, estructuras <div>, o cualquier personalización compleja.

 

Métodos principales a sobrescribir

Cuando extends Walker_Nav_Menu, los métodos más usados para modificar el HTML son:

<?php
start_lvl()     // Inicio de un submenú (<ul>)
end_lvl()       // Fin de un submenú
start_el()      // Inicio de un ítem de menú (<li>)
end_el()        // Fin de un ítem de menú

 

Cómo crear un custom Walker para menús

Creamos un archivo llamado CustomMenuWalker.phpdentro de tu tema o en un plugin.

<?php

class CustomMenuWalker extends Walker_Nav_Menu {

    public function startLvl( &$output, $depth = 0, $args = [] ) {
        $indent  = str_repeat( "\t", $depth );
        $output .= "\n$indent<ul class=\"submenu-level-$depth\">\n";
    }

    public function endLvl( &$output, $depth = 0, $args = [] ) {
        $indent  = str_repeat( "\t", $depth );
        $output .= "$indent</ul>\n";
    }

    public function startEl( &$output, $item, $depth = 0, $args = [], $id = 0 ) {
        $indent      = ( $depth ) ? str_repeat( "\t", $depth ) : '';
        $classNames  = implode( ' ', $item->classes );
        $classAttr   = $classNames ? ' class="' . esc_attr( $classNames ) . '"' : '';
        $output     .= "$indent<li$classAttr>";

        $title      = apply_filters( 'the_title', $item->title, $item->ID );
        $attributes = ' href="' . esc_attr( $item->url ) . '"';

        $output .= '<a' . $attributes . '>';
        $output .= esc_html( $title );
        $output .= '</a>';
    }

    public function endEl( &$output, $item, $depth = 0, $args = [] ) {
        $output .= "</li>\n";
    }
}

 

Cómo usar el Walker en wp_nav_menu()

Dentro del archivo header.phpo donde imprimas el menú:

<?php
wp_nav_menu([
    'theme_location' => 'main_menu',
    'container'      => false,
    'menu_class'     => 'main-nav',
    'walker'         => new CustomMenuWalker()
]);
?>

 

¿Dónde registrar el menú?

En tu archivo functions.phpo en un plugin:

<?php
function registerThemeMenus() {
    register_nav_menus([
        'main_menu' => 'Menú principal'
    ]);
}
add_action( 'after_setup_theme', 'registerThemeMenus' );

 

Estructura de archivos sugerida

/wp-content/themes/tu-tema/
│
├── functions.php
├── header.php
├── inc/
│   └── CustomMenuWalker.php

 

Y en functions.php, incluir la clase:

<?php
require_once get_template_directory() . '/inc/CustomMenuWalker.php';

 

Ejemplo: Walker para Bootstrap 5

Si estás usando Bootstrap, necesitas que los submenús tengan la clase dropdown-menu, y los elementos liprincipales tengan dropdowncon data-bs-toggle.

Aquí un fragmento:

<?php
public function startEl( &$output, $item, $depth = 0, $args = [], $id = 0 ) {
    $hasChildren = in_array( 'menu-item-has-children', $item->classes );

    $classes   = $hasChildren ? 'dropdown' : '';
    $output   .= '<li class="nav-item ' . $classes . '">';

    $linkClass = $hasChildren ? 'nav-link dropdown-toggle' : 'nav-link';
    $attrs     = 'class="' . $linkClass . '"';
    $attrs    .= $hasChildren ? ' data-bs-toggle="dropdown" role="button" aria-expanded="false"' : '';
    $attrs    .= ' href="' . esc_url( $item->url ) . '"';

    $output .= '<a ' . $attrs . '>' . esc_html( $item->title ) . '</a>';
}

 

Consejos adicionales

  • Siempre valida la salida con esc_html() y esc_attr() para seguridad.
  • Usa depth para personalizar niveles específicos del menú.
  • Pruebalo con distintos temas y clases de CSS.

 

Crear un Walker personalizado en WordPress te da el control total sobre la salida de HTML en los menús. Es ideal cuando trabajás con frameworks CSS o necesitás una estructura completamente a medida.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to Top
0
Would love your thoughts, please comment.x
()
x