I need to clone a menu. Is there any way to do this?

Comments

NancyDru’s picture

In admin >> site building >> menus there is a link to "Add a New Menu." That will create a new menu and a block that needs to be enabled. You may then locate that menu in the menus list and "Add a menu item" to it.

I'm not sure why you'd want to create a duplicate menu, but you could do it.

Nancy W.
Drupal Cookbook (for New Drupallers)
Adding Hidden Design or How To notes in your database

jraper@groups.drupal.org’s picture

Here's the drill - I have a large multi-level left-side menu with many entries. Client wants to try out a series of variants of the Menu with some downstream menu-levels moved to a right-side menu block that is exposed based on path. Rather than duplicate the menu variants by hand (with various degrees of upper-levels removed), I would like to automatically "Clone" the existing full menu x times and then simply remove the entries that I do not need in the new clones. There are FAR fewer upper-level entries to remove than there would be lower-level entries to create.

...And - I don't want to lose the original full menu in case the Client decides that he likes the current setup best.

NancyDru’s picture

Go to http://streamlinefencenc.com and go to the "Products" page and see if that would solution take care of you. The block can be moved anywhere.

Nancy W.
Drupal Cookbook (for New Drupallers)
Adding Hidden Design or How To notes in your database

jraper@groups.drupal.org’s picture

Is that the link you intended? That takes me to a page for the purchase of fencing. If that IS the correct link, please help me a little here - what am I looking for?

NancyDru’s picture

It's a site I developed. On the Products page you will see a secondary menu in the upper left of the content section.

How to get it:
Go to "Admin >> site building >> menus >> settings" and change the "Menu containing primary links" and "Menu containing secondary links" to Navigation.

Now go to "Admin >> site building >> blocks" and create a block (whatever block description you want to give it, e.g. "secondary menu") that is php format and contains:

<?php
$localNav = _menu_get_active_trail();
if($localNav[1]) {
    print theme_menu_tree($localNav[1]);
}
?>

That will create that secondary menu in a block if, and only if, there are secondary links under the menu item.

Nancy W.
Drupal Cookbook (for New Drupallers)
Adding Hidden Design or How To notes in your database

jraper@groups.drupal.org’s picture

Let's say that left-side menu on your site had 10 sub-levels and a total of 5,000 individual menu entries that linked to the pages in (what is for us) a medium-sided site. Now your client wants evaluate the site with that menu divided up into a main left-side menu (say of the first three levels) and place the remaining seven levels in a new menu that would reside on the right-hand side of the page. Each third-level entry in the left-side menu will link to a distinct (potentially) seven-level menu in the right-hand side of the page. There will be HUNDREDS of right-hand menus, one for each third-level entry in the left-hand menu.

Now, generating these HUNDREDS of right-hand menus will require duplicating the appropriate segment of the original 10-level, 5,000 entry menu. So - is there a command you can type (or a module that you can install and utilize) that will duplicate the existing menu and make it available for editing in the Drupal menu admin page so that you can simply delete those levels/entries that you don't need for each of the "new" right-hand menus.

NancyDru’s picture

But it looks like it's not happening. The only thing I can suggest is looking at the menu table and see if there's a way to duplicate sections of it or to move pieces in bulk (by changing the parent id - pid).

Nancy W.
Drupal Cookbook (for New Drupallers)
Adding Hidden Design or How To notes in your database

waltWright’s picture

I followed your directions above for showing the secondary menu in the side column and it works very well for me, except the secondary menu is also showing in the header (Garland Theme). So now I've got my Nav primary menu showing horizontal in the header top and the secondary menu showing horizonal in the header bottom and also vertical in the side column. Ideas?

Thanks,

Walt

NancyDru’s picture

Go into your style sheet and mark the secondaries as display:none.

Nancy W.
Drupal Cookbook (for New Drupallers)
Adding Hidden Design or How To notes in your database

waltWright’s picture

Thanks for the code and css modification.

jkopel’s picture

Using CSS to hide the secondary links works fine, but perhaps there is a better way.
If they are hidden they still have to load, and the will add extra size to the page.
If you edit the page template in your theme you can make them go away without incuring the extra overhead of loading them.
Look for a section like:

 <?php if ($secondary_links): ?>
            <div id="secondary" class="clear-block">
              <?php print theme('menu_links', $secondary_links); ?>
            </div>
          <?php endif; ?>

If you simply delete that whole group, or just comment out the print statement with // then you will never see the secondary menus again.

waltWright’s picture

Thanks. I'll try that.

One thing I've noticed is that the menu title is static text. You can override it with new text when configuring a block, but it is still static.

Can you think of a way that I can use Nancy's php snippet to show the secondary menu in the left column, but ALSO be able to change the menu title to indicate that the submenu is the child of the primary menu item?

For example, if my top tier menu is Home, Welcome, and Organization;
and if Welcome includes Contact, Location, and Map;
then it would be nice if when I click on Welcome, the sub-menu shows in the left-hand column (already working), except that the title of that menu changes to "Welcome"

Currently, I just have it hard-coded to "Menu"

NancyDru’s picture

<?php
  $localNav = _menu_get_active_trail();
  $mid = 0;
  foreach ($localNav as $key => $value) {
    if ($value > 0) { $mid = $value; }
  }
  $menu = menu_get_item($mid);
  echo '<h2 class="title">'. $menu['title'] .'</h2>';
  if($localNav[1]) {
      print theme_menu_tree($localNav[1]);
  }
?>

