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()yesc_attr()para seguridad. - Usa
depthpara 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.




