special_menu_items.module 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. /**
  3. * @file
  4. * Module to enable placeholder or separator menu items.Placeholder is a menu item which is
  5. * actually not a link. Something like this is useful with drop down menus where we want to
  6. * have a parent link which is actually not linking to a page but which is just acting as a
  7. * parent and grouping some children below it.
  8. * A separator menu item is something like "-------" which is also not linking anywhere but
  9. * merely a mean to structure menus.
  10. *
  11. * Written by Tamir Al Zoubi and Karim Djelid - Servit Open Source Solutions - www.servit.ch
  12. */
  13. /**
  14. *Implementation of hook_menu()
  15. */
  16. function special_menu_items_menu() {
  17. $items['<nolink>'] = array(
  18. 'page callback' => 'drupal_not_found',
  19. 'access callback' => TRUE,
  20. 'type' => MENU_CALLBACK,
  21. );
  22. $items['<separator>'] = array(
  23. 'page callback' => 'drupal_not_found',
  24. 'access callback' => TRUE,
  25. 'type' => MENU_CALLBACK,
  26. );
  27. $items['admin/config/system/special_menu_items'] = array(
  28. 'title' => 'Special Menu Items',
  29. 'description' => 'Configure Special Menu Items.',
  30. 'page callback' => 'drupal_get_form',
  31. 'page arguments' => array('special_menu_items_admin_settings_form'),
  32. 'access arguments' => array('administer site configuration'),
  33. 'type' => MENU_NORMAL_ITEM,
  34. );
  35. return $items;
  36. }
  37. /**
  38. * Override of theme_link()
  39. * This function will render link if it is "nolink" or "separator". Otherwise it will call originally
  40. * overwritten menu_item_link function.
  41. */
  42. function special_menu_items_link(array $variables) {
  43. if (in_array($variables['path'], array('<nolink>', '<separator>'))) {
  44. switch ($variables['path']) {
  45. case '<nolink>':
  46. $tag = variable_get('special_menu_items_nolink_tag', '<span>');
  47. $title = $variables['options']['html'] ? $variables['text'] : check_plain($variables['text']);
  48. $variables['options']['attributes']['class'][] = 'nolink';
  49. break;
  50. case '<separator>':
  51. $tag = variable_get('special_menu_items_separator_tag', '<span>');
  52. $title = variable_get('special_menu_items_separator_value', '<hr>');
  53. $variables['options']['attributes']['class'][] = 'separator';
  54. break;
  55. }
  56. $attributes = drupal_attributes($variables['options']['attributes']);
  57. if ($tag != '<a>') {
  58. // <a> tags can have these but a <span> cannot, so we remove them.
  59. foreach (array('accesskey', 'target', 'rel', 'name') as $attribute) {
  60. $attributes = preg_replace("/ $attribute=\".*\"/i", "", $attributes);
  61. }
  62. }
  63. return special_menu_items_render_menu_item($tag, $title, $attributes);
  64. }
  65. // Call the original theme function for normal menu link.
  66. return theme('special_menu_items_link_default', $variables);
  67. }
  68. /**
  69. * Returns menu item rendered.
  70. */
  71. function special_menu_items_render_menu_item($tag, $value, $attrs = array()) {
  72. // $attrs may be a string already or an array
  73. if (is_array($attrs)) {
  74. $attrs = drupal_attributes($attrs);
  75. }
  76. $length = strlen($tag);
  77. if ($tag[0] == '<' && $tag[$length - 1] == '>') {
  78. $tag = substr($tag, 1, $length-2);
  79. }
  80. $closingtag = explode(' ', $tag,2);
  81. $closingtag = '</' . $closingtag[0] . '>';
  82. $tag = '<' . $tag . $attrs . '>';
  83. return $tag . $value . $closingtag;
  84. }
  85. /**
  86. * Implementation of hook_theme_registry_alter()
  87. * We replace theme_menu_item_link with our own function.
  88. */
  89. function special_menu_items_theme_registry_alter(&$registry) {
  90. // Save previous value from registry in case another theme overwrites menu_item_link
  91. $registry['special_menu_items_link_default'] = $registry['link'];
  92. $registry['link']['function'] = 'special_menu_items_link';
  93. }
  94. /**
  95. * Implementation of hook_form_FROM_ID_alter()
  96. * Description changed, added nolink and separator as path types.
  97. */
  98. function special_menu_items_form_menu_edit_item_alter(&$form, &$form_state) {
  99. // Some menu items have a pre-defined path which cannot be modified hence no default_value
  100. if (isset($form['link_path']['#default_value'])) {
  101. $default_value = $form['link_path']['#default_value'];
  102. if (preg_match('/^<nolink>\/[0-9]+$/', $default_value)) {
  103. $default_value = '<nolink>';
  104. }
  105. elseif (preg_match('/^<separator>\/[0-9]+$/', $default_value)) {
  106. $default_value = '<separator>';
  107. }
  108. $form['link_path']['#default_value'] = $default_value;
  109. $form['link_path']['#description'] .= ' ' . t('Enter "%nolink" to generate non-linkable item, enter "%separator" to generate separator item.', array('%nolink' => '<nolink>', '%separator' => '<separator>'));
  110. }
  111. }
  112. /**
  113. * Implementation of hook_init().
  114. */
  115. function special_menu_items_init() {
  116. // Make breadcrumb of nolink menu item nonlinkable.
  117. $breadcrumb = drupal_get_breadcrumb();
  118. foreach($breadcrumb as $key => $crumb){
  119. if (strlen(strstr($crumb,'<nolink>')) > 0) {
  120. $crumb = strip_tags($crumb);
  121. $tag = variable_get('special_menu_items_nolink_tag', '<span>');
  122. $breadcrumb[$key] = special_menu_items_render_menu_item($tag, $crumb);
  123. }
  124. }
  125. drupal_set_breadcrumb($breadcrumb);
  126. }
  127. /**
  128. * Special Menu Items admin settings form.
  129. *
  130. * @return
  131. * The settings form used by Special Menu Items.
  132. */
  133. function special_menu_items_admin_settings_form() {
  134. $form['special_menu_items_nolink_tag'] = array(
  135. '#type' => 'textfield',
  136. '#title' => t('HTML tag for "nolink"'),
  137. '#description' => t('By default, Special Menu Items will use a span tag for the nolink menu item. Here you can specify your own tag.'),
  138. '#default_value' => variable_get('special_menu_items_nolink_tag', '<span>'),
  139. );
  140. $form['special_menu_items_separator_tag'] = array(
  141. '#type' => 'textfield',
  142. '#title' => t('HTML tag for "separator"'),
  143. '#description' => t('By default, Special Menu Items will use a span tag for the separator menu item. Here you can specify your own tag.'),
  144. '#default_value' => variable_get('special_menu_items_separator_tag', '<span>'),
  145. );
  146. $form['special_menu_items_separator_value'] = array(
  147. '#type' => 'textfield',
  148. '#title' => t('Value to be displayed for the "separator"'),
  149. '#description' => t('By default, Special Menu Items will use a "&lt;hr&gt;" value for the separator. You can specify your own value for the separator.'),
  150. '#default_value' => variable_get('special_menu_items_separator_value', '<hr>'),
  151. );
  152. return system_settings_form($form);
  153. }
  154. /**
  155. * Implements hook_menu_link_update()
  156. *
  157. */
  158. /*
  159. function special_menu_items_menu_link_update($link) {
  160. //do all links in db
  161. global $db_type;
  162. if ($db_type == 'pgsql') {
  163. db_query("UPDATE {menu_links} SET link_path=link_path||'/'||mlid WHERE (link_path='<nolink>' OR link_path='<separator>') AND hidden != -1");
  164. }
  165. else {
  166. db_query("UPDATE {menu_links} SET link_path=CONCAT(CONCAT(link_path,'/'),mlid) WHERE (link_path='<nolink>' OR link_path='<separator>') AND hidden!=-1");
  167. }
  168. }
  169. *
  170. */