Hi,

I would like to remove the "navigation" menu as a possible parent menu. I.e., when you select the "menu" options from "add/edit page" none of the navigation or submenu's should show up. The people who're actually going to add pages etc. will not want this and it will only confuse them.

Any advice is much appreciated.

Klaas

Comments

klaasvanschelven’s picture

I've adapted the following drupal code like so:

modules/menu/menu.module

contains a method menu_parent_options()

I've put a hack in that checks for the menu_title not being "navigation".

How should I go about moving this into a separate module?

marcvangend’s picture

Your questions made me wonder: shouldn't it be part of the Drupal core menu module to set different permissions for each menu? I think it would be a great feature, I think I will add a feature request in the issue tracker.
There is a module which already does something like that: http://drupal.org/project/menu_per_role. However, it has no stable version yet and it requires hacking in core files.

[update] The issue is here: http://drupal.org/node/241972. [/update]

1websitedesigner’s picture

Hi.

The menu settings per content type module removes the Admin menu very easily, plus offers other useful menu options, I'd highly recommend it! (Works with Drupal 5 and Drupal 6)

http://drupal.org/project/ctm

Martin

dean.p’s picture

Thanks Martin, just what I was after and "Menu Settings per Content Type" has just made my mandatory module list ;)

rjl’s picture

Have you checked out the Forms API? http://drupal.org/node/37775

Because, you should be able to do this with a simple module that implements hook_form_alter()
You want to change the array used with $form['menu']['parent']['#options'] to show only the menus you want.

You could also hack into the menu.module itself - see this code from menu_form_alter().

    // Generate a list of possible parents (not including this item or descendants).
    $options = menu_parent_options(menu_get_menus(), $item);
    $default = $item['menu_name'] .':'. $item['plid'];
    if (!isset($options[$default])) {
      $default = 'navigation:0';
    }
    $form['menu']['parent'] = array(
      '#type' => 'select',
      '#title' => t('Parent item'),
      '#default_value' => $default,
      '#options' => $options,
      '#description' => t('The maximum depth for an item and all its children is fixed at !maxdepth.  Some menu items may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)),
      '#attributes' => array('class' => 'menu-title-select'),
    );

Hope that is a little helpful.

klaasvanschelven’s picture

Thanks - that's really helpful. Will be my first module so it may take a while before I'll get to it... but will post results.

btw, I also stumbled across the following comment in the code:

  // hook_form_alter is too late in itself because all the possible parents are
  // retrieved here, unless menu_override_parent_selector is set to TRUE.

So I'll have to set that variable somehow...

klaasvanschelven’s picture

// $Id$

function parentmenufilter_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['menu']['parent']['#options'])) {
    $options = array();

    $original = $form['menu']['parent']['#options'];
    foreach ($original as $id => $display) {
      if ((strpos($id, "navigation") !== 0) && (strpos($id, "secondary-links") !==0 ) && (strpos($id, "secondary-links") !== 0))
        $options[$id] = $display;
    }

    $form['menu']['parent']['#options'] = $options;
  }


}

A few more lines but the original but at least it will allow for cleaner upgrades...

Anonymous’s picture

Hi,
I need exactly what you describe, too. But I'm an absolute newbie with drupal. What do I do with your codelines? Where do I add those, or are you still going to write a module for that?
Thanks!

cu,
Frank

baronmunchowsen’s picture

Hi - looks very useful. Where does this code go? template.php? I'm having no luck with it.

Many thanks,

brett1’s picture

I think you place the code in the modules/menu/menu.admin.inc
i am not sure how?

i copied the entire code above and placed it at the bottom of the menu code.
it did not work -
i think that is because the menu module had ended and the code has to be embedded.
hmm actually no - i think i did it right ????

i obviously need help

there was away in the version 5.x
where the parent item did not show the navigation

Anonymous’s picture

Just create a little module for this, it's very easy!

1. Create a subdir sites/all/modules/parentmenufilter/ (or /usr/share/drupal/modules/ or wherever you would like have your module).

2. In this subdir create parentmenufilter.info with