However, I prefer no title; I use the techniques shown in Showing which Menu item you're on and Highlight the expandable section of a menu.

Nancy W.
Drupal Cookbook (for New Drupallers)
Adding Hidden Design or How To notes in your database

waltWright’s picture

Thanks for the above php code that ; it works really well except for one circumstance that I am not able to troubleshoot.

- I created the secondary menu block and placed it into the left column.
- Within the default Navigation menu, there is menu item called "Content" that is disabled by default.

Anytime I bring up a node that references the front page (or by default, "/node"), I would expect no menu item title to show up in the left column. Instead, the title "Content" shows up, even though that item in the Navigation menu is disabled. I'm quite sure that it is that menu item, because I have enabled it, then changed the name, then disabled it. It still shows up in the block.

After exploring the sql backend, I discovered that the unchangeable path for "Content" web item is "node" - meaning the front page, which partly explains why the title tries to show up in the secondary menu block. To be sure that the "Create Content" child item wasn't messing something up, I reassigned the parent of "Create Content" so that it was not the child to "Content"

...but it didn't matter. With "Create Content" menu item reassigned to a different parent menu item and with "Content" disabled, the "Content" menu title still shows up in the secondary menu block in the left column.

Ideas? I have an idea to add some code to the php that would ignore any menu item at the root level, if I had time to figure it out (but probably don't...) Thanks.

waltWright’s picture

I found a very good workaround for the problem that I was having that eliminated the kruft from my working menu.

  • I created a new menu called "Primary Menu"
  • I reassigned each desirable menu item from parent "Navigation" to parent "Primary Menu"
  • I reset the "Menu containing primary links" (admin/build/menu/settings) from "Navigation" to "Primary"
  • I reset the "Menu containing secondary links" (admin/build/menu/settings) from "Navigation" to "Primary"

    This gave me absolute control over what appears in the menu. The system assigned root items (e.g. My Blogs) can be knowingly placed in the menu structure, rather than forced into my menu without control.

    By the way, I think I understand what the original post (by jdraper) meant when he wanted to clone a menu: sometimes it is nice to start with a template for a custom menu. Although you can steal items and branches from one menu by reassigning the parent (e.g. reassigning the parent from "Navigation" to "Primary Menu" like I did above), it would have been more reassuring to maintain the integrity of the original Navigation menu for purposes of maintaining an easy way of returning to default settings.

    Another great use of a cloned menu is when you need to assign the very similar menu blocks to different pages of your website. You can start off with a cloned menu and modify it slightly to suit.

  • NancyDru’s picture

    What I would try is the standard "hide the create content from anonymous users" solution (http://drupal.org/node/120622). I suspect this will resolve it as I don't see this problem on my sites with the above code.

    Nancy W.
    Drupal Cookbook (for New Drupallers)
    Adding Hidden Design or How To notes in your database

    Jacobtv’s picture

    Will this also work with tertiary menus?

    stevryn’s picture

    I have a site which uses a theme that has "suckerfish menus". For those to work properly you must have the menu expanded. Recently a request was made to use a couple of other themes that do not use "suckerfish" menus. they want to give people "choices" of how the site looks. In this case the menus should be collapsed. The only way I saw around it was to create duplicate menus for each theme. This is fine for a small navigation, but when you have ALOT...its really painful!!!

    It would be nice to be able to clone menus, like you can blocks and nodes!

    NancyDru’s picture

    Can't you change your page.tpl.php template to do this?

    stevryn’s picture

    Can you give me a bit of guidance on how to do that? I am not much of a developer, just learning as I go!

    NancyDru’s picture

    raimondious’s picture

    For anyone searching, I think the answer to the original question is no, not within the basic interface. Would love if someone answered with a module that clones.

    ramper’s picture

    I really think being able to clone a menu would add great versatility to a site. After searching all over, it seems only a module can do that - so here's a request for anyone listening and capable of writing a module... :)
    While there can be any number of reasons for wanting to clone an existing menu, here's mine:
    I just need different menu items for various user roles. I really liked the Menu per role as it was just perfect for what I need - but unfortunately the original module author decided not to port it to D6.
    So the only way for me is to make a new menu, add the menu items (most of them are common for all the menus, but there are some items which are for specific roles) one by one, then configure the block for each role! Being able to clone a "master" menu and just disabling certain menu items would be great - if only I knew how to write a module!

    NancyDru’s picture

    Specifically, are you asking for a module that duplicates Menu Per Role for Drupal 6? It would seem to me that modifying the access callback function would be able to do that rather easily. I don't remember what all functionality MPR had besides that; I ditched the module when they started rolling out multiple D5 releases.

    As for writing modules, if you already know PHP, you're 80% of the way there. There is a contrib module that will build the skeleton for you. Most modules are relatively straight-forward. Unfortunately what you want here may be a bit more advanced than a first-timer might want to tackle.

    I have some other pressing commitments at the moment, but keep bugging me and I'll be thinking about this.

    NancyDru’s picture

    There is a D6 version now.

    rrobert.ah’s picture

    If you are familiar with SQL, then i'll suggest to copy the entry in the database table, it's dru_menu_links, change the menu specified in the menu items.

    NancyDru’s picture

    First "dru_' is your database prefix. If I didn't know that, I would never find that table in any of my databases.

    Menu_links rows are only one menu item each. If you want a whole menu, then you have to copy every row for that menu. Certainly that would make Menu Per Role functionality a bit more difficult to accomplish (think about menu updates), but possibly faster than the access callback technique.