diff --git a/core/includes/menu.inc b/core/includes/menu.inc index 6b62bf8..cdeeb08 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -1747,37 +1747,6 @@ function menu_list_system_menus() { } /** - * Returns an array of links to be rendered as the Main menu. - */ -function menu_main_menu() { - $config = config('menu.settings'); - $menu_enabled = module_exists('menu'); - // When menu module is not enabled, we need a hardcoded default value. - $main_links_source = $menu_enabled ? $config->get('main_links') : 'main'; - return menu_navigation_links($main_links_source); -} - -/** - * Returns an array of links to be rendered as the Secondary links. - */ -function menu_secondary_menu() { - $config = config('menu.settings'); - $menu_enabled = module_exists('menu'); - // When menu module is not enabled, we need a hardcoded default value. - $main_links_source = $menu_enabled ? $config->get('main_links') : 'main'; - $secondary_links_source = $menu_enabled ? $config->get('secondary_links') : 'account'; - - // If the secondary menu source is set as the primary menu, we display the - // second level of the primary menu. - if ($secondary_links_source == $main_links_source) { - return menu_navigation_links($main_links_source, 1); - } - else { - return menu_navigation_links($secondary_links_source, 0); - } -} - -/** * Returns an array of links for a navigation menu. * * @param $menu_name @@ -1787,6 +1756,8 @@ function menu_secondary_menu() { * * @return * An array of links of the specified menu and level. + * + * @todo this should become a service. */ function menu_navigation_links($menu_name, $level = 0) { // Don't even bother querying the menu table if no menu is specified. diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 88ab65d..fe45dc3 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -2838,8 +2838,6 @@ function template_preprocess_page(&$variables) { $variables['language'] = $language_interface; $variables['language']->dir = $language_interface->direction ? 'rtl' : 'ltr'; $variables['logo'] = theme_get_setting('logo'); - $variables['main_menu'] = theme_get_setting('toggle_main_menu') ? menu_main_menu() : array(); - $variables['secondary_menu'] = theme_get_setting('toggle_secondary_menu') ? menu_secondary_menu() : array(); $variables['action_links'] = menu_local_actions(); $variables['site_name'] = (theme_get_setting('toggle_name') ? check_plain($site_config->get('name')) : ''); $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? filter_xss_admin($site_config->get('slogan')) : ''); diff --git a/core/modules/block/tests/block_test.info.yml b/core/modules/block/tests/block_test.info.yml index 5ba4c4c..ab2ae8e 100644 --- a/core/modules/block/tests/block_test.info.yml +++ b/core/modules/block/tests/block_test.info.yml @@ -4,3 +4,6 @@ package: Testing version: VERSION core: 8.x hidden: true +regions: + account: 'Account links' + main_menu: 'Main menu' diff --git a/core/modules/block/tests/themes/block_test_theme/block_test_theme.info b/core/modules/block/tests/themes/block_test_theme/block_test_theme.info new file mode 100644 index 0000000..5c20015 --- /dev/null +++ b/core/modules/block/tests/themes/block_test_theme/block_test_theme.info @@ -0,0 +1,16 @@ +name = Block test theme +description = Theme for testing the block system +core = 8.x +hidden = TRUE + +regions[account] = Account links +regions[main_menu] = Main menu +regions[sidebar_first] = Left sidebar +regions_hidden[] = sidebar_first +regions[sidebar_second] = Right sidebar +regions_hidden[] = sidebar_second +regions[content] = Content +regions[header] = Header +regions[footer] = Footer +regions[highlighted] = Highlighted +regions[help] = Help diff --git a/core/modules/block/tests/themes/block_test_theme/block_test_theme.info.yml b/core/modules/block/tests/themes/block_test_theme/block_test_theme.info.yml index c19cbf5..6057fb5 100644 --- a/core/modules/block/tests/themes/block_test_theme/block_test_theme.info.yml +++ b/core/modules/block/tests/themes/block_test_theme/block_test_theme.info.yml @@ -10,6 +10,8 @@ regions: footer: Footer highlighted: Highlighted help: Help + main_menu: Main Menu + account: Account regions_hidden: - sidebar_first - sidebar_second diff --git a/core/modules/block/tests/themes/block_test_theme/page.tpl.php b/core/modules/block/tests/themes/block_test_theme/page.tpl.php index ba72882..0e93b1c 100644 --- a/core/modules/block/tests/themes/block_test_theme/page.tpl.php +++ b/core/modules/block/tests/themes/block_test_theme/page.tpl.php @@ -38,15 +38,19 @@ + + + - - + + diff --git a/core/modules/menu/config/menu.settings.yml b/core/modules/menu/config/menu.settings.yml index bd3574e..0b617f8 100644 --- a/core/modules/menu/config/menu.settings.yml +++ b/core/modules/menu/config/menu.settings.yml @@ -1,3 +1 @@ -main_links: main -secondary_links: account override_parent_selector: '0' diff --git a/core/modules/menu/lib/Drupal/menu/Plugin/block/block/MenuNavigation.php b/core/modules/menu/lib/Drupal/menu/Plugin/block/block/MenuNavigation.php new file mode 100644 index 0000000..9575550 --- /dev/null +++ b/core/modules/menu/lib/Drupal/menu/Plugin/block/block/MenuNavigation.php @@ -0,0 +1,92 @@ + 'main', + 'level' => 0, + ); + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, &$form_state) { + $form['menu'] = array( + '#type' => 'select', + '#title' => t('Source menu'), + '#default_value' => $this->configuration['menu'], + '#options' => menu_get_menus(), + '#required' => TRUE, + ); + $form['level'] = array( + '#type' => 'select', + '#title' => t('Starting level'), + '#default_value' => $this->configuration['level'], + '#options' => drupal_map_assoc(array(0, 1, 2, 3, 4, 5, 6, 7, 8)), + '#required' => TRUE, + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, &$form_state) { + $this->setConfig('menu', $form_state['values']['menu']); + $this->setConfig('level', $form_state['values']['level']); + } + + /** + * {@inheritdoc} + */ + protected function blockBuild() { + // @todo BlockManager fails to merge default settings. + $this->configuration += $this->settings(); + + $menu_name = $this->configuration['menu']; + $level = $this->configuration['level']; + // @todo menu_nagivation_links should be migrated to a menu link service and + // that should be injected here. + $links = menu_navigation_links($menu_name, $level); + // Do not output this entire block if there are no visible/accessible links. + // @todo This is insufficient for the real world. Respect #access. + if (empty($links)) { + return array(); + } + $build = array( + '#theme' => 'links', + '#links' => $links, + ); + if (!empty($this->configuration['id'])) { + $build['#attributes']['id'] = drupal_html_id($this->configuration['id']); + } + return $build; + } + +} diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php index 89287f5..bb2ee20 100644 --- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php +++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php @@ -34,6 +34,8 @@ public static function getInfo() { function setUp() { parent::setUp(); + $this->drupalPlaceBlock('menu_navigation', array('region' => 'account'), array('menu' => 'account')); + $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); // Create users. @@ -163,7 +165,9 @@ function addCustomMenu() { $this->drupalGet('admin/structure/block/list/block_plugin_ui:' . config('system.theme')->get('default') . '/add'); $this->assertText($label); - // Enable the block. + // Enable the block after flushing the plugin definitions to ensure the + // new menu is found by the plugin manager. + $this->container->get('plugin.manager.block')->clearCachedDefinitions(); $this->drupalPlaceBlock('menu_menu_block:' . $menu_name); return menu_load($menu_name); } diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index d13655e..b0c4720 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -720,6 +720,12 @@ function menu_preprocess_block(&$variables) { if ($variables['block']->module == 'menu') { $variables['attributes']['role'] = 'navigation'; } + if ($variables['block']->id == 'menu_navigation') { + $variables['attributes']['class'][] = 'links'; + $variables['attributes']['class'][] = 'inline'; + $variables['attributes']['class'][] = 'clearfix'; + $variables['title_attributes']['class'][] = 'element-invisible'; + } } /** diff --git a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php index 0479793..de640a4 100644 --- a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php +++ b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php @@ -19,7 +19,7 @@ class OpenIDFunctionalTest extends OpenIDTestBase { * * @var array */ - public static $modules = array('openid_test'); + public static $modules = array('block', 'openid', 'test_page_test', 'menu', 'openid_test'); protected $web_user; diff --git a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDRegistrationTest.php b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDRegistrationTest.php index 7389580..3b6baf9 100644 --- a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDRegistrationTest.php +++ b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDRegistrationTest.php @@ -21,7 +21,7 @@ class OpenIDRegistrationTest extends OpenIDTestBase { * * @var array */ - public static $modules = array('openid_test', 'language'); + public static $modules = array('block', 'openid', 'test_page_test', 'menu', 'openid_test', 'language'); public static function getInfo() { return array( @@ -122,6 +122,7 @@ function testRegisterUserWithoutEmailVerification() { $this->assertLink(t('Log out'), 0, 'User was logged in.'); $user = user_load_by_name('john'); + $this->assertTrue($user, 'User was registered with right username.'); $this->assertEqual($user->mail, 'john@example.com', 'User was registered with right email address.'); $this->assertEqual($user->timezone, 'Europe/London', 'User was registered with right timezone.'); @@ -263,6 +264,7 @@ function testRegisterUserWithAXButNoSREG() { $this->assertLink(t('Log out'), 0, 'User was logged in.'); $user = user_load_by_name('john'); + $this->assertTrue($user, 'User was registered with right username.'); $this->assertEqual($user->mail, 'john@example.com', 'User was registered with right email address.'); $this->assertEqual($user->timezone, 'Europe/London', 'User was registered with right timezone.'); diff --git a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php index 3110d88..aa6a986 100644 --- a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php +++ b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php @@ -15,11 +15,18 @@ abstract class OpenIDTestBase extends WebTestBase { /** + * The user account links block placed in the account region. + * + * @var \Drupal\block\Plugin\Core\Entity\Block + */ + protected $block; + + /** * Modules to enable. * * @var array */ - public static $modules = array('block', 'openid', 'test_page_test'); + public static $modules = array('block', 'openid', 'test_page_test', 'menu'); function setUp() { parent::setUp(); @@ -28,6 +35,12 @@ function setUp() { $this->admin_user = $this->drupalCreateUser(array('administer blocks')); $this->drupalLogin($this->admin_user); $this->drupalPlaceBlock('user_login_block'); + // Place the user links block in the content region. + $this->block = $this->drupalPlaceBlock('menu_navigation', array('region' => 'content'), array( + 'menu' => 'account', + 'level' => 0, + 'id' => 'secondary-menu', + )); $this->drupalLogout(); // Use a different front page than login page for testing OpenID login from diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php index 3b666a0..5cec845 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php @@ -282,6 +282,8 @@ function testThemeCallbackHookCustomTheme() { * Tests for menu_link_maintain(). */ function testMenuLinkMaintain() { + $this->drupalPlaceBlock('menu_navigation', array('region' => 'main_menu'), array('menu' => 'main')); + $admin_user = $this->drupalCreateUser(array('access content', 'administer site configuration')); $this->drupalLogin($admin_user); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index ebe5548..b209f4c 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -3017,6 +3017,8 @@ function _system_rebuild_theme_data() { $defaults = array( 'engine' => 'phptemplate', 'regions' => array( + 'account' => 'Account links', + 'main_menu' => 'Main navigation', 'sidebar_first' => 'Left sidebar', 'sidebar_second' => 'Right sidebar', 'content' => 'Content', diff --git a/core/modules/system/templates/page.tpl.php b/core/modules/system/templates/page.tpl.php index 6ddeeed..fd6e3cc 100644 --- a/core/modules/system/templates/page.tpl.php +++ b/core/modules/system/templates/page.tpl.php @@ -29,10 +29,6 @@ * in theme settings. * * Navigation: - * - $main_menu (array): An array containing the Main menu links for the - * site, if they have been configured. - * - $secondary_menu (array): An array containing the Secondary menu links for - * the site, if they have been configured. * - $breadcrumb: The breadcrumb trail for the current page. * * Page content (in order of occurrence in the default page.tpl.php): @@ -56,6 +52,8 @@ * comment/reply/12345). * * Regions: + * - $page['account']: Items for the account region. + * - $page['main_menu']: Items for the main menu region. * - $page['help']: Dynamic help text, mostly for admin pages. * - $page['highlighted']: Items for the highlighted content region. * - $page['content']: The main content of the current page. @@ -102,14 +100,18 @@ + + + - + diff --git a/core/modules/user/lib/Drupal/user/Tests/UserAccountLinksTests.php b/core/modules/user/lib/Drupal/user/Tests/UserAccountLinksTests.php index deec20e..ce01c2b 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserAccountLinksTests.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserAccountLinksTests.php @@ -15,6 +15,13 @@ class UserAccountLinksTests extends WebTestBase { /** + * The user account links block placed in the account region. + * + * @var \Drupal\block\Plugin\Core\Entity\Block + */ + protected $block; + + /** * Modules to enable. * * @var array @@ -29,6 +36,15 @@ public static function getInfo() { ); } + protected function setUp() { + parent::setUp(); + $this->block = $this->drupalPlaceBlock('menu_navigation', array('region' => 'account'), array( + 'menu' => 'account', + 'level' => 0, + 'id' => 'secondary-menu', + )); + } + /** * Tests the secondary menu. */ @@ -63,6 +79,11 @@ function testSecondaryMenu() { // For a logged-out user, expect no secondary links. $element = $this->xpath('//ul[@id=:menu_id]', array(':menu_id' => 'secondary-menu')); $this->assertEqual(count($element), 0, 'No secondary-menu for logged-out users.'); + // The wrapping list should not appear either. + $settings = $this->block->get('settings'); + $this->assertNoRaw($settings['id']); + // The entire menu block should not appear either. + $this->assertNoRaw(check_plain($this->block->label())); } /** diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php index bd75e06..8de1715 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php @@ -13,6 +13,14 @@ * Tests resetting a user password. */ class UserPasswordResetTest extends WebTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('menu', 'block'); + /** * The user object to test password resetting. * @@ -20,6 +28,13 @@ class UserPasswordResetTest extends WebTestBase { */ protected $account; + /** + * The user account links block placed in the account region. + * + * @var \Drupal\block\Plugin\Core\Entity\Block + */ + protected $block; + public static function getInfo() { return array( 'name' => 'Reset password', @@ -30,7 +45,12 @@ public static function getInfo() { public function setUp() { parent::setUp(); - + // Place the user links block in the content region. + $this->block = $this->drupalPlaceBlock('menu_navigation', array('region' => 'content'), array( + 'menu' => 'account', + 'level' => 0, + 'id' => 'secondary-menu', + )); // Create a user. $account = $this->drupalCreateUser(); diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/MenuTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/MenuTest.php index 5903552..b49359d 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/MenuTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/MenuTest.php @@ -12,6 +12,13 @@ */ class MenuTest extends WizardTestBase { + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('block', 'menu'); + public static function getInfo() { return array( 'name' => 'Menu functionality', @@ -20,6 +27,11 @@ public static function getInfo() { ); } + protected function setUp() { + parent::setUp(); + $this->drupalPlaceBlock('menu_navigation', array('region' => 'main_menu'), array('menu' => 'main')); + } + /** * Tests the menu functionality. */ diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardTestBase.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardTestBase.php index 0abb524..2dc2522 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardTestBase.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardTestBase.php @@ -21,7 +21,7 @@ */ public static $modules = array('views_ui', 'block'); - function setUp() { + protected function setUp() { parent::setUp(); // Create and log in a user with administer views permission. diff --git a/core/profiles/standard/config/block.block.bartik.account_links.yml b/core/profiles/standard/config/block.block.bartik.account_links.yml new file mode 100644 index 0000000..97b183c --- /dev/null +++ b/core/profiles/standard/config/block.block.bartik.account_links.yml @@ -0,0 +1,13 @@ +id: bartik.account_links +label: 'Account links' +region: account +weight: '0' +module: menu +status: '1' +plugin: menu_navigation +settings: + menu: account + level: '0' + id: secondary-menu + subject: 'Menu Navigation' +langcode: und diff --git a/core/profiles/standard/config/block.block.bartik.main_menu.yml b/core/profiles/standard/config/block.block.bartik.main_menu.yml new file mode 100644 index 0000000..895c255 --- /dev/null +++ b/core/profiles/standard/config/block.block.bartik.main_menu.yml @@ -0,0 +1,13 @@ +id: bartik.main_menu +label: 'Main menu' +region: main_menu +weight: '0' +module: menu +status: '1' +plugin: menu_navigation +settings: + menu: main + level: '0' + id: main-menu + subject: 'Menu Navigation' +langcode: und diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index a0594b0..b473a2a 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -3,6 +3,7 @@ * @file * Install, update and uninstall functions for the standard installation profile. */ +use Drupal\Component\Uuid\Uuid; /** * Implements hook_install(). @@ -265,3 +266,51 @@ function standard_install() { config('system.theme')->set('admin', 'seven')->save(); variable_set('node_admin_theme', '1'); } + +/** + * Place and create the main menu and secondary links menu navigation blocks. + * + * @ingroup config_upgrade + */ +function standard_update_8001() { + // Place main-menu. + $block = config('block.block.bartik.main_menu'); + $uuid = new Uuid(); + $block + ->set('id', 'bartik.main_menu') + ->set('uuid', $uuid->generate()) + ->set('plugin', 'menu_navigation') + ->set('module', 'menu') + ->set('region', 'main_menu') + ->set('weight', 0) + ->set('status', 1) + ->set('visibility', array()) + ->set('label', 'Main menu') + ->set('settings', array( + 'menu' => 'main', + 'level' => 0, + 'id' => 'main-menu', + 'subject' => 'Menu Navigation', + )); + $block->save(); + // Place secondary-menu (account links). + $block = config('block.block.bartik.account_links'); + $uuid = new Uuid(); + $block + ->set('id', 'bartik.account_links') + ->set('uuid', $uuid->generate()) + ->set('plugin', 'menu_navigation') + ->set('module', 'menu') + ->set('region', 'account') + ->set('weight', 0) + ->set('status', 1) + ->set('visibility', array()) + ->set('label', 'Account links') + ->set('settings', array( + 'menu' => 'account', + 'level' => 0, + 'id' => 'secondary-menu', + 'subject' => 'Menu Navigation', + )); + $block->save(); +} diff --git a/core/themes/bartik/bartik.info.yml b/core/themes/bartik/bartik.info.yml index 028de3e..6a45674 100644 --- a/core/themes/bartik/bartik.info.yml +++ b/core/themes/bartik/bartik.info.yml @@ -28,5 +28,7 @@ regions: footer_thirdcolumn: 'Footer third column' footer_fourthcolumn: 'Footer fourth column' footer: Footer + account: 'Account links' + main_menu: 'Main menu' settings: shortcut_module_link: '0' diff --git a/core/themes/bartik/bartik.theme b/core/themes/bartik/bartik.theme index 9a6c8a9..df07ed2 100644 --- a/core/themes/bartik/bartik.theme +++ b/core/themes/bartik/bartik.theme @@ -5,6 +5,8 @@ * Functions to support theming in the Bartik theme. */ +use Drupal\block\Plugin\Core\Entity\Block; + /** * Implements hook_preprocess_HOOK() for html.tpl.php. * @@ -151,3 +153,32 @@ function bartik_field__taxonomy_term_reference($variables) { return $output; } + +/** + * Implements hook_block_view_alter(). + */ +function bartik_block_view_alter(array &$build, Block $block) { + if ($block->id() == 'bartik.main_menu') { + $build['#prefix'] = ''; + $build['#theme'] = 'links__system_main_menu'; + $build['content']['#attributes']['id'] = 'main-menu-links'; + $build['#heading'] = array( + 'text' => t('Main menu'), + 'level' => 'h2', + 'class' => array('element-invisible'), + ); + } + if ($block->id() == 'bartik.account_links') { + $build['#prefix'] = ''; + $build['#theme'] = 'links__system_secondary_menu'; + $build['content']['#attributes']['id'] = 'secondary-menu-links'; + $build['content']['#attributes']['class'][] = 'inline'; + $build['#heading'] = array( + 'text' => t('Secondary menu'), + 'level' => 'h2', + 'class' => array('element-invisible'), + ); + } +} diff --git a/core/themes/bartik/templates/page.tpl.php b/core/themes/bartik/templates/page.tpl.php index 8b31e55..e020c09 100644 --- a/core/themes/bartik/templates/page.tpl.php +++ b/core/themes/bartik/templates/page.tpl.php @@ -36,10 +36,6 @@ * make the site slogan visually hidden, but still accessible. * * Navigation: - * - $main_menu (array): An array containing the Main menu links for the - * site, if they have been configured. - * - $secondary_menu (array): An array containing the Secondary menu links for - * the site, if they have been configured. * - $breadcrumb: The breadcrumb trail for the current page. * * Page content (in order of occurrence in the default page.tpl.php): @@ -63,7 +59,9 @@ * comment/reply/12345). * * Regions: + * - $page['account']: Items for the account region. * - $page['header']: Items for the header region. + * - $page['main_menu']: Items for the main menu region. * - $page['featured']: Items for the featured region. * - $page['highlighted']: Items for the highlighted content region. * - $page['help']: Dynamic help text, mostly for admin pages. @@ -89,24 +87,8 @@ ?>
-