personalizar el marcado de un menú existente.

A veces necesitamos que el marcado de un menú concreto se pueda personalizar. Seguramente este no es el código más óptimo y se puede mejorar. Pero por ahora es como he resuelto yo la necesidad para realizar un marcado diferente del que trae los menús de Drupal.

Lo primero es sacar el nombre de todos los menús que tenemos en nuestro sitio, para ello tenemos la función <?php $name menu_get_names(); ?>, que nos pinta un array con el nombre de todos los menús disponibles.

Para pintar un nuevo marcado crearemos un nueblo bloque y usaremos hook_block_view para generar el nuevo marcado.

<?php

    case 'responsive_mainmenu':
     
$block['subject'] = '<none>'; // t('responsive main menu');
     
$block['content'] = _mainmenu_responsive();
    break;

?>

Cuando sabemos el nombre del menú y la profundidad que queremos consigue usamos el siguiente código para generar parte del html personalizado.

<?php
/**
 * @name  _mainmenu_responsive
 * @return a string with all the li elements
 */

function _mainmenu_responsive(){

  $tree = menu_tree_all_data($name, $deep);
 
//si usamos i18n tendremos que usar a su vez la función i18n_menu_localize_tree
 
Global $language
 
$items = i18n_menu_localize_tree($tree, $language->language);
 
 
$output = '';
  foreach (
$items as $key => $item) {

    $title $item['link']['link_title'];

    $classdropdwon = (count($item['below']) != 0 ) ? 'nav_item_with_dropdown' : '' ;

    $output .= '<li class="nav_item  '. $classdropdwon . '">';
   
$output .= l(     
     
$title,     
     
$item['link']['link_path'],      
      array(
       
'attributes' => array(
         
'class' => array('nav_item_link nav_item_section'), 
         
'data-back-ref' => 'Ayuda' ),
       
'html' => TRUE)
        );
      if(
count($item['below']) != 0 ){

        $output .= _mainmenubelow($item['below']);
      }

    $output .= '</li>';
    }

  return theme('mainmenu_responsive', array('item' =>$output));
}
?>

Mediante hook_theme definimos la función que usaremos para pintar el tpl y que es usada en la función

<?php
function example_responsivemenu_theme() {

  $items = array(
   
'mainmenu_responsive' => array(
     
'variables' => array('items'=>NULL),
     
'template' => 'responsive-mainmenu'
   
),

?>

Ya solo queda definir el tpl para pintar todo lo que se ha generado.

<?php
<nav role="navigation">
    <
ul data-morph="nav" data-morph-stack="1" data-morph-devices="mobile">
      <?
php print $item; ?>

    </ul>
</nav>
?>

Nota importante, no es el código más limpio, por ejemplo en la función _mainmenu_responsive() se podría haber almacenado la información en un array en vez de un string para pasarlo al tpl, y se debería haber usado también drupal_render_array para generar todo el marcado y html.

Un saludo

Oskar