Projet

Général

Profil

Paste
Télécharger (12,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / menu_attributes / menu_attributes.module @ 2e0f6994

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 configuration.'),
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
    'item_description' => t('Specifies a unique ID to be added to the item.'),
60
    'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
61
  );
62
  $info['name'] = array(
63
    'label' => t('Name'),
64
    'scope' => array(MENU_ATTRIBUTES_LINK),
65
  );
66
  $info['rel'] = array(
67
    'label' => t('Relationship'),
68
    'description' => t("Specifies the relationship between the current page and the link. Enter 'nofollow' here to nofollow this link."),
69
    'scope' => array(MENU_ATTRIBUTES_LINK),
70
  );
71
  $info['class'] = array(
72
    'label' => t('Classes'),
73
    'description' => t('Enter additional classes to be added to the link.'),
74
    'item_description' => t('Enter additional CSS class names to be added to the item.'),
75
    'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
76
  );
77
  $info['style'] = array(
78
    'label' => t('Style'),
79
    'description' => t('Enter additional styles to be applied to the link.'),
80
    'item_description' => t('Enter additional styles attribute to be applied to the item.'),
81
    'scope' => array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM),
82
  );
83
  $info['target'] = array(
84
    'label' => t('Target'),
85
    'description' => t('Specifies where to open the link. Using this attribute breaks XHTML validation.'),
86
    'form' => array(
87
      '#type' => 'select',
88
      '#options' => array(
89
        '' => t('None (i.e. same window)'),
90
        '_blank' => t('New window (_blank)'),
91
        '_top' => t('Top window (_top)'),
92
        '_self' => t('Same window (_self)'),
93
        '_parent' => t('Parent window (_parent)'),
94
      ),
95
    ),
96
    'scope' => array(MENU_ATTRIBUTES_LINK),
97
  );
98
  $info['accesskey'] = array(
99
    'label' => t('Access Key'),
100
    'description' => t('Specifies a <a href="@accesskey">keyboard shortcut</a> to access this link.', array('@accesskey' => url('http://en.wikipedia.org/wiki/Access_keys'))),
101
    'form' => array(
102
      '#maxlength' => 1,
103
      '#size' => 1,
104
    ),
105
    'scope' => array(MENU_ATTRIBUTES_LINK),
106
  );
107
  return $info;
108
}
109

    
110
/**
111
 * Fetch an array of menu attributes.
112
 */
113
function menu_attributes_get_menu_attribute_info() {
114
  $attributes = module_invoke_all('menu_attribute_info');
115

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

    
132
  return $attributes;
133
}
134

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

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

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

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

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

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

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

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

    
219
      // If the item description is set, override the form description.
220
      if ($group == MENU_ATTRIBUTES_ITEM && isset($info['item_description'])) {
221
        $info['form']['#description'] = $info['item_description'];
222
      }
223

    
224
      $form['options'][$group][$attribute] = $info['form'] + array(
225
        '#access' => $info['enabled'],
226
      );
227
    }
228
  }
229

    
230
  // Add form values for the reset of $item['options'] and
231
  // $item['options']['attributes'] so the values will carry over during save.
232
  foreach ($item['options'] as $key => $value) {
233
    if ($key !== 'attributes' && !isset($form['options'][$key])) {
234
      $form['options'][$key] = array(
235
        '#type' => 'value',
236
        '#value' => $value,
237
      );
238
    }
239
  }
240
  foreach (array(MENU_ATTRIBUTES_LINK, MENU_ATTRIBUTES_ITEM) as $group) {
241
    if (isset($item['options'][$group])) {
242
      foreach ($item['options'][$group] as $key => $value) {
243
        if (!isset($form['options'][$group][$key])) {
244
          $form['options'][$group][$key] = array(
245
            '#type' => 'value',
246
            '#value' => $value,
247
          );
248
        }
249
      }
250
    }
251
  }
252

    
253
  // Hide the 'description' field since we will be using our own 'title' field.
254
  if (isset($form['description'])) {
255
    $form['description']['#access'] = FALSE;
256

    
257
    // Because this form uses a special $form['description'] field which is
258
    // really the 'title' attribute, we need to add special pre-submit handling
259
    // to ensure our field gets saved as the title attribute.
260
    array_unshift($complete_form['#submit'], '_menu_attributes_form_submit');
261
  }
