Issue #3008927 by tim.plunkett, tedbow: The Layout Builder breadcrumbs for defaults don't lead to the view mode being edited

8.7.x
xjm 2019-02-13 13:51:49 -06:00
parent ba0c245c75
commit 89a75c0780
12 changed files with 105 additions and 36 deletions

View File

@ -5,9 +5,12 @@
* Provides hook implementations for Layout Builder.
*/
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
@ -288,3 +291,22 @@ function layout_builder_plugin_filter_layout__layout_builder_alter(array &$defin
] + $definitions;
}
}
/**
* Implements hook_system_breadcrumb_alter().
*/
function layout_builder_system_breadcrumb_alter(Breadcrumb &$breadcrumb, RouteMatchInterface $route_match, array $context) {
// Remove the extra 'Manage display' breadcrumb for Layout Builder defaults.
if ($route_match->getRouteObject()->hasOption('_layout_builder') && $route_match->getParameter('section_storage_type') === 'defaults') {
$links = array_filter($breadcrumb->getLinks(), function (Link $link) use ($route_match) {
$entity_type_id = $route_match->getParameter('entity_type_id');
return $link->getUrl()->getRouteName() !== "entity.entity_view_display.$entity_type_id.default";
});
// Links cannot be removed from an existing breadcrumb object. Create a new
// object but carry over the cacheable metadata.
$cacheability = CacheableMetadata::createFromObject($breadcrumb);
$breadcrumb = new Breadcrumb();
$breadcrumb->setLinks($links);
$breadcrumb->addCacheableDependency($cacheability);
}
}

View File

@ -93,3 +93,10 @@ function layout_builder_post_update_remove_layout_is_rebuilding() {
function layout_builder_post_update_routing_entity_form() {
// Empty post-update hook.
}
/**
* Clear caches due to routing changes to changing the URLs for defaults.
*/
function layout_builder_post_update_routing_defaults() {
// Empty post-update hook.
}

View File

@ -151,7 +151,7 @@ class DefaultsSectionStorage extends SectionStorageBase implements ContainerFact
continue;
}
$path = $entity_route->getPath() . '/display-layout/{view_mode_name}';
$path = $entity_route->getPath() . '/display/{view_mode_name}/layout';
$defaults = [];
$defaults['entity_type_id'] = $entity_type_id;

View File

