Drupal: automatically add menu items when new nodes are added

て烟熏妆下的殇ゞ 提交于 2019-12-05 09:26:55

Yes.

I am sure there is a module do to something like that, but you could also create your own.

There are two ways you could go about it.

You could use hook_menu() to query for the items you want and return the correct menu structure. You would need to also make sure the menu cache is rebuilt on a node save using hook_nodeapi(). See henricks' comments below about why this is a bad idea

Alternitivly you could use hook_nodeapi() to add custom menu items with menu_link_save().

Edit

hook_menu should return an array of menu items, often these are pretty static however there is nothing wrong with these arrays being dynamically generated.

So you can query the node table to get a list of nodes you want, loop through these items and dynamically create an array which contains the correct menu items.

very roughly:

function example_menu() {
  $result = db_query('select * from node where ...'); // put in your own select items and where clause
  $menu = array();
  while ($row = db_fetch_object($result)) {
    $menu['my_path/' . $row->nid;] = array(
      // See hook menu docs for what to put here.
    );
  }
  return $menu;
}

You can do it with Rules on Drupal 7. This module: http://drupal.org/project/menu_rules adds some actions to rules. One of them is to create a menu item for a node. You select: Event: Create a node | Update a node Condition: Content type is "your content type" Action: Update a menu item for node (there is a checkbox to create the menu item if it doesnt exist)

There's also the Menu Position module that allows to put content under specific menu entries, depending on their content type, their language and taxonomy. It also has a small API to add other criteria.

You should take a look at the Auto Menu module - while the Drupal 6 version is still a dev release, it might cover your needs. If not, you can take it as an example of how to use menu_link_save() to create your own solution.

I would also go for a menu_link_save() call. Together with the Rules module, you can set up an action whenever a new node is saved, to create an appropriate menu item automatically.

You might want to have a look at the tutorial I wrote some time ago, which deals with programatically creating menu items using menu_link_save() and Rules: http://jan.tomka.name/blog/programmatically-creating-menu-items-drupal

Here is case where you can do this.... A node campaign creating menu item 'CAMPAIGN 001' when it is created. Using default_menu_link Now another content type, 'Sub Campaign' creating a node, using campaign as EntityRef so its menu item should be under the Menu Item of campaign created earlier.

function mymodule_node_insert($node) {
  if ($node->type == 'sub-campaign') {
    if (isset($node->field_reference_campaign['und'][0]['target_id'])) {
      $campaign_node_id = $node->field_photo_album_campaign['und'][0]['target_id'];
      $campaign_loaded = node_load($campaign_node_id);
      // Get menu link id for the campaign node.
      $campaign_node_id_mlid = custom_node_mlid($campaign_node_id);
      $campaign_loaded_title = strtolower(str_replace(' ', "-", $campaign_loaded->title));
      $campaign_loaded_title_link_path = 'campaign/' . $campaign_loaded_title . '/photo-albums';
      //I will query if it exist or not, if not then will create a sub menu item.
      $link_exist = db_query("SELECT * FROM {menu_links} WHERE link_path = :link_path", array(':link_path' => $campaign_loaded_title_link_path))->fetchField();
      dsm($link_exist);
      if (!$link_exist) {
        // Create menu item under campaign.
        custom_create_menu_item($campaign_loaded_title_link_path, 'photo-albums', $campaign_node_id_mlid);
        //watchdog('glue_site - Menu Item', 'Link Created');
      }
      else {
        //dsm('Link Exist.');
        watchdog('glue_site - Menu Item', 'Link Already Exist');
      }
    }
  }
  if ($node->type == 'campaign') {

  }
}

Then a custom function to create menu item

function custom_create_menu_item($campaign_loaded_title_link_path, $type, $plid) {
  switch ($type) {
    case 'photo-albums':
      $item = array(
        'link_path' => $campaign_loaded_title_link_path,
        // If changing the title here, change it in template.php as well.
        'link_title' => 'Sub Campaign',
        'menu_name' => 'menu-campaign-menu', // Menu machine name, for example: main-menu
        'weight' => 0,
        'plid' => $plid, // Parent menu item, 0 if menu item is on top level
        'module' => 'menu',
        'router_path' => 'campaign/%/sub-campaign',
        'customized' => '1',
      );
      menu_link_save($item);
      menu_cache_clear_all();
      watchdog('glue_site - Menu Item', 'Link Created');
      break;
  }
} 

To get the mlid of parent node. Campaign node...

function custom_node_mlid($nid) {
  // Require menu node module.
  $arr = menu_node_get_links($nid);
  $mlid = array_keys($arr);
  return $mlid[0];
}

For this you need menu_node

This is a simple problem that unfortunately the Drupal community has decided it wants to make complicated. Forget about all the hacky solutions with rules and hooks. There are two modules, depending on whether you're on Drupal 6 or Drupal 7, that solve the problem very elegantly. I advise against actually creating menu entries. Instead the two modules below dynamically render the nodes in the menu, so that your menu editor doesn't get filled with thousands of nodes. Then, for example, if you decide you want all the blog posts to be moved from [Our Blog] to [About Us]->[News] it's just a mater of changing one setting. No updating thousands of nodes.

D6 Menu Trails

D7 Menu Position

Lars Johnson

It looks like there's a Drupal module that does this: Auto Menu. Some more details about this module (from its project page):

The Auto Menu module automatically generates menu entries on node creation/edition. Parent menu item can be specified on a per content type basis.

This module acts when the menu section of a node is left empty only. So, users can still organize menus manually. Moreover, default setting for content types is to not create menu items automatically.

Menu Views is an interesting module for Drupal 7 to automatically generate menu links. It allows you to use the power of Views to create menu links and can be used out-of-the-box in combination with modules such as Superfish and Nice Menus.

(PS: my reputation is not high enough to provide more than two links, therefore I have marked the other modules bold instead of providing hyperlinks)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!