name = Parentmenu filter
description = Remove entries from the parent menu listing
core = 6.x
package = "Other"

3. In the same subdir create a file parentmenufilter.module with the php-code from klaasvanschelven "my solution".

That's it. Go to drupals module page and enable the parentmenufilter module. Now when creating a page, navigation and secondary links won't show up as possible menu parents anymore (note there is a typo in the code referencing secondary-links twice. I guess it should be primary-links once).

philpro’s picture

This was exactly what I needed and it works like a charm for all of my drupal 6.x sites. I've added it to my module tool belt for use in the future. Thanks for the snippet.

baronmunchowsen’s picture

I have created a very simple module which allows you to hide the 'Navigation' menu from the 'Menu Settings' drop-down menu on the create/edit content forms.

I am not sure how to go about turning this into a proper module, and to be honest with you the code may not be bomb-proof at all. All I know is that it has been working for me and hopefully it will help someone else out too. Basically, use at your own risk, try it on a development site first before putting it on a live site and fingers crossed it works as well for you as it does for me.

If the following code is wrong or rubbish or massivly flawed please let me know! I am quite nervous to post this here! Can you tell?!

If you follow the instructions below, you should end up with a module which:

  • hides the 'Navigation' menu
  • allows you to select which of your remaining menus you want to show/hide
  • allows you to specify which of your roles you want to be able to see every menu, and which you want to restrict to your settings

Step (1)

Create a directory in your sites/all/modules directory called 'mhn'

Step (2)

Create a file within the mhn directory you've just created called mhn.info
Add this code to it:

name = "Menu Hide Navigation"
description = "A module that hides the navigation menu from the menu settings drop-down in the node create/edit form"

Step (3)

Create a file within the mhn directory called mhn.module
Add this code to it:

<?php

/***** mhn_perm *****/

function mhn_perm() {
	return array('display all menus', 'administer mhn');
} 

/***** mhn_menu *****/

function mhn_menu($may_cache) {
	$items = array();

	$items[] = array(
		'path' => 'admin/build/mhn',
		'title' => t('Menu Hide Navigation Settings'),
		'callback' => 'mhn_admin_settings',
		'access' => user_access('administer mhn'),
		'type' => MENU_NORMAL_ITEM,

	);

	return $items;
}

/***** mhn_admin_settings *****/

function mhn_admin_settings(){
	$content = '<p>'.l('Click here to specify user access control settings for this module', 'admin/user/access').' . You can select which roles will be affected by the following settings.</p><p>The Navigation Menu will always be hidden. You can pick and choose which of the remaining menus you <strong>wish to be visible</strong> on the node create/edit forms:</p>';

	$content .= drupal_get_form(mhn_admin_settings_form);

	return $content;
}

/***** mhn_admin_settings_form *****/
function mhn_admin_settings_form(){

	$result = db_query("SELECT * FROM {menu} WHERE pid < 1");
	
	while($data = db_fetch_object($result)){
		$form['mhn_menus_'.$data->mid] = array(
			'#type' => 'checkbox',
			'#title' => t($data->title),
			'#default_value' => variable_get('mhn_menus_'.$data->mid, 1),
			'#description' => t('Uncheck to hide menu'),
		);
	}

	return system_settings_form($form);
}

/***** mhn_form_alter *****/

function mhn_form_alter($form_id, &$form) {
	if ($form['#id'] == 'node-form' && !user_access('display all menus')) {
		$item = array();
		if ($form['nid']['#value'] > 0) {
			$item = db_fetch_array(db_query("SELECT * FROM {menu} WHERE path = 'node/%d'", $form['nid']['#value']));
			if (isset($form['#post']['menu']) && is_array($form['#post']['menu'])) {
	 			$item = !is_array($item) ? $form['#post']['menu'] : (($form['#post']['op'] == t('Preview')) ? array_merge($item, $form['#post']['menu']) : array_merge($form['#post']['menu'], $item));
			}
		}

		$mhn_arrays = array();
		$options = array();
	
		$result = db_query("SELECT * FROM {menu} WHERE pid < 1");
		while($data = db_fetch_object($result)){
			if(variable_get('mhn_menus_'.$data->mid, 0)){
				$mhn_arrays[] = menu_parent_options($item['mid'], variable_get('menu_parent_items', $data->mid));
			}
		}
	
		foreach($mhn_arrays as $mhn_array){
			while(list($id,$msg) = each($mhn_array)){ 
				$options[$id] = $msg; 
			}
		}
	
		$form['menu']['pid'] = array(
			'#type' => 'select',
			'#title' => t('Parent item'),
			'#default_value' => $item['pid'],
			'#options' => $options,
		);
	}
}

