This module snippet illustrates how you can force a node from one or more content types to be included in the menu system before the content will be allowed to save successfully. This can be useful in a number of situations, some of which might include: 1) You'd like to guide your content authors and ensure that their content of a particular type is correctly added to the menu as they create the content (no possibility of orphaned nodes that were supposed to be in the menu but didn't get added)... 2) You use the [menupath-raw] token in Pathauto for a particular content type. When using [menupath-raw] as the URL alias for a node, Pathauto always expects the node to be in the menu - if it is not, the alias will not be generated, and an error will be returned (at the time of this writing, at least).

You can see in the example below how to apply this code to one or more content types (the example shows both the Page and Story content types being affected).

If you need help setting up a simple module to use this code in, please see How to create a simple Drupal 6 module in three easy steps. Also be sure to have a look at this article from Lullabot on Modifying forms in Drupal 5 and 6 (which also has advice on how to identify any form ID you need).

<?php
/**
 * Implementation of hook_form_alter().
 */
function customsite_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    // Force all "Page" content to be added to the menu.
    case 'page_node_form':
      // Make the menu fieldset expanded by default so it won't need to be opened.
      $form['menu']['#collapsed'] = FALSE;
      // Trigger the validation function.
      $form['#validate'][] = 'customsite_force_menu_validate';
    break;

    // Force all "Story" content to be added to the menu.
    case 'story_node_form':
      // Make the menu fieldset expanded by default so it won't need to be opened.
      $form['menu']['#collapsed'] = FALSE;
      // Trigger the validation function.
      $form['#validate'][] = 'customsite_force_menu_validate';
    break;
  }
}

// Validation function to force inclusion in the menu.
function customsite_force_menu_validate($node, &$form) {
  // Stop form submission if the node does not have a menu entry yet.
  if (empty($form['values']['menu']['link_title'])) { 
    form_set_error('menu][link_title', t('Please add this content to the menu first.'));
  }
}
?>

Comments

dnewkerk’s picture

Since some people will be more comfortable using hook_theme() in template.php instead, I'm trying to write this example using that method as well, though it is not working quite yet. The validation function does not seem to get called (or at least what it tries to do doesn't happen). It's a bit earlier version of the code and doesn't have examples for multiple content types, but I decided to wait to add that until confirming this could work in template.php in the first place. If anyone can confirm if this is possible and how, would be appreciated (and I'll finish it up and add the additional example to the handbook page).

Again, code not yet working:

<?php
/**
 * Implementation of hook_theme().
 * template.php version of the code.
 */
function customtheme_theme(){
  return array(
    'page_node_form' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}

// Force all "Page" content to be added to the menu.
function customtheme_page_node_form($form) {
  // Make the menu expanded by default so it won't need to be opened.
  $form['menu']['#collapsed'] = FALSE;
  // Trigger the validation function.
  $form['#validate'][] = 'customtheme_page_node_form_validate';
  
  return drupal_render($form);
}

// Validation function to force inclusion in the menu.
function customtheme_page_node_form_validate($node, &$form) {
  // Stop form submission if the node does not have a menu entry yet.
  if (empty($form['values']['menu']['link_title'])) { 
    form_set_error('menu][link_title', t('Please add this content to the menu first.'));
  }
}
?>
vivianspencer’s picture

The following module: http://drupal.org/project/menu_force now does this