
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_Menu
para construir el HTML de los <ul>
, <li>
, submenús, etc.
Cuando necesitas cambiar esa estructura, puedes extender Walker_Nav_Menu
y 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.php
dentro 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.php
o 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.php
o 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 li
principales tengan dropdown
con 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()
yesc_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.