1

I want to change the menu-item icons for the Mobile sliding menu module. I have set up the icomoon library and changed the CSS file according to the documentation. I have added custom icon classes to the menu items (which works as long as they are not as block in a mmenu). The mmenu always overwrites this with its own markup.

I have found some occurrences of menu icon assignments in the source code, but I don't want to hack modules.

mmenu.api.php describes some hooks.

/**
* Allows modules to add more mmenu icon classes.
*/
function hook_mmenu_icon() {
  $icons = array(
    'path' => array(
      'home' => 'icon-home',
      'about' => 'icon-office',
      'contact' => 'icon-envelope',
    ),
    'block' => array(
      array(
        'module' => 'system',
        'delta' => 'main-menu',
        'icon_class' => 'icon-enter',
      ),
    ),
  );
  return $icons;
}

/**
 * Allows modules to alter mmenu icon class settings.
 */
function hook_mmenu_icon_alter(&$icons) {
  $icons['path']['home'] = 'icon-home1';
}

I have no clue how to use these. I have tried to put them in my template.php like this.

function mythemename_mmenu_icon() {...}

It's not working. Apart from that, this wouldn't be a user-friendly solution. Ideally it would support icon-api. So any help is highly appreciated.

  • mmenu.module, line 163, that's the function that generates icons, try to override it, if you succeed, please post your answer here, i did hack the module, so i'm also interested in this solution. – pinueve Aug 16 '17 at 21:25
  • Thanks for your comment, i have tried this already. But it's a hassle, i can't expect editors to handle module hacks, even if it would be an override somewhere. They can, of course, handle a dropdown of icons when adding a new menu item. We'll see if someone steps in here... :) – Volker Aug 17 '17 at 14:27
  • Have you tried the icon-api ? Maybe this just works in combination with mmenu module .. ? (Or maybe you'll only have to remove the icons set from mmenu in the mentioned hook - if they're two icons ..) – rémy Aug 21 '17 at 8:57
  • You should make function mymodulename_mmenu_icon() {..} in your costom module's .module file – Jdrupal Aug 27 '17 at 6:55
3
+200

Here is what I ended up with, after using hook_mmenu_icon() and configuring the Icon API to use the icomoon bundle.

enter image description here

How I did it?

First of all, I opted for using the Icomoon module, which allows me to import my own defined icons collections, assembled using the icomoon app.

This is an example of a custom collection I created (and the renaming/mapping of icons to the menu points I had in mind).

enter image description here

After, I had to go to the administration interface of Icon API providers and import the icons (/admin/config/media/icon/import). I named the imported bundle 'icomoon', which will be important for the code I wrote. This is what that admin interface looked like.

enter image description here

The code

The code you need will use hook_mmenu_icon(), since you want to define your own path to icon class associations.

This is what my code looks like.

/**
* Implements hook_mmenu_icon().
*
* Here we map URLs to icon classes.
*/
function YOUR_CUSTOM_MODULE_mmenu_icon() {
  $icons = array(
    'path' => array(
      'home' => 'icon-home',
      'node/1' => 'icon-node1',
    ),
  );
  _inject_inline_css($icons);
  return $icons;
}

Notice the use of Drupal's internal paths as the key to the $icons array. This is needed by the module (inside mmenu_get_icon_class()) in order to assign our custom CSS class to the menu item that points to it.

The rest of the code is quite custom and just a random idea of how you could go about doing the assignments you need. Probably there are better approaches.

/**
 * Function for injecting Icon API icons as CSS background images.
 */
function _inject_inline_css($icons) {
  // Load a bundle provider from the Icon API.
  $bundle = icon_bundles('icomoon');

  // Sanitization, normalization.
  if (empty($bundle)) {
    return;
  }
  if (!isset($bundle['settings']['extension'])) {
    $bundle['settings']['extension'] = 'png';
  }

  $css_data = array();

  // Configure an existing icon class, 'home'.
  $icon_path = $bundle['path'] . '/' . strtoupper($bundle['settings']['extension']) . '/home' . '.' . $bundle['settings']['extension'];
  $icon_info = image_get_info($icon_path);
  $icon_url = file_create_url($icon_path);
  $css_data[$icons['path']['home']] = array(
    'background-image' => 'url("' . $icon_url . '")',
    'background-size' => 'contain',
    // Or, as an alternative.
    // 'background-size' => '$icon_info['width'] . 'px ' . $icon_info['height'] . 'px'',      
    'background-repeat' => 'no-repeat',
    'background-position' => 'center',
  );

  // Add a custom icon class, 'node/1'.
  $icon_path = $bundle['path'] . '/' . strtoupper($bundle['settings']['extension']) . '/node1' . '.' . $bundle['settings']['extension'];
  $icon_info = image_get_info($icon_path);
  $icon_url = file_create_url($icon_path);
  $css_data[$icons['path']['node/1']] = array(
    'background-image' => 'url("' . $icon_url . '")',
    'background-size' => 'contain',
    // Or, as an alternative.
    // 'background-size' => '$icon_info['width'] . 'px ' . $icon_info['height'] . 'px'',      
    'background-repeat' => 'no-repeat',
    'background-position' => 'center',
  );

  // Generate and add inline CSS, mapping the mmenu icon classes to the icomoon icons.
  $css_string = '';
  foreach ($css_data as $class => $css_properties) {
    $css_string .= '.' . $class . ' {';
    foreach ($css_properties as $css_property => $css_value) {
      $css_string .= "$css_property: $css_value;";
    }
    $css_string .= '}';
  }
  drupal_add_css($css_string, array('type' => 'inline'));
}
0

The hooks should be implemented in a module.

Create two files: mymodule.info + mymodule.module in path a module search path like /sites/all/modules/custom/mymodule/

The documentation on https://www.drupal.org/node/2324139 is indeed inconclusive where to implement the hooks.

0

If you have a custom module, implement hook_mmenu_icon() in your MODULENAME.module file like you showed above. If you don't have a custom module, you can create one. (If you don't know how, there is documentation on http://drupal.org.)

You can replace 'icon-home' with the path to your icon.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.