Issue #2594425 by Sam152, gapple, naveenvalecha, dubcanada, Nitesh Pawar, Fonski, bircher, Eric115, ricovandevin, pameeela, mishradileep, juusechec, dawehner, jibran, xjm, ifrik, swentel, kim.pepper, Wim Leers, acbramley, 4aficiona2, yoroy, alexpott, ckaotik, andypost, FeyP: Add the option in system menu block to "Expand all items in this tree"
parent
f7f07d81ac
commit
f335587290
|
@ -130,7 +130,7 @@ class MenuLinkDefaultForm implements MenuLinkFormInterface, ContainerInjectionIn
|
||||||
$form['expanded'] = [
|
$form['expanded'] = [
|
||||||
'#type' => 'checkbox',
|
'#type' => 'checkbox',
|
||||||
'#title' => t('Show as expanded'),
|
'#title' => t('Show as expanded'),
|
||||||
'#description' => $this->t('If selected and this menu link has children, the menu will always appear expanded.'),
|
'#description' => $this->t('If selected and this menu link has children, the menu will always appear expanded. This option may be overridden for the entire menu tree when placing a menu block.'),
|
||||||
'#default_value' => $this->menuLink->isExpanded(),
|
'#default_value' => $this->menuLink->isExpanded(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,7 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
|
||||||
'provider' => 'system',
|
'provider' => 'system',
|
||||||
'label_display' => 'visible',
|
'label_display' => 'visible',
|
||||||
'level' => 1,
|
'level' => 1,
|
||||||
|
'expand_all_items' => FALSE,
|
||||||
'depth' => 0,
|
'depth' => 0,
|
||||||
];
|
];
|
||||||
$this->assertEntity('user_1', $visibility, 'sidebar_first', 'bartik', -11, $settings);
|
$this->assertEntity('user_1', $visibility, 'sidebar_first', 'bartik', -11, $settings);
|
||||||
|
|
|
@ -348,7 +348,7 @@ class MenuLinkContent extends ContentEntityBase implements MenuLinkContentInterf
|
||||||
|
|
||||||
$fields['expanded'] = BaseFieldDefinition::create('boolean')
|
$fields['expanded'] = BaseFieldDefinition::create('boolean')
|
||||||
->setLabel(t('Show as expanded'))
|
->setLabel(t('Show as expanded'))
|
||||||
->setDescription(t('If selected and this menu link has children, the menu will always appear expanded.'))
|
->setDescription(t('If selected and this menu link has children, the menu will always appear expanded. This option may be overridden for the entire menu tree when placing a menu block.'))
|
||||||
->setDefaultValue(FALSE)
|
->setDefaultValue(FALSE)
|
||||||
->setDisplayOptions('view', [
|
->setDisplayOptions('view', [
|
||||||
'label' => 'hidden',
|
'label' => 'hidden',
|
||||||
|
|
|
@ -864,6 +864,47 @@ class MenuUiTest extends BrowserTestBase {
|
||||||
$this->assertSession()->statusCodeEquals(403);
|
$this->assertSession()->statusCodeEquals(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the "expand all items" feature.
|
||||||
|
*/
|
||||||
|
public function testExpandAllItems() {
|
||||||
|
$this->drupalLogin($this->adminUser);
|
||||||
|
$menu = $this->addCustomMenu();
|
||||||
|
$node = $this->drupalCreateNode(['type' => 'article']);
|
||||||
|
|
||||||
|
// Create three menu items, none of which are expanded.
|
||||||
|
$parent = $this->addMenuLink('', $node->toUrl()->toString(), $menu->id(), FALSE);
|
||||||
|
$child_1 = $this->addMenuLink($parent->getPluginId(), $node->toUrl()->toString(), $menu->id(), FALSE);
|
||||||
|
$child_2 = $this->addMenuLink($parent->getPluginId(), $node->toUrl()->toString(), $menu->id(), FALSE);
|
||||||
|
|
||||||
|
// The menu will not automatically show all levels of depth.
|
||||||
|
$this->drupalGet('<front>');
|
||||||
|
$this->assertSession()->linkExists($parent->getTitle());
|
||||||
|
$this->assertSession()->linkNotExists($child_1->getTitle());
|
||||||
|
$this->assertSession()->linkNotExists($child_2->getTitle());
|
||||||
|
|
||||||
|
// Update the menu block to show all levels of depth as expanded.
|
||||||
|
$block_id = $this->blockPlacements[$menu->id()];
|
||||||
|
$this->drupalGet('admin/structure/block/manage/' . $block_id);
|
||||||
|
$this->assertSession()->checkboxNotChecked('settings[expand_all_items]');
|
||||||
|
$this->drupalPostForm(NULL, [
|
||||||
|
'settings[depth]' => 2,
|
||||||
|
'settings[level]' => 1,
|
||||||
|
'settings[expand_all_items]' => 1,
|
||||||
|
], t('Save block'));
|
||||||
|
|
||||||
|
// Ensure the setting is persisted.
|
||||||
|
$this->drupalGet('admin/structure/block/manage/' . $block_id);
|
||||||
|
$this->assertSession()->checkboxChecked('settings[expand_all_items]');
|
||||||
|
|
||||||
|
// Ensure all three links are shown, including the children which would
|
||||||
|
// usually be hidden without the "expand all items" setting.
|
||||||
|
$this->drupalGet('<front>');
|
||||||
|
$this->assertSession()->linkExists($parent->getTitle());
|
||||||
|
$this->assertSession()->linkExists($child_1->getTitle());
|
||||||
|
$this->assertSession()->linkExists($child_2->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns standard menu link.
|
* Returns standard menu link.
|
||||||
*
|
*
|
||||||
|
|
|
@ -337,6 +337,9 @@ block.settings.system_menu_block:*:
|
||||||
depth:
|
depth:
|
||||||
type: integer
|
type: integer
|
||||||
label: 'Maximum number of levels'
|
label: 'Maximum number of levels'
|
||||||
|
expand_all_items:
|
||||||
|
type: boolean
|
||||||
|
label: 'Expand all items'
|
||||||
|
|
||||||
block.settings.local_tasks_block:
|
block.settings.local_tasks_block:
|
||||||
type: block_settings
|
type: block_settings
|
||||||
|
|
|
@ -5,7 +5,9 @@ namespace Drupal\system\Plugin\Block;
|
||||||
use Drupal\Core\Block\BlockBase;
|
use Drupal\Core\Block\BlockBase;
|
||||||
use Drupal\Core\Cache\Cache;
|
use Drupal\Core\Cache\Cache;
|
||||||
use Drupal\Core\Form\FormStateInterface;
|
use Drupal\Core\Form\FormStateInterface;
|
||||||
|
use Drupal\Core\Menu\MenuActiveTrailInterface;
|
||||||
use Drupal\Core\Menu\MenuLinkTreeInterface;
|
use Drupal\Core\Menu\MenuLinkTreeInterface;
|
||||||
|
use Drupal\Core\Menu\MenuTreeParameters;
|
||||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
|
||||||
|
@ -31,6 +33,13 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
|
||||||
*/
|
*/
|
||||||
protected $menuTree;
|
protected $menuTree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The active menu trail service.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Menu\MenuActiveTrailInterface
|
||||||
|
*/
|
||||||
|
protected $menuActiveTrail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new SystemMenuBlock.
|
* Constructs a new SystemMenuBlock.
|
||||||
*
|
*
|
||||||
|
@ -42,10 +51,13 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
|
||||||
* The plugin implementation definition.
|
* The plugin implementation definition.
|
||||||
* @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree
|
* @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree
|
||||||
* The menu tree service.
|
* The menu tree service.
|
||||||
|
* @param \Drupal\Core\Menu\MenuActiveTrailInterface $menu_active_trail
|
||||||
|
* The active menu trail service.
|
||||||
*/
|
*/
|
||||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MenuLinkTreeInterface $menu_tree) {
|
public function __construct(array $configuration, $plugin_id, $plugin_definition, MenuLinkTreeInterface $menu_tree, MenuActiveTrailInterface $menu_active_trail) {
|
||||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||||
$this->menuTree = $menu_tree;
|
$this->menuTree = $menu_tree;
|
||||||
|
$this->menuActiveTrail = $menu_active_trail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,7 +68,8 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
|
||||||
$configuration,
|
$configuration,
|
||||||
$plugin_id,
|
$plugin_id,
|
||||||
$plugin_definition,
|
$plugin_definition,
|
||||||
$container->get('menu.link_tree')
|
$container->get('menu.link_tree'),
|
||||||
|
$container->get('menu.active_trail')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +111,13 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
|
||||||
'#required' => TRUE,
|
'#required' => TRUE,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$form['menu_levels']['expand_all_items'] = [
|
||||||
|
'#type' => 'checkbox',
|
||||||
|
'#title' => $this->t('Expand all menu items'),
|
||||||
|
'#default_value' => !empty($config['expand_all_items']),
|
||||||
|
'#description' => $this->t('Override the option found on each menu link used for expanding children and instead display the whole menu tree as expanded.'),
|
||||||
|
];
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +137,7 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
|
||||||
public function blockSubmit($form, FormStateInterface $form_state) {
|
public function blockSubmit($form, FormStateInterface $form_state) {
|
||||||
$this->configuration['level'] = $form_state->getValue('level');
|
$this->configuration['level'] = $form_state->getValue('level');
|
||||||
$this->configuration['depth'] = $form_state->getValue('depth');
|
$this->configuration['depth'] = $form_state->getValue('depth');
|
||||||
|
$this->configuration['expand_all_items'] = $form_state->getValue('expand_all_items');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,7 +145,14 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
|
||||||
*/
|
*/
|
||||||
public function build() {
|
public function build() {
|
||||||
$menu_name = $this->getDerivativeId();
|
$menu_name = $this->getDerivativeId();
|
||||||
|
if ($this->configuration['expand_all_items']) {
|
||||||
|
$parameters = new MenuTreeParameters();
|
||||||
|
$active_trail = $this->menuActiveTrail->getActiveTrailIds($menu_name);
|
||||||
|
$parameters->setActiveTrail($active_trail);
|
||||||
|
}
|
||||||
|
else {
|
||||||
$parameters = $this->menuTree->getCurrentRouteMenuTreeParameters($menu_name);
|
$parameters = $this->menuTree->getCurrentRouteMenuTreeParameters($menu_name);
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust the menu tree parameters based on the block's configuration.
|
// Adjust the menu tree parameters based on the block's configuration.
|
||||||
$level = $this->configuration['level'];
|
$level = $this->configuration['level'];
|
||||||
|
@ -173,6 +201,7 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
|
||||||
return [
|
return [
|
||||||
'level' => 1,
|
'level' => 1,
|
||||||
'depth' => 0,
|
'depth' => 0,
|
||||||
|
'expand_all_items' => FALSE,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,3 +178,16 @@ function system_post_update_extra_fields(&$sandbox = NULL) {
|
||||||
function system_post_update_states_clear_cache() {
|
function system_post_update_states_clear_cache() {
|
||||||
// Empty post-update hook.
|
// Empty post-update hook.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize 'expand_all_items' values to system_menu_block.
|
||||||
|
*/
|
||||||
|
function system_post_update_add_expand_all_items_key_in_system_menu_block(&$sandbox = NULL) {
|
||||||
|
\Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'block', function ($block) {
|
||||||
|
if (strpos($block->getPluginId(), 'system_menu_block:') === 0) {
|
||||||
|
$block->set('settings.expand_all_items', FALSE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\system\Functional\Update;
|
||||||
|
|
||||||
|
use Drupal\block\Entity\Block;
|
||||||
|
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests updating menu blocks configuration.
|
||||||
|
*
|
||||||
|
* @group Update
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
class MenuBlockPostUpdateTest extends UpdatePathTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setDatabaseDumpFiles() {
|
||||||
|
$this->databaseDumpFiles = [
|
||||||
|
// Use a more recent fixture for performance, do not run all pre-8.4
|
||||||
|
// updates when testing this feature.
|
||||||
|
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.4.0.bare.standard.php.gz',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests updating blocks with default 'expand_all_items' value.
|
||||||
|
*
|
||||||
|
* @see system_post_update_add_expand_all_items_key_in_system_menu_block()
|
||||||
|
*/
|
||||||
|
public function testPostUpdateMenuBlockFields() {
|
||||||
|
$this->assertArrayNotHasKey('expand_all_items', Block::load('bartik_account_menu')->get('settings'));
|
||||||
|
$this->runUpdates();
|
||||||
|
$this->assertArrayHasKey('expand_all_items', Block::load('bartik_account_menu')->get('settings'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -282,6 +282,76 @@ class SystemMenuBlockTest extends KernelTestBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the config expanded option.
|
||||||
|
*
|
||||||
|
* @dataProvider configExpandedTestCases
|
||||||
|
*/
|
||||||
|
public function testConfigExpanded($active_route, $menu_block_level, $expected_items) {
|
||||||
|
$block = $this->blockManager->createInstance('system_menu_block:' . $this->menu->id(), [
|
||||||
|
'region' => 'footer',
|
||||||
|
'id' => 'machinename',
|
||||||
|
'theme' => 'stark',
|
||||||
|
'level' => $menu_block_level,
|
||||||
|
'depth' => 0,
|
||||||
|
'expand_all_items' => TRUE,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$route = $this->container->get('router.route_provider')->getRouteByName($active_route);
|
||||||
|
$request = new Request();
|
||||||
|
$request->attributes->set(RouteObjectInterface::ROUTE_NAME, $active_route);
|
||||||
|
$request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, $route);
|
||||||
|
$this->container->get('request_stack')->push($request);
|
||||||
|
|
||||||
|
$block_build = $block->build();
|
||||||
|
$items = isset($block_build['#items']) ? $block_build['#items'] : [];
|
||||||
|
$this->assertEquals($expected_items, $this->convertBuiltMenuToIdTree($items));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function configExpandedTestCases() {
|
||||||
|
return [
|
||||||
|
'All levels' => [
|
||||||
|
'example5',
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
'test.example1' => [],
|
||||||
|
'test.example2' => [
|
||||||
|
'test.example3' => [
|
||||||
|
'test.example4' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'test.example5' => [
|
||||||
|
'test.example7' => [],
|
||||||
|
],
|
||||||
|
'test.example6' => [],
|
||||||
|
'test.example8' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'Level two in "example 5" branch' => [
|
||||||
|
'example5',
|
||||||
|
2,
|
||||||
|
[
|
||||||
|
'test.example7' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'Level three in "example 5" branch' => [
|
||||||
|
'example5',
|
||||||
|
3,
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
'Level three in "example 4" branch' => [
|
||||||
|
'example4',
|
||||||
|
3,
|
||||||
|
[
|
||||||
|
'test.example4' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to allow for easy menu link tree structure assertions.
|
* Helper method to allow for easy menu link tree structure assertions.
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: '0'
|
label_display: '0'
|
||||||
level: 1
|
level: 1
|
||||||
depth: 1
|
depth: 1
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: '1'
|
label_display: '1'
|
||||||
level: 1
|
level: 1
|
||||||
depth: 0
|
depth: 0
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: '0'
|
label_display: '0'
|
||||||
level: 1
|
level: 1
|
||||||
depth: 1
|
depth: 1
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: visible
|
label_display: visible
|
||||||
level: 1
|
level: 1
|
||||||
depth: 0
|
depth: 0
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: visible
|
label_display: visible
|
||||||
level: 1
|
level: 1
|
||||||
depth: 0
|
depth: 0
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: '0'
|
label_display: '0'
|
||||||
level: 1
|
level: 1
|
||||||
depth: 1
|
depth: 1
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: '0'
|
label_display: '0'
|
||||||
level: 1
|
level: 1
|
||||||
depth: 0
|
depth: 0
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: '0'
|
label_display: '0'
|
||||||
level: 1
|
level: 1
|
||||||
depth: 1
|
depth: 1
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
|
@ -20,4 +20,5 @@ settings:
|
||||||
label_display: visible
|
label_display: visible
|
||||||
level: 1
|
level: 1
|
||||||
depth: 0
|
depth: 0
|
||||||
|
expand_all_items: false
|
||||||
visibility: { }
|
visibility: { }
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue