special_menu_items.module in Special menu items 7
Same filename and directory in other branches
Module to enable placeholder or separator menu items.Placeholder is a menu item which is actually not a link. Something like this is useful with drop down menus where we want to have a parent link which is actually not linking to a page but which is just acting as a parent and grouping some children below it. A separator menu item is something like "-------" which is also not linking anywhere but merely a mean to structure menus.
Written by Tamir Al Zoubi and Karim Djelid - Servit Open Source Solutions - www.servit.ch
File
special_menu_items.moduleView source
<?php
/**
* @file
* Module to enable placeholder or separator menu items.Placeholder is a menu item which is
* actually not a link. Something like this is useful with drop down menus where we want to
* have a parent link which is actually not linking to a page but which is just acting as a
* parent and grouping some children below it.
* A separator menu item is something like "-------" which is also not linking anywhere but
* merely a mean to structure menus.
*
* Written by Tamir Al Zoubi and Karim Djelid - Servit Open Source Solutions - www.servit.ch
*/
/**
*Implementation of hook_menu()
*/
function special_menu_items_menu() {
$items['<nolink>'] = array(
'page callback' => 'drupal_not_found',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['<separator>'] = array(
'page callback' => 'drupal_not_found',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['admin/config/system/special_menu_items'] = array(
'title' => 'Special Menu Items',
'description' => 'Configure Special Menu Items.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'special_menu_items_admin_settings_form',
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Override of theme_link()
* This function will render link if it is "nolink" or "separator". Otherwise it will call originally
* overwritten menu_item_link function.
*/
function special_menu_items_link(array $variables) {
if (in_array($variables['path'], array(
'<nolink>',
'<separator>',
))) {
switch ($variables['path']) {
case '<nolink>':
$tag = variable_get('special_menu_items_nolink_tag', '<span>');
$title = $variables['options']['html'] ? $variables['text'] : check_plain($variables['text']);
break;
case '<separator>':
$tag = variable_get('special_menu_items_separator_tag', '<span>');
$title = variable_get('special_menu_items_separator_value', '<hr>');
break;
}
$attributes = drupal_attributes($variables['options']['attributes']);
if ($tag != '<a>') {
// <a> tags can have these but a <span> cannot, so we remove them.
foreach (array(
'accesskey',
'target',
'rel',
'name',
) as $attribute) {
$attributes = preg_replace("/ {$attribute}=\".*\"/i", "", $attributes);
}
}
return special_menu_items_render_menu_item($tag, $title, $attributes);
}
// Call the original theme function for normal menu link.
return theme('special_menu_items_link_default', $variables);
}
/**
* Returns menu item rendered.
*/
function special_menu_items_render_menu_item($tag, $value, $attrs = array()) {
// $attrs may be a string already or an array
if (is_array($attrs)) {
$attrs = drupal_attributes($attrs);
}
$length = strlen($tag);
if ($tag[0] == '<' && $tag[$length - 1] == '>') {
$tag = substr($tag, 1, $length - 2);
}
$closingtag = preg_replace('#^(\\w+)#', '</$1>', $tag);
$tag = '<' . $tag . $attrs . '>';
return $tag . $value . $closingtag;
}
/**
* Alter the theme's primary and secondary links.
*
*/
function special_menu_items_preprocess_page(&$vars, $hook) {
foreach (array(
'main_menu',
'secondary_menu',
) as $menu) {
foreach (array_keys($vars[$menu]) as $key) {
if (in_array($vars[$menu][$key]['href'], array(
'<nolink>',
'<separator>',
))) {
switch ($vars[$menu][$key]['href']) {
case '<nolink>':
$tag = variable_get('special_menu_items_nolink_tag', '<span>');
$title = $vars[$menu][$key]['title'];
$attrs = isset($vars[$menu][$key]['attributes']) ? $vars[$menu][$key]['attributes'] : array();
$vars[$menu][$key]['title'] = special_menu_items_render_menu_item($tag, $title, $attrs);
$vars[$menu][$key]['attributes']['class'][] = 'nolink';
break;
case '<separator>':
$vars[$menu][$key]['title'] = variable_get('special_menu_items_separator_value', '<hr>');
$vars[$menu][$key]['attributes']['class'][] = 'separator';
break;
}
//render in HTML
$vars[$menu][$key]['html'] = TRUE;
unset($vars[$menu][$key]['attributes']['title']);
unset($vars[$menu][$key]['href']);
}
//unset($vars[$menu][$key]['attributes']['title']);
}
}
}
/**
* Implementation of hook_theme_registry_alter()
* We replace theme_menu_item_link with our own function.
*/
function special_menu_items_theme_registry_alter(&$registry) {
// Save previous value from registry in case another theme overwrites menu_item_link
$registry['special_menu_items_link_default'] = $registry['link'];
$registry['link']['function'] = 'special_menu_items_link';
}
/**
* Implementation of hook_form_FROM_ID_alter()
* Description changed, added nolink and separator as path types.
*/
function special_menu_items_form_menu_edit_item_alter(&$form, &$form_state) {
// Some menu items have a pre-defined path which cannot be modified hence no default_value
if (isset($form['link_path']['#default_value'])) {
$default_value = $form['link_path']['#default_value'];
if (preg_match('/^<nolink>\\/[0-9]+$/', $default_value)) {
$default_value = '<nolink>';
}
elseif (preg_match('/^<separator>\\/[0-9]+$/', $default_value)) {
$default_value = '<separator>';
}
$form['link_path']['#default_value'] = $default_value;
$form['link_path']['#description'] .= ' ' . t('Enter "%nolink" to generate non-linkable item, enter "%separator" to generate separator item.', array(
'%nolink' => '<nolink>',
'%separator' => '<separator>',
));
}
}
/**
* Implementation of hook_init().
*/
function special_menu_items_init() {
// Make breadcrumb of nolink menu item nonlinkable.
$breadcrumb = drupal_get_breadcrumb();
foreach ($breadcrumb as $key => $crumb) {
if (strlen(strstr($crumb, '<nolink>')) > 0) {
$crumb = strip_tags($crumb);
$tag = variable_get('special_menu_items_nolink_tag', '<span>');
$breadcrumb[$key] = special_menu_items_render_menu_item($tag, $crumb);
}
}
drupal_set_breadcrumb($breadcrumb);
}
/**
* Special Menu Items admin settings form.
*
* @return
* The settings form used by Special Menu Items.
*/
function special_menu_items_admin_settings_form() {
$form['special_menu_items_nolink_tag'] = array(
'#type' => 'textfield',
'#title' => t('HTML tag for "nolink"'),
'#description' => t('By default, Special Menu Items will use a span tag for the nolink menu item. Here you can specify your own tag.'),
'#default_value' => variable_get('special_menu_items_nolink_tag', '<span>'),
);
$form['special_menu_items_separator_tag'] = array(
'#type' => 'textfield',
'#title' => t('HTML tag for "separator"'),
'#description' => t('By default, Special Menu Items will use a span tag for the separator menu item. Here you can specify your own tag.'),
'#default_value' => variable_get('special_menu_items_separator_tag', '<span>'),
);
$form['special_menu_items_separator_value'] = array(
'#type' => 'textfield',
'#title' => t('Value to be displayed for the "separator"'),
'#description' => t('By default, Special Menu Items will use a "<hr>" value for the separator. You can specify your own value for the separator.'),
'#default_value' => variable_get('special_menu_items_separator_value', '<hr>'),
);
return system_settings_form($form);
}
/**
* Implements hook_menu_link_update()
*
*/
/*
function special_menu_items_menu_link_update($link) {
//do all links in db
global $db_type;
if ($db_type == 'pgsql') {
db_query("UPDATE {menu_links} SET link_path=link_path||'/'||mlid WHERE (link_path='<nolink>' OR link_path='<separator>') AND hidden != -1");
}
else {
db_query("UPDATE {menu_links} SET link_path=CONCAT(CONCAT(link_path,'/'),mlid) WHERE (link_path='<nolink>' OR link_path='<separator>') AND hidden!=-1");
}
}
*
*/
Functions
Name | Description |
---|---|
special_menu_items_admin_settings_form | Special Menu Items admin settings form. |
special_menu_items_form_menu_edit_item_alter | Implementation of hook_form_FROM_ID_alter() Description changed, added nolink and separator as path types. |
special_menu_items_init | Implementation of hook_init(). |
special_menu_items_link | Override of theme_link() This function will render link if it is "nolink" or "separator". Otherwise it will call originally overwritten menu_item_link function. |
special_menu_items_menu | Implementation of hook_menu() |
special_menu_items_preprocess_page | Alter the theme's primary and secondary links. |
special_menu_items_render_menu_item | Returns menu item rendered. |
special_menu_items_theme_registry_alter | Implementation of hook_theme_registry_alter() We replace theme_menu_item_link with our own function. |