You are here

megamenu.module in Megamenu 7

Same filename and directory in other branches
  1. 6.2 megamenu.module
  2. 6 megamenu.module

Takes existing menus and produces blocks that render the menu as a megamenu.

File

megamenu.module
View source
<?php

/**
 * @file
 * Takes existing menus and produces blocks that render the menu as a megamenu.
 */

/**
 * Load all the helper/utility functions for this module.
 */
module_load_include('inc', 'megamenu', 'megamenu.utilities');

/**
 * Implements hook_help().
 */
function megamenu_help($path, $arg) {
  switch ($path) {
    case 'admin/config/user-interface/megamenu':
      $output = '<p>' . t('To enable a Megamenu, go to !link in the admin section. There you can place a Megamenu, most likely in the header region, and it will inherit its structure from the associated Drupal menu.', array(
        '!link' => l(t('Site building -> Blocks'), 'admin/structure/block'),
      )) . '</p>';
      return $output;
  }
}

/**
 * Implements hook_page_build().
 *
 * We are adding the JavaScript and CSS here rather than theme_menu_tree()
 * because when block caching is enabled none of it would get fired
 * and the menus are unstyled.
 */
function megamenu_page_build(&$page) {
  $path = drupal_get_path('module', 'megamenu');

  // Add JavaScript.
  drupal_add_js(array(
    'megamenu' => array(
      'timeout' => variable_get('megamenu_menu_timeout', 500),
      'sizewait' => variable_get('megamenu_menu_sizewait', 500),
      'hoverwait' => variable_get('megamenu_menu_hoverwait', 500),
    ),
  ), 'setting');
  drupal_add_js($path . '/megamenu.js');

  // Add main CSS functionality.
  drupal_add_css($path . '/megamenu.css');

  // Load default skins.
  // @todo Don't load if custom skin (but not custom CSS)...
  drupal_add_css($path . '/megamenu-skins.css');

  //I THINK YOU SHOULD CONSIDER MOVING THIS

  // Add custom CSS to extend or define skins: if exists.

  /*
  $customcsspath = file_directory_path() .'/megamenu/megamenu-custom.css';
  if (file_exists($customcsspath)) {
    drupal_add_css($customcsspath);
  }
  */
}

/**
 * Implements hook_menu().
 */