@ -39,7 +39,10 @@ class LayoutBuilderTest extends BrowserTestBase {
$this->drupalPlaceBlock('local_tasks_block');
// Create two nodes.
$this->createContentType(['type' => 'bundle_with_section_field']);
$this->createContentType([
'type' => 'bundle_with_section_field',
'name' => 'Bundle with section field',
]);
$this->createNode([
'type' => 'bundle_with_section_field',
'title' => 'The first node title',
@ -131,7 +134,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$this->drupalPostForm(NULL, ['layout[enabled]' => TRUE], 'Save');
$assert_session->linkExists('Manage layout');
$this->clickLink('Manage layout');
$assert_session->addressEquals("$field_ui_prefix/display-layout/default");
$assert_session->addressEquals("$field_ui_prefix/display/default/layout");
// The body field is only present once.
$assert_session->elementsCount('css', '.field--name-body', 1);
// The extra field is only present once.
@ -145,7 +148,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$this->drupalGet("$field_ui_prefix/display/default");
$assert_session->linkExists('Manage layout');
$this->clickLink('Manage layout');
$assert_session->addressEquals("$field_ui_prefix/display-layout/default");
$assert_session->addressEquals("$field_ui_prefix/display/default/layout");
// The body field is only present once.
$assert_session->elementsCount('css', '.field--name-body', 1);
// The extra field is only present once.
@ -161,7 +164,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$page->pressButton('Add Block');
$assert_session->pageTextContains('Powered by Drupal');
$assert_session->pageTextContains('This is the label');
$assert_session->addressEquals("$field_ui_prefix/display-layout/default");
$assert_session->addressEquals("$field_ui_prefix/display/default/layout");
// Save the defaults.
$page->pressButton('Save layout');
@ -207,7 +210,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$assert_session->fieldDisabled('layout[allow_custom]');
// Alter the defaults.
$this->drupalGet("$field_ui_prefix/display-layout/default");
$this->drupalGet("$field_ui_prefix/display/default/layout");
$assert_session->linkExists('Add Block');
$this->clickLink('Add Block');
$assert_session->linkExists('Title');
@ -269,13 +272,13 @@ class LayoutBuilderTest extends BrowserTestBase {
$this->drupalPostForm("$field_ui_prefix/fields/add-field", $edit, 'Save and continue');
$page->pressButton('Save field settings');
$page->pressButton('Save settings');
$this->drupalGet("$field_ui_prefix/display-layout/default");
$this->drupalGet("$field_ui_prefix/display/default/layout");
$assert_session->pageTextContains('My text field');
$assert_session->elementExists('css', '.field--name-field-my-text');
// Delete the field.
$this->drupalPostForm("$field_ui_prefix/fields/node.bundle_with_section_field.field_my_text/delete", [], 'Delete');
$this->drupalGet("$field_ui_prefix/display-layout/default");
$this->drupalGet("$field_ui_prefix/display/default/layout");
$assert_session->pageTextNotContains('My text field');
$assert_session->elementNotExists('css', '.field--name-field-my-text');
}
@ -379,7 +382,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$assert_session->elementExists('css', '.field--name-body');
$page->pressButton('Save layout');
$this->drupalPostForm('admin/structure/menu/manage/myothermenu/delete', [], 'Delete');
$this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display-layout/default');
$this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default/layout');
$assert_session->elementNotExists('css', '.layout--layout-test-dependencies-plugin');
$assert_session->elementExists('css', '.field--name-body');
@ -407,7 +410,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$this->drupalPostForm('admin/structure/menu/manage/mymenu/delete', [], 'Delete');
// Ensure that the menu block is gone, but that the other block remains.
$this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display-layout/default');
$this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default/layout');
$assert_session->pageTextContains('Powered by Drupal');
$assert_session->pageTextNotContains('My Menu');
$assert_session->elementNotExists('css', '.block.menu--mymenu');
@ -434,7 +437,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$this->drupalPostForm("$field_ui_prefix/display/default", ['layout[allow_custom]' => TRUE], 'Save');
// Customize the default view mode.
$this->drupalGet("$field_ui_prefix/display-layout/default");
$this->drupalGet("$field_ui_prefix/display/default/layout");
$this->clickLink('Add Block');
$this->clickLink('Powered by Drupal');
$page->fillField('settings[label]', 'This is the default view mode');
@ -454,7 +457,7 @@ class LayoutBuilderTest extends BrowserTestBase {
// Enable the full view mode and customize it.
$this->drupalPostForm("$field_ui_prefix/display/default", ['display_modes_custom[full]' => TRUE], 'Save');
$this->drupalPostForm("$field_ui_prefix/display/full", ['layout[enabled]' => TRUE], 'Save');
$this->drupalGet("$field_ui_prefix/display-layout/full");
$this->drupalGet("$field_ui_prefix/display/full/layout");
$this->clickLink('Add Block');
$this->clickLink('Powered by Drupal');
$page->fillField('settings[label]', 'This is the full view mode');
@ -650,7 +653,7 @@ class LayoutBuilderTest extends BrowserTestBase {
$this->drupalPostForm("$field_ui_prefix/display/default", ['layout[enabled]' => TRUE], 'Save');
// Customize the default view mode.
$this->drupalGet("$field_ui_prefix/display-layout/default");
$this->drupalGet("$field_ui_prefix/display/default/layout");
// Add a block whose content is controlled by state and is empty by default.
$this->clickLink('Add Block');
@ -729,6 +732,43 @@ class LayoutBuilderTest extends BrowserTestBase {
$assert_session->pageTextNotContains('Content fields');
}
/**
* Tests the expected breadcrumbs of the Layout Builder UI.
*/
public function testBreadcrumb() {
$page = $this->getSession()->getPage();
$this->drupalPlaceBlock('system_breadcrumb_block');
$this->drupalLogin($this->drupalCreateUser([
'configure any layout',
'administer node display',
'administer content types',
'access administration pages',
]));
// From the manage display page, go to manage the layout.
$this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default');
$this->drupalPostForm(NULL, ['layout[enabled]' => TRUE], 'Save');
$this->drupalPostForm(NULL, ['layout[allow_custom]' => TRUE], 'Save');
$page->clickLink('Manage layout');
$breadcrumb_titles = [];
foreach ($page->findAll('css', '.breadcrumb a') as $link) {
$breadcrumb_titles[$link->getText()] = $link->getAttribute('href');
}
$base_path = base_path();
$expected = [
'Home' => $base_path,
'Administration' => $base_path . 'admin',
'Structure' => $base_path . 'admin/structure',
'Content types' => $base_path . 'admin/structure/types',
'Bundle with section field' => $base_path . 'admin/structure/types/manage/bundle_with_section_field',
'Manage display' => $base_path . 'admin/structure/types/manage/bundle_with_section_field/display/default',
];
$this->assertSame($expected, $breadcrumb_titles);
}
/**
* Tests a config-based implementation of Layout Builder.
*

View File

@ -280,20 +280,20 @@ class LayoutSectionTest extends BrowserTestBase {
public function testLayoutDeletingField() {
$assert_session = $this->assertSession();
$this->drupalGet('/admin/structure/types/manage/bundle_with_section_field/display-layout/default');
$this->drupalGet('/admin/structure/types/manage/bundle_with_section_field/display/default/layout');
$assert_session->statusCodeEquals(200);
$assert_session->elementExists('css', '.field--name-body');
// Delete the field from both bundles.
$this->drupalGet('/admin/structure/types/manage/bundle_without_section_field/fields/node.bundle_without_section_field.body/delete');
$this->submitForm([], 'Delete');
$this->drupalGet('/admin/structure/types/manage/bundle_with_section_field/display-layout/default');
$this->drupalGet('/admin/structure/types/manage/bundle_with_section_field/display/default/layout');
$assert_session->statusCodeEquals(200);
$assert_session->elementExists('css', '.field--name-body');
$this->drupalGet('/admin/structure/types/manage/bundle_with_section_field/fields/node.bundle_with_section_field.body/delete');
$this->submitForm([], 'Delete');
$this->drupalGet('/admin/structure/types/manage/bundle_with_section_field/display-layout/default');
$this->drupalGet('/admin/structure/types/manage/bundle_with_section_field/display/default/layout');
$assert_session->statusCodeEquals(200);
$assert_session->elementNotExists('css', '.field--name-body');
}

View File

@ -38,7 +38,7 @@ class LayoutBuilderContextMappingUpdatePathTest extends UpdatePathTestBase {
// Overrides.
'node/1',
// Defaults.
'admin/structure/types/manage/article/display-layout/default',
'admin/structure/types/manage/article/display/default/layout',
];
foreach ($paths as $path) {
$this->drupalGet($path);

View File

@ -63,7 +63,7 @@ class AjaxBlockTest extends WebDriverTestBase {
$this->drupalPostForm("$field_ui_prefix/display/default", ['layout[enabled]' => TRUE], 'Save');
$assert_session->linkExists('Manage layout');
$this->clickLink('Manage layout');
$assert_session->addressEquals("$field_ui_prefix/display-layout/default");
$assert_session->addressEquals("$field_ui_prefix/display/default/layout");
// The body field is present.
$assert_session->elementExists('css', '.field--name-body');

View File

@ -50,7 +50,7 @@ class BlockFilterTest extends WebDriverTestBase {
$this->drupalPostForm("$field_ui_prefix/display/default", ['layout[enabled]' => TRUE], 'Save');
$assert_session->linkExists('Manage layout');
$this->clickLink('Manage layout');
$assert_session->addressEquals("$field_ui_prefix/display-layout/default");
$assert_session->addressEquals("$field_ui_prefix/display/default/layout");
// Open the block listing.
$assert_session->linkExists('Add Block');

View File

@ -32,7 +32,7 @@ class InlineBlockTest extends InlineBlockTestBase {
'Save'
);
$this->clickLink('Manage layout');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display-layout/default');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout');
// Add a basic block with the body field set.
$this->addInlineBlockToLayout('Block title', 'The DEFAULT block body');
$this->assertSaveLayout();
@ -89,7 +89,7 @@ class InlineBlockTest extends InlineBlockTestBase {
$assert_session->pageTextNotContains('The 2nd NEW block body!');
// The default layout entity block should be changed.
$this->drupalGet(static::FIELD_UI_PREFIX . '/display-layout/default');
$this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout');
$assert_session->pageTextContains('The DEFAULT block body');
// Confirm default layout still only has 1 entity block.
$assert_session->elementsCount('css', static::INLINE_BLOCK_LOCATOR, 1);
@ -284,7 +284,7 @@ class InlineBlockTest extends InlineBlockTestBase {
// Add a block to default layout.
$this->drupalGet(static::FIELD_UI_PREFIX . '/display/default');
$this->clickLink('Manage layout');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display-layout/default');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout');
$this->addInlineBlockToLayout('Block title', 'The DEFAULT block body');
$this->assertSaveLayout();
@ -312,7 +312,7 @@ class InlineBlockTest extends InlineBlockTestBase {
$this->drupalGet(static::FIELD_UI_PREFIX . '/display/default');
$this->clickLink('Manage layout');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display-layout/default');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout');
$this->assertNotEmpty($this->blockStorage->load($default_block_id));
$this->assertNotEmpty($usage->getUsage($default_block_id));
@ -349,7 +349,7 @@ class InlineBlockTest extends InlineBlockTestBase {
// Add another block to the default.
$this->drupalGet(static::FIELD_UI_PREFIX . '/display/default');
$this->clickLink('Manage layout');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display-layout/default');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout');
$this->addInlineBlockToLayout('Title 2', 'Body 2');
$this->assertSaveLayout();
$cron->run();
@ -456,7 +456,7 @@ class InlineBlockTest extends InlineBlockTestBase {
'Save'
);
$layout_default_path = 'admin/structure/types/manage/bundle_with_section_field/display-layout/default';
$layout_default_path = 'admin/structure/types/manage/bundle_with_section_field/display/default/layout';
$this->drupalGet($layout_default_path);
// Add a basic block with the body field set.
$page->clickLink('Add Block');

View File

@ -58,7 +58,7 @@ class LayoutBuilderUiTest extends WebDriverTestBase {
$page = $this->getSession()->getPage();
// Remove all of the sections from the page.
$this->drupalGet(static::FIELD_UI_PREFIX . '/display-layout/default');
$this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout');
$page->clickLink('Remove section');
$assert_session->assertWaitOnAjaxRequest();
$page->pressButton('Remove');
@ -68,7 +68,7 @@ class LayoutBuilderUiTest extends WebDriverTestBase {
$assert_session->pageTextNotContains('Add Block');
// Reload the page.
$this->drupalGet(static::FIELD_UI_PREFIX . '/display-layout/default');
$this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout');
// Assert that there are no sections on the page.
$assert_session->pageTextNotContains('Remove section');
$assert_session->pageTextNotContains('Add Block');
@ -82,13 +82,13 @@ class LayoutBuilderUiTest extends WebDriverTestBase {
$page = $this->getSession()->getPage();
// Make and then discard changes.
$this->assertModifiedLayout(static::FIELD_UI_PREFIX . '/display-layout/default');
$this->assertModifiedLayout(static::FIELD_UI_PREFIX . '/display/default/layout');
$page->clickLink('Discard changes');
$page->pressButton('Confirm');
$assert_session->pageTextNotContains('You have unsaved changes.');
// Make and then save changes.
$this->assertModifiedLayout(static::FIELD_UI_PREFIX . '/display-layout/default');
$this->assertModifiedLayout(static::FIELD_UI_PREFIX . '/display/default/layout');
$page->pressButton('Save layout');
$assert_session->pageTextNotContains('You have unsaved changes.');
}

View File

@ -58,7 +58,7 @@ class TestMultiWidthLayoutsTest extends WebDriverTestBase {
);
$this->clickLink('Manage layout');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display-layout/default');
$assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout');
$width_options = [
[

View File

@ -385,7 +385,7 @@ class DefaultsSectionStorageTest extends UnitTestCase {
'known' => new Route('/admin/entity/whatever', [], [], ['_admin_route' => TRUE]),
'with_bundle' => new Route('/admin/entity/{bundle}'),
'layout_builder.defaults.with_bundle_key.view' => new Route(
'/admin/entity/whatever/display-layout/{view_mode_name}',
'/admin/entity/whatever/display/{view_mode_name}/layout',
[
'entity_type_id' => 'with_bundle_key',
'bundle_key' => 'my_bundle_type',
@ -410,7 +410,7 @@ class DefaultsSectionStorageTest extends UnitTestCase {
]
),
'layout_builder.defaults.with_bundle_key.discard_changes' => new Route(
'/admin/entity/whatever/display-layout/{view_mode_name}/discard-changes',
'/admin/entity/whatever/display/{view_mode_name}/layout/discard-changes',
[
'entity_type_id' => 'with_bundle_key',
'bundle_key' => 'my_bundle_type',
@ -432,7 +432,7 @@ class DefaultsSectionStorageTest extends UnitTestCase {
]
),
'layout_builder.defaults.with_bundle_key.disable' => new Route(
'/admin/entity/whatever/display-layout/{view_mode_name}/disable',
'/admin/entity/whatever/display/{view_mode_name}/layout/disable',
[
'entity_type_id' => 'with_bundle_key',
'bundle_key' => 'my_bundle_type',
@ -452,7 +452,7 @@ class DefaultsSectionStorageTest extends UnitTestCase {
]
),
'layout_builder.defaults.with_bundle_parameter.view' => new Route(
'/admin/entity/{bundle}/display-layout/{view_mode_name}',
'/admin/entity/{bundle}/display/{view_mode_name}/layout',
[
'entity_type_id' => 'with_bundle_parameter',
'section_storage_type' => 'defaults',
@ -474,7 +474,7 @@ class DefaultsSectionStorageTest extends UnitTestCase {
]
),
'layout_builder.defaults.with_bundle_parameter.discard_changes' => new Route(
'/admin/entity/{bundle}/display-layout/{view_mode_name}/discard-changes',
'/admin/entity/{bundle}/display/{view_mode_name}/layout/discard-changes',
[
'entity_type_id' => 'with_bundle_parameter',
'section_storage_type' => 'defaults',
@ -495,7 +495,7 @@ class DefaultsSectionStorageTest extends UnitTestCase {
]
),
'layout_builder.defaults.with_bundle_parameter.disable' => new Route(
'/admin/entity/{bundle}/display-layout/{view_mode_name}/disable',
'/admin/entity/{bundle}/display/{view_mode_name}/layout/disable',
[
'entity_type_id' => 'with_bundle_parameter',
'section_storage_type' => 'defaults',