262

    
263
  // Restrict access to the new form elements.
264
  $has_visible_children = (bool) element_get_visible_children($form['options']['attributes']);
265
  $user_has_access = user_access('administer menu attributes');
266
  $form['options']['attributes']['#access'] = ($has_visible_children && $user_has_access);
267

    
268
  $has_visible_children = (bool) element_get_visible_children($form['options']['item_attributes']);
269
  $form['options']['item_attributes']['#access'] = ($has_visible_children && $user_has_access);
270
}
271

    
272
/**
273
 * Form submit handler for menu item links.
274
 *
275
 * Move the title attributes value into the 'description' value so that it
276
 * will get properly saved.
277
 */
278
function _menu_attributes_form_submit($form, &$form_state) {
279
  if (isset($form_state['values']['menu']['options']['attributes']['title'])) {
280
    $form_state['values']['menu']['description'] = $form_state['values']['menu']['options']['attributes']['title'];
281
  }
282
  elseif (isset($form_state['values']['options']['attributes']['title'])) {
283
    $form_state['values']['description'] = $form_state['values']['options']['attributes']['title'];
284
  }
285
}
286

    
287
/**
288
 * Implements hook_form_FORM_ID_alter().
289
 *
290
 * Alters the menu settings form with our menu attribute settings.
291
 *
292
 * @see menu_configure_form()
293
 */
294
function menu_attributes_form_menu_configure_alter(&$form, $form_state) {
295
  if (!user_access('administer menu attributes')) {
296
    return;
297
  }
298

    
299
  $form['attributes_title'] = array(
300
    '#type' => 'item',
301
    '#title' => t('Menu item attribute options'),
302
  );
303
  $form['attributes_vertical_tabs'] = array(
304
    '#type' => 'vertical_tabs',
305
    '#attached' => array(
306
      'js' => array(drupal_get_path('module', 'menu_attributes') . '/menu_attributes.js'),
307
    ),
308
  );
309

    
310
  $attributes = menu_attributes_get_menu_attribute_info();
311
  foreach ($attributes as $attribute => $info) {
312
    $form['attributes'][$attribute] = array(
313
      '#type' => 'fieldset',
314
      '#title' => $info['label'],
315
      '#group' => 'attributes_vertical_tabs',
316
      '#description' => $info['form']['#description'],
317
    );
318
    $form['attributes'][$attribute]["menu_attributes_{$attribute}_enable"] = array(
319
      '#type' => 'checkbox',
320
      '#title' => t('Enable the @attribute attribute.', array('@attribute' => drupal_strtolower($info['label']))),
321
      '#default_value' => $info['enabled'],
322
    );
323
    $form['attributes'][$attribute]["menu_attributes_{$attribute}_default"] = array(
324
      '#title' => t('Default'),
325
      '#description' => '',
326
      '#states' => array(
327
        'invisible' => array(
328
          'input[name="menu_attributes_' . $attribute . '_enable"]' => array('checked' => FALSE),
329
        ),
330
      ),
331
    ) + $info['form'];
332
  }
333
}
334

    
335
/**
336
 * Implements MODULE_preprocess_HOOK().
337
 *
338
 * Adds appropriate attributes to the list item.
339
 *
340
 * @see theme_menu_link()
341
 */
342
function menu_attributes_preprocess_menu_link(&$variables) {
343
  $options = &$variables['element']['#localized_options'];
344
  $attributes = &$variables['element']['#attributes'];
345

    
346
  if (isset($options['item_attributes'])) {
347
    foreach ($options['item_attributes'] as $attribute => $value) {
348
      if (!empty($value)) {
349
        // Class get's special treatment, as it's an array and it should not
350
        // replace existing values.
351
        if ($attribute == 'class') {
352
          $value = !is_array($value) ? explode(' ', $value) : $value;
353
          if (isset($attributes[$attribute])) {
354
            $value = array_merge($attributes[$attribute], $value);
355
          }
356
        }
357
        // Override the attribute.
358
        $attributes[$attribute] = $value;
359
      }
360
    }
361

    
362
    // Clean up, so we're not passing this to l().
363
    unset($options['item_attributes']);
364
  }
365
}