' . t('To use footer sitemap you must enable the footer sitemap within Drupal\'s block management system and configure the block by choosing menus that you wish to display in the footer sitemap.', array('@url' => url('admin/build/block'))) . '
'; break; case 'admin/help#footer_sitemap': return '' . t('Footer sitemap will output a block that may be placed into footer region to display a sitemap. ' . 'The output may be configured in the block settings where you can configure which menus will be ' . 'used to construct the sitemap and in the individual menus where you can specify which menu items ' . 'should be hidden.') . '
'; break; } } /** * Implements hook_block_info(). */ function footer_sitemap_block_info() { $blocks = array(); $blocks['footer_sitemap'] = array( 'info' => t('Footer Sitemap'), // 'cache' => DRUPAL_CACHE_PER_PAGE, //e.vincent 'cache' => DRUPAL_CACHE_GLOBAL, ); return $blocks; } /** * Implements hook_block_view(). */ function footer_sitemap_block_view($delta = '') { $block = array(); $block['subject'] = t('Site map'); $block['content'] = array( '#theme' => 'footer_site_map', '#site_map' => footer_sitemap_get_footer_links_output(), ); return $block; } /** * Implements hook_block_configure(). */ function footer_sitemap_block_configure($delta = '') { $form['footer_sitemap_menu'] = array( '#type' => 'select', '#multiple' => TRUE, '#title' => t('Menu to display as footer sitemap'), '#required' => TRUE, '#options' => menu_get_menus(), '#default_value' => variable_get('footer_sitemap_menu', array()), ); return $form; } /** * Implements hook_block_save(). */ function footer_sitemap_block_save($delta = '', $edit = array()) { variable_set('footer_sitemap_menu', $edit['footer_sitemap_menu']); } /** * Implements hook_theme(). */ function footer_sitemap_theme() { return array( 'footer_site_map' => array( 'variables' => array('site_map' => NULL), 'template' => 'footer-site-map', ), 'footer_menu' => array( 'variables' => array('menu_output' => NULL, 'class' => NULL), 'template' => 'footer-menu', ), 'tree_links' => array( 'variables' => array('links' => array(), 'attributes' => array(), 'exclude_mlids' => array()), 'file' => 'footer_sitemap.theme.inc', ), ); } /** * Implements hook_form_FORMID_alter(). * * In here we add checkboxes to hide menu items from footer sitemap and a * custom submit callback. */ function footer_sitemap_form_menu_overview_form_alter(&$form, $form_state) { if (in_array($form['#menu']['menu_name'], variable_get('footer_sitemap_menu', array()))) { foreach ($form as $key => &$row) { if (strpos($key, 'mlid') !== FALSE) { $mlid = $row['#item']['mlid']; $hidden = in_array($mlid, variable_get('footer_sitemap_hidden_links', array())); $row['footer_sitemap_hide'] = array( '#type' => 'checkbox', '#default_value' => $hidden ); } } $form['#submit'][] = 'footer_sitemap_menu_overview_form_submit'; } } /** * Submits hidden items for footer sitemap. * * @see footer_sitemap_form_menu_overview_form_alter() */ function footer_sitemap_menu_overview_form_submit($form, $form_state) { $hidden_items = variable_get('footer_sitemap_hidden_links', array()); foreach ($form_state['values'] as $item) { if (!empty($item['mlid'])) { // First unset the item. unset($hidden_items[$item['mlid']]); // If it is selected set the item. if ($item['footer_sitemap_hide'] == 1) { $hidden_items[$item['mlid']] = $item['mlid']; } } } variable_set('footer_sitemap_hidden_links', $hidden_items); } /** * Form callback to add footer_sitemap hide checkbox into the list of menu * items. * * @param array $variables * Associative array of variables. * @return string * HTML form to list menu links with "Hide from footer sitemap" checkbox. */ function footer_sitemap_menu_overview_form($variables) { $form = $variables['form']; drupal_add_tabledrag('menu-overview', 'match', 'parent', 'menu-plid', 'menu-plid', 'menu-mlid', TRUE, MENU_MAX_DEPTH - 1); drupal_add_tabledrag('menu-overview', 'order', 'sibling', 'menu-weight'); $header = array( t('Menu link'), array('data' => t('Enabled'), 'class' => array('checkbox')), array('data' => t('Hide from footer sitemap'), 'class' => 'checkbox'), t('Weight'), array('data' => t('Operations'), 'colspan' => '2'), ); $rows = array(); foreach (element_children($form) as $mlid) { if (isset($form[$mlid]['hidden'])) { $element = &$form[$mlid]; // Build a list of operations. $operations = array(); foreach (element_children($element['operations']) as $op) { $operations[] = array('data' => drupal_render($element['operations'][$op]), 'class' => array('menu-operations')); } while (count($operations) < 2) { $operations[] = ''; } // Add special classes to be used for tabledrag.js. $element['plid']['#attributes']['class'] = array('menu-plid'); $element['mlid']['#attributes']['class'] = array('menu-mlid'); $element['weight']['#attributes']['class'] = array('menu-weight'); // Change the parent field to a hidden. // This allows any value but hides the field. $element['plid']['#type'] = 'hidden'; $row = array(); $row[] = theme('indentation', array('size' => $element['#item']['depth'] - 1)) . drupal_render($element['title']); $row[] = array('data' => drupal_render($element['hidden']), 'class' => array('checkbox', 'menu-enabled')); $row[] = array('data' => drupal_render($element['footer_sitemap_hide']), 'class' => array('checkbox')); $row[] = drupal_render($element['weight']) . drupal_render($element['plid']) . drupal_render($element['mlid']); $row = array_merge($row, $operations); $row = array_merge(array('data' => $row), $element['#attributes']); $row['class'][] = 'draggable'; $rows[] = $row; } } $output = ''; if (empty($rows)) { $rows[] = array(array('data' => $form['#empty_text'], 'colspan' => '7')); } $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'menu-overview'))); $output .= drupal_render_children($form); return $output; } /** * Implements hook_theme_registry_alter(). */ function footer_sitemap_theme_registry_alter(&$registry) { $registry['menu_overview_form']['file'] = drupal_get_path('module', 'footer_sitemap') . '/footer_sitemap.module'; $registry['menu_overview_form']['type'] = 'module'; $registry['menu_overview_form']['theme path'] = drupal_get_path('module', 'footer_sitemap'); $registry['menu_overview_form']['theme paths'] = drupal_get_path('module', 'footer_sitemap'); $registry['menu_overview_form']['function'] = 'footer_sitemap_menu_overview_form'; } /** * Generates output of the footer sitemap. * * @return string * Final HTML output for the footer sitemap links. */ function footer_sitemap_get_footer_links_output() { $menu_names = variable_get('footer_sitemap_menu', array()); $output = array(); foreach ($menu_names as $menu_name) { $output[$menu_name] = array( '#theme' => 'footer_menu', '#menu_output' => footer_sitemap_menu_display($menu_name), '#class' => $menu_name, ); } return $output; } /** * Outputs menu based on provided tree. * * @param string $menu_name * Menu name. * @return string * HTML output for one menu. */ function footer_sitemap_menu_display($menu_name) { if ($menu_name == NULL) { return ''; } $tree = footer_sitemap_tree_all_links($menu_name); // Set class for root items. foreach ($tree as $key => $item) { $tree[$key]['attributes']['class'] = array('fs-root-link'); } return array( '#theme' => 'tree_links', '#links' => $tree, '#attributes' => array('class' => 'footer_links_' . $menu_name), '#exclude_mlids' => variable_get('footer_sitemap_hidden_links', array()) ); } /** * Gets menu tree based on provided menu name. * * @param string $menu_name * Menu name * @param int $from_level * Level of the highest item/s. * @param int $to_level * Level of the lowest item/s. * @return array * Associative array of menu links. */ function footer_sitemap_tree_all_links($menu_name, $from_level = 0, $to_level = 0) { // Don't even bother querying the menu table if no menu is specified. if (empty($menu_name)) { return array(); } //e.vincent localize menu add i18n_menu_localize_tree //return footer_sitemap_tree_links(i18n_menu_localize_tree(menu_tree_all_data($menu_name)), $from_level, $to_level); return footer_sitemap_tree_links(menu_tree_all_data($menu_name), $from_level, $to_level); } /** * Generates navigation links with sub levels. * * @param array $tree * Menu links tree to be processed. * @param int $from_level * Level of the highest item/s. * @param int $to_level * Level of the lowest item/s. * @return array * Associative array of menu links. */ function footer_sitemap_tree_links($tree, $from_level = 0, $to_level = 0) { $initial_from_level = $from_level; // Go down the active trail until the right level is reached. while ($from_level-- > 0 && $tree) { // Loop through the current level's items // until we find one that is in trail. while ($item = array_shift($tree)) { if ($item['link']['in_active_trail']) { // If the item is in the active trail, we continue in the subtree. $tree = empty($item['below']) ? array() : $item['below']; break; } } } return _footer_sitemap_build_links($tree, $initial_from_level, $to_level); } /** * Helper function to build recursive links tree. * * @param array $tree * Menu links tree to be processed. * @param int $from_level * Level of the highest item/s. * @param int $to_level * Level of the lowest item/s. * @return array * Associative array of menu links. */ function _footer_sitemap_build_links($tree, $from_level, $to_level) { global $language; static $levels; $links = array(); foreach ($tree as $item) { if (isset($item['link']['localized_options']['langcode']) && $item['link']['localized_options']['langcode'] != $language->language) { continue; } if (!$item['link']['hidden']) { $class = ''; $l = $item['link']['localized_options']; $l['href'] = $item['link']['href']; $l['title'] = $item['link']['title']; if ($item['link']['in_active_trail']) { $class = ' active-trail'; } if ($item['below'] && ($to_level == 0 || $to_level > ($levels + $from_level))) { $levels++; $l['children'] = _footer_sitemap_build_links($item['below'], $from_level, $to_level); } // Keyed with the unique mlid to generate classes in theme_links(). $links['menu-' . $item['link']['mlid'] . $class] = $l; } } return $links; }