Drupal 7, when creating a basic page I want the users to be able to add a menu item as a sub item only under local menu items, not under items that link off site. How can I restrict the list of menu Parent item to only ones that point to node/# and not display any that are absolute urls?
1 Answer
What I ended up doing was using TEMPLATE_form_node_alter() and creating my own duplicated versions of menu_parent_options(), _menu_get_options() and _menu_parents_recurse() so I could call them instead of the default drupal functions to build my menu. And in _menu_parents_recurse() you can access the link information like link_path, and just set the menu links I wanted to exclude.
function _my_menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, $depth_limit) {
foreach ($tree as $data) {
if ($data['link']['depth'] > $depth_limit) {
// Don't iterate through any links on this level.
break;
}
// Exclude menus that are absolute/external
if (stripos($data['link']['link_path'], 'http') !== false) {
$data['link']['mlid'] = $exclude;
}
if ($data['link']['mlid'] != $exclude && $data['link']['hidden'] >= 0) {
$title = $indent . ' ' . truncate_utf8($data['link']['title'], 30, TRUE, FALSE);
if ($data['link']['hidden']) {
$title .= ' (' . t('disabled') . ')';
}
$options[$menu_name . ':' . $data['link']['mlid']] = $title;
if ($data['below']) {
_my_menu_parents_recurse($data['below'], $menu_name, $indent . '--', $options, $exclude, $depth_limit);
}
}
}
}
I was hoping for a more "correct" method (hook_preprocess_link maybe, but it doesn't exist in D7, only 6 and 8) but this one works.