function megamenu_menu() {
  $items = array();
  $items['admin/config/user-interface/megamenu'] = array(
    'title' => 'Mega menus',
    'description' => 'Make megamenu (aka megadropdowns) from a Drupal menu',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'megamenu_admin_form',
    ),
    'file' => 'megamenu.admin.inc',
    'access arguments' => array(
      'administer mega menu',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/user-interface/megamenu/settings/%'] = array(
    'title' => 'Mega Menus Settings',
    'description' => 'Configure the mega menu',
    'page callback' => 'drupal_get_form',
    'file' => 'megamenu.admin.inc',
    'page arguments' => array(
      'megamenu_settings_form',
      5,
    ),
    'access arguments' => array(
      'administer mega menu',
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function megamenu_permission() {
  return array(
    'administer mega menu' => array(
      'title' => t('Administer Megamenu'),
      'description' => t('Perform administration tasks for Megamenu.'),
    ),
  );
}

/**
 * Implements hook_theme().
 */
function megamenu_theme() {
  return array(
    'megamenu_admin' => array(
      'arguments' => array(
        'form' => NULL,
      ),
      'render element' => 'form',
      'template' => 'megamenu_admin',
    ),
  );
}
function megamenu_preprocess_megamenu_admin(&$variables) {
  foreach (_megamenu_menulist() as $menu_name) {
    $variables['menu'][$menu_name]['details'] = menu_load($menu_name);
  }
}

/**
 * Implements hook_block_info().
 */
function megamenu_block_info() {
  $blocks = array();
  $menus = _megamenu_enabled_menus();
  foreach ($menus as $menu_name) {
    $menu_details = menu_load($menu_name);
    $blocks[$menu_name] = array(
      'info' => t('Megamenu - @title', array(
        '@title' => $menu_details['title'],
      )),
      'cache' => DRUPAL_CACHE_PER_PAGE,
    );
  }
  return $blocks;
}

/**
 * Implements hook_block_view().
 *
 * @todo Temp debugging value, should be left unset in production.
 */
function megamenu_block_view($delta = '') {
  $menus = _megamenu_enabled_menus();
  if ($menus) {
    $key = array_search($delta, $menus);
    if ($key !== FALSE) {
      $block['subject'] = '';
      $block['content'] = megamenu_theme_menu_tree($menus[$key]);
      return $block;
    }
  }
}

/**
 * Theme a menu tree.
 *
 * This function takes a menu tree, such as primary links, and generates
 * HTML markup of the menu so that it can be styled as a mega menu. It
 * takes the first three nested levels of the menu tree and creates a
 * structure of nested lists with appropriate classes and IDs assigned (even,
 * odd, active, etc.).
 *
 * First, we iterate through the first level of menu items
 * (branch/tier-1/megamenu-bin). Each item will be the megamenu-parent of the
 * second level of links (twig/tier-2/megamenu-slot). Next we iterate through
 * the twigs of the menu tree to fill the megamenu-bins. A bin is an unordered
 * list which contains slots (twig/tier-2 items). To fill the slots we iterate
 * through each twig, where the leaves are the deepest level of the menu tree
 * (tier-3). Each leaf is a list item containing a tier-3 menu link.
 *
 * Abbreviations: t1, t2, & t3 stands for tier-1, tier-2, and tier-3
 * respectively. They represent nested level menu items.
 *
 * @param string $menu_name
 *    The menu tree to be marked up (i.e. primary_links).
 *
 * @return string
 *    HTML markup for a mega menu
 */
function megamenu_theme_menu_tree($menu_name) {
  $menu_tree = _megamenu_get_menu_tree($menu_name);
  if (function_exists('i18n_menu_localize_tree')) {
    $menu_tree = i18n_menu_localize_tree($menu_tree);
  }
  $skin = _megamenu_get_skin_by_name($menu_name);

  // @todo Currently, these attributes are set menu wide. Eventually these might should be set per menu level?

  /* @todo temp value, should be attached to branch level in admin interface */
  $slot_orientation = _megamenu_get_slot_orientation_by_name($menu_name);

  /* @todo temp value, should be attached to twig level in admin interface. */

  //_megamenu_get_slot_attributes_by_name($menu_name);
  $slot_attributes = '';
  $t1_position = 0;
  $branch_count = count($menu_tree);
  $branch_items = array();

  // Branch iteration.
  foreach ($menu_tree as $branch) {
    $twig_items_list = '';
    if ($branch['below']) {
      $t2_position = 0;
      $twig_count = count($branch['below']);

      // Twig iteration.
      foreach ($branch['below'] as $twig) {
        $leaf_items_list = '';

        // Leaf detection.
        if ($twig['below']) {
          $t3_position = 0;
          $leaf_count = count($twig['below']);

          // Leaf iteration.
          foreach ($twig['below'] as $leaf) {

            // Active or active-trail?
            $active = _megamenu_active_classes($leaf);

            // $leaf_link_options['attributes'] = array('class'=>$active);
            $t3_count_attributes = _megamenu_count_attributes($t3_position, $leaf_count);
            $t3_position++;
            $leaf_items[] = array(
              'data' => l($leaf['link']['link_title'], $leaf['link']['href'], $leaf['link']['options']),
              'id' => 'megamenu-mlid-' . $leaf['link']['mlid'],
              'class' => array(
                'megamenu-item',
                'megamenu-item-' . $t3_count_attributes,
                $active,
              ),
            );
          }

          // Build leaf list.
          $leaf_list_options = array(
            'class' => array(
              'megamenu-items',
              $slot_attributes,
            ),
          );
          $leaf_items_list = theme('item_list', array(
            'items' => $leaf_items,
            'attributes' => $leaf_list_options,
          ));
          $leaf_items_list = _megamenu_strip_list_wrapper($leaf_items_list);
          unset($leaf_items);
        }
        $t2_count_attributes = _megamenu_count_attributes($t2_position, $twig_count);
        $t2_position++;

        // Are we active / active-trail ?
        $active = _megamenu_active_classes($twig);

        //$link_options['attributes'] = array('class'=>$active);

        // This twig's <li> content.
        $twig_data = '<h3 class="megamenu-slot-title">' . l(_megamenu_get_translated_menu_title($menu_name, $twig['link']['mlid']), $twig['link']['href'], $twig['link']['options']) . '</h3>' . $leaf_items_list;
        $twig_items[] = array(
          'data' => $twig_data,
          'id' => 'megamenu-mlid-' . $twig['link']['mlid'],
          'class' => array(
            'megamenu-slot',
            'megamenu-slot-' . $t2_count_attributes,
            $active,
          ),
        );
      }

      // Build twig list.
      $twig_list_options = array(
        'class' => array(
          'megamenu-bin',
          'megamenu-slots-' . $slot_orientation,
        ),
      );
      $twig_items_list = theme('item_list', array(
        'items' => $twig_items,
        'attributes' => $twig_list_options,
      ));
      $twig_items_list = _megamenu_strip_list_wrapper($twig_items_list);
      unset($twig_items);
    }

    // END twig detection
    // Setup active link classes.
    $active = _megamenu_active_classes($branch);

    // Link options.
    $branch_link_options['attributes'] = array(
      'class' => $active,
    );

    // Setup $t1_count_attributes (classes).
    $t1_count_attributes = _megamenu_count_attributes($t1_position, $branch_count);
    $t1_position++;
    $branch_link = l(_megamenu_get_translated_menu_title($menu_name, $branch['link']['mlid']), $branch['link']['href'], $branch['link']['options']);
    $branch_items[] = array(
      'data' => '<h2 class="megamenu-parent-title">' . $branch_link . '</h2>' . $twig_items_list,
      'id' => 'megamenu-mlid-' . $branch['link']['mlid'],
      'class' => array(
        'megamenu-parent',
        'megamenu-parent-' . $t1_count_attributes,
        'menu-' . $branch['link']['mlid'],
        $active,
      ),
    );
    unset($twig_items_list);
  }

  // Build branch list.
  $branch_list_options = array(
    'id' => 'megamenu-' . $menu_name,
    'class' => array(
      'megamenu-menu',
      $slot_orientation,
      'megamenu-skin-' . $skin,
    ),
  );
  $output = theme('item_list', array(
    'items' => $branch_items,
    'attributes' => $branch_list_options,
  ));
  $output = _megamenu_strip_list_wrapper($output);
  return $output;
}