1 layout.admin.inc layout_list_page()

Output a list of layouts that are managed.

File

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

Code

function layout_list_page() {
  $layouts = layout_load_all();
  $layout_template_info = layout_get_layout_template_info();

  // Group layouts by path.
  $layout_paths = array();
  $path_groups = array();
  $path_groups_end = array();
  foreach ($layouts as $layout) {
    $path = $layout->getPath();
    // Move admin layouts to the bottom of the list. Note that default layout
    // has a NULL path, which path_is_admin() won't like in PHP 8.1.
    if (is_null($path) || path_is_admin($path)) {
      $path_groups_end[$path][$layout->name] = $layout;
    }
    else {
      $path_groups[$path][$layout->name] = $layout;
    }
    // Build a list of all layout paths to check callbacks.
    if ($path) {
      $layout_paths[] = $path;
    }
  }

  // Put admin layouts at the bottom of the list.
  foreach ($path_groups_end as $path => $name) {
    foreach ($name as $layout) {
      $path_groups[$path][$layout->name] = $layout;
    }
  }

  if (!empty($layout_paths)) {
    $page_callbacks = db_query('
    SELECT path, page_callback
    FROM {menu_router}
    WHERE path IN (:paths)
    ', array(':paths' => $layout_paths))
      ->fetchAllKeyed();
  }
  else {
    $page_callbacks = array();
  }

  // Assemble the rows of the table.
  $override_rows = array();
  $stand_alone_rows = array();
  foreach ($path_groups as $path => $group) {
    // Print a row for rearranging a group of layouts.
    $operations = array(
      '#type' => 'dropbutton',
      '#links' => _layout_get_group_operations($path, $group),
    );
    $row = array();
    // Default layouts have a null path.
    if ($path === '') {
      $row[] = array('data' => t('Default layouts (used on all paths without a specific layout)'));
      // Empty columns are intentional so that they may be hidden with
      // priority-low class on the $header array.
      $row[] = '';
      $row[] = '';
      $row[] = '';
    }
    else {
      if (strpos($path, '%') === FALSE) {
        $path_link = t('Path: ') . l($path, $path);
      }
      else {
        $path_link = t('System path: ') . check_plain($path);
      }

      $class = array();
      if (!$page_callbacks[$path]) {
        $class[] = 'missing-path';
        $path_link .= ' <span class="path-parenthetical">(' . t('missing callback') . ')</span>';
      }
      $row[] = array('data' => $path_link, 'class' => $class);
      // Empty columns are intentional.
      $row[] = '';
      $row[] = '';
      $row[] = '';
    }

    if (count($operations['#links']) !== 0) {
      $row[] = backdrop_render($operations);
    }
    else {
      $row[] = '';
    }

    if (isset($page_callbacks[$path]) && $page_callbacks[$path] == 'layout_page_callback') {
      $stand_alone_rows[] = array('data' => $row, 'class' => array('layout-group'));
    }
    else {
      $override_rows[] = array('data' => $row, 'class' => array('layout-group'));
    }

    foreach ($group as $layout) {
      $operations = array(
        '#type' => 'dropbutton',
        '#links' => _layout_get_operations($layout),
      );
      if ($layout->storage === LAYOUT_STORAGE_OVERRIDE) {
        $storage = t('Overridden');
      }
      elseif ($layout->storage === LAYOUT_STORAGE_DEFAULT) {
        $storage = t('Default (module-provided)');
      }
      else {
        $storage = t('Custom');
      }

      // Create a link to the settings page.
      $info = $layout_template_info[$layout->layout_template];
      $template = l($info['title'], 'admin/structure/layouts/manage/' . $layout->name . '/configure');

      $row = array();
      $row[] = theme('layout_info', array('layout' => $layout));
      $row[] = $template;
      $row[] = theme('layout_condition_info', array('layout' => $layout));
      $row[] = $storage;
      $row[] = backdrop_render($operations);
      $class = array('layout-row');
      if ($layout->disabled) {
        $class[] = 'disabled';
      }

      if (isset($page_callbacks[$path]) && $page_callbacks[$path] == 'layout_page_callback') {
        $stand_alone_rows[] = array('data' => $row, 'class' => $class);
      }
      else {
        $override_rows[] = array('data' => $row, 'class' => $class);
      }
    }
  }

  $header = array(
    array('data' => t('Layout'), 'class' => array('layout-title')),
    array('data' => t('Template'), 'class' => array('layout-template', 'priority-low')),
    array('data' => t('Visibility conditions'), 'class' => array('layout-conditions', 'priority-low')),
    array('data' => t('Storage state'), 'class' => array('layout-status', 'priority-low')),
    array('data' => t('Operations'), 'class' => array('layout-operations')),
  );

  $help = '<p>' . t('There are two kinds of <em>Layouts</em>:') . '</p>';
  $help_items = array();
  $help_items[] = t('<strong>Layout pages</strong> are layouts that create new stand-alone pages on the site.  Without the layouts, these pages would not exist.');
  $help_items[] = t('<strong>Layout overrides</strong> are layouts that override existing pages on the site. Without these layout overrides, these pages would use other layouts. Which one is used will depend on the path and visibility conditions. If no other layouts match, one of the defaults will be used.');
  $help .= theme('item_list', array('items' => $help_items));
  $help .= '<p>' . t('As a page is rendered, a <em>Layout</em> is selected as follows.') . '</p>';
  $help_items = array();
  $help_items[] = array(
    'data' => t('The <em>Path</em> for the page is compared to those in the alphabetical list here, and <em>Visibility conditions</em> are evaluated.'),
    'children' => array(
      t('Each path may have one or more layouts available. These are listed beneath the path.'),
      array(
        'data' => t('The top available layout for each path is is evaluated for matching visibility conditions first, followed by the second, etc.'),
        'children' => array(t('Available layouts can be reordered to adjust priority.')),
      ),
      t('The first layout to match all conditions will be selected.'),
    ),
  );
  $help_items[] = t('If no match is found, or if visibility conditions are not met, the page will use one of the <em>Default layouts</em> shown at the bottom of this page.');
  $help .= theme('item_list', array('items' => $help_items));
  $help .= '<p>' . t('Note: Paths used by the layout system are <em>menu router paths</em>, not normal paths or !link. For the default About page, <code>node/%</code> is the menu router path, <code>node/2</code> is the normal path, and <code>about</code> is the URL alias.', array('!link' => l(t('URL aliases'), 'admin/config/urls/path'))) . '</p>';
  $help .= '<p class="align-right">' . t('For more information and details, see the <a href="https://docs.backdropcms.org/documentation/layouts-and-templates" target="_blank">online documentation</a>.') . '</p>';

  $page = array();
  $page['help'] = array(
    '#type' => 'details',
    '#summary' => t('How layouts work'),
    '#details' => $help,
    '#attributes' => array(
      'class' => array('description'),
    ),
    '#weight' => -1,
  );
  $page['#attached']['css'][] = backdrop_get_path('module', 'layout') . '/css/layout.admin.css';
  $page['stand_alone'] = array(
    '#type' => 'help',
    '#markup' => '<h2>' . t('Layout pages') . '</h2>' . t('These layouts will create new stand-alone pages on the site.'),
    '#weight' => 0,
  );
  $page['stand_alone_table'] = array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $stand_alone_rows,
    '#attributes' => array('class' => array('layout-list')),
    '#empty' => t('No layout pages have been created yet.'),
    '#weight' => 1,
  );
  $page['override'] = array(
    '#type' => 'help',
    '#markup' => '<h2>' . t('Layout overrides') . '</h2>' . t('These layouts will override existing pages on the site.'),
    '#weight' => 2,
  );
  $page['override_table'] = array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $override_rows,
    '#attributes' => array('class' => array('layout-list')),
    '#empty' => t('No layout overrides have been created yet.'),
    '#weight' => 3,
  );
  return $page;
}