1 node.types.inc node_type_form($form, &$form_state, $type = NULL)

Form constructor for the node type editing form.

Parameters

$type: (optional) An object representing the node type, when editing an existing node type.

See also

node_type_form_validate()

node_type_form_submit()

Related topics

File

core/modules/node/node.types.inc, line 86
Content type editing user interface.

Code

function node_type_form($form, &$form_state, $type = NULL) {
  if (!isset($type->type)) {
    // This is a new type. Populate with the defaults...
    $type = node_type_set_defaults();
    // ...and set the page title.
    backdrop_set_title(t('Add content type'));
  }

  // Make the type object available to implementations of hook_form_alter().
  $form['#node_type'] = $type;

  // Create the body field by default on form submission. This may be altered by
  // other modules.
  $form['body'] = array(
    '#type' => 'value',
    '#value' => TRUE,
  );

  $form['name'] = array(
    '#title' => t('Name'),
    '#type' => 'textfield',
    '#default_value' => $type->name,
    '#description' => t('The human-readable name of this content type; as to be displayed on the <a href="@url"><em>Add content</em></a> page. It is recommended that this name begins with a capital letter and contains only letters, numbers, and spaces. This name must be unique.', array('@url' => url('node/add'))),
    '#required' => TRUE,
    '#size' => 30,
  );

  $form['type'] = array(
    '#type' => 'machine_name',
    '#default_value' => $type->type,
    '#maxlength' => 32,
    '#disabled' => $type->module !== 'node',
    '#machine_name' => array(
      'exists' => 'node_type_load',
    ),
    '#description' => t('A unique machine-readable name for this content type. It must only contain lowercase letters, numbers, and underscores. This name will be used for constructing the URL of the <a href="@url"><em>Add content</em></a> page, in which underscores will be converted into hyphens.', array('@url' => url('node/add'))),
  );

  // Add a toggle for the "Description" field.
  $form['description_enable'] = array(
    '#type' => 'checkbox',
    '#title' => t('Provide description'),
    '#default_value' => $type->description != '' ? 1 : 0,
  );
  $form['description'] = array(
    '#type' => 'textarea',
    '#title' => t('Description'),
    '#title_display' => 'invisible',
    '#default_value' => $type->description,
    '#states' => array(
      'visible' => array(
        ':input[name="description_enable"]' => array('checked' => TRUE),
      ),
    ),
  );
  // We need to implement the description as a separate form element, so that it
  // is shown for both the checkbox and the text field.
  $form['description_description'] = array(
    '#type' => 'item',
    // Fields of #type 'item' do not support #attributes - use
    // #wrapper_attributes instead.
    '#wrapper_attributes' => array('class' => array('description', 'form-item-description')),
    '#markup' => t('This text will be shown on the <a href="@url"><em>Add content</em></a> page.', array('@url' => url('node/add'))),
  );

  // Prepare various messages about automatic permission assignment, and
  // warnings if no role is configured to create/edit/delete content of this
  // type.
  $system_config = config('system.core');
  // Prepare the array with the human-readable labels of any roles that are have
  // been configured in the "Default roles" section in
  // admin/config/people/roles. This array is used by format_plural() later.
  $default_admin_role = $system_config->get('user_admin_role');
  $default_editor_role = $system_config->get('user_editor_role');
  $auto_permission_roles = array();
  if ($default_admin_role && $admin_role = user_role_load($default_admin_role)) {
    $auto_permission_roles['%admin'] = $admin_role->label;
  }
  if ($default_editor_role && $editor_role = user_role_load($default_editor_role)) {
    $auto_permission_roles['%editor'] = $editor_role->label;
  }
  // Handle the case where the same role has been configured to be both the
  // default admin as well as the default editor.
  $auto_permission_roles = array_unique($auto_permission_roles);
  // Prepare the $auto_permission_roles array for format_plural() when there's
  // only one role.
  if (count($auto_permission_roles) == 1) {
    $one_role = reset($auto_permission_roles);
    unset($auto_permission_roles);
    $auto_permission_roles['%role'] = $one_role;
  }

  $permissions_assigned = FALSE;
  $content_type_permissions = node_type_form_permissions($type->type);
  foreach ($content_type_permissions['checkboxes'] as $role => $checkboxes) {
    if (!empty($checkboxes['#default_value'])) {
      // At least one permission related to this content type is assigned to at
      // least one role.
      $permissions_assigned = TRUE;
      break;
    }
  }

  // Edge case, where both the default admin role and the default content editor
  // role have been disabled in in admin/config/people/roles, while at the same
  // time no other role has been granted any permission associated with this
  // content type. We show this warning for both new and existing content types.
  if (!$permissions_assigned) {
    $permissions_message = t('No permissions assigned for this content type. Content of this type may not be able to be created, updated or deleted until permissions have been configured appropriately.');
    $permissions_message_type = 'warning';
  }
  // Show some info messages if automatic permission assignment is enabled for
  // at least one of the default admin/editor roles. We only show these when
  // creating a new content type.
  if (!empty($auto_permission_roles) && empty($type->type)) {
    $permissions_message = format_plural(
    count($auto_permission_roles), 
    'The %role role has been assigned permissions to create, edit, and delete content of this type.', 
    'The %admin and %editor roles have been assigned permissions to create, edit, and delete content of this type.', 
    $auto_permission_roles
    );
    $permissions_message_type = 'info';
  }

  if (isset($permissions_message)) {
    if (user_access('administer permissions')) {
      $permissions_message .= ' ' . t('You can make any necessary adjustments in the <em>Permissions</em> tab below.');
    }
    else {
      $user_module_permissions = module_invoke('user', 'permission');
      $permissions_message .= ' ' . t('Only roles with the %permission permission can make any necessary adjustments.', array('%permission' => $user_module_permissions['administer permissions']['title']));
    }

    // We are mimicking the style of a warning/info message here. If we used
    // backdrop_set_message(), the message would be placed at the top of the
    // page, which would make it unnecessarily prominent and potentially
    // distracting. We are placing it right above the vertical tabs section
    // instead (closer to where permissions can be configured). Intentionally
    // not placing it inside the "Permissions" tab either, since that is not the
    // default tab, so it wouldn't be visible, and we need to show some warnings
    // to people even if they don't have access to the "Permissions" tab.
    $form['permissions_message_container'] = array(
      '#type' => 'container',
      '#attributes' => array('class' => array(
        'messages',
        $permissions_message_type,
      )),
    );
    $form['permissions_message_container']['message'] = array(
      '#type' => 'markup',
      '#markup' => $permissions_message,
    );
  }

  $form['additional_settings'] = array(
    '#type' => 'vertical_tabs',
    '#attached' => array(
      'js' => array(backdrop_get_path('module', 'node') . '/js/node.types.js'),
    ),
  );

  // Submission form settings.
  $form['submission'] = array(
    '#type' => 'fieldset',
    '#title' => t('Submission form settings'),
    '#collapsible' => TRUE,
    '#group' => 'additional_settings',
    '#weight' => -15,
  );
  $form['submission']['title_label'] = array(
    '#title' => t('Title field label'),
    '#type' => 'textfield',
    '#default_value' => $type->title_label,
    '#required' => TRUE,
  );
  if (!$type->has_title) {
    // Avoid overwriting a content type that intentionally does not have a
    // title field.
    $form['submission']['title_label']['#attributes'] = array('disabled' => 'disabled');
    $form['submission']['title_label']['#description'] = t('This content type does not have a title field.');
    $form['submission']['title_label']['#required'] = FALSE;
  }

  // Add a toggle for the "Explanation or submission guidelines" field.
  $form['submission']['help_enable'] = array(
    '#type' => 'checkbox',
    '#title' => t('Provide explanation or submission guidelines'),
    '#default_value' => $type->help != '' ? 1 : 0,
  );
  $form['submission']['help'] = array(
    '#type' => 'textarea',
    '#title' => t('Explanation or submission guidelines'),
    '#title_display' => 'invisible',
    '#default_value' => $type->help,
    '#states' => array(
      'visible' => array(
        ':input[name="help_enable"]' => array('checked' => TRUE),
      ),
    ),
  );
  // We need to implement the description as a separate form element, so that it
  // is shown for both the checkbox and the text field.
  $form['submission']['help_description'] = array(
    '#type' => 'item',
    // Fields of #type 'item' do not support #attributes - use
    // #wrapper_attributes instead.
    '#wrapper_attributes' => array('class' => array('description', 'form-item-description')),
    '#markup' => t('This text will be displayed at the top of the page when creating or editing content of this type.'),
  );

  $form['submission']['node_preview'] = array(
    '#type' => 'radios',
    '#title' => t('Preview before submitting'),
    '#default_value' => $type->settings['node_preview'],
    '#options' => array(
      BACKDROP_DISABLED => t('Disabled'),
      BACKDROP_OPTIONAL => t('Optional'),
    ),
  );

  // Publishing settings.
  $form['workflow'] = array(
    '#type' => 'fieldset',
    '#title' => t('Publishing settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
    '#weight' => -10,
  );
  $form['workflow']['scheduling_enabled'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show option for scheduling'),
    '#default_value' => $type->settings['scheduling_enabled'],
  );
  $form['workflow']['status_default'] = array(
    '#type' => 'radios',
    '#title' => t('Default publish action'),
    '#options' => array(
      NODE_PUBLISHED => t('Publish immediately'),
      NODE_NOT_PUBLISHED => t('Save as draft'),
      NODE_SCHEDULED => t('Schedule for later'),
    ),
    '#default_value' => $type->settings['status_default'],
    '#required' => TRUE,
  );
  $form['workflow']['status_default'][NODE_PUBLISHED]['#description'] = t('Published content can be accessed by site visitors.');
  $form['workflow']['status_default'][NODE_NOT_PUBLISHED]['#description'] = t('Content saved as draft can be accessed only by the content creator or site administrators.');
  $form['workflow']['status_default'][NODE_SCHEDULED]['#description'] = t('Content is saved as draft. It will be automatically published at the date and time selected.');
  $form['workflow']['status_default'][NODE_SCHEDULED]['#states'] = array(
    'visible' => array(
      'input[name="scheduling_enabled"]' => array('checked' => TRUE),
    ),
  );
  $form['workflow']['sticky'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Sticky'),
    '#options' => array(
      'sticky_enabled' => t('Show option to make sticky'),
      'sticky_default' => t('Make sticky by default'),
    ),
    '#description' => t('Sticky content may be shown at the top of listings.'),
  );
  $form['workflow']['sticky']['sticky_enabled'] = array(
    '#default_value' => $type->settings['sticky_enabled'],
    '#parents' => array('sticky_enabled'),
    '#return_value' => 1,
  );
  $form['workflow']['sticky']['sticky_default'] = array(
    '#default_value' => $type->settings['sticky_default'],
    '#parents' => array('sticky_default'),
    '#return_value' => 1,
  );
  $form['workflow']['promote'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Promote'),
    '#options' => array(
      'promote_enabled' => t('Show option to promote'),
      'promote_default' => t('Promote by default'),
    ),
    '#description' => t('Promoted content will often be shown on the main homepage or blog.'),
  );
  $form['workflow']['promote']['promote_enabled'] = array(
    '#default_value' => $type->settings['promote_enabled'],
    '#parents' => array('promote_enabled'),
    '#return_value' => 1,
  );
  $form['workflow']['promote']['promote_default'] = array(
    '#default_value' => $type->settings['promote_default'],
    '#parents' => array('promote_default'),
    '#return_value' => 1,
  );

  // Multilingual support.
  if (module_exists('language')) {
    $form['multilingual'] = array(
      '#type' => 'fieldset',
      '#title' => t('Multilingual support'),
      '#collapsible' => TRUE,
      '#group' => 'additional_settings',
      '#weight' => -5,
    );
    $form['multilingual']['language'] = array(
      '#type' => 'checkbox',
      '#title' => t('Multilingual support'),
      '#default_value' => $type->settings['language'],
      '#description' => t('Add a language selection field to the editing form, allowing you to select from one of the <a href="!languages">enabled languages</a>. If disabled, new content is saved with no defined language. Existing content will not be affected by changing this option.', array('!languages' => url('admin/config/regional/language'))),
    );
  }

  // URL alias pattern.
  // @see: path_pattern_settings_form().

  // Content type permissions.
  $form['permissions'] = array(
    '#type' => 'fieldset',
    '#title' => t('Permissions'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
    '#access' => user_access('administer permissions'),
    '#weight' => 0,
  );
  $form['permissions']['permissions'] = $content_type_permissions;

  // Revision settings.
  $form['revision'] = array(
    '#type' => 'fieldset',
    '#title' => t('Revision settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
    '#weight' => 10,
  );
  $form['revision']['revision']['revision_enabled'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable option to create revisions'),
    '#default_value' => $type->settings['revision_enabled'],
    '#parents' => array('revision_enabled'),
    '#description' => t('Revisions allow content editors to view changes over time and revert changes if needed.'),
  );
  $form['revision']['revision']['revision_default'] = array(
    '#type' => 'checkbox',
    '#title' => t('Create new revision by default'),
    '#description' => t('If enabled, revisions to content will be created by default. People with the "Administer content" permission will see an option to create a revision.'),
    '#default_value' => $type->settings['revision_default'],
    '#parents' => array('revision_default'),
    '#states' => array(
      'visible' => array(
        'input[name="revision_enabled"]' => array('checked' => TRUE),
      ),
      'enabled' => array(
        'input[name="revision_enabled"]' => array('checked' => TRUE),
      ),
    ),
  );

  // Menu settings.
  // @see: menu_form_node_type_form_alter().

  // Display settings.
  $form['display'] = array(
    '#type' => 'fieldset',
    '#title' => t('Display settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'additional_settings',
    '#weight' => 20,
  );
  $form['display']['node_submitted'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display author and date information'),
    '#default_value' => $type->settings['node_submitted'],
    '#description' => t('Author username and publish date will be displayed.'),
  );
  $node_submitted_state = array(
    'visible' => array(
      'input[name="node_submitted"]' => array('checked' => TRUE),
    ),
  );
  $form['display']['node_submitted_format'] = array(
    '#type' => 'textfield',
    '#title' => t('Author/date format'),
    '#default_value' => $type->settings['node_submitted_format'],
    '#description' => t('The format to use for the author username and publish date. Example: "Submitted by [node:author] on [node:created:medium]"'),
    '#states' => $node_submitted_state,
  );
  $form['display']['node_submitted_tokens'] = array(
    '#type' => 'item', // Needed for states to work.
    '#theme' => 'token_tree_link',
    '#token_types' => array('node'),
    '#global_types' => TRUE,
    '#click_insert' => TRUE,
    '#states' => $node_submitted_state,
  );
  if (config_get('system.core', 'user_pictures')) {
    $form['display']['node_user_picture'] = array(
      '#type' => 'checkbox',
      '#title' => t('Display the author picture'),
      '#default_value' => $type->settings['node_user_picture'],
      '#description' => t('Author picture will be included along with username and publish date, if provided.'),
      // Hide the picture settings when submitted info is disabled.
      '#states' => $node_submitted_state,
    );
  }
  $form['display']['hidden_path'] = array(
    '#type' => 'checkbox',
    '#title' => t('Hide path display'),
    '#default_value' => $type->settings['hidden_path'],
    '#description' => t('If enabled, this content can be placed as a block or within a listing but will not be accessible at its URL without proper permissions. This facilitates "hidden path" content that is meant to be embedded with other content and never on its own. Users who have the "View hidden paths" permission will still be able to visit the full page URL, while those without this permission will receive a "Page not found" error.'),
  );

  // Comment settings.
  // @see: comment_form_node_type_form_alter().

  $form['old_type'] = array(
    '#type' => 'value',
    '#value' => $type->type,
  );

  $form['actions'] = array('#type' => 'actions');
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save content type'),
    '#weight' => 40,
  );

  if ($type->module === 'node' && !empty($type->type)) {
    $form['actions']['delete'] = array(
      '#type' => 'submit',
      '#value' => t('Delete content type'),
      '#weight' => 45,
      '#limit_validation_errors' => array(),
      '#validate' => array(),
      '#submit' => array('node_type_form_delete'),
    );
  }

  $path = 'admin/structure/types';
  $options = array();
  $options['attributes']['class'][] = 'form-cancel';

  $form['actions']['cancel'] = array(
    '#type' => 'link',
    '#title' => t('Cancel'),
    '#href' => $path,
    '#options' => $options,
    '#weight' => 50,
  );

  return $form;

}