?>

Step (4)

Head to the module page, activate the 'mhn' module and then head to the admin > site building > Menu Hide Navigation Settings page to choose which menus to show/hide. Also head to the admin > users > access contol page to specify which roles you want to be able to see all of the menus.

Thanks!

tombh’s picture

I tried making the module as you suggested but couldn't seem to get it working, my feeling is that it was something to do with permissions -- I always find them complicated so maybe it was me.

So what I did was take the code from the form_alter function and put it into my own 'glue' module and hard coded the mids I wanted to be available depending on $form_id. And by jove! it works like a treat :) It's exactly what I need. With all possible menu items being displayed there were literally hundreds to choose from -- a usability nightmare!

So big thanks to you baronmunchowsen.

baronmunchowsen’s picture

Good stuff, glad it helped you somewhat. I should also say that if you're logged in as the primary user of the site (first account you create) then all the menus will appear, and whatever you setup to show/hide won't apply. I didn't get as far as to include this, because I'm using it to restrict access for people who have very limited permissions primarily.

Also, I've only tested this on drupal 5.

Also, please let me know what problems you encountered specifically and I'll see if I can help.

mnlund’s picture

Just a little trick...

Your variable_get functions doesn't have a default paramter, and unless you have saved the settings once, the alter function can't find any settings per pid. Therefore, to make this excellent module work out of the box, hit save settings on the settings page after you have enabled the module.

baronmunchowsen’s picture

Step 2.5

Create a file within the mhn directory you've just created called mhn.install
Add this code to it:

<?php
?>

Don't know whether having a .install file is mandatory, but I have one and didn't include it in my post above.

Can the default parameters be created in the .install file? I'll look into this and post back.

marcvangend’s picture

baronmunchowsen, did you every work some more on this code?
I could really use this functionality right now (using D5), but somehow I can't get it to work. No matter what i try, all menu items are still shown. it seems that the line

$mhn_arrays[] = menu_parent_options($item['mid'], variable_get('menu_parent_items', $data->mid));

outputs all menu items.

baronmunchowsen’s picture

Since the time that I wrote the post above I also discovered that you can control what menus are visible to the user on the node create/edit form via the admin > build > menu > settings page - removing the need in many cases for the use of this script. Perhaps look there first to see if that meets your requirements post back if not. Certainly in alot of simple cases this is all the functionality I really need.

Ta.

scip’s picture

Only seems to let you choose one or all - have two menus I want to allow editors to use, leaving the navigation one hidden.

marcvangend’s picture

Exactly, that's what I found too, the one-or-all option is too limited for my situation.

asiby’s picture

I need to do the same thing, but inside organic groups (OG).

There is a module called OG Menu that makes it possible for each Organic Group to have its own totally separate menu tree. So I am thinking about modifying the part of the OG module that allow the creation of pages inside the OG. The goal is to make sure that the possible parent items will be limited to the ones that are under a menu that is assigned to the OG itself. If more than one menu is assigned to the OG, then I guess that I will display all of their items as possible parent item.

At first it will be hard coded. Then if the concept works, I will try to see if I can create a separate module that will add this functionnality (with hooks and stuff) without messing with the original OG module.

Does it make sense? Ideas? Advices?

Cheers

Live long ... and prosper!

mobilehippie’s picture

asiby, did you ever find a solution for presenting only available Organic Group Menus for a node? I have a similar issue I'm trying to solve. We could code a custom module, but if you already found a solution, I'd love to hear it.