Projet

Général

Profil

Paste
Télécharger (24,4 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / nice_menus / nice_menus.module @ 87dbc3bf

1
<?php
2

    
3
/**
4
 * @file
5
 * Module to enable CSS dropdown and flyout menus.
6
 *
7
 * Maintainer: Addison Berry (add1sun)
8
 * Originally written by Jake Gordon (jakeg)
9
 */
10

    
11
/**
12
 * Implements hook_help().
13
 */
14
function nice_menus_help($path, $arg) {
15
  $output = '';
16
  switch ($path) {
17
    case 'admin/config/modules#description':
18
      $output .= t('Make drop down/flyout CSS menus for site and admin menus.');
19
      break;
20

    
21
    case 'admin/config/user-interface/nice_menus':
22
      $output .= t('<p>This is a simple module that enables the site to have drop down/flyout CSS menus for site and admin navigation.</p><p>Remember to activate and configure the menu blocks in !link</p>', array('!link' => l(t('admin/structure/block'), 'admin/structure/block')));
23
      break;
24
  }
25
  return $output;
26
}
27

    
28
/**
29
 * Implements hook_form_alter().
30
 */
31
function nice_menus_form_alter(&$form, $form_state, $form_id) {
32
  switch ($form_id) {
33
    case 'system_theme_settings':
34
      // This is a global setting, so only insert the field
35
      // on the global settings page.
36
      if (arg(4) && arg(4) != 'global') {
37
        return;
38
      }
39

    
40
      // Have to add a custom submit handler since this form doesn't use
41
      // the standard system submit handler.
42
      $form['#submit'][] = 'nice_menus_system_theme_settings_submit';
43

    
44
      // Add global theme setting for a custom CSS file.
45
      $form['nice_menus_custom_css'] = array(
46
        '#type' => 'textfield',
47
        '#title' => t('Path to custom Nice menus CSS file'),
48
        '#description' => t('To override the default Nice menus CSS layout, enter the path to your custom CSS file.  It should be a relative path from the root of your Drupal install (e.g. sites/all/themes/example/mymenu.css).'),
49
        '#default_value' => variable_get('nice_menus_custom_css', ''),
50
        // Field appears below submit buttons without this -- yucky.
51
        '#weight' => 0,
52
      );
53
      break;
54
  }
55
}
56

    
57
/**
58
 * Records the Nice menu custom CSS file per theme.
59
 */
60
function nice_menus_system_theme_settings_submit($form, &$form_state) {
61
  variable_set('nice_menus_custom_css', $form_state['values']['nice_menus_custom_css']);
62
}
63

    
64
/**
65
 * Implements hook_menu().
66
 */
67
function nice_menus_menu() {
68
  $items['admin/config/user-interface/nice_menus'] = array(
69
    'title' => 'Nice menus',
70
    'description' => 'Configure Nice menus.',
71
    'page callback' => 'drupal_get_form',
72
    'page arguments' => array('nice_menus_admin_settings'),
73
    'access arguments' => array('administer site configuration'),
74
    'file' => 'nice_menus.admin.inc',
75
  );
76

    
77
  return $items;
78
}
79

    
80
/**
81
 * Implements hook_library().
82
 */
83
function nice_menus_library() {
84
  $module_path = drupal_get_path('module', 'nice_menus');
85
  // Jquery bgiframe.
86
  $libraries['jquery.bgiframe'] = array(
87
    'title' => 'bgiframe',
88
    'website' => 'http://docs.jquery.com/Plugins/bgiframe',
89
    'version' => '2.1',
90
    'js' => array(
91
      $module_path . '/js/jquery.bgiframe.js' => array(),
92
    ),
93
  );
94

    
95
  // Jquery hoverIntent.
96
  $libraries['jquery.hoverIntent'] = array(
97
    'title' => 'hoverIntent',
98
    'website' => 'http://cherne.net/brian/resources/jquery.hoverIntent.html',
99
    'version' => '0.5',
100
    'js' => array(
101
      $module_path . '/js/jquery.hoverIntent.js' => array(),
102
    ),
103
  );
104

    
105
  // Superfish.
106
  $libraries['superfish'] = array(
107
    'title' => 'Superfish',
108
    'website' => 'http://users.tpg.com.au/j_birch/plugins/superfish/',
109
    'version' => '1.4.8',
110
    'js' => array(
111
      $module_path . '/js/superfish.js' => array(),
112
    ),
113
    'dependencies' => array(
114
      array('nice_menus', 'jquery.bgiframe'),
115
      array('nice_menus', 'jquery.hoverIntent'),
116
    ),
117
  );
118

    
119
  // Nicemenus.
120
  $libraries['nice_menus'] = array(
121
    'title' => 'Nice Menus',
122
    'website' => 'http://drupal.org/project/nice_menus',
123
    'version' => '1.0',
124
    'js' => array(
125
      // Add the Superfish options variables.
126
      $module_path . '/js/nice_menus.js' => array(),
127
    ),
128
    'dependencies' => array(
129
      array('nice_menus', 'superfish'),
130
    ),
131
  );
132
  // Add the javascript according to configuration settings.
133
  $libraries['nice_menus']['js'][] = array(
134
    'type' => 'setting',
135
    'data' => array(
136
      'nice_menus_options' => array(
137
        'delay' => variable_get('nice_menus_sf_delay', 800),
138
        'speed' => variable_get('nice_menus_sf_speed', 'slow'),
139
      ),
140
    ),
141
  );
142

    
143
  $jquery = drupal_get_library('system', 'jquery');
144
  if (version_compare($jquery['version'], '1.7', '>=')) {
145
    $plugins = array(
146
      'jquery.hoverIntent' => array(
147
        'js' => 'jquery.hoverIntent.js',
148
        'version_pattern' => '@hoverIntent\s+(r[0-9]+)@i'
149
      ),
150
      'jquery.bgiframe' => array(
151
        'js' => 'jquery.bgiframe.js',
152
        'version_pattern' => '@version\s+([0-9a-zA-Z\.-]+)@i'
153
      ),
154
      'superfish' => array(
155
        'js' => 'superfish.js',
156
        'version_pattern' => '@Superfish\s(v[0-9\.-]+)@i'
157
      )
158
    );
159

    
160
    // config libraries directory.
161
    $searchdir = array(
162
      'libraries/',
163
      conf_path() . '/libraries/',
164
      'profiles/' . drupal_get_profile() . '/libraries/',
165
      'sites/all/libraries/'
166
    );
167

    
168
    foreach ($plugins as $plugin => $file_info) {
169

    
170
      $libraries_file = NULL;
171

    
172
      // check libraries module.
173
      if (module_exists('libraries') && libraries_get_path($plugin) != '') {
174
        $library_directory = libraries_get_path($plugin);
175
        if (is_file(DRUPAL_ROOT . '/' . $library_directory . $plugin . '/' . $file_info['js'])) {
176
          $libraries_file = $library_directory . $plugin . '/' . $file_info['js'];
177
        }
178
      }
179

    
180
      // scan dir.
181
      if ($libraries_file === NULL) {
182
        foreach ($searchdir as $libraries_dir) {
183
          if (is_file(DRUPAL_ROOT . '/' . $libraries_dir . $plugin . '/' . $file_info['js'])) {
184
            $libraries_file = $libraries_dir . $plugin . '/' . $file_info['js'];
185
            break;
186
          }
187
        }
188
      }
189

    
190
      // add to libraries.
191
      if ($libraries_file !== NULL) {
192
        $libraries[$plugin]['version'] = nice_menus_get_version($libraries_file, array(
193
          'pattern' => $file_info['version_pattern']
194
        ));
195
        $libraries[$plugin]['js'] = array($libraries_file => array());
196
      }
197
    }
198
  }
199

    
200
  return $libraries;
201
}
202

    
203
/**
204
 * Gets the version information from an arbitrary library.
205
 *
206
 * @return
207
 *   A string containing the version of the library.
208
 */
209
function nice_menus_get_version($file, $options = array()) {
210
  // Provide defaults.
211
  $options += array(
212
    'file' => '',
213
    'pattern' => '',
214
    'lines' => 10,
215
    'cols' => 200,
216
  );
217

    
218
  $file = DRUPAL_ROOT . '/' . $file;
219

    
220
  if (!is_file($file)) {
221
    return;
222
  }
223
  $file = fopen($file, 'r');
224
  while ($options['lines'] && $line = fgets($file, $options['cols'])) {
225
    if (preg_match($options['pattern'], $line, $version)) {
226
      fclose($file);
227
      return $version[1];
228
    }
229
    $options['lines']--;
230
  }
231
  fclose($file);
232
}
233

    
234
/**
235
 * Implements hook_block_info().
236
 */
237
function nice_menus_block_info() {
238
  $blocks = array();
239
  for ($i = 1; $i <= variable_get('nice_menus_number', '2'); $i++) {
240
    $blocks[$i]['info'] = variable_get('nice_menus_name_' . $i, 'Nice menu ' . $i) . ' (Nice menu)';
241
    // We have too many things changing per user, per page to cache.
242
    $blocks[$i]['cache'] = DRUPAL_NO_CACHE;
243
  }
244
  return $blocks;
245
}
246

    
247
/**
248
 * Implements hook_block_configure().
249
 */
250
function nice_menus_block_configure($delta) {
251
  $form['nice_menus_name_' . $delta] = array(
252
    '#type' => 'textfield',
253
    '#title' => t('Menu name'),
254
    '#default_value' => variable_get('nice_menus_name_' . $delta, 'Nice menu ' . $delta),
255
  );
256
  $form['nice_menus_menu_' . $delta] = array(
257
    '#type' => 'select',
258
    '#title' => t('Menu parent'),
259
    '#description' => t('The menu parent from which to show a Nice menu.'),
260
    '#default_value' => variable_get('nice_menus_menu_' . $delta, 'navigation:0'),
261
    '#options' => menu_parent_options(menu_get_menus(), 0),
262
  );
263
  $form['nice_menus_depth_' . $delta] = array(
264
    '#type' => 'select',
265
    '#title' => t('Menu depth'),
266
    '#description' => t('The depth of the menu, i.e. the number of child levels starting with the parent selected above. Leave set to -1 to display all children and use 0 to display no children.'),
267
    '#default_value' => variable_get('nice_menus_depth_' . $delta, -1),
268
    '#options' => drupal_map_assoc(range(-1, 5)),
269
  );
270
  $form['nice_menus_type_' . $delta] = array(
271
    '#type' => 'select',
272
    '#title' => t('Menu style'),
273
    '#description' => t('right: menu items are listed on top of each other and expand to the right') . '<br />' . t('left: menu items are listed on top of each other and expand to the left') . '<br />' . t('down: menu items are listed side by side and expand down'),
274
    '#default_value' => variable_get('nice_menus_type_' . $delta, 'right'),
275
    '#options' => drupal_map_assoc(array('right', 'left', 'down')),
276
  );
277
  $form['nice_menus_respect_expand_' . $delta] = array(
278
    '#type' => 'select',
279
    '#title' => t('Respect "Show as expanded" option'),
280
    '#description' => t('Menu items have a "Show as expanded" option, which is disabled by default. Since menu items do NOT have this option checked by default, you should choose Yes here once you have configured the menu items that you DO want to expand.'),
281
    '#options' => array(
282
      0 => t('No'),
283
      1 => t('Yes'),
284
    ),
285
    '#default_value' => variable_get('nice_menus_respect_expand_' . $delta, 0),
286
  );
287
  return $form;
288
}
289

    
290
/**
291
 * Implements hook_block_save().
292
 */
293
function nice_menus_block_save($delta, $edit) {
294
  variable_set('nice_menus_name_' . $delta, $edit['nice_menus_name_' . $delta]);
295
  variable_set('nice_menus_menu_' . $delta, $edit['nice_menus_menu_' . $delta]);
296
  variable_set('nice_menus_depth_' . $delta, $edit['nice_menus_depth_' . $delta]);
297
  variable_set('nice_menus_type_' . $delta, $edit['nice_menus_type_' . $delta]);
298
  variable_set('nice_menus_respect_expand_' . $delta, $edit['nice_menus_respect_expand_' . $delta]);
299
}
300

    
301
/**
302
 * Implements hook_block_view().
303
 */
304
function nice_menus_block_view($delta = 1) {
305
  // Build the Nice menu for the block.
306
  list($menu_name, $mlid) = explode(':', variable_get('nice_menus_menu_' . $delta, 'navigation:0'));
307
  $direction = variable_get('nice_menus_type_' . $delta, 'right');
308
  $depth = variable_get('nice_menus_depth_' . $delta, '-1');
309
  $respect_expanded = variable_get('nice_menus_respect_expand_' . $delta, 0);
310
  if ($output = theme('nice_menus', array(
311
    'id' => $delta,
312
    'menu_name' => $menu_name,
313
    'mlid' => $mlid,
314
    'direction' => $direction,
315
    'depth' => $depth,
316
    'respect_expanded' => $respect_expanded))) {
317
    $block['content']['#markup'] = $output['content'];
318
    if (variable_get('nice_menus_type_' . $delta, 'right') == 'down') {
319
      $class = 'nice-menu-hide-title';
320
    }
321
    else {
322
      $class = 'nice-menu-show-title';
323
    }
324
    // If we're building the navigation block
325
    // use the same block title logic as menu module.
326
    global $user;
327
    if ($output['subject'] == t('navigation') && $user->uid) {
328
      $subject = $user->name;
329
    }
330
    else {
331
      $subject = $output['subject'];
332
    }
333
    $block['subject'] = '<span class="' . $class . '">' . check_plain($subject) . '</span>';
334
    $block['content']['#contextual_links']['simple_menus'] = array('admin/structure/menu/manage', array($menu_name));
335
  }
336
  else {
337
    $block['content'] = FALSE;
338
  }
339
  return $block;
340
}
341

    
342
/**
343
 * add nice_menus js library.
344
 */
345
function _load_nice_menus_library() {
346
  static $is_load = FALSE;
347
  if ($is_load === FALSE) {
348
    // Add Superfish JavaScript, if enabled.
349
    if (variable_get('nice_menus_js', 1) == 1) {
350
      drupal_add_library('nice_menus', 'nice_menus');
351
    }
352
    // Add main CSS functionality.
353
    drupal_add_css(drupal_get_path('module', 'nice_menus') . '/css/nice_menus.css', array('group' => CSS_DEFAULT, 'basename' => 'nice_menus.css'));
354
    // Add custom CSS layout if specified.
355
    if ($custom = variable_get('nice_menus_custom_css', '')) {
356
      drupal_add_css($custom, array('group' => CSS_DEFAULT, 'basename' => '/css/nice_menus_custom.css'));
357
    }
358
    // Fall back to default layout.
359
    else {
360
      drupal_add_css(drupal_get_path('module', 'nice_menus') . '/css/nice_menus_default.css', array('group' => CSS_DEFAULT, 'basename' => '/css/nice_menus_default.css'));
361
    }
362
    $is_load = TRUE;
363
  }
364
}
365

    
366
/**
367
 * Implements hook_theme().
368
 */
369
function nice_menus_theme() {
370
  return array(
371
    'nice_menus_tree' => array(
372
      'variables' => array(
373
        'menu_name' => NULL,
374
        'mlid' => NULL,
375
        'depth' => -1,
376
        'menu' => NULL,
377
        'respect_expanded' => 0,
378
      ),
379
    ),
380
    'nice_menus_build' => array(
381
      'variables' => array(
382
        'menu' => NULL,
383
        'depth' => -1,
384
        'trail' => NULL,
385
        'respect_expanded' => 0,
386
      ),
387
    ),
388
    'nice_menus' => array(
389
      'variables' => array(
390
        'id' => NULL,
391
        'menu_name' => NULL,
392
        'mlid' => NULL, 'direction' =>
393
        'right', 'depth' => -1,
394
        'respect_expanded' => 0,
395
        'menu' => NULL,
396
      ),
397
    ),
398
    'nice_menus_main_menu' => array(
399
      'variables' => array('direction' => 'down', 'depth' => -1),
400
    ),
401
    'nice_menus_secondary_menu' => array(
402
      'variables' => array('direction' => 'down', 'depth' => -1),
403
    ),
404
  );
405
}
406

    
407
/**
408
 * Builds the active trail from the page's menu data.
409
 *
410
 * @param array $page_menu
411
 *   The menu data for a page.
412
 *
413
 * @return mixed
414
 *   An array of parent menu item ids.
415
 */
416
function nice_menus_build_page_trail($page_menu) {
417
  $trail = array();
418
  foreach ($page_menu as $item) {
419
    if ($item['link']['in_active_trail']) {
420
      $trail[] = $item['link']['mlid'];
421
    }
422
    if ($item['below']) {
423
      $trail = array_merge($trail, nice_menus_build_page_trail($item['below']));
424
    }
425
  }
426
  return $trail;
427
}
428

    
429
/**
430
 * Builds the final Nice menu.
431
 *
432
 * @return mixed
433
 *   An HTML string of properly nested Nice menu lists.
434
 */
435
function theme_nice_menus_tree($variables) {
436
  // load nice_menus js and css.
437
  _load_nice_menus_library();
438

    
439
  /*
440
   * The top-level menu name that contains the menu to use (e.g. navigation
441
   * or main-menu) for Drupal menus. For custom $menus this is just the
442
   * name for menu display.
443
   */
444
  $menu_name = $variables['menu_name'];
445

    
446
  /*
447
   * The menu ID from which to start building the items, i.e. the parent
448
   * of the displayed menu.
449
   */
450
  $mlid = $variables['mlid'];
451

    
452
  /*
453
   * The number of children levels to display. Use -1 to display all children
454
   * and use 0 to display no children.
455
   */
456
  $depth = $variables['depth'];
457

    
458
  /*
459
   * Optional. A custom menu array to use for theming -- it should have.
460
   * the same structure as that returned by menu_tree_all_data().
461
   */
462
  $menu = $variables['menu'];
463
  $respect_expanded = $variables['respect_expanded'];
464
  // Load the full menu array.
465
  $menu = isset($menu) ? $menu : menu_tree_all_data($menu_name);
466
  if (isset($menu)) {
467
    $page_menu = menu_tree_page_data($menu_name);
468
    $trail = nice_menus_build_page_trail($page_menu);
469
    unset($page_menu);
470
  }
471

    
472
  // Allow i18n module to translate strings where available.
473
  if (module_exists('i18n_menu')) {
474
    $menu = i18n_menu_localize_tree($menu);
475
  }
476
  // Assume depth == 0 by default, overriden if mlid is specified.
477
  $parent_depth = 0;
478

    
479
  // For custom $menus and menus built all the way from the top-level we.
480
  // don't need to "create" the specific sub-menu and we need to get the title.
481
  // from the $menu_name since there is no "parent item" array.
482
  // Create the specific menu if we have a mlid.
483
  if (!empty($mlid)) {
484
    // Load the parent menu item.
485
    $item = menu_link_load($mlid);
486
    $title = check_plain($item['title']);
487
    // The depth for our parent item, if it exists.
488
    $parent_depth = ($item['depth']) ? $item['depth'] : 0;
489

    
490
    // Narrow down the full menu to the specific sub-tree we need.
491
    for ($p = 1; $p < 10; $p++) {
492
      if ($sub_mlid = $item["p$p"]) {
493
        $subitem = menu_link_load($sub_mlid);
494
        // Menu sets these ghetto-ass keys in _menu_tree_check_access().
495
        $menu = $menu[(50000 + $subitem['weight']) . ' ' . $subitem['title'] . ' ' . $subitem['mlid']]['below'];
496
      }
497
    }
498
  }
499
  // Otherwise just set a title and move on.
500
  else {
501
    // Get the title from the DB since we don't have it in the $menu.
502
    $result = db_query("SELECT title FROM {menu_custom} WHERE menu_name = :menu_name", array(':menu_name' => $menu_name))->fetchField();
503
    $title = check_plain($result);
504
  }
505

    
506
  $output['content'] = '';
507
  $output['subject'] = $title;
508

    
509
  if ($menu) {
510
    // Set the total menu depth counting from this parent if we need it.
511
    $depth = ($depth > 0) ? ($parent_depth + $depth) : $depth;
512
    $output['content'] .= theme('nice_menus_build', array(
513
      'menu' => $menu,
514
      'depth' => $depth,
515
      'trail' => $trail,
516
      'respect_expanded' => $respect_expanded,
517
    ));
518
  }
519

    
520
  return $output;
521
}
522

    
523
/**
524
 * Helper function that builds the nested lists of a Nice menu.
525
 *
526
 * @param array $variables
527
 *   Menu arguments.
528
 */
529
function theme_nice_menus_build($variables) {
530
  // Menu array from which to build the nested lists.
531
  $menu = $variables['menu'];
532

    
533
  // The number of children levels to display. Use -1 to display all children
534
  // and use 0 to display no children.
535
  $depth = $variables['depth'];
536

    
537
  // An array of parent menu items.
538
  $trail = $variables['trail'];
539
  // "Show as expanded" option.
540
  $respect_expanded = $variables['respect_expanded'];
541

    
542
  $output = '';
543
  // Prepare to count the links so we can mark first, last, odd and even.
544
  $index = 0;
545
  $count = 0;
546
  foreach ($menu as $menu_count) {
547
    if ($menu_count['link']['hidden'] == 0) {
548
      $count++;
549
    }
550
  }
551
  // Get to building the menu.
552
  foreach ($menu as $menu_item) {
553
    $mlid = $menu_item['link']['mlid'];
554
    // Check to see if it is a visible menu item.
555
    if (!isset($menu_item['link']['hidden']) || $menu_item['link']['hidden'] == 0) {
556
      // Check our count and build first, last, odd/even classes.
557
      $index++;
558
      $first_class = ($index == 1) ? 'first' : '';
559
      $oddeven_class = ($index % 2 == 0) ? 'even' : 'odd';
560
      $last_class = ($index == $count) ? 'last' : '';
561
      // Build class name based on menu path
562
      // e.g. to give each menu item individual style.
563
      $class = str_replace(array('http', 'https', '://', 'www'), '', $menu_item['link']['href']);
564
      // Strip funny symbols.
565
      $class = drupal_html_class('menu-path-' . $class);
566
      if ($trail && in_array($mlid, $trail)) {
567
        $class .= ' active-trail';
568
      }
569
      // If it has children build a nice little tree under it.
570
      // Build a nice little tree under it if it has children, and has been set
571
      // to expand (when that option is being respected).
572
      if ((!empty($menu_item['link']['has_children'])) &&
573
          (!empty($menu_item['below'])) && $depth != 0 &&
574
          ($respect_expanded == 0 || $menu_item['link']['expanded'])) {
575
        // Keep passing children into the function 'til we get them all.
576
        if ($menu_item['link']['depth'] <= $depth || $depth == -1) {
577
          $children = array(
578
            '#theme' => 'nice_menus_build',
579
            '#prefix' => '<ul>',
580
            '#suffix' => '</ul>',
581
            '#menu' => $menu_item['below'],
582
            '#depth' => $depth,
583
            '#trail' => $trail,
584
            '#respect_expanded' => $respect_expanded,
585
          );
586
        }
587
        else {
588
          $children = '';
589
        }
590
        // Set the class to parent only of children are displayed.
591
        $parent_class = ($children && ($menu_item['link']['depth'] <= $depth || $depth == -1)) ? 'menuparent ' : '';
592
        $element = array(
593
          '#below' => $children,
594
          '#title' => $menu_item['link']['title'],
595
          '#href' => $menu_item['link']['href'],
596
          '#localized_options' => $menu_item['link']['localized_options'],
597
          '#attributes' => array(
598
            'class' => array(
599
              'menu-' . $mlid,
600
              $parent_class,
601
              $class,
602
              $first_class,
603
              $oddeven_class,
604
              $last_class,
605
            ),
606
          ),
607
          '#original_link' => $menu_item['link'],
608
        );
609
        $variables['element'] = $element;
610

    
611
        // Check for context reactions menu.
612
        if (module_exists('context')) {
613
          context_preprocess_menu_link($variables);
614
          if (isset($variables['element']['#localized_options']['attributes']['class']) &&
615
            in_array('active', $variables['element']['#localized_options']['attributes']['class']) &&
616
            !in_array('active-trail', $variables['element']['#attributes']['class'])) {
617
            $variables['element']['#attributes']['class'][] = ' active-trail';
618
          }
619
        }
620

    
621
        $output .= theme('menu_link', $variables);
622
      }
623
      else {
624
        $element = array(
625
          '#below' => '',
626
          '#title' => $menu_item['link']['title'],
627
          '#href' => $menu_item['link']['href'],
628
          '#localized_options' => $menu_item['link']['localized_options'],
629
          '#attributes' => array(
630
            'class' => array(
631
              'menu-' . $mlid,
632
              $class,
633
              $first_class,
634
              $oddeven_class,
635
              $last_class,
636
            ),
637
          ),
638
          '#original_link' => $menu_item['link'],
639
        );
640
        $variables['element'] = $element;
641

    
642
        // Check for context reactions menu.
643
        if (module_exists('context')) {
644
          context_preprocess_menu_link($variables);
645
          if (isset($variables['element']['#localized_options']['attributes']['class']) &&
646
            in_array('active', $variables['element']['#localized_options']['attributes']['class']) &&
647
            !in_array('active-trail', $variables['element']['#attributes']['class'])) {
648
            $variables['element']['#attributes']['class'][] = ' active-trail';
649
          }
650
        }
651

    
652
        $output .= theme('menu_link', $variables);
653
      }
654
    }
655
  }
656
  return $output;
657
}
658

    
659
/**
660
 * Theme function to allow any menu tree to be themed as a Nice menu.
661
 *
662
 * @param array $variables
663
 *   is an array, menu arguments.
664
 *
665
 * @return mixed
666
 *   An HTML string of Nice menu links.
667
 */
668
function theme_nice_menus($variables) {
669
  $output = array(
670
    'content' => '',
671
    'subject' => '',
672
  );
673

    
674
  // The Nice menu ID.
675
  $id = $variables['id'];
676
  // The top parent menu name from which to build the full menu.
677
  $menu_name = $variables['menu_name'];
678
  // The menu ID from which to build the displayed menu.
679
  $mlid = $variables['mlid'];
680
  // Optional. The direction the menu expands. Default is 'right'.
681
  $direction = $variables['direction'];
682
  // The number of children levels to display. Use -1 to display all children
683
  // and use 0 to display no children.
684
  $depth = $variables['depth'];
685
  /*
686
   * Optional. A custom menu array to use for theming --
687
   * it should have the same structure as that returned
688
   * by menu_tree_all_data(). Default is the standard menu tree.
689
   */
690
  $menu = $variables['menu'];
691
  // "Show as expanded" option.
692
  $respect_expanded = $variables['respect_expanded'];
693
  if ($menu_tree = theme('nice_menus_tree', array(
694
    'menu_name' => $menu_name,
695
    'mlid' => $mlid,
696
    'depth' => $depth,
697
    'menu' => $menu,
698
    'respect_expanded' => $respect_expanded))) {
699
    if ($menu_tree['content']) {
700
      $output['content'] = '<ul class="nice-menu nice-menu-' . $direction . ' nice-menu-' . $menu_name . '" id="nice-menu-' . $id . '">' . $menu_tree['content'] . '</ul>' . "\n";
701
      $output['subject'] = $menu_tree['subject'];
702
    }
703
  }
704
  return $output;
705
}
706

    
707
/**
708
 * Theme the main menu as a Nice menu.
709
 *
710
 * @return mixed
711
 *   An HTML string of Nice main menu links.
712
 */
713
function theme_nice_menus_main_menu($variables) {
714
  // Optional. The direction the menu expands. Default is 'down'.
715
  $direction = $variables['direction'];
716

    
717
  // The number of children levels to display. Use -1 to display all children.
718
  // and use 0 to display no children.
719
  $depth = $variables['depth'];
720
  $menu_name = variable_get('menu_main_links_source', 'main-menu');
721
  $output = theme('nice_menus', array(
722
    'id' => 0,
723
    'menu_name' => $menu_name,
724
    'mlid' => 0,
725
    'direction' => $direction,
726
    'depth' => $depth,
727
  ));
728
  return $output['content'];
729
}
730

    
731
/**
732
 * Theme the secondary menu as a Nice menu.
733
 *
734
 * @return mixed
735
 *   An HTML string of Nice secondary menu links.
736
 */
737
function theme_nice_menus_secondary_menu($variables) {
738
  // Optional. The direction the menu expands. Default is 'down'.
739
  $direction = $variables['direction'];
740

    
741
  // The number of children levels to display. Use -1 to display all children
742
  // and use 0 to display no children.
743
  $depth = $variables['depth'];
744
  $menu_name = variable_get('menu_secondary_links_source', 'user-menu');
745
  $output = theme('nice_menus', array(
746
    'id' => 0,
747
    'menu_name' => $menu_name,
748
    'mlid' => 0,
749
    'direction' => $direction,
750
    'depth' => $depth,
751
  ));
752
  return $output['content'];
753
}