Projet

Général

Profil

Paste
Télécharger (11,5 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / menu_attributes / menu_attributes.module @ c8740e19

1
<?php
2

    
3
/**
4
 * @file
5
 * Alters the menu item form to allow the administrator to specify additional
6
 * attributes for the menu link
7
 */
8

    
9
define('MENU_ATTRIBUTES_LINK', 'attributes');
10
define('MENU_ATTRIBUTES_ITEM', 'item_attributes');
11

    
12
/**
13
 * Implements hook_permission().
14
 */
15
function menu_attributes_permission() {
16
  return array(
17
    'administer menu attributes' => array(
18
      'title' => t('Administer menu attributes'),
19
      'description' => t('Administer menu attributes.'),
20
    ),
21
  );
22
}
23

    
24
/**
25
 * Implements hook_menu_link_alter().
26
 */
27
function menu_attributes_menu_link_alter(&$item, $menu) {
28
  if (isset($item['options']['attributes']) && is_array($item['options']['attributes'])) {
29
    // Filter out blank attributes.
30
    foreach ($item['options']['attributes'] as $key => $value) {
31
      if ((is_array($value) && empty($value)) || is_string($value) && !drupal_strlen($value)) {
32
        unset($item['options']['attributes'][$key]);
33
      }
34
    }
35

    
36
    // Convert classes to an array.
37
    if (isset($item['options']['attributes']['class']) && is_string($item['options']['attributes']['class'])) {
38
      $item['options']['attributes']['class'] = array_filter(explode(' ', $item['options']['attributes']['class']));
39
    }
40
  }
41
}
42

    
43
/**
44
 * Implements hook_menu_attribute_info().
45
 */
46
function menu_attributes_menu_attribute_info() {
47
  $info['title'] = array(
48
    'label' => t('Title'),
49
    'description' => t('The description displayed when hovering over the link.'),
50
    'form' => array(
51
      '#type' => 'textarea',
52
      '#rows' => 2,
53
    ),
54
    'scope' => array(MENU_ATTRIBUTES_LINK),
55
  );
56
  $info['id'] = array(
57
    'label' => t('ID'),
58
    'description' => t('Specifies a unique ID for the link.'),
59
    'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
60
  );
61
  $info['name'] = array(
62
    'label' => t('Name'),
63
    'scope' => array(MENU_ATTRIBUTES_LINK),
64
  );
65
  $info['rel'] = array(
66
    'label' => t('Relationship'),
67
    'description' => t("Specifies the relationship between the current page and the link. Enter 'nofollow' here to nofollow this link."),
68
    'scope' => array(MENU_ATTRIBUTES_LINK),
69
  );
70
  $info['class'] = array(
71
    'label' => t('Classes'),
72
    'description' => t('Enter additional classes to be added to the link.'),
73
    'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
74
  );
75
  $info['style'] = array(
76
    'label' => t('Style'),
77
    'description' => t('Enter additional styles to be applied to the link.'),
78
    'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
79
  );
80
  $info['target'] = array(
81
    'label' => t('Target'),
82
    'description' => t('Specifies where to open the link. Using this attribute breaks XHTML validation.'),
83
    'form' => array(
84
      '#type' => 'select',
85
      '#options' => array(
86
        '' => t('None (i.e. same window)'),
87
        '_blank' => t('New window (_blank)'),
88
        '_top' => t('Top window (_top)'),
89
        '_self' => t('Same window (_self)'),
90
        '_parent' => t('Parent window (_parent)'),
91
      ),
92
    ),
93
    'scope' => array(MENU_ATTRIBUTES_LINK),
94
  );
95
  $info['accesskey'] = array(
96
    'label' => t('Access Key'),
97
    'description' => t('Specifies a <a href="@accesskey">keyboard shortcut</a> to access this link.', array('@accesskey' => url('http://en.wikipedia.org/wiki/Access_keys'))),
98
    'form' => array(
99
      '#maxlength' => 1,
100
      '#size' => 1,
101
    ),
102
    'scope' => array(MENU_ATTRIBUTES_LINK),
103
  );
104
  return $info;
105
}
106

    
107
/**
108
 * Fetch an array of menu attributes.
109
 */
110
function menu_attributes_get_menu_attribute_info() {
111
  $attributes = module_invoke_all('menu_attribute_info');
112

    
113
  // Merge in default values.
114
  foreach ($attributes as $attribute => &$info) {
115
    $info += array(
116
      'form' => array(),
117
      'enabled' => variable_get("menu_attributes_{$attribute}_enable", 1),
118
      'default' => '',
119
    );
120
    $info['form'] += array(
121
      '#type' => 'textfield',
122
      '#title' => $info['label'],
123
      '#description' => isset($info['description']) ? $info['description'] : '',
124
      '#default_value' => variable_get("menu_attributes_{$attribute}_default", $info['default']),
125
    );
126
  }
127
  drupal_alter('menu_attribute_info', $attributes);
128

    
129
  return $attributes;
130
}
131

    
132
/**
133
 * Implements hook_form_FORM_ID_alter().
134
 *
135
 * Adds menu attribute options to the edit menu item form.
136
 *
137
 * @see menu_edit_item()
138
 * @see _menu_attributes_form_alter()
139
 * @see menu_attributes_form_menu_edit_item_submit()
140
 */
141
function menu_attributes_form_menu_edit_item_alter(&$form, $form_state) {
142
  $item = $form['original_item']['#value'];
143
  _menu_attributes_form_alter($form, $item, $form);
144
}
145

    
146
/**
147
 * Implements hook_form_FORM_ID_alter().
148
 *
149
 * Adds menu attribute options to the node's edit menu item form.
150
 *
151
 * @see _menu_attributes_form_alter()
152
 */
153
function menu_attributes_form_node_form_alter(&$form, $form_state) {
154
  if (isset($form['menu']['link']) && isset($form['#node']->menu)) {
155
    $item = $form['#node']->menu;
156
    _menu_attributes_form_alter($form['menu']['link'], $item, $form);
157
  }
158
}
159

    
160
/**
161
 * Add the menu attributes to a menu item edit form.
162
 *
163
 * @param $form
164
 *   The menu item edit form passed by reference.
165
 * @param $item
166
 *   The optional existing menu item for context.
167
 */
168
function _menu_attributes_form_alter(array &$form, array $item = array(), array &$complete_form) {
169
  $form['options']['#tree'] = TRUE;
170
  $form['options']['#weight'] = 50;
171

    
172
  // Unset the previous value so that the new values get saved.
173
  unset($form['options']['#value']['attributes']);
174
  unset($form['options']['#value']['item_attributes']);
175

    
176
  $form['options'][MENU_ATTRIBUTES_LINK] = array(
177
    '#type' => 'fieldset',
178
    '#title' => t('Menu link attributes'),
179
    '#collapsible' => TRUE,
180
    '#collapsed' => FALSE,
181
    '#tree' => TRUE,
182
  );
183

    
184
  $form['options'][MENU_ATTRIBUTES_ITEM] = array(
185
    '#type' => 'fieldset',
186
    '#title' => t('Menu item attributes'),
187
    '#collapsible' => TRUE,
188
    '#collapsed' => TRUE,
189
    '#tree' => TRUE,
190
  );
191

    
192
  $attributes = menu_attributes_get_menu_attribute_info();
193
  foreach ($attributes as $attribute => $info) {
194
    // If no scope is set, this attribute should be available to both link
195
    // and item.
196
    if (!isset($info['scope'])) {
197
      $info['scope'] = array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM);
198
    }
199

    
200
    // Define fields for each scope.
201
    foreach ($info['scope'] as $group) {
202
      // Merge in the proper default value.
203
      if (isset($item['options'][$group][$attribute])) {
204
        // If the menu link already has this attribute, use it.
205
        $info['form']['#default_value'] = $item['options'][$group][$attribute];
206
        // Convert the classes array to a string for the form.
207
        if ($attribute == 'class' && is_array($info['form']['#default_value'])) {
208
          $info['form']['#default_value'] = implode(' ', $info['form']['#default_value']);
209
        }
210
      }
211
      elseif ($item['mlid']) {
212
        // If this is an existing link, use the raw default (usually empty).
213
        $info['form']['#default_value'] = $info['default'];
214
      }
215
      $form['options'][$group][$attribute] = $info['form'] + array(
216
        '#access' => $info['enabled'],
217
      );
218
    }
219
  }
220

    
221
  // Add form values for the reset of $item['options'] and
222
  // $item['options']['attributes'] so the values will carry over during save.
223
  foreach ($item['options'] as $key => $value) {
224
    if ($key !== 'attributes' && !isset($form['options'][$key])) {
225
      $form['options'][$key] = array(
226
        '#type' => 'value',
227
        '#value' => $value,
228
      );
229
    }
230
  }
231
  foreach (array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM) as $group) {
232
    if (isset($item['options'][$group])) {
233
      foreach ($item['options'][$group] as $key => $value) {
234
        if (!isset($form['options'][$group][$key])) {
235
          $form['options'][$group][$key] = array(
236
            '#type' => 'value',
237
            '#value' => $value,
238
          );
239
        }
240
      }
241
    }
242
  }
