Index: modules/menu/menu.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v retrieving revision 1.53 diff -u -p -r1.53 menu.admin.inc --- modules/menu/menu.admin.inc 20 Jul 2009 18:51:33 -0000 1.53 +++ modules/menu/menu.admin.inc 15 Aug 2009 17:01:07 -0000 @@ -402,43 +402,54 @@ function menu_edit_item_submit($form, &$ */ function menu_edit_menu(&$form_state, $type, $menu = array()) { $system_menus = menu_list_system_menus(); - if ($type == 'edit') { - $form['menu_name'] = array('#type' => 'value', '#value' => $menu['menu_name']); - $form['#insert'] = FALSE; - $form['delete'] = array( - '#type' => 'submit', - '#value' => t('Delete'), - '#access' => !isset($system_menus[$menu['menu_name']]), - '#submit' => array('menu_custom_delete_submit'), - '#weight' => 10, - ); + $menu += array('menu_name' => '', 'title' => '', 'description' => ''); + + $form['#title'] = $menu['title']; + + // The title of a system menu cannot be altered. + if (isset($system_menus[$menu['menu_name']])) { + $form['title'] = array('#type' => 'value', '#value' => $menu['title']); } else { - $menu = array('menu_name' => '', 'title' => '', 'description' => ''); - $form['menu_name'] = array( + $form['title'] = array( '#type' => 'textfield', - '#title' => t('Menu name'), - '#maxsize' => MENU_MAX_MENU_NAME_LENGTH_UI, - '#description' => t('The machine-readable name of this menu. This text will be used for constructing the URL of the menu overview page for this menu. This name must contain only lowercase letters, numbers, and hyphens, and must be unique.'), + '#title' => t('Title'), + '#default_value' => $menu['title'], '#required' => TRUE, + '#field_suffix' => '  ', ); - $form['#insert'] = TRUE; } - $form['#title'] = $menu['title']; - if (isset($system_menus[$menu['menu_name']])) { - $form['title'] = array( - '#type' => 'value', - '#value' => $menu['title'], - ); + + // The internal menu name can only be defined during initial menu creation. + if ($type == 'edit') { + $form['#insert'] = FALSE; + $form['menu_name'] = array('#type' => 'value', '#value' => $menu['menu_name']); } else { - $form['title'] = array( + $form['#insert'] = TRUE; + $js_settings = array( + 'type' => 'setting', + 'data' => array( + 'machineReadableValue' => array( + 'title' => array( + 'text' => t('URL path'), + 'target' => 'menu-name', + 'searchPattern' => '[^a-z0-9]+', + 'replaceToken' => '-', + ), + ), + ), + ); + $form['menu_name'] = array( '#type' => 'textfield', - '#title' => t('Title'), - '#default_value' => $menu['title'], + '#title' => t('Menu name'), + '#maxsize' => MENU_MAX_MENU_NAME_LENGTH_UI, + '#description' => t('This text will be used to construct the URL for the menu. The name must contain only lowercase letters, numbers and hyphens, and must be unique.'), '#required' => TRUE, + '#attached_js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings), ); } + $form['description'] = array( '#type' => 'textarea', '#title' => t('Description'), @@ -448,6 +459,13 @@ function menu_edit_menu(&$form_state, $t '#type' => 'submit', '#value' => t('Save'), ); + // Only custom menus may be deleted. + $form['delete'] = array( + '#type' => 'submit', + '#value' => t('Delete'), + '#access' => $type == 'edit' && !isset($system_menus[$menu['menu_name']]), + '#submit' => array('menu_custom_delete_submit'), + ); return $form; } Index: modules/node/content_types.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/content_types.inc,v retrieving revision 1.87 diff -u -p -r1.87 content_types.inc --- modules/node/content_types.inc 14 Aug 2009 00:12:57 -0000 1.87 +++ modules/node/content_types.inc 15 Aug 2009 17:02:13 -0000 @@ -58,7 +58,6 @@ function theme_node_admin_overview($name * Generates the node type editing form. */ function node_type_form(&$form_state, $type = NULL) { - drupal_add_js(drupal_get_path('module', 'node') . '/content_types.js'); if (!isset($type->type)) { // This is a new type. Node module managed types are custom and unlocked. $type = node_type_set_defaults(array('custom' => 1, 'locked' => 0)); @@ -78,10 +77,23 @@ function node_type_form(&$form_state, $t '#description' => t('The human-readable name of this content type. This text will be displayed as part of the list on the add new content page. It is recommended that this name begin with a capital letter and contain only letters, numbers, and spaces. This name must be unique.'), '#required' => TRUE, '#size' => 30, - '#field_suffix' => '  ', + '#field_suffix' => ' ' . ($type->locked ? t('Machine name: @name', array('@name' => $type->type)) : ' ') . '', ); if (!$type->locked) { + $js_settings = array( + 'type' => 'setting', + 'data' => array( + 'machineReadableValue' => array( + 'name' => array( + 'text' => t('Machine name'), + 'target' => 'type', + 'searchPattern' => '[^a-z0-9]+', + 'replaceToken' => '_', + ), + ), + ), + ); $form['identity']['type'] = array( '#title' => t('Machine name'), '#type' => 'textfield', @@ -89,6 +101,7 @@ function node_type_form(&$form_state, $t '#maxlength' => 32, '#required' => TRUE, '#description' => t('The machine-readable name of this content type. This text will be used for constructing the URL of the add new content page for this content type. This name must contain only lowercase letters, numbers, and underscores. Underscores will be converted into hyphens when constructing the URL of the add new content page. This name must be unique.'), + '#attached_js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings), ); } else { @@ -96,12 +109,6 @@ function node_type_form(&$form_state, $t '#type' => 'value', '#value' => $type->type, ); - $form['identity']['type_display'] = array( - '#title' => t('Machine name'), - '#type' => 'item', - '#markup' => theme('placeholder', $type->type), - '#description' => t('The machine-readable name of this content type. This field cannot be modified for system-defined content types.'), - ); } $form['identity']['description'] = array( Index: modules/node/content_types.js =================================================================== RCS file: modules/node/content_types.js diff -N modules/node/content_types.js --- modules/node/content_types.js 11950 ??? 1901 -1381474112:29304:-1343964016 -0000 1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,29 +0,0 @@ -// $Id: content_types.js,v 1.5 2009/07/04 14:57:23 dries Exp $ -(function ($) { - -Drupal.behaviors.contentTypes = { - attach: function () { - if ($('#edit-type').val() == $('#edit-name').val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_') || $('#edit-type').val() == '') { - $('.form-item-type-wrapper').hide(); - $('#edit-name').keyup(function () { - var machine = $(this).val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_'); - if (machine != '_' && machine != '') { - $('#edit-type').val(machine); - $('#node-type-name-suffix').empty().append(' Machine name: ' + machine + ' [').append($('' + Drupal.t('Edit') + '').click(function () { - $('.form-item-type-wrapper').show(); - $('#node-type-name-suffix').hide(); - $('#edit-name').unbind('keyup'); - return false; - })).append(']'); - } - else { - $('#edit-type').val(machine); - $('#node-type-name-suffix').text(''); - } - }); - $('#edit-name').keyup(); - } - } -}; - -})(jQuery); Index: modules/system/system.js =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.js,v retrieving revision 1.30 diff -u -p -r1.30 system.js --- modules/system/system.js 12 Aug 2009 11:43:10 -0000 1.30 +++ modules/system/system.js 15 Aug 2009 17:15:18 -0000 @@ -169,5 +169,67 @@ Drupal.behaviors.pageCache = { }, }; +/** + * Attach the auto machine readable name behavior. + * + * Settings are expected to be an object of elements to process, where the key + * defines the source element in the form and the value is an object defining + * the following properties: + * - text: The label to display before the auto-generated value. + * - target: The target form element name. + * - searchPattern: A regular expression (without modifiers) matching disallowed + * characters in the machine readable name, f.e. '[^a-z0-9]+'. + * - replaceToken: A replacement string to replace disallowed characters, f.e. + * '-' or '_'. + * + * @see menu_edit_menu() + */ +Drupal.behaviors.machineReadableValue = { + attach: function () { + for (var value in Drupal.settings.machineReadableValue) { + var settings = Drupal.settings.machineReadableValue[value]; + + var searchPattern = new RegExp(settings.searchPattern, 'g'); + // Build selector for the source name entered by a user. + var source = '#edit-' + value; + var suffix = source + '-suffix'; + // Build selector for the machine readable name. + var target = '#edit-' + settings.target; + // Build selector for the wrapper element around the target field. + var wrapper = '.' + settings.target + '-wrapper'; + + // Do not process the element if we got an error or the given name and the + // machine readable name are identical or the machine readable name is + // empty. + if (!$(target).hasClass('error') && ($(target).val() == $(source).val().toLowerCase().replace(searchPattern, settings.replaceToken) || $(target).val() == '')) { + // Hide wrapper element. + $(wrapper).hide(); + // Bind keyup event to source element. + $(source).keyup(function () { + var machine = $(this).val().toLowerCase().replace(searchPattern, settings.replaceToken); + if (machine != '_' && machine != '') { + // Set machine readable name to the user entered value. + $(target).val(machine); + // Append the machine readable name and a link to edit it to the source field. + $(suffix).empty().append(' ' + settings.text + ': ' + machine + ' [').append($('' + Drupal.t('Edit') + '').click(function () { + $(wrapper).show(); + $(target).focus(); + $(suffix).hide(); + $(source).unbind('keyup'); + return false; + })).append(']'); + } + else { + $(target).val(machine); + $(suffix).text(''); + } + }); + // Call keyup event on source element. + $(source).keyup(); + } + } + } +}; + })(jQuery);