No menu link attributes are added to the markup, such as target. When added to core Drupal menus manually or through a module changes are not incorporated into YUI Menu.

Add theme_ override functions and split up markup function and l() calls so alterations can be quickly changed in template.php

Add attributes array to markup (possibly detect for Menu Attributes module, might help remove forum issues for people who don't know how to send the attributes array properly)

Comments

bakyildiz’s picture

I am not a perfect Drupal module developer. Can you guide me to do the changes?

  1. Add theme_ override functions"
  2. split up markup function
  3. l() calls
dfaulkner’s picture

I'm trying to hack on this a bit, since it's suddenly become important to me. ;) I'm trying to add in support for menu_attributes, but without much luck so far. I'm new to module hacking so advice and (gentle!) criticism would be welcomed!

so far, my attention has focused on get_html_menu_script() and compose_markap_body(), where those two functions at li's to $output. From get_html_menu_script:

$output .= '<li  class="'.(("tns" == variable_get('yuimenu_type','tns') || "tnm"==variable_get('yuimenu_type','tns'))? "yuimenubaritem":"yuimenuitem").'">'. l($menu_item['link']['title'], $menu_item['link']['href'],array('attributes' => array('class'=>(("tns" == variable_get('yuimenu_type','tns') || "tnm"==variable_get('yuimenu_type','tns'))? "yuimenubaritemlabel":"yuimenuitemlabel"))))."</li>";

What I tried to do was to wrap this in a test for $menu_item['link']['options']['attributes'] and merge in the attributes array if present:

      if (isset($menu_item['link']['options']['attributes']) && is_array($menu_item['link']['options']['attributes'])) {
        $output .= '<li  class="'.(("tns" == variable_get('yuimenu_type','tns') || "tnm"==variable_get('yuimenu_type','tns'))? "yuimenubaritem":"yuimenuitem").'">'. l($menu_item['link']['title'], $menu_item['link']['href'],array('attributes' => array_merge($menu_item['link']['options']['attributes'],array('class'=>(("tns" == variable_get('yuimenu_type','tns') || "tnm"==variable_get('yuimenu_type','tns'))? "yuimenubaritemlabel":"yuimenuitemlabel")))))."</li>";
      }
      else {
        $output .= '<li  class="'.(("tns" == variable_get('yuimenu_type','tns') || "tnm"==variable_get('yuimenu_type','tns'))? "yuimenubaritem":"yuimenuitem").'">'. l($menu_item['link']['title'], $menu_item['link']['href'],array('attributes' => array('class'=>(("tns" == variable_get('yuimenu_type','tns') || "tnm"==variable_get('yuimenu_type','tns'))? "yuimenubaritemlabel":"yuimenuitemlabel"))))."</li>";
      }

That doesn't seem to do the trick though. I am totally unsure if I'm going about this the right way. Feel free to slap my wrist and suggest an alternate route.

Update: This does work for the top-level menu items, but the attributes on child menu items do not appear. Am I misunderstanding how the children are built?

dfaulkner’s picture

So, apparently I did misunderstand how children are built. The yuimenu_init invokes either get_yui_top_script() [which I'm using] or get_yui_top_markup() or get_yui_left_script(). I'll just talk about get_yui_top_script() for now.

get_yui_top_script() produces a little bit of JSON that describes the submenus. The YUI libraries pick that up and use it to render the menus.

I tried adding a bit of code to build a JSON array from the attributes list, but so far all it's done is keep the submenus from being rendered. I'm sure I'm on the right track now, but I haven't figured out the YUI menu sufficiently to know how to represent the attributes in JSON. some help with this bit would be nice.

In any case, here's my "adjustment" (can't call it a patch yet) for get_yui_top_script(). The entire function is listed for completeness, but just search for "$attributes" and you'll see the changes made. create_inner_menu_attributes() is my helper function to build the JSON.

Suggestions, criticism, etc, very welcome at this point.

function create_inner_menu_attributes($menu_item) {
	$j=1;
	$attributes=$menu_item['link']['options']['attributes'];
	$output .= "attributes [ ";
	foreach($attributes as $attr => $value) {
		$output .= "{ ". $attr .": \"".$value."\" }".($j++<count($attributes)?',':'');
	}
	$output .= " ]";
	return $output;
}

function create_inner_menu($menu_id) {
  $menu = load_menu($menu_id);
  $j=1; 
  foreach ($menu as $menu_item) {
    $mlid = $menu_item['link']['mlid'];
    if ($menu_item['link']['hidden'] == 0) {
	  $attributes=create_inner_menu_attributes($menu_item);
      if ($menu_item['link']['has_children'] > 0) {
        $output .= "{ text: \"".rep_char($menu_item['link']['title'])."\",url: \"".url(rep_char($menu_item['link']['href']))."\", ". $attributes .", submenu: { id: \"".url(rep_char($menu_item['link']['title']))."\", itemdata: [\n";
        $output .= create_inner_menu($menu_item['link']['menu_name'].':'.$mlid);
        $output .= "]}}".($j++<count($menu)?',':'');
      }
      else {
          $output .= "{ text: \"".rep_char($menu_item['link']['title'])."\", url: \"".url(rep_char($menu_item['link']['href']))."\", ". $attributes ." }".($j++<count($menu)?',':'')."\n";
      }
    }
  }
  return $output;
}

relayer3000’s picture

Hi everyone, I used this code to solve this issue, I hope it will work well for you.

I'm not a good php programmer. If you have any suggestion please post your comments.

 function create_inner_menu($menu_id) {
  $menu = load_menu($menu_id);
  $j=1;
  foreach ($menu as $menu_item) {
    $mlid = $menu_item['link']['mlid'];

    if ($menu_item['link']['hidden'] == 0) {

    if($menu_item['link']['external']==1){
           $attributes = "target: '_blank' ";}
           else{$attributes="target: ''";}

      if ($menu_item['link']['has_children'] > 0) {
        $output .= "{ text: \"".rep_char($menu_item['link']['title'])."\",url: \"".url(rep_char($menu_item['link']['href']))."\", ". $attributes .", submenu: { id: \"".url(rep_char($menu_item['link']['title']))."\", itemdata: [\n";
        $output .= create_inner_menu($menu_item['link']['menu_name'].':'.$mlid);
        $output .= "]}}".($j++<count($menu)?',':'');
      }
      else {
          $output .= "{ text: \"".rep_char($menu_item['link']['title'])."\", url: \"".url(rep_char($menu_item['link']['href']))."\", ". $attributes ." }".($j++<count($menu)?',':'')."\n";
      }
    }
  }
  return $output;
}
mstrelan’s picture

subscribe