| 1 |
<?php
|
| 2 |
// $Id: accordion_menu.module,v 1.1 2009/07/03 10:13:21 suryanto Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* Accordion menu output
|
| 6 |
*/
|
| 7 |
function accordion_menu_output($tree, &$active_menu = 0) {
|
| 8 |
$output = "<div id='accordion'>";
|
| 9 |
$items = array();
|
| 10 |
|
| 11 |
// Pull out just the menu items we are going to render so that we
|
| 12 |
// get an accurate count for the first/last classes.
|
| 13 |
foreach ($tree as $data) {
|
| 14 |
if (!$data['link']['hidden']) {
|
| 15 |
$items[] = $data;
|
| 16 |
}
|
| 17 |
}
|
| 18 |
|
| 19 |
$num_items = count($items);
|
| 20 |
$i = 0;
|
| 21 |
foreach ($items as $i => $data) {
|
| 22 |
//print_r($data);
|
| 23 |
$output .= "<h3><a href='".url($data['link']['href'])."'>".$data['link']['link_title']."</a></h3>";
|
| 24 |
$output .= "<div>";
|
| 25 |
if ($data['link']['in_active_trail'] == '1') {
|
| 26 |
$active_menu = $i;
|
| 27 |
}
|
| 28 |
$i++;
|
| 29 |
$extra_class = NULL;
|
| 30 |
if ($i == 0) {
|
| 31 |
$extra_class = 'first';
|
| 32 |
}
|
| 33 |
if ($i == $num_items - 1) {
|
| 34 |
$extra_class = 'last';
|
| 35 |
}
|
| 36 |
$link = theme('menu_item_link', $data['link']);
|
| 37 |
$subtree = _accordion_menu_subtree($data['link']);
|
| 38 |
if ($subtree) {
|
| 39 |
$output .= menu_tree_output($subtree);
|
| 40 |
}
|
| 41 |
$output .= "</div>";
|
| 42 |
}
|
| 43 |
$output .= "</div>";
|
| 44 |
|
| 45 |
return $output;
|
| 46 |
}
|
| 47 |
|
| 48 |
|
| 49 |
/**
|
| 50 |
* Traverses the menu tree and returns the sub-tree of the item
|
| 51 |
* indicated by the parameter.
|
| 52 |
*
|
| 53 |
* @param $item
|
| 54 |
* An menu item whose children should be found.
|
| 55 |
*
|
| 56 |
* @return
|
| 57 |
* The items below the passed menu item.
|
| 58 |
*/
|
| 59 |
function _accordion_menu_subtree($item) {
|
| 60 |
static $index = array();
|
| 61 |
static $indexed = array();
|
| 62 |
|
| 63 |
// This looks expensive, but menu_tree_all_data uses static caching.
|
| 64 |
$tree = menu_tree_all_data($item['menu_name']);
|
| 65 |
|
| 66 |
// Index the tree to find the path to this item.
|
| 67 |
if (!isset($indexed[$item['menu_name']])) {
|
| 68 |
$index += _accordion_menu_index($tree);
|
| 69 |
$indexed[$item['menu_name']] = TRUE;
|
| 70 |
}
|
| 71 |
// Traverse the tree.
|
| 72 |
foreach ($index[$item['mlid']]['parents'] as $mlid) {
|
| 73 |
$key = $index[$mlid]['key'];
|
| 74 |
if (!isset($tree[$key])) {
|
| 75 |
return array();
|
| 76 |
}
|
| 77 |
$tree = $tree[$key]['below'];
|
| 78 |
}
|
| 79 |
$key = $index[$item['mlid']]['key'];
|
| 80 |
return isset($tree[$key]) ? $tree[$key]['below'] : array();
|
| 81 |
}
|
| 82 |
|
| 83 |
|
| 84 |
/**
|
| 85 |
* Indexes the menu tree by mlid. This is needed to identify the items
|
| 86 |
* without relying on titles. This function is recursive.
|
| 87 |
*
|
| 88 |
* @param $tree
|
| 89 |
* A tree of menu items such as the return value of menu_tree_all_data()
|
| 90 |
*
|
| 91 |
* @return
|
| 92 |
* An array associating mlid values with the internal keys of the menu tree.
|
| 93 |
*/
|
| 94 |
function _accordion_menu_index($tree, $ancestors = array(), $parent = NULL) {
|
| 95 |
$index = array();
|
| 96 |
if ($parent) $ancestors[] = $parent;
|
| 97 |
foreach ($tree as $key => $item) {
|
| 98 |
$index[$item['link']['mlid']] = array(
|
| 99 |
'key' => $key,
|
| 100 |
'parents' => $ancestors,
|
| 101 |
);
|
| 102 |
if (!empty($item['below'])) {
|
| 103 |
$index += _accordion_menu_index($item['below'], $ancestors, $item['link']['mlid']);
|
| 104 |
}
|
| 105 |
}
|
| 106 |
return $index;
|
| 107 |
}
|
| 108 |
|
| 109 |
|
| 110 |
/**
|
| 111 |
* Implementation of hook_perm
|
| 112 |
*/
|
| 113 |
function accordion_menu_perm() {
|
| 114 |
return array('administer accordion menu');
|
| 115 |
}
|
| 116 |
|
| 117 |
/**
|
| 118 |
* Implementation of hook_menu().
|
| 119 |
*/
|
| 120 |
function accordion_menu_menu() {
|
| 121 |
$items['admin/settings/accordion_menu'] = array(
|
| 122 |
'title' => 'Accordion Menu',
|
| 123 |
'page callback' => 'drupal_get_form',
|
| 124 |
'page arguments' => array('accordion_menu_admin_settings', 2),
|
| 125 |
'access arguments' => array('administer accordion menu'),
|
| 126 |
'type' => MENU_NORMAL_ITEM,
|
| 127 |
);
|
| 128 |
return $items;
|
| 129 |
}
|
| 130 |
|
| 131 |
/**
|
| 132 |
* Implementation of hook_settings().
|
| 133 |
*/
|
| 134 |
function accordion_menu_admin_settings() {
|
| 135 |
$menus = menu_get_names();
|
| 136 |
$options = array();
|
| 137 |
foreach ($menus as $menu) {
|
| 138 |
$options[$menu] = $menu;
|
| 139 |
}
|
| 140 |
$form['accordion_menu_select'] = array(
|
| 141 |
'#type' => 'select',
|
| 142 |
'#title' => t("Select menu"),
|
| 143 |
'#options' => $options,
|
| 144 |
'#default_value' => variable_get('accordion_menu_select', $navigation),
|
| 145 |
'#description' => t("Select menu to show in accordion format."),
|
| 146 |
);
|
| 147 |
return system_settings_form($form);
|
| 148 |
}
|
| 149 |
|
| 150 |
/**
|
| 151 |
* Implementation of hook_block().
|
| 152 |
*/
|
| 153 |
function accordion_menu_block($op = 'list', $delta = 0) {
|
| 154 |
if ($op == 'list')
|
| 155 |
{
|
| 156 |
$blocks[0]['info'] = 'Accordion Menu';
|
| 157 |
return $blocks;
|
| 158 |
}
|
| 159 |
|
| 160 |
if ($op == 'view')
|
| 161 |
{
|
| 162 |
$menu_id = variable_get('accordion_menu_select', 'navigation');
|
| 163 |
$tree = menu_tree_page_data($menu_id);
|
| 164 |
$active_menu = 0;
|
| 165 |
$content = accordion_menu_output($tree, $active_menu);
|
| 166 |
|
| 167 |
$js = "\$(function() {\n";
|
| 168 |
$js .= "\$(\"#accordion\").accordion({ header: 'h3', cookie: { path: '/' }, active: ".$active_menu.", event: 'mouseover', autoHeight: false
|
| 169 |
});\n";
|
| 170 |
$js .= "});\n";
|
| 171 |
|
| 172 |
jquery_ui_add('ui.accordion');
|
| 173 |
drupal_add_js($js, 'inline');
|
| 174 |
|
| 175 |
$block['subject'] = '<none>';
|
| 176 |
$block['content'] = $content;
|
| 177 |
return $block;
|
| 178 |
}
|
| 179 |
}
|