243

    
244
  // Hide the 'description' field since we will be using our own 'title' field.
245
  if (isset($form['description'])) {
246
    $form['description']['#access'] = FALSE;
247

    
248
    // Because this form uses a special $form['description'] field which is
249
    // really the 'title' attribute, we need to add special pre-submit handling
250
    // to ensure our field gets saved as the title attribute.
251
    array_unshift($complete_form['#submit'], '_menu_attributes_form_submit');
252
  }
253

    
254
  // Restrict access to the new form elements.
255
  $has_visible_children = (bool) element_get_visible_children($form['options']['attributes']);
256
  $user_has_access = user_access('administer menu attributes');
257
  $form['options']['attributes']['#access'] = ($has_visible_children && $user_has_access);
258
}
259

    
260
/**
261
 * Form submit handler for menu item links.
262
 *
263
 * Move the title attributes value into the 'description' value so that it
264
 * will get properly saved.
265
 */
266
function _menu_attributes_form_submit($form, &$form_state) {
267
  if (isset($form_state['values']['menu']['options']['attributes']['title'])) {
268
    $form_state['values']['menu']['description'] = $form_state['values']['menu']['options']['attributes']['title'];
269
  }
270
  elseif (isset($form_state['values']['options']['attributes']['title'])) {
271
    $form_state['values']['description'] = $form_state['values']['options']['attributes']['title'];
272
  }
273
}
274

    
275
/**
276
 * Implements hook_form_FORM_ID_alter().
277
 *
278
 * Alters the menu settings form with our menu attribute settings.
279
 *
280
 * @see menu_configure_form()
281
 */
