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

Render the settings form for layout.

Related topics

File

core/modules/layout/layout.admin.inc, line 346
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(),
  );
  if ($layout->layout_template != NULL) {
    $layout_template = $layout->layout_template;
  }
  else {
    // If no layout template has been selected, then pre-select the template
    // used by the default layout, to avoid AJAX validation errors in the form.
    $layout_template = config_get('layout.layout.default', 'layout_template');
  }
  $form['layout_template'] = array(
    '#title' => t('Layout template'),
    '#type' => 'radios',
    '#default_value' => $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));
    }
  }

  // Path entry field with dynamic information about the entered path and
  // toggleable placeholder examples.
  $path = isset($form_state['values']['path']) ? $form_state['values']['path'] : $layout->getPath();
  $is_new = isset($layout->is_new) && $layout->is_new;
  $has_placeholder = strpos((string) $path, '%') !== FALSE;
  if (empty($path)) {
    $path_matches_text = t('Please enter a path.');
  }
  else {
    if (_layout_menu_router_path_exists($path)) {
      if ($has_placeholder) {
        if ($is_new) {
          $path_matches_text = t('This layout will override the default layout for existing page(s) whose paths match this pattern.');
        }
        else {
          $path_matches_text = t('This layout overrides the default layout for existing page(s) whose paths match this pattern.');
        }
      }
      else {
        if ($is_new) {
          $path_matches_text = t('This layout will override the default layout for an existing page whose path matches this pattern.');
        }
        else {
          $path_matches_text = t('This layout overrides the default layout for an existing page whose path matches this pattern.');
        }
      }
    }
    else {
      if ($has_placeholder) {
        if ($is_new) {
          $path_matches_text = t('This path will create pages whose paths match this pattern.');
        }
        else {
          $path_matches_text = t('This path provides pages whose paths match this pattern.');
        }
      }
      else {
        if ($is_new) {
          $path_matches_text = t('This path will create a page at this path.');
        }
        else {
          $path_matches_text = t('This path provides a page at this path.');
        }
      }
    }
  }
  $form['path_matches_text'] = array(
    '#type' => 'value',
    '#value' => $path_matches_text,
  );
  $path_matches = array(
    '#type' => 'container',
    '#access' => !$layout->isDefault(),
    '#attributes' => array(
      'id' => array('layout-path-matches'),
    ),
    'path_matches_text' => array('#markup' => $path_matches_text),
  );
  $path_matches_description = backdrop_render($path_matches);
  $toggle = ' <a class="layout-placeholder-examples-toggle" href="#">' . t('Show examples') . '<span class="arrow"></span></a>';
  $description_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 = '<div class="layout-placeholder-examples">' . t('Some common examples of placeholders include:') . theme('item_list', array('items' => $description_items)) . '</div>';
  $form['path'] = array(
    '#title' => t('Path'),
    '#field_prefix' => url('', array('absolute' => TRUE)),
    '#type' => 'textfield',
    '#default_value' => $layout->getPath(),
    '#required' => TRUE,
    '#access' => !$layout->isDefault(),
    '#description' => $path_matches_description . t('Use the percent symbol ("%") to indicate a placeholder in the path.') . $toggle . $description_list,
  );

  $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;
  $context_description = t('Contexts provide additional information to blocks displayed within the layout. Most placeholders in the path will automatically create context(s).');
  $form['context_wrapper'] = array(
    '#title' => t('Contexts'),
    '#type' => 'item',
    '#id' => 'context-wrapper',
  );
  $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']['description'] = array(
    '#markup' => '',
    '#prefix' => '<div class="description">',
    '#suffix' => '</div>',
  );
  $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',
      ),
    );
    $context_description .= ' ' . t('Relationships create contexts from data provided by existing contexts.');
  }
  $form['context_wrapper']['context']['description']['#markup'] = $context_description;

  $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 && $layout_path) {
    $router_item_path = (string) $router_item['path'];
    if ($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',
    '#id' => 'layout-access',
    '#access' => !$layout->isDefault(),
  );
  $form['conditions']['description'] = array(
    '#markup' => t('Visibility conditions allow this layout to selectively apply to different situations, such as different types of content at the same path.'),
    '#prefix' => '<div class="description">',
    '#suffix' => '</div>',
  );
  $form['conditions']['links'] = array(
    '#theme' => 'layout_action_links',
  );
  $form['conditions']['links']['add'] = array(
    '#type' => 'submit',
    '#value' => t('Add 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;
}