0

I'm altering the "Edit menu link" form

function module_name_form_menu_edit_item_alter(&$form, &$form_state, $form_id) {
    $form['html_content'] = array(
        '#type' => 'textarea',
        '#title' => t('HTML Content'),
        '#maxlength' => 180,
        '#required' => FALSE,
        '#description' => 'Put here the HTML code of the menu'
    );
}

The text area is showing fine, but it's not saving the information I put into. How can I solve that?

2
  • 1
    Are you expecting Drupal to automatically save the data in this custom form element, associate it with the menu link, then re-load it for you every time you re-load that menu link in any context??!!
    – Clive
    Mar 20, 2012 at 10:18
  • Hi Clive, I'm new to Drupal. Any ideas how to save this? Using "set_variable" is not the right way in my opinion since there are lots of menu links.
    – Omar Abid
    Mar 20, 2012 at 10:35

1 Answer 1

3

Generally speaking, only the form builds with system_settings_form() automatically saves the form field content of all the form fields present in the form. This is because its form submission handler (system_settings_form_submit()) contains the following code.

  foreach ($form_state['values'] as $key => $value) {
    if (is_array($value) && isset($form_state['values']['array_filter'])) {
      $value = array_keys(array_filter($value));
    }
    variable_set($key, $value);
  }

The form you are altering has a different form submission handler, menu_edit_item_submit(), which doesn't contain similar code. The function that is called for saving the menu item, menu_link_save() saves the fields it knows of, and which are defined in the database schema for the table used for this purpose.

  if (!$existing_item) {
    $item['mlid'] = db_insert('menu_links')
      ->fields(array(
      'menu_name' => $item['menu_name'], 
      'plid' => $item['plid'], 
      'link_path' => $item['link_path'], 
      'hidden' => $item['hidden'], 
      'external' => $item['external'], 
      'has_children' => $item['has_children'], 
      'expanded' => $item['expanded'], 
      'weight' => $item['weight'], 
      'module' => $item['module'], 
      'link_title' => $item['link_title'], 
      'options' => serialize($item['options']), 
      'customized' => $item['customized'], 
      'updated' => $item['updated'],
    ))
      ->execute();
  }
db_update('menu_links')
  ->fields(array(
  'menu_name' => $item['menu_name'], 
  'plid' => $item['plid'], 
  'link_path' => $item['link_path'], 
  'router_path' => $item['router_path'], 
  'hidden' => $item['hidden'], 
  'external' => $item['external'], 
  'has_children' => $item['has_children'], 
  'expanded' => $item['expanded'], 
  'weight' => $item['weight'], 
  'depth' => $item['depth'], 
  'p1' => $item['p1'], 
  'p2' => $item['p2'], 
  'p3' => $item['p3'], 
  'p4' => $item['p4'], 
  'p5' => $item['p5'], 
  'p6' => $item['p6'], 
  'p7' => $item['p7'], 
  'p8' => $item['p8'], 
  'p9' => $item['p9'], 
  'module' => $item['module'], 
  'link_title' => $item['link_title'], 
  'options' => serialize($item['options']), 
  'customized' => $item['customized'],
))
  ->condition('mlid', $item['mlid'])
  ->execute();

In your case, you need to alter the form, adding the form field, and a form submission handler that saves your data in your own database table.
As there are more than one button on that form, I prefer associate a new form submission handler to the specific button, such as with the following code.

$form['actions']['submit']['#submit'][] = 'mymodule_menu_edit_save_submit';

You could also be interested in doing something when the menu item is deleted (in which case, you should delete the data from your database table); the delete button is $form['actions']['delete'].

7
  • It's not possible to edit the menus table schema? (instead of adding my own table)
    – Omar Abid
    Mar 20, 2012 at 10:51
  • To alter the schema defined from another module is generally not preferable; the reason is that you could introduce compatibility issues with future versions (e.g. Drupal will add a database row with the same name you are using for your own data, or Drupal will change the name of the database table used for saving the menu item links). If you are going to alter a database table used by Drupal, you need to implement the code to alter the table, and implement hook_schema_alter().
    – apaderno
    Mar 20, 2012 at 11:34
  • So far, I have never seen a case where altering an already existing table was justified. Consider there could be also collateral performance effects. (A database schema is optimized for the fields being defined, not for the fields added from third-party modules.)
    – apaderno
    Mar 20, 2012 at 11:38
  • Good. Where to save the data then? (I'm using variable_set and variable_get right now)
    – Omar Abid
    Mar 20, 2012 at 14:41
  • You just save the data in a database table your module creates when it is installed.
    – apaderno
    Mar 20, 2012 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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