diff --git a/core/modules/aggregator/config/install/views.view.aggregator_sources.yml b/core/modules/aggregator/config/install/views.view.aggregator_sources.yml index 8612cff..3e904ff 100644 --- a/core/modules/aggregator/config/install/views.view.aggregator_sources.yml +++ b/core/modules/aggregator/config/install/views.view.aggregator_sources.yml @@ -18,14 +18,17 @@ display: id: default display_title: Master position: 0 + provider: views display_options: access: type: perm options: perm: 'access news feeds' + provider: null cache: type: none options: { } + provider: views query: type: views_query options: @@ -34,6 +37,7 @@ display: replica: false query_comment: false query_tags: { } + provider: views exposed_form: type: basic options: @@ -44,6 +48,7 @@ display: expose_sort_order: true sort_asc_label: Asc sort_desc_label: Desc + provider: views pager: type: full options: @@ -78,9 +83,11 @@ display: field: fid id: fid plugin_id: numeric + provider: views relationship: none group_type: group admin_label: '' + dependencies: { } label: '' exclude: false alter: @@ -131,8 +138,6 @@ display: format_plural_plural: '@count' prefix: '' suffix: '' - entity_type: aggregator_feed - entity_field: fid filters: { } sorts: { } title: Sources @@ -143,11 +148,13 @@ display: arguments: { } field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } feed_1: display_plugin: feed id: feed_1 display_title: Feed position: 2 + provider: views display_options: field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null @@ -155,6 +162,7 @@ display: type: opml options: grouping: { } + provider: views path: aggregator/opml fields: title: @@ -164,6 +172,9 @@ display: relationship: none group_type: group admin_label: '' + dependencies: + module: + - aggregator label: '' exclude: false alter: @@ -207,8 +218,7 @@ display: hide_alter_empty: true display_as_link: false plugin_id: aggregator_title_link - entity_type: aggregator_feed - entity_field: title + provider: aggregator url: id: url table: aggregator_feed @@ -216,6 +226,9 @@ display: relationship: none group_type: group admin_label: '' + dependencies: + module: + - views label: '' exclude: false alter: @@ -259,8 +272,7 @@ display: hide_alter_empty: true display_as_link: false plugin_id: url - entity_type: aggregator_feed - entity_field: url + provider: views description: id: description table: aggregator_feed @@ -268,6 +280,9 @@ display: relationship: none group_type: group admin_label: '' + dependencies: + module: + - views label: '' exclude: false alter: @@ -310,8 +325,7 @@ display: empty_zero: false hide_alter_empty: true plugin_id: xss - entity_type: aggregator_feed - entity_field: description + provider: views link: id: link table: aggregator_feed @@ -319,6 +333,9 @@ display: relationship: none group_type: group admin_label: '' + dependencies: + module: + - views label: '' exclude: false alter: @@ -362,8 +379,7 @@ display: hide_alter_empty: true display_as_link: false plugin_id: url - entity_type: aggregator_feed - entity_field: link + provider: views defaults: fields: false title: false @@ -378,24 +394,32 @@ display: language_field: '' xml_url_field: url url_field: '' + provider: views displays: page_1: page_1 default: '0' title: 'OPML feed' sitename_title: true + display_extenders: { } page_1: display_plugin: page id: page_1 display_title: Page position: 1 + provider: views display_options: field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: aggregator/sources menu: - type: normal + type: + normal: normal + tab: '0' + 'default tab': '0' title: Sources description: '' + parent: '' weight: 0 context: '0' menu_name: tools + display_extenders: { } diff --git a/core/modules/file/config/install/views.view.files.yml b/core/modules/file/config/install/views.view.files.yml index 711efee..2176965 100644 --- a/core/modules/file/config/install/views.view.files.yml +++ b/core/modules/file/config/install/views.view.files.yml @@ -176,8 +176,6 @@ display: empty: '' hide_alter_empty: true plugin_id: file - entity_type: file - entity_field: fid filename: id: filename table: file_managed @@ -210,8 +208,6 @@ display: empty: '' hide_alter_empty: true plugin_id: file - entity_type: file - entity_field: filename filemime: id: filemime table: file_managed @@ -263,8 +259,6 @@ display: link_to_file: false filemime_image: false plugin_id: file_filemime - entity_type: file - entity_field: filemime filesize: id: filesize table: file_managed @@ -315,8 +309,6 @@ display: hide_alter_empty: true file_size_display: formatted plugin_id: file_size - entity_type: file - entity_field: filesize status: id: status table: file_managed @@ -366,8 +358,6 @@ display: empty_zero: false hide_alter_empty: true plugin_id: file_status - entity_type: file - entity_field: status created: id: created table: file_managed @@ -420,8 +410,6 @@ display: custom_date_format: '' timezone: '' plugin_id: date - entity_type: file - entity_field: created changed: id: changed table: file_managed @@ -474,8 +462,6 @@ display: custom_date_format: '' timezone: '' plugin_id: date - entity_type: file - entity_field: changed count: id: count table: file_usage @@ -573,8 +559,6 @@ display: default_group_multiple: { } group_items: { } plugin_id: string - entity_type: file - entity_field: filename filemime: id: filemime table: file_managed @@ -613,8 +597,6 @@ display: default_group_multiple: { } group_items: { } plugin_id: string - entity_type: file - entity_field: filemime status: id: status table: file_managed @@ -654,8 +636,6 @@ display: default_group_multiple: { } group_items: { } plugin_id: file_status - entity_type: file - entity_field: status sorts: { } title: Files header: { } @@ -682,6 +662,7 @@ display: show_admin_links: true field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } page_1: display_plugin: page id: page_1 @@ -690,12 +671,16 @@ display: display_options: path: admin/content/files menu: - type: tab + type: + tab: tab + normal: '0' + 'default tab': '0' title: Files description: '' - menu_name: admin + parent: '' weight: 0 - context: '' + context: '0' + menu_name: admin display_description: '' defaults: pager: true @@ -711,6 +696,7 @@ display: required: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } page_2: display_plugin: page id: page_2 @@ -999,8 +985,6 @@ display: break_phrase: false not: false plugin_id: file_fid - entity_type: file - entity_field: fid style: type: table options: @@ -1062,3 +1046,4 @@ display: required: true field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } diff --git a/core/modules/node/config/install/views.view.content.yml b/core/modules/node/config/install/views.view.content.yml index 2a44101..79d5e0b 100644 --- a/core/modules/node/config/install/views.view.content.yml +++ b/core/modules/node/config/install/views.view.content.yml @@ -1,3 +1,4 @@ +uuid: 3726fb5a-ed6c-4c0f-b20e-14f6108dd984 langcode: en status: true dependencies: @@ -148,7 +149,6 @@ display: empty_zero: false hide_alter_empty: true plugin_id: node_bulk_form - entity_type: node title: id: title table: node_field_data @@ -165,8 +165,6 @@ display: hide_alter_empty: true link_to_node: true plugin_id: node - entity_type: node - entity_field: title type: id: type table: node_field_data @@ -184,8 +182,6 @@ display: link_to_node: false machine_name: '' plugin_id: node_type - entity_type: node - entity_field: type name: id: name table: users_field_data @@ -206,8 +202,6 @@ display: anonymous_text: '' format_username: true plugin_id: user_name - entity_type: user - entity_field: name status: id: status table: node_field_data @@ -227,8 +221,6 @@ display: type_custom_false: '' not: '' plugin_id: boolean - entity_type: node - entity_field: status changed: id: changed table: node_field_data @@ -247,8 +239,6 @@ display: custom_date_format: '' timezone: '' plugin_id: date - entity_type: node - entity_field: changed edit_node: id: edit_node table: node @@ -257,7 +247,6 @@ display: exclude: true text: Edit plugin_id: node_link_edit - entity_type: node delete_node: id: delete_node table: node @@ -266,7 +255,6 @@ display: exclude: true text: Delete plugin_id: node_link_delete - entity_type: node dropbutton: id: dropbutton table: views @@ -286,7 +274,6 @@ display: value: false plugin_id: node_status group: 1 - entity_type: node status: id: status table: node_field_data @@ -331,8 +318,6 @@ display: operator: '=' value: '0' plugin_id: boolean - entity_type: node - entity_field: status type: id: type table: node_field_data @@ -372,8 +357,6 @@ display: default_group_multiple: { } group_items: { } plugin_id: bundle - entity_type: node - entity_field: type title: id: title table: node_field_data @@ -412,8 +395,6 @@ display: default_group_multiple: { } group_items: { } plugin_id: string - entity_type: node - entity_field: title langcode: id: langcode table: node_field_data @@ -453,8 +434,6 @@ display: default_group_multiple: { } group_items: { } plugin_id: language - entity_type: node - entity_field: langcode sorts: { } title: Content empty: @@ -481,6 +460,7 @@ display: 1: AND field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: default display_title: Master id: default @@ -489,20 +469,24 @@ display: display_options: path: admin/content/node menu: - type: 'default tab' + type: + 'default tab': 'default tab' + normal: '0' + tab: '0' title: Content description: '' - menu_name: admin + parent: '' weight: -10 - context: '' + context: '0' + menu_name: admin tab_options: - type: normal + type: tab title: Content description: 'Find and manage content' - menu_name: admin weight: -10 field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: page display_title: Page id: page_1 diff --git a/core/modules/node/config/install/views.view.glossary.yml b/core/modules/node/config/install/views.view.glossary.yml index 1625bdd..1bdb92a 100644 --- a/core/modules/node/config/install/views.view.glossary.yml +++ b/core/modules/node/config/install/views.view.glossary.yml @@ -113,8 +113,6 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - entity_type: node - entity_field: title name: id: name table: users_field_data @@ -168,8 +166,6 @@ display: overwrite_anonymous: false anonymous_text: '' format_username: true - entity_type: user - entity_field: name changed: id: changed table: node_field_data @@ -222,8 +218,6 @@ display: hide_alter_empty: true custom_date_format: '' timezone: '' - entity_type: node - entity_field: changed arguments: title: id: title @@ -256,8 +250,6 @@ display: fail: 'not found' validate_options: { } break_phrase: false - entity_type: node - entity_field: title relationships: uid: id: uid @@ -347,8 +339,7 @@ display: default_group_multiple: { } group_items: { } plugin_id: language - entity_type: node - entity_field: langcode + display_extenders: { } attachment_1: id: attachment_1 display_title: Attachment @@ -400,14 +391,13 @@ display: fail: 'not found' validate_options: { } break_phrase: false - entity_type: node - entity_field: title displays: default: default page_1: page_1 inherit_arguments: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } page_1: id: page_1 display_title: Page @@ -419,10 +409,16 @@ display: options: { } path: glossary menu: - type: normal + type: + normal: normal + tab: '0' + 'default tab': '0' title: Glossary + description: '' + parent: '' weight: 0 + context: '0' menu_name: main - parent: '' field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml index ad1e38f..4b5caf0 100644 --- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml @@ -70,6 +70,7 @@ display: arguments: { } field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: default display_title: Master id: default @@ -89,7 +90,10 @@ display: entity_type: node entity_field: nid menu: - type: tab + type: + tab: tab + normal: '0' + 'default tab': '0' title: 'Test contextual link' description: '' menu_name: tools @@ -97,6 +101,7 @@ display: context: '1' field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: page display_title: Page id: page_1 diff --git a/core/modules/user/config/install/views.view.user_admin_people.yml b/core/modules/user/config/install/views.view.user_admin_people.yml index ff62509..703ef86 100644 --- a/core/modules/user/config/install/views.view.user_admin_people.yml +++ b/core/modules/user/config/install/views.view.user_admin_people.yml @@ -188,7 +188,6 @@ display: empty_zero: false hide_alter_empty: true plugin_id: user_bulk_form - entity_type: user name: id: name table: users_field_data @@ -242,8 +241,6 @@ display: anonymous_text: '' format_username: true plugin_id: user_name - entity_type: user - entity_field: name status: id: status table: users_field_data @@ -297,8 +294,6 @@ display: type_custom_false: '' not: '0' plugin_id: boolean - entity_type: user - entity_field: status roles_target_id: id: roles_target_id table: user__roles @@ -402,8 +397,6 @@ display: custom_date_format: '' timezone: '' plugin_id: date - entity_type: user - entity_field: created access: id: access table: users_field_data @@ -456,8 +449,6 @@ display: custom_date_format: '' timezone: '' plugin_id: date - entity_type: user - entity_field: access edit_node: id: edit_node table: users @@ -508,7 +499,6 @@ display: hide_alter_empty: true text: Edit plugin_id: user_link_edit - entity_type: user dropbutton: id: dropbutton table: views @@ -617,8 +607,6 @@ display: hide_alter_empty: true link_to_user: false plugin_id: user_mail - entity_type: user - entity_field: mail filters: combine: id: combine @@ -787,8 +775,6 @@ display: operator: '=' value: '0' plugin_id: boolean - entity_type: user - entity_field: status uid_raw: id: uid_raw table: users @@ -828,7 +814,6 @@ display: default_group_multiple: { } group_items: { } plugin_id: numeric - entity_type: user sorts: created: id: created @@ -843,8 +828,6 @@ display: label: '' granularity: second plugin_id: date - entity_type: user - entity_field: created title: People empty: area_text_custom: @@ -875,6 +858,7 @@ display: 1: AND field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } page_1: display_plugin: page id: page_1 @@ -884,19 +868,23 @@ display: path: admin/people/list show_admin_links: false menu: - type: 'default tab' + type: + 'default tab': 'default tab' + normal: '0' + tab: '0' title: List description: 'Find and manage people interacting with your site.' - menu_name: admin + parent: '' weight: -10 - context: '' + context: '0' + menu_name: admin tab_options: type: normal title: People description: 'Manage user accounts, roles, and permissions.' - menu_name: admin weight: 0 defaults: show_admin_links: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } diff --git a/core/modules/views/config/schema/views.display.schema.yml b/core/modules/views/config/schema/views.display.schema.yml index 6531990..a14fef3 100644 --- a/core/modules/views/config/schema/views.display.schema.yml +++ b/core/modules/views/config/schema/views.display.schema.yml @@ -23,8 +23,11 @@ views.display.page: label: 'Menu' mapping: type: - type: string + type: sequence label: 'Type' + sequence: + - type: string + label: 'Menu type' title: type: text label: 'Title' diff --git a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php index ef531b4..c0174b1 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php @@ -69,25 +69,27 @@ public function getDerivativeDefinitions($base_plugin_definition) { $executable->setDisplay($display_id); $menu = $executable->display_handler->getOption('menu'); - if (in_array($menu['type'], array('tab', 'default tab'))) { - $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; - $route_name = $view_route_names[$executable->storage->id() . '.' . $display_id]; - - // Don't add a local task for views which override existing routes. - // @todo Alternative it could just change the existing entry. - if ($route_name != $plugin_id) { - continue; - } + foreach ($menu['type'] as $type) { + if (in_array($type, array('tab', 'default tab'))) { + $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; + $route_name = $view_route_names[$executable->storage->id() . '.' . $display_id]; + + // Don't add a local task for views which override existing routes. + // @todo Alternative it could just change the existing entry. + if ($route_name != $plugin_id) { + continue; + } - $this->derivatives[$plugin_id] = array( - 'route_name' => $route_name, - 'weight' => $menu['weight'], - 'title' => $menu['title'], - ) + $base_plugin_definition; + $this->derivatives[$plugin_id] = array( + 'route_name' => $route_name, + 'weight' => $menu['weight'], + 'title' => $menu['title'], + ) + $base_plugin_definition; - // Default local tasks have themselves as root tab. - if ($menu['type'] == 'default tab') { - $this->derivatives[$plugin_id]['base_route'] = $route_name; + // Default local tasks have themselves as root tab. + if ($type == 'default tab') { + $this->derivatives[$plugin_id]['base_route'] = $route_name; + } } } } @@ -108,29 +110,31 @@ public function alterLocalTasks(&$local_tasks) { $menu = $executable->display_handler->getOption('menu'); // We already have set the base_route for default tabs. - if (in_array($menu['type'], array('tab'))) { - $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; - $view_route_name = $view_route_names[$executable->storage->id() . '.' . $display_id]; - - // Don't add a local task for views which override existing routes. - if ($view_route_name != $plugin_id) { - unset($local_tasks[$plugin_id]); - continue; - } + foreach ($menu['type'] as $type) { + if (in_array('tab', array_filter($menu['type']))) { + $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; + $view_route_name = $view_route_names[$executable->storage->id() . '.' . $display_id]; + + // Don't add a local task for views which override existing routes. + if ($view_route_name != $plugin_id) { + unset($local_tasks[$plugin_id]); + continue; + } - // Find out the parent route. - // @todo Find out how to find both the root and parent tab. - $path = $executable->display_handler->getPath(); - $split = explode('/', $path); - array_pop($split); - $path = implode('/', $split); - - $pattern = '/' . str_replace('%', '{}', $path); - if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) { - foreach ($routes->all() as $name => $route) { - $local_tasks['views_view:' . $plugin_id]['base_route'] = $name; - // Skip after the first found route. - break; + // Find out the parent route. + // @todo Find out how to find both the root and parent tab. + $path = $executable->display_handler->getPath(); + $split = explode('/', $path); + array_pop($split); + $path = implode('/', $split); + + $pattern = '/' . str_replace('%', '{}', $path); + if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) { + foreach ($routes->all() as $name => $route) { + $local_tasks['views_view:' . $plugin_id]['base_route'] = $name; + // Skip after the first found route. + break; + } } } } diff --git a/core/modules/views/src/Plugin/views/display/Page.php b/core/modules/views/src/Plugin/views/display/Page.php index 3dd9a3d..adab3dc 100644 --- a/core/modules/views/src/Plugin/views/display/Page.php +++ b/core/modules/views/src/Plugin/views/display/Page.php @@ -45,7 +45,8 @@ protected function defineOptions() { $options['menu'] = array( 'contains' => array( - 'type' => array('default' => 'none'), + 'type' => array('default' => array()), + // Do not translate menu and title as menu system will. 'title' => array('default' => ''), 'description' => array('default' => ''), 'weight' => array('default' => 0), @@ -97,23 +98,27 @@ public function optionsSummary(&$categories, &$options) { parent::optionsSummary($categories, $options); $menu = $this->getOption('menu'); - if (!is_array($menu)) { - $menu = array('type' => 'none'); + if (!is_array($menu) || empty($menu['type'])) { + $menu = array('type' => array('none')); } - switch ($menu['type']) { - case 'none': - default: - $menu_str = $this->t('No menu'); - break; - case 'normal': - $menu_str = $this->t('Normal: @title', array('@title' => $menu['title'])); - break; - case 'tab': - case 'default tab': - $menu_str = $this->t('Tab: @title', array('@title' => $menu['title'])); - break; + $menus = array(); + foreach (array_filter($menu['type']) as $type) { + switch ($type) { + case 'none': + $menus[] = $this->t('No menu'); + break; + case 'normal': + $menus[] = $this->t('Normal: @title', array('@title' => $menu['title'])); + break; + case 'tab': + case 'default tab': + $menus[] = $this->t('Tab: @title', array('@title' => $menu['title'])); + break; + } } + $menu_str = implode(' | ', $menus); + $options['menu'] = array( 'category' => 'page', 'title' => $this->t('Menu'), @@ -122,7 +127,7 @@ public function optionsSummary(&$categories, &$options) { // This adds a 'Settings' link to the style_options setting if the style // has options. - if ($menu['type'] == 'default tab') { + if (!empty($menu['type']['default tab'])) { $options['menu']['setting'] = $this->t('Parent menu item'); $options['menu']['links']['tab_options'] = $this->t('Change settings for the parent menu'); } @@ -143,16 +148,21 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#tree' => TRUE, ); $menu = $this->getOption('menu'); - if (empty($menu)) { - $menu = array('type' => 'none', 'title' => '', 'weight' => 0); - } + $menu += array( + 'type' => array('none'), + 'title' => '', + 'description' => '', + 'weight' => 0, + 'menu_name' => '', + 'parent' => '', + ); $form['menu']['type'] = array( '#prefix' => '
', '#suffix' => '
', - '#title' => $this->t('Type'), - '#type' => 'radios', + '#title' => $this->t('Menu Link Types'), + '#type' => 'checkboxes', + '#multiple' => TRUE, '#options' => array( - 'none' => $this->t('No menu entry'), 'normal' => $this->t('Normal menu entry'), 'tab' => $this->t('Menu tab'), 'default tab' => $this->t('Default menu tab') @@ -342,12 +352,14 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { if ($form_state->get('section') == 'menu') { $path = $this->getOption('path'); - $menu_type = $form_state->getValue(array('menu', 'type')); - if ($menu_type == 'normal' && strpos($path, '%') !== FALSE) { + $menu_types = array_filter($form_state->getValue(array('menu', 'type'))); + $form_state->setValueForElement($form['menu']['type'], $menu_types); + + if (in_array('normal', $menu_types) && strpos($path, '%') !== FALSE) { $form_state->setError($form['menu']['type'], $this->t('Views cannot create normal menu items for paths with a % in them.')); } - if ($menu_type == 'default tab' || $menu_type == 'tab') { + if (in_array('default tab', $menu_types) || in_array('tab', $menu_types)) { $bits = explode('/', $path); $last = array_pop($bits); if ($last == '%') { @@ -355,7 +367,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { } } - if ($menu_type != 'none' && $form_state->isValueEmpty(array('menu', 'title'))) { + if (!in_array('none', $menu_types) && $form_state->isValueEmpty(array('menu', 'title'))) { $form_state->setError($form['menu']['title'], $this->t('Title is required for this menu type.')); } } @@ -373,7 +385,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { list($menu['menu_name'], $menu['parent']) = explode(':', $menu['parent'], 2); $this->setOption('menu', $menu); // send ajax form to options page if we use it. - if ($form_state->getValue(array('menu', 'type')) == 'default tab') { + if ($form_state->getValue(array('menu', 'type', 'default tab'))) { $form_state->get('view')->addFormToStack('display', $this->display['id'], 'tab_options'); } break; @@ -390,13 +402,13 @@ public function validate() { $errors = parent::validate(); $menu = $this->getOption('menu'); - if (!empty($menu['type']) && $menu['type'] != 'none' && empty($menu['title'])) { + if (!empty($menu['type']) && empty($menu['title'])) { $errors[] = $this->t('Display @display is set to use a menu but the menu link text is not set.', array('@display' => $this->display['display_title'])); } - if ($menu['type'] == 'default tab') { + if (!empty($menu['type']['default tab'])) { $tab_options = $this->getOption('tab_options'); - if (!empty($tab_options['type']) && $tab_options['type'] != 'none' && empty($tab_options['title'])) { + if (!empty($tab_options['type']) && empty($menu['type']['none']) && empty($tab_options['title'])) { $errors[] = $this->t('Display @display is set to use a parent menu but the parent menu link text is not set.', array('@display' => $this->display['display_title'])); } } diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php index fd93c3c..b8f4656 100644 --- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php @@ -108,7 +108,7 @@ public function getPath() { protected function isDefaultTabPath() { $menu = $this->getOption('menu'); $tab_options = $this->getOption('tab_options'); - return $menu['type'] == 'default tab' && !empty($tab_options['type']) && $tab_options['type'] != 'none'; + return !empty($menu['type']['default tab']) && !empty($tab_options['type']) && $tab_options['type'] != 'none'; } /** @@ -302,33 +302,40 @@ public function getMenuLinks() { $view_id_display = "{$view_id}.{$display_id}"; $menu_link_id = 'views.' . str_replace('/', '.', $view_id_display); - if ($path) { - $menu = $this->getOption('menu'); - if (!empty($menu['type']) && $menu['type'] == 'normal') { - $links[$menu_link_id] = array(); - // Some views might override existing paths, so we have to set the route - // name based upon the altering. - $links[$menu_link_id] = array( - 'route_name' => isset($view_route_names[$view_id_display]) ? $view_route_names[$view_id_display] : "view.$view_id_display", - // Identify URL embedded arguments and correlate them to a handler. - 'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'), - 'id' => $menu_link_id, - ); - $links[$menu_link_id]['title'] = $menu['title']; - $links[$menu_link_id]['description'] = $menu['description']; - $links[$menu_link_id]['parent'] = $menu['parent']; - - if (isset($menu['weight'])) { - $links[$menu_link_id]['weight'] = intval($menu['weight']); + if ($path && ($menu = $this->getOption('menu')) && !empty($menu['type'])) { + foreach ($menu['type'] as $type) { + if ($type == 'normal') { + $links[$menu_link_id] = array(); + // Some views might override existing paths, so we have to set the + // route name based upon the altering. + $view_id_display = "{$this->view->storage->id()}.{$this->display['id']}"; + $links[$menu_link_id] = array( + 'route_name' => isset($view_route_names[$view_id_display]) ? $view_route_names[$view_id_display] : "view.$view_id_display", + // Identify URL embedded arguments and correlate them to a handler. + 'load arguments' => array( + $this->view->storage->id(), + $this->display['id'], + '%index' + ), + 'id' => $menu_link_id, + ); + $links[$menu_link_id]['title'] = $menu['title']; + $links[$menu_link_id]['description'] = $menu['description']; + $links[$menu_link_id]['parent'] = $menu['parent']; + + + if (isset($menu['weight'])) { + $links[$menu_link_id]['weight'] = intval($menu['weight']); + } + + // Insert item into the proper menu. + $links[$menu_link_id]['menu_name'] = $menu['menu_name']; + // Keep track of where we came from. + $links[$menu_link_id]['metadata'] = array( + 'view_id' => $view_id, + 'display_id' => $display_id, + ); } - - // Insert item into the proper menu. - $links[$menu_link_id]['menu_name'] = $menu['menu_name']; - // Keep track of where we came from. - $links[$menu_link_id]['metadata'] = array( - 'view_id' => $view_id, - 'display_id' => $display_id, - ); } } diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php index bbf06ce..b6fdd11 100644 --- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php +++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php @@ -1049,7 +1049,7 @@ protected function pageDisplayOptions(array $form, FormStateInterface $form_stat // Generate the menu links settings if the user checked the link checkbox. if (!empty($page['link'])) { - $display_options['menu']['type'] = 'normal'; + $display_options['menu']['type'] = array('normal' => 'normal'); $display_options['menu']['title'] = $page['link_properties']['title']; $display_options['menu']['menu_name'] = $page['link_properties']['menu_name']; } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml index c9b40a5..af17cac 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_page_display_menu.yml @@ -24,6 +24,7 @@ display: plugin_id: numeric field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: default display_title: Master id: default @@ -33,22 +34,26 @@ display: path: test_page_display_menu/default title: 'Test default page' menu: - type: 'default tab' + type: + 'default tab': 'default tab' + normal: '0' + tab: '0' title: 'Test default tab' description: '' - menu_name: tools + parent: '' weight: -10 context: '0' + menu_name: tools tab_options: type: normal title: 'Test parent path' description: '' - menu_name: tools weight: 0 defaults: title: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: page display_title: Page id: page_1 @@ -58,16 +63,21 @@ display: path: test_page_display_menu/local title: 'Test local page' menu: - type: tab + type: + tab: tab + normal: '0' + 'default tab': '0' title: 'Test local tab' description: '' - menu_name: tools + parent: '' weight: 0 context: '0' + menu_name: tools defaults: title: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: page display_title: Page id: page_2 @@ -77,16 +87,21 @@ display: path: test_page_display_menu_link title: 'Test menu link' menu: - type: normal + type: + normal: normal + tab: '0' + 'default tab': '0' title: 'Test menu link' description: '' - menu_name: tools + parent: '' weight: 0 context: '0' + menu_name: tools defaults: title: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: page display_title: Page id: page_3 @@ -96,17 +111,21 @@ display: path: test_page_display_menu/child title: 'Test page as child' menu: - type: normal + type: + normal: normal + tab: '0' + 'default tab': '0' title: 'Test child' - parent: system.admin description: '' - menu_name: tools + parent: '' weight: 0 context: '0' + menu_name: tools defaults: title: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: page display_title: Page id: page_4 @@ -116,7 +135,10 @@ display: path: test-path title: 'Tests a menu with a non-existing parent' menu: - type: normal + type: + normal: normal + tab: '0' + 'default tab': '0' title: 'Test child' parent: system.admin description: '' @@ -127,6 +149,7 @@ display: title: false field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null + display_extenders: { } display_plugin: page display_title: Page id: page_4 diff --git a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php index c75d96f..486dba7 100644 --- a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php @@ -78,7 +78,7 @@ public function testGetDerivativeDefinitionsWithoutLocalTask() { $display_plugin->expects($this->once()) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'normal'))); + ->will($this->returnValue(array('type' => array('normal' => 'normal')))); $executable->display_handler = $display_plugin; $result = array(array($executable, 'page_1')); @@ -110,7 +110,7 @@ public function testGetDerivativeDefinitionsWithLocalTask() { $display_plugin->expects($this->once()) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'tab', 'weight' => 12, 'title' => 'Example title'))); + ->will($this->returnValue(array('type' => array('tab' => 'tab'), 'weight' => 12, 'title' => 'Example title'))); $executable->display_handler = $display_plugin; $result = array(array($executable, 'page_1')); @@ -155,7 +155,7 @@ public function testGetDerivativeDefinitionsWithOverrideRoute() { $display_plugin->expects($this->once()) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'tab', 'weight' => 12))); + ->will($this->returnValue(array('type' => array('tab' => 'tab'), 'weight' => 12))); $executable->display_handler = $display_plugin; $result = array(array($executable, 'page_1')); @@ -196,7 +196,7 @@ public function testGetDerivativeDefinitionsWithDefaultLocalTask() { $display_plugin->expects($this->exactly(2)) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'default tab', 'weight' => 12, 'title' => 'Example title'))); + ->will($this->returnValue(array('type' => array('default tab' => 'default tab'), 'weight' => 12, 'title' => 'Example title'))); $executable->display_handler = $display_plugin; $result = array(array($executable, 'page_1')); @@ -257,7 +257,7 @@ public function testGetDerivativeDefinitionsWithExistingLocalTask() { $display_plugin->expects($this->exactly(2)) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'tab', 'weight' => 12, 'title' => 'Example title'))); + ->will($this->returnValue(array('type' => array('tab' => 'tab'), 'weight' => 12, 'title' => 'Example title'))); $display_plugin->expects($this->once()) ->method('getPath') ->will($this->returnValue('path/example')); diff --git a/core/modules/views_ui/src/Tests/DisplayPathTest.php b/core/modules/views_ui/src/Tests/DisplayPathTest.php index 71b2035..14e2992 100644 --- a/core/modules/views_ui/src/Tests/DisplayPathTest.php +++ b/core/modules/views_ui/src/Tests/DisplayPathTest.php @@ -116,19 +116,27 @@ public function testMenuOptions() { $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => $random_string), t('Apply')); $this->drupalGet('admin/structure/views/view/test_view'); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', array('menu[type]' => 'default tab', 'menu[title]' => 'Test tab title'), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', array('menu[type][default tab]' => 'default tab', 'menu[title]' => 'Test tab title'), t('Apply')); $this->assertResponse(200); $this->assertUrl('admin/structure/views/nojs/display/test_view/page_1/tab_options'); - $this->drupalPostForm(NULL, array('tab_options[type]' => 'tab', 'tab_options[title]' => $this->randomString()), t('Apply')); + $this->drupalPostForm(NULL, array('tab_options[type]' => 'normal', 'tab_options[title]' => 'Test tab title'), t('Apply')); $this->assertResponse(200); $this->assertUrl('admin/structure/views/view/test_view/edit/page_1'); - - $this->drupalGet('admin/structure/views/view/test_view'); $this->assertLink(t('Tab: @title', array('@title' => 'Test tab title'))); // If it's a default tab, it should also have an additional settings link. $this->assertLinkByHref('admin/structure/views/nojs/display/test_view/page_1/tab_options'); + // It can be default tab and normal menu item as well. + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', array('menu[type][normal]' => 'normal', 'menu[title]' => 'Test'), t('Apply')); + $this->assertResponse(200); + $this->assertUrl('admin/structure/views/nojs/display/test_view/page_1/tab_options'); + + $this->drupalPostForm(NULL, array('tab_options[type]' => 'normal', 'tab_options[title]' => 'Test tab title'), t('Apply')); + $this->assertResponse(200); + $this->assertUrl('admin/structure/views/view/test_view/edit/page_1'); + $this->assertLink(t('Normal: @title | Tab: @title', array('@title' => 'Test'))); + // Ensure that you can select a parent in case the parent does not exist. $this->drupalGet('admin/structure/views/nojs/display/test_page_display_menu/page_5/menu'); $this->assertResponse(200);