Hi

Is there any way to get Drupal to check the 'expanded' box for a menu item when you create it by adding a peice of content. With my default setup of Drupal, when I add a new page the options I have for a menu item for the page are the 'menu link title' the 'parent item' and the 'weight'. So when I create a new page I can create a new menu item on the fly, but I have no way of making it 'expanded'.

This means that I then have to go to /admin/build/menu-customize/primary-links for example and check the 'expanded' box if I want the menu to show up in a suckerfish menu.

This extra step is not too complicated for me, but I am not going to be managing the content on the site and I can see my client finding it odd that this extra step has to be taken to get the menu to show up. I can also see my client forgetting to do it in some months time and then wondering why his menu item is not appearing.

Is there any way to make menu items expanded by default, or to add the 'expanded' option to the 'create content' page

Thanks for any answers

Phil

Comments

stevenc’s picture

I think your best bet is to alter the menu link as it's being created.

http://api.drupal.org/api/function/hook_menu_link_alter/6

---------------------------------
Steven Wright

Slalom

philingle’s picture

Hi Steve
Thanks for the link, I am not really techie enough to know what to do with it though. Do I just stick the code

<?php
function hook_menu_link_alter(&$item, $menu) {
  // Example 1 - make all new admin links hidden (a.k.a disabled).
  if (strpos($item['link_path'], 'admin') === 0 && empty($item['mlid'])) {
    $item['hidden'] = 1;
  }
  // Example 2  - flag a link to be altered by hook_translated_menu_link_alter()
  if ($item['link_path'] == 'devel/cache/clear') {
    $item['options']['alter'] = TRUE;
  }
}
?>

into my page.tpl.php somewhere?

philingle’s picture

Hi

I am still not sure how to utilise the info on the page you have given me. I am not a coder so it is all a bit alien to me. Any help would be appreciated

Nathan.Ray-1’s picture

Hi Phil,

I've stumbled upon your post with the same problem and i was unable to find a fix anywhere online. After taking a look at the menu.module file (sitewww/modules/menu/*)
I've have found you simply need to change the line:

339 // Set default values.
340 $node->menu = $item + array('link_title' => '', 'mlid' => 0, 'plid' => 0, 'menu_name' => $menu_name, 'weight' => 0, 'options' => array(), 'module' => 'menu', 'expanded' => 0, 'hidden' => 0, 'has_children' => 0, 'customized' => 0);

to

339 // Set default values.
340 $node->menu = $item + array('link_title' => '', 'mlid' => 0, 'plid' => 0, 'menu_name' => $menu_name, 'weight' => 0, 'options' => array(), 'module' => 'menu', 'expanded' => 1, 'hidden' => 0, 'has_children' => 0, 'customized' => 0);

Hope this helps,

Nathan

natparnell’s picture

Nathan, you're a genius. Many thanks. This saved me hours of looking.

remydenton’s picture

The better way of doing this is to create a custom module, which is what stevenc was suggesting (if you haven't done this before, read up here for D6 or here for D7).

Here is some code you can put in your D7 module to expand menu items for all new nodes. Make sure you replace HOOK with the name of your module:

function HOOK_node_insert($node){
  if ($node->menu['enabled'] == 1){
    ($node->menu['expanded'] = 1);
  }
}

For those on D6, here is a version that should work for you (haven't tested since I'm working on a D7 site):

function HOOK_nodeapi(&$node, $op) {
  switch ($op) {
    case 'insert':
      if ($node->menu['enabled'] == 1){
        ($node->menu['expanded'] = 1);
      }
      break;
  }
}
Dowd’s picture

Thanks for this, it may not be the proper way of doing it, but has saved a lot of coding/searching around for an answer!

mheinke’s picture

node insert definitely isnt the right way...

HansKuiters’s picture

HOOK_node_insert didn't do the trick for me. I used:

function HOOK_menu_link_alter(&$item){
  if ($item['enabled'] == 1){
    ($item['expanded'] = 1);
  }
}
mheinke’s picture

This is still a valid solution

jwilson3’s picture

There may be a hand ful of ways to do this for D8, but this is working for us:

/**
 * Implements hook_menu_link_content_presave().
 */
function mymodule_menu_link_content_presave(EntityInterface $entity) {
  if ($entity->menu_name->value == 'menumachinename') {
    $entity->expanded = 1;
  }
}

You could probably also do something more general for all menu items in all menus, similar to other responses for d7 and d6. (Note this is untested)

/**
 * Implements hook_menu_link_content_presave().
 */
function mymodule_menu_link_content_presave(EntityInterface $entity) {
  if ($entity->enabled == 1) {
    $entity->expanded = 1;
  }
}
Jeff Burnz’s picture

Thanks jwilson3, this is bugbear for me also, it's such a bummer the expanded toggle was removed from the menu overview page, one of the worst "UX improvements" in D7 and again made it into D8.

drupaleye’s picture

Got this error when trying to make a new page with a menu item after making a custom module i Drupal 8:

The website encountered an unexpected error. Please try again later.
Recoverable fatal error: Argument 1 passed to menu_auto_expand_menu_link_content_presave() must be an instance of EntityInterface, instance of Drupal\menu_link_content\Entity\MenuLinkContent given in menu_auto_expand_menu_link_content_presave() (line 6 of modules/menu_auto_expand/menu_auto_expand.module).

I made a folder in modules called: menu_auto_expand
file: menu_auto_expand.info.yml

name: Menu Auto Expand
type: module
description: This is a custom module  to make all menu items in main menu expanded as default
package: Custom
core: 8.x

file: menu_auto_expand.module

<?php

 /**
 * Implements hook_menu_link_content_presave().
 */
function menu_auto_expand_menu_link_content_presave(EntityInterface $entity) {
  if ($entity->menu_name->value == 'main') {
    $entity->expanded = 1;
  }
}

(installed the module)
What did I do wrong? Did I forget some part of the module or does the hook no longer work in D8?

gregbeat’s picture

Try this for Drupal 8

<?php

 /**
 * Implements hook_ENTITY_TYPE_presave().
 */
function mymodule_menu_link_content_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->menu_name->value == 'main') {
    $entity->expanded = 1;
  }
}
shelane’s picture

In a custom module, I included this:

/**
 * Implements hook_menu_link_alter().
 */
function mymodule_menu_link_alter(&$item){
  $item['expanded'] = 1;
}

This is tested and working. This hook cannot be used in a theme template.php file.

Of course that is extremely aggressive. You might consider doing something like:

/**
 * Implements hook_menu_link_alter().
 */
function mymodule_menu_link_alter(&$item){
  if ($item['plid'] == 0 && in_array($item['menu_name'], array('main-menu', 'user-menu'))) {
    $item['expanded'] = 1;
  }
}

That would limit it to the menu(s) you'd want (replace with correct menu names) and only parent items.