You are here

menu_icons.module in Menu Icons 6

Same filename and directory in other branches
  1. 8 menu_icons.module
  2. 6.2 menu_icons.module
  3. 7.3 menu_icons.module

Module to associate icons with menu items

@author dylan@opensourcery.com

File

menu_icons.module
View source
<?php

/**
 * @file
 * Module to associate icons with menu items
 * 
 * @author dylan@opensourcery.com
 * 
 */

// TODO - allow file uploads on the menu form, instead of textarea
// TODO - provide option for linked, inline img tags, in addition to background CSS
// TODO - implement blocks

/**
 * Implementation of hook_init()
 *
 */
function menu_icons_init() {
  drupal_set_html_head('<link type="text/css" rel="stylesheet" media="all" href="' . url('menu_icons/css') . '" />');
  drupal_add_css(drupal_get_path('module', 'menu_icons') . '/menu_icons.css');
}

/**
 * Implementation of hook_form_alter
 *
 */
function menu_icons_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['menu']['#title']) && $form['menu']['#title'] == 'Menu settings') {
    $form['menu']['icon_path'] = _menu_icons_get_form($form['menu']['mlid']['#value']);
    $form['#submit'][] = '_menu_icons_submit';
  }
}

/**
 * Build the form structure.
 *
 * @return A form array with a textfield for a menu icon.
 */
function _menu_icons_get_form($mlid) {
  return array(
    '#type' => 'textfield',
    '#title' => t('Icon path'),
    '#default_value' => menu_icons_get_path($mlid),
    '#description' => t('A Drupal path to the icon or image to associate with this menu item.'),
    '#required' => FALSE,
  );
}

/**
 * Process the submitted form
 *
 */
function _menu_icons_submit($form, &$form_state) {

  // FIXME - mlid is not available when a menu item is created.  May need to patch core to fix this.
  if ($form['menu']['icon_path']['#value'] && $form_state['values']['menu']['mlid']) {
    db_query("INSERT INTO {menu_icons} SET mlid = %d, path = '%s' ON DUPLICATE KEY UPDATE path = '%s'", $form_state['values']['menu']['mlid'], $form['menu']['icon_path']['#value'], $form['menu']['icon_path']['#value']);
  }
}

/**
 * Query the database for a particular icon
 *
 * @param Menu id $mlid
 * @return path
 */
function menu_icons_get_path($mlid) {
  return db_result(db_query("SELECT path FROM {menu_icons} WHERE mlid = %d", $mlid));
}

/**
 * Implementation of hook_menu()
 *
 */