282
function menu_attributes_form_menu_configure_alter(&$form, $form_state) {
283
  if (!user_access('administer menu attributes')) {
284
    return;
285
  }
286

    
287
  $form['attributes_title'] = array(
288
    '#type' => 'item',
289
    '#title' => t('Menu item attribute options'),
290
  );
291
  $form['attributes_vertical_tabs'] = array(
292
    '#type' => 'vertical_tabs',
293
    '#attached' => array(
294
      'js' => array(drupal_get_path('module', 'menu_attributes') . '/menu_attributes.js'),
295
    ),
296
  );
297

    
298
  $attributes = menu_attributes_get_menu_attribute_info();
299
  foreach ($attributes as $attribute => $info) {
300
    $form['attributes'][$attribute] = array(
301
      '#type' => 'fieldset',
302
      '#title' => $info['label'],
303
      '#group' => 'attributes_vertical_tabs',
304
      '#description' => $info['form']['#description'],
305
    );
306
    $form['attributes'][$attribute]["menu_attributes_{$attribute}_enable"] = array(
307
      '#type' => 'checkbox',
308
      '#title' => t('Enable the @attribute attribute.', array('@attribute' => drupal_strtolower($info['label']))),
309
      '#default_value' => $info['enabled'],
310
    );
311
    $form['attributes'][$attribute]["menu_attributes_{$attribute}_default"] = array(
312
      '#title' => t('Default'),
313
      '#description' => '',
314
      '#states' => array(
315
        'invisible' => array(
316
          'input[name="menu_attributes_' . $attribute . '_enable"]' => array('checked' => FALSE),
317
        ),
318
      ),
319
    ) + $info['form'];
320
  }
321
}
322

    
323
/**
324
 * Implements MODULE_preprocess_HOOK().
325
 *
326
 * Adds appropriate attributes to the list item.
327
 *
328
 * @see theme_menu_link()
329
 */
330
function menu_attributes_preprocess_menu_link(&$variables) {
331
  $options = &$variables['element']['#localized_options'];
332
  $attributes = &$variables['element']['#attributes'];
333

    
334
  if (isset($options['item_attributes'])) {
335
    foreach ($options['item_attributes'] as $attribute => $value) {
336
      if (!empty($value)) {
337
        // Class get's special treatment, as it's an array and it should not
338
        // replace existing values.
339
        if ($attribute == 'class') {
340
          $value = explode(' ', $value);
341
          if (isset($attributes[$attribute])) {
342
            $value = array_merge($attributes[$attribute], $value);
343
          }
344
        }
345
        // Override the attribute.
346
        $attributes[$attribute] = $value;
347
      }
348
    }
349

    
350
    // Clean up, so we're not passing this to l().
351
    unset($options['item_attributes']);
352
  }
353
}