1.20.x layout.admin.inc layout_settings_form($form, &$form_state, Layout $layout)

Render the settings form for layout.

Related topics

File

modules/layout/layout.admin.inc, line 220
Admin page callbacks for the Layout module.

Code

function layout_settings_form($form, &$form_state, Layout $layout) {
  form_load_include($form_state, 'inc', 'layout', 'layout.admin');
  form_load_include($form_state, 'inc', 'layout', 'layout.context.admin');

  $form_state['layout'] = &$layout;
  $form['#tree'] = TRUE;

  $form['#attached']['js'][] = backdrop_get_path('module', 'layout') . '/js/layout.admin.js';
  $form['#attached']['css'][] = backdrop_get_path('module', 'layout') . '/css/layout.admin.css';

  $messages = array();
  if ($layout->locked) {
    $messages['warning'] = array(
      layout_locked_message($layout, 'layout'),
    );
  }
  $form['messages'] = array(
    '#theme' => 'status_messages',
    '#messages' => $messages,
    '#weight' => -100,
    // Prefix/suffix used to identify in AJAX requests.
    '#prefix' => '<div id="layout-messages">',
    '#suffix' => '</div>',
  );

  $form['title'] = array(
    '#title' => t('Layout name'),
    '#type' => 'textfield',
    '#maxlength' => 128,
    '#default_value' => $layout->title,
    '#required' => TRUE,
    '#access' => !$layout->isDefault(),
  );
  $form['name'] = array(
    '#type' => 'machine_name',
    '#machine_name' => array(
      'source' => array('title'),
      'exists' => 'layout_load',
    ),
    '#maxlength' => 128,
    '#default_value' => $layout->name,
    '#required' => TRUE,
    '#access' => !$layout->isDefault(),
  );
  $form['layout_template'] = array(
    '#title' => t('Layout template'),
    '#type' => 'radios',
    '#default_value' => $layout->layout_template,
    '#options' => array(),
    '#wrapper_attributes' => array('class' => array('clearfix', 'layout-options')),
    '#required' => TRUE,
  );

  // Get the list of layout template options. The list needs to be rebuilt (see
  // https://github.com/backdrop/backdrop-issues/issues/984)
  $all_template_info = layout_get_layout_template_info(NULL, TRUE);

  $excluded = config_get('layout.settings', 'excluded_templates');
  foreach ($all_template_info as $template_name => $template_info) {
    if (!in_array($template_name, $excluded)) {
      $form['layout_template']['#options'][$template_name] = theme('layout_template_option', array('template_info' => $template_info));
    }
  }

  $items = array(
    t('Content: <code>node/%</code>'),
    t('User accounts: <code>user/%</code>'),
    t('Taxonomy terms: <code>taxonomy/term/%</code>'),
    t('Comments: <code>comment/%</code>'),
  );
  $description_list = theme('item_list', array('items' => $items));

  $form['path'] = array(
    '#title' => t('Path'),
    '#field_prefix' => url('', array('absolute' => TRUE)),
    '#type' => 'textfield',
    '#default_value' => $layout->getPath(),
    '#required' => TRUE,
    '#description' => '<p>' . t('Use the percent symbol ("%") to indicate a placeholder in the path. Some common examples include:') . '</p>' . $description_list,
    '#access' => !$layout->isDefault(),
  );
  $form['path_update'] = array(
    '#type' => 'submit',
    '#value' => t('Check path'),
    '#validate' => array(
      'layout_settings_form_validate',
    ),
    '#submit' => array(
      'layout_settings_form_update_layout',
      'layout_settings_form_path_rebuild',
    ),
    '#ajax' => array(
      'callback' => 'layout_settings_form_path_ajax',
      'disable' => FALSE,
      'progress' => 'none',
    ),
    '#attributes' => array(
      'data-layout-path-update' => 'true',
      'class' => array('js-hide'),
    ),
    '#access' => !$layout->isDefault(),
  );

  // Get all contexts except those provided by relationships.
  $contexts = $layout->getContexts(LayoutContext::USAGE_TYPE_ALL ^ LayoutContext::USAGE_TYPE_RELATIONSHIP);
  $built_in_contexts = isset($contexts['overrides_path']) ? 2 : 1;
  $form['context_wrapper'] = array(
    '#title' => t('Contexts'),
    '#type' => 'item',
    '#id' => 'context-wrapper',
    '#description' => t('(Optional) Contexts define what blocks are available within this layout. Most placeholders in the path will be associated with a context automatically.'),
    // Current user context is always present.
  );
  $form['context_wrapper']['#access'] = !$layout->isDefault();
  $form['context_wrapper']['#prefix'] = '<div id="layout-contexts">';
  $form['context_wrapper']['#suffix'] = '</div>';
  $form['context_wrapper']['context'] = array(
    '#type' => 'container',
    '#parents' => array('context'),
  );

  $form['context_wrapper']['context']['links'] = array(
    '#theme' => 'layout_action_links',
  );
  $form['context_wrapper']['context']['links']['add'] = array(
    '#type' => 'submit',
    '#value' => t('Add context'),
    '#attributes' => array('class' => array('layout-link-button', 'layout-access-add')),
    '#validate' => array(),
    '#submit' => array(
      'layout_settings_form_update_layout',
      'layout_settings_form_context_add',
    ),
    '#ajax' => array(
      'callback' => 'layout_ajax_form_open_dialog',
    ),
  );

  // Get contexts from relationships
  $relevant_relationships = layout_relationships_get_relevant_info($contexts);
  if (!empty($relevant_relationships)) {
    $form['context_wrapper']['context']['links']['add_relationship'] = array(
      '#type' => 'submit',
      '#name' => 'relationship_add_button',
      '#value' => t('Add relationship'),
      '#attributes' => array('class' => array('layout-link-button', 'layout-access-add')),
      '#validate' => array(),
      '#submit' => array(
        'layout_settings_form_update_layout',
        'layout_settings_form_context_add',
      ),
      '#ajax' => array(
        'callback' => 'layout_ajax_form_open_dialog',
      ),
    );
  }

  $all_context_info = _layout_get_all_info('layout_context');
  $context_options = array();
  foreach ($all_context_info as $plugin_name => $context_info) {
    if (empty($context_info['hidden'])) {
      $context_options[$plugin_name] = $context_info['title'];
    }
  }

  $form['context_wrapper']['context']['required'] = array(
    '#theme' => 'layout_settings_context_table',
    '#layout_path' => $layout->getPath(),
    '#access' => count($contexts) > $built_in_contexts,
  );

  foreach ($contexts as $context_key => $layout_context) {
    if ($layout_context->usageType !== LayoutContext::USAGE_TYPE_SYSTEM) {
      // Contexts that are locked to a particular position (such as node/%).
      if ($layout_context->position && $layout_context->required) {
        $form['context_wrapper']['context']['required'][$context_key]['summary'] = array(
          '#markup' => $layout_context->getAdminSummary($layout->getPath()),
        );
        if ($layout_context->locked) {
          $form['context_wrapper']['context']['required'][$context_key]['plugin'] = array(
            '#markup' => check_plain($all_context_info[$layout_context->plugin]['title']),
          );
        }
        else {
          $form['context_wrapper']['context']['required'][$context_key]['plugin'] = array(
            '#type' => 'select',
            '#options' => $context_options,
            '#default_value' => $layout_context->plugin,
          );
        }
      }
      // Custom contexts and required contexts that do not need position (such
      // as admin/dashboard).
      else {
        $form['context_wrapper']['context']['required'][$context_key]['summary'] = array(
          '#markup' => $layout_context->getAdminSummary($layout->getPath()),
        );
        $form['context_wrapper']['context']['required'][$context_key]['plugin'] = array(
          '#markup' => check_plain($all_context_info[$layout_context->plugin]['title']),
        );
      }
      if (!$layout_context->required) {
        $form['context_wrapper']['context']['required'][$context_key]['operations'] = array(
          '#type' => 'container',
          '#attributes' => array('class' => array('layout-operations')),
        );
        $form['context_wrapper']['context']['required'][$context_key]['operations']['remove'] = array(
          '#type' => 'submit',
          '#value' => t('Remove'),
          '#attributes' => array('class' => array('layout-link-button', 'layout-context-remove')),
          '#validate' => array(),
          '#submit' => array(
            'layout_settings_form_context_remove',
            'layout_settings_form_update_layout',
          ),
          '#ajax' => array(
            'callback' => 'layout_ajax_form_update',
          ),
          '#name' => 'conditions_' . $context_key . '_remove',
        );
        $form['context_wrapper']['context']['required'][$context_key]['operations']['configure'] = array(
          '#type' => 'submit',
          '#value' => t('Configure'),
          '#attributes' => array('class' => array('layout-link-button', 'layout-context-configure')),
          '#validate' => array(
            'layout_settings_form_validate',
          ),
          '#submit' => array(
            'layout_settings_form_context_edit',
          ),
          '#ajax' => array(
            'callback' => 'layout_ajax_form_open_dialog',
          ),
          '#name' => 'conditions_' . $context_key . '_configure',
        );
      }
    }
  }

  $all_relationship_info = _layout_get_all_info('layout_relationship');
  foreach ($layout->relationships as $relationship_key => $relationship) {
    $form['context_wrapper']['context']['required'][$relationship_key]['summary'] = array(
      '#markup' => $relationship->getAdminSummary(),
    );
    $form['context_wrapper']['context']['required'][$relationship_key]['plugin'] = array(
      '#markup' => isset($all_relationship_info[$relationship->plugin]['title']) ?
        check_plain($all_relationship_info[$relationship->plugin]['title']) :
        t('Broken'),
    );
    $form['context_wrapper']['context']['required'][$relationship_key]['operations'] = array(
      '#type' => 'container',
      '#attributes' => array('class' => array('layout-operations')),
    );
    $form['context_wrapper']['context']['required'][$relationship_key]['operations']['remove'] = array(
      '#type' => 'submit',
      '#value' => t('Remove'),
      '#attributes' => array('class' => array('layout-link-button', 'layout-context-remove')),
      '#validate' => array(),
      '#submit' => array(
        'layout_settings_form_context_relationship_remove',
        'layout_settings_form_update_layout',
      ),
      '#ajax' => array(
        'callback' => 'layout_ajax_form_update',
      ),
      '#name' => 'conditions_' . $relationship_key . '_remove',
    );
    $form['context_wrapper']['context']['required'][$relationship_key]['operations']['configure'] = array(
      '#type' => 'submit',
      '#value' => t('Configure'),
      '#attributes' => array('class' => array('layout-link-button', 'layout-context-configure')),
      '#validate' => array(
        'layout_settings_form_validate',
      ),
      '#submit' => array(
        'layout_settings_form_context_relationship_edit',
      ),
      '#ajax' => array(
        'callback' => 'layout_ajax_form_open_dialog',
      ),
      '#name' => 'conditions_' . $relationship_key . '_configure',
    );
  }

  // Display a notice if overriding a system path that normally contains
  // placeholders e.g. node/1 instead of node/%. This is usually (but not always)
  // a misconfiguration of the layout.
  $layout_path = $layout->getPath();
  $router_item = menu_get_item($layout_path);
  if ($router_item && $router_item['path'] !== $layout_path && substr_count($router_item['path'], '/') === substr_count($layout_path, '/') && layout_context_required_by_path($router_item['path'])) {
    $message = t('The path entered will create a new page and disable the current "@old_path". If you intended to add a layout for "@old_path", use the path "@new_path" and add a URL path condition for "@old_path".', array('@new_path' => $router_item['path'], '@old_path' => $layout->getPath()));
    if (backdrop_is_ajax()) {
      backdrop_set_message($message, 'warning');
    }
    else {
      $form['messages']['#messages']['warning'][] = $message;
    }
  }

  $form['conditions'] = array(
    '#title' => t('Visibility conditions'),
    '#type' => 'item',
    '#description' => t('Visibility conditions allow this layout to selectively apply to different situations, such as different types of content at the same placeholder path.'),
    '#id' => 'layout-access',
    '#access' => !$layout->isDefault(),
  );
  $form['conditions']['links'] = array(
    '#theme' => 'layout_action_links',
  );
  $form['conditions']['links']['add'] = array(
    '#type' => 'submit',
    '#value' => t('Add visibility condition'),
    '#attributes' => array('class' => array('layout-link-button', 'layout-access-add')),
    '#validate' => array(),
    '#submit' => array(
      'layout_settings_form_update_layout',
      'layout_settings_form_condition_add',
    ),
    '#ajax' => array(
      'callback' => 'layout_ajax_form_open_dialog',
    ),
  );
  $form['conditions']['active'] = array(
    '#type' => 'container',
    '#theme' => 'layout_conditions',
    '#attributes' => array('class' => array('layout-access-list')),
  );
  foreach ($layout->conditions as $access_key => $layout_access) {
    $form['conditions']['active'][$access_key] = array(
      '#type' => 'container',
      '#attributes' => array('class' => array('layout-condition')),
      '#id' => NULL,
    );
    $form['conditions']['active'][$access_key]['label'] = array(
      '#markup' => $layout_access->summary(),
    );
    $form['conditions']['active'][$access_key]['operations'] = array(
      '#type' => 'container',
      '#attributes' => array('class' => array('layout-operations')),
    );
    $form['conditions']['active'][$access_key]['operations']['remove'] = array(
      '#type' => 'submit',
      '#value' => t('Remove'),
      '#attributes' => array('class' => array('layout-link-button', 'layout-access-remove')),
      '#validate' => array(),
      '#submit' => array(
        'layout_settings_form_condition_remove',
        'layout_settings_form_update_layout',
      ),
      '#ajax' => array(
        'callback' => 'layout_ajax_form_update',
      ),
      '#name' => 'conditions_' . $access_key . '_remove',
    );
    $form['conditions']['active'][$access_key]['operations']['configure'] = array(
      '#type' => 'submit',
      '#value' => t('Configure'),
      '#attributes' => array('class' => array('layout-link-button', 'layout-access-configure')),
      '#validate' => array(
        'layout_settings_form_validate',
      ),
      '#submit' => array(
        'layout_settings_form_condition_edit',
      ),
      '#ajax' => array(
        'callback' => 'layout_ajax_form_open_dialog',
      ),
      '#name' => 'conditions_' . $access_key . '_configure',
    );
  }

  $form['actions'] = array('#type' => 'actions');
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => empty($layout->is_new) ? t('Save layout') : t('Create layout'),
    '#validate' => array(
      'layout_settings_form_validate',
    ),
    '#submit' => array(
      'layout_settings_form_update_layout',
      'layout_settings_form_save_submit',
    ),
  );
  if (isset($_SESSION['layout_new_name']) || isset($layout->locked)) {
    $form['actions']['reset'] = array(
      '#type' => 'submit',
      '#value' => t('Cancel'),
      '#limit_validation_errors' => array(array('actions', 'reset')),
      '#validate' => array(),
      '#submit' => array(
        'layout_settings_form_reset',
      ),
    );
  }

  return $form;
}