function menu_icons_menu() {
  $items = array();
  $items['menu_icons/css'] = array(
    'title' => 'Menu icons CSS',
    'page callback' => 'menu_icons_css',
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  $items['admin/settings/menu_icons'] = array(
    'title' => 'Menu Icon settings',
    'description' => 'Associates icons with menu items',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'menu_icons_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'menu_name' => 'menu_icons',
  );
  return $items;
}

/**
 * Build the module settings form
 *
 * @return a form array
 */
function menu_icons_admin_settings() {
  $form = array();
  $form['menu_icons_default_icon'] = array(
    '#type' => 'textfield',
    '#title' => t('Icon path'),
    '#default_value' => variable_get('menu_icons_default_icon', ''),
    '#description' => t('A Drupal path to the icon or image to use as a default.'),
    '#required' => FALSE,
  );
  return system_settings_form($form);
}

/**
 * Page callback for generated CSS file
 *
 */
function menu_icons_css() {
  drupal_set_header('Content-Type: text/css; charset=utf-8');
  print _menu_icons_css_generate();
}

/**
 * Build CSS based on menu IDs
 *
 * @return A string with the CSS
 */
function _menu_icons_css_generate() {

  // TODO - Cache this step
  $css = '';
  $result = db_query("SELECT mlid, path FROM {menu_icons}");
  while ($icon = db_fetch_array($result)) {
    $css .= theme('menu_icons_css_item', $icon['mlid'], check_url(url($icon['path'])));
  }
  return $css;
}

/**
 * Implementation of hook_theme
 *
 */
function menu_icons_theme() {
  return array(
    'menu_icons_css_item' => array(
      'arguments' => array(
        'mlid' => NULL,
        'path' => NULL,
      ),
      'template' => 'menu_icons_css_item',
    ),
    'menu_icons' => array(
      'arguments' => array(
        'menu_name' => NULL,
        'hide_children' => FALSE,
        'hide_titles' => FALSE,
      ),
    ),
    'menu_icons_tree' => array(
      'arguments' => array(
        'menu_name' => NULL,
        'hide_children' => FALSE,
        'hide_titles' => FALSE,
      ),
    ),
    'menu_icons_build' => array(
      'arguments' => array(
        'menu' => NULL,
        'hide_children' => FALSE,
        'hide_titles' => FALSE,
      ),
    ),
    'menu_icons_primary_links' => array(
      'arguments' => array(
        'menu_name' => NULL,
        'hide_titles' => FALSE,
      ),
    ),
    'menu_icons_icon' => array(
      'arguments' => array(
        'icon',
      ),
    ),
  );
}

/**
 * Theme a given menu, with icons
 *
 * @param $menu_name The menu name
 * @param $hide_children If set to true, children of this menu will not be displayed
 * @param $hide_titles If set to true, titles will be hidden, and only images will display
 * 
 * @return The HTML string of the rendered menu
 */
function theme_menu_icons($menu_name, $hide_children = FALSE, $hide_titles = FALSE) {
  $output = array();
  if ($menu_tree = theme('menu_icons_tree', $menu_name, $hide_children, $hide_titles)) {
    if ($menu_tree['content']) {
      $output['content'] = '<ul class="menu_icons_menu">' . $menu_tree['content'] . '</ul>' . "\n";
      $output['subject'] = $menu_tree['subject'];
    }
  }
  return $output;
}

/**
 * Theme a given menu tree, with icons
 *
 * @param $menu_name The menu name
 * @param $hide_children If set to true, children of this menu will not be displayed
 * @param $hide_titles If set to true, titles will be hidden, and only images will display
 * 
 * @return The HTML string of the rendered menu tree
 */
function theme_menu_icons_tree($menu_name, $hide_children = FALSE, $hide_titles = FALSE) {
  $menu = menu_tree_all_data($menu_name);
  $result = db_result(db_query("SELECT title FROM {menu_custom} WHERE menu_name = '%s'", $menu_name));
  $title = check_plain($result);
  $output['content'] = '';
  $output['subject'] = $title;
  if ($menu) {
    $output['content'] .= theme('menu_icons_build', $menu, $hide_children, $hide_titles);
  }
  return $output;
}

/**
 * Helper function that builds the nested lists of a nice menu.
 * Borrowed from nice_menus
 *
 * @param $menu
 *   Menu array from which to build the nested lists.
 */
function theme_menu_icons_build($menu, $hide_children = FALSE, $hide_titles = FALSE) {

  // TODO - enable supression of link titles to show icons only
  $output = '';
  foreach ($menu as $menu_item) {
    $mlid = $menu_item['link']['mlid'];

    // Check to see if it is a visible menu item.
    if ($menu_item['link']['hidden'] == 0) {

      // Build class name based on menu path
      // e.g. to give each menu item individual style.
      // Strip funny symbols.
      $clean_path = str_replace(array(
        'http://',
        '<',
        '>',
        '&',
        '=',
        '?',
        ':',
      ), '', $menu_item['link']['href']);

      // Convert slashes to dashes.
      $clean_path = str_replace('/', '-', $clean_path);
      $path_class = 'menu-path-' . $clean_path;

      // If it has children build a nice little tree under it.
      if (!empty($menu_item['link']['has_children']) && !empty($menu_item['below']) && !$hide_children) {

        // Keep passing children into the function 'til we get them all.
        $children = theme('menu_icons_build', $menu_item['below']);

        // Set the class to parent only of children are displayed.
        $parent_class = $children ? 'menuparent ' : '';
        $output .= '<li id="menu-' . $mlid . '" class="' . $parent_class . $path_class . '">' . theme('menu_item_link', $menu_item['link']);

        // Build the child UL only if children are displayed for the user.
        if ($children) {
          $output .= '<ul>';
          $output .= $children;
          $output .= "</ul>\n";
        }
        $output .= "</li>\n";
      }
      else {
        $output .= '<li id="menu-' . $mlid . '" class="' . $path_class . '">' . theme('menu_item_link', $menu_item['link']) . '</li>' . "\n";
      }
    }
  }
  return $output;
}

/**
 * Theme primary links as menu icons
 *
 * @return
 *   An HTML string of nice menu primary links.
 */
function theme_menu_icons_primary_links($menu_name = NULL, $hide_titles = FALSE) {
  $menu_name = variable_get('menu_primary_links_source', 'primary-links');
  $output = theme('menu_icons', $menu_name, TRUE, $hide_titles);
  return $output['content'];
}

/**
 * Theme an icon
 *
 * @param $icon An array with 'path' and 'title'
 * @return An HTML string with an inline image
 */
function theme_menu_icons_icon($icon) {
  return '<img src="' . check_url(url($icon['path'])) . '" alt="' . check_plain($icon['title']) . '"/>';
}

/**
 * Return the path to the menu icon for the currently active item
 * Useful for providing context-sensitive image blocks
 *
 * @param inheret If set to true, and the active item doesn't have
 * an icon, the next-highest parent with an icon will be returned.
 * 
 */
function menu_icons_get_active_icon($inherit = TRUE) {
  foreach (array_reverse(menu_get_active_trail()) as $menu) {
    if ($menu['mlid'] && ($path = menu_icons_get_path($menu['mlid']))) {
      return array(
        'path' => $path,
        'title' => $menu['title'],
      );
    }
    else {
      if (!$inherit) {
        if (variable_get('menu_icons_default_icon', '')) {
          return array(
            'path' => variable_get('menu_icons_default_icon', ''),
            'title' => 'default',
          );
        }
      }
    }
  }
  if (variable_get('menu_icons_default_icon', '')) {
    return array(
      'path' => variable_get('menu_icons_default_icon', ''),
      'title' => 'default',
    );
  }
}

/**
 * Implementation of hook_cron()
 *
 */
function menu_icons_cron() {

  // FIXME - delete icons for menu items that no longer exist
}

Functions

Namesort descending Description
menu_icons_admin_settings Build the module settings form
menu_icons_cron Implementation of hook_cron()
menu_icons_css Page callback for generated CSS file
menu_icons_form_alter Implementation of hook_form_alter
menu_icons_get_active_icon Return the path to the menu icon for the currently active item Useful for providing context-sensitive image blocks
menu_icons_get_path Query the database for a particular icon
menu_icons_init Implementation of hook_init()
menu_icons_menu Implementation of hook_menu()
menu_icons_theme Implementation of hook_theme
theme_menu_icons Theme a given menu, with icons
theme_menu_icons_build Helper function that builds the nested lists of a nice menu. Borrowed from nice_menus
theme_menu_icons_icon Theme an icon
theme_menu_icons_primary_links Theme primary links as menu icons
theme_menu_icons_tree Theme a given menu tree, with icons
_menu_icons_css_generate Build CSS based on menu IDs
_menu_icons_get_form Build the form structure.
_menu_icons_submit Process the submitted form