diff --git a/core/modules/block_content/config/install/views.view.block_content.yml b/core/modules/block_content/config/install/views.view.block_content.yml new file mode 100644 index 0000000..2ed9764 --- /dev/null +++ b/core/modules/block_content/config/install/views.view.block_content.yml @@ -0,0 +1,452 @@ +langcode: en +status: true +dependencies: + module: + - block_content + - user +id: block_content +label: 'Custom block library' +module: views +description: 'Find and manage custom blocks.' +tag: '' +base_table: block_content_field_data +base_field: id +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'administer blocks' + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: mini + options: + items_per_page: 50 + offset: 0 + id: 0 + total_pages: null + tags: + previous: '‹ previous' + next: 'next ›' + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + info: info + type: type + changed: changed + operations: operations + info: + info: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + type: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: changed + empty_table: true + row: + type: fields + fields: + info: + id: info + table: block_content_field_data + field: info + relationship: none + group_type: group + admin_label: '' + label: 'Block description' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_entity: true + entity_type: null + entity_field: info + plugin_id: block_content + type: + id: type + table: block_content_field_data + field: type + relationship: none + group_type: group + admin_label: '' + label: 'Block type' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_entity: false + machine_name: '0' + entity_type: block_content + entity_field: type + plugin_id: block_content_type + changed: + id: changed + table: block_content_field_data + field: changed + relationship: none + group_type: group + admin_label: '' + label: Updated + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + date_format: short + custom_date_format: '' + timezone: '' + entity_type: block_content + entity_field: changed + plugin_id: date + operations: + id: operations + table: block_content + field: operations + relationship: none + group_type: group + admin_label: '' + label: Operations + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + destination: true + entity_type: block_content + plugin_id: entity_operations + filters: + info: + id: info + table: block_content_field_data + field: info + relationship: none + group_type: group + admin_label: '' + operator: contains + value: '' + group: 1 + exposed: true + expose: + operator_id: info_op + label: 'Block description' + description: '' + use_operator: false + operator: info_op + identifier: info + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: block_content + entity_field: info + plugin_id: string + type: + id: type + table: block_content + field: type + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: type_op + label: 'Block type' + description: '' + use_operator: false + operator: type_op + identifier: type + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: block_content + entity_field: type + plugin_id: bundle + sorts: { } + title: 'Custom block library' + header: { } + footer: { } + empty: + area_text_custom: + id: area_text_custom + table: views + field: area_text_custom + relationship: none + group_type: group + admin_label: '' + empty: true + tokenize: false + content: 'There are no custom blocks available.' + plugin_id: text_custom + block_content_listing_empty: + admin_label: '' + empty: true + field: block_content_listing_empty + group_type: group + id: block_content_listing_empty + label: '' + relationship: none + table: block_content + plugin_id: block_content_listing_empty + entity_type: block_content + relationships: { } + arguments: { } + display_extenders: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: admin/structure/block/block-content + menu: + type: tab + title: 'Custom block library' + description: '' + parent: block.admin_display + weight: 0 + context: '0' + menu_name: admin diff --git a/core/modules/block_content/src/BlockContentViewsData.php b/core/modules/block_content/src/BlockContentViewsData.php index 200d18f..d2d2680 100644 --- a/core/modules/block_content/src/BlockContentViewsData.php +++ b/core/modules/block_content/src/BlockContentViewsData.php @@ -40,6 +40,13 @@ public function getViewsData() { ); } + $data['block_content']['block_content_listing_empty'] = array( + 'title' => t('Empty block library behavior'), + 'help' => t('Provides a link to the add a new block.'), + 'area' => array( + 'id' => 'block_content_listing_empty', + ), + ); // Advertise this table as a possible base table. $data['block_content_revision']['table']['base']['help'] = $this->t('Block Content revision is a history of changes to block content.'); $data['block_content_revision']['table']['base']['defaults']['title'] = 'info'; diff --git a/core/modules/block_content/src/Plugin/views/area/ListingEmpty.php b/core/modules/block_content/src/Plugin/views/area/ListingEmpty.php new file mode 100644 index 0000000..681f664 --- /dev/null +++ b/core/modules/block_content/src/Plugin/views/area/ListingEmpty.php @@ -0,0 +1,91 @@ +accessManager = $access_manager; + $this->currentUser = $current_user; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('access_manager'), + $container->get('current_user') + ); + } + + /** + * {@inheritdoc} + */ + public function render($empty = FALSE) { + if (!$empty || !empty($this->options['empty'])) { + $element = array( + '#theme' => 'links', + '#links' => array( + array( + 'url' => Url::fromRoute('block_content.add_page'), + 'title' => $this->t('Add a custom block'), + ), + ), + '#access' => $this->accessManager->checkNamedRoute('block_content.add_page', array(), $this->currentUser), + ); + return $element; + } + return array(); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentListTest.php b/core/modules/block_content/src/Tests/BlockContentListTest.php index 03b60e3..aeed4dc 100644 --- a/core/modules/block_content/src/Tests/BlockContentListTest.php +++ b/core/modules/block_content/src/Tests/BlockContentListTest.php @@ -7,13 +7,14 @@ namespace Drupal\block_content\Tests; -use Drupal\simpletest\WebTestBase; - /** * Tests the listing of custom blocks. * + * Tests the fallback block content list when Views is disabled. + * * @group block_content * @see \Drupal\block\BlockContentListBuilder + * @see \Drupal\block_content\Tests\BlockContentListViewsTest */ class BlockContentListTest extends BlockContentTestBase { diff --git a/core/modules/block_content/src/Tests/BlockContentListTest.php b/core/modules/block_content/src/Tests/BlockContentListViewsTest.php similarity index 72% copy from core/modules/block_content/src/Tests/BlockContentListTest.php copy to core/modules/block_content/src/Tests/BlockContentListViewsTest.php index 03b60e3..6bdadac 100644 --- a/core/modules/block_content/src/Tests/BlockContentListTest.php +++ b/core/modules/block_content/src/Tests/BlockContentListViewsTest.php @@ -2,27 +2,27 @@ /** * @file - * Contains \Drupal\block_content\Tests\BlockContentListTest. + * Contains \Drupal\block_content\Tests\BlockContentListViewsTest. */ namespace Drupal\block_content\Tests; - -use Drupal\simpletest\WebTestBase; +use Drupal\Core\Url; /** - * Tests the listing of custom blocks. + * Tests the Views-powered listing of custom blocks. * * @group block_content * @see \Drupal\block\BlockContentListBuilder + * @see \Drupal\block_content\Tests\BlockContentListTest */ -class BlockContentListTest extends BlockContentTestBase { +class BlockContentListViewsTest extends BlockContentTestBase { /** * Modules to enable. * * @var array */ - public static $modules = array('block', 'block_content', 'config_translation'); + public static $modules = ['block', 'block_content', 'config_translation', 'views']; /** * Tests the custom block listing page. @@ -36,16 +36,21 @@ public function testListing() { // Test for the table. $element = $this->xpath('//div[@class="layout-content"]//table'); - $this->assertTrue($element, 'Configuration entity list table found.'); + $this->assertTrue($element, 'Views table found.'); // Test the table header. $elements = $this->xpath('//div[@class="layout-content"]//table/thead/tr/th'); - $this->assertEqual(count($elements), 2, 'Correct number of table header cells found.'); + $this->assertEqual(count($elements), 4, 'Correct number of table header cells found.'); // Test the contents of each th cell. - $expected_items = array(t('Block description'), t('Operations')); + $expected_items = [t('Block description'), t('Block type'), t('Updated'), t('Operations')]; foreach ($elements as $key => $element) { - $this->assertIdentical((string) $element[0], $expected_items[$key]); + if ($element->xpath('a')) { + $this->assertIdentical(trim((string) $element->xpath('a')[0]), $expected_items[$key]); + } + else { + $this->assertIdentical(trim((string) $element[0]), $expected_items[$key]); + } } $label = 'Antelope'; @@ -62,15 +67,15 @@ public function testListing() { // Confirm that once the user returns to the listing, the text of the label // (versus elsewhere on the page). - $this->assertFieldByXpath('//td', $label, 'Label found for added block.'); + $this->assertFieldByXpath('//td/a', $label, 'Label found for added block.'); // Check the number of table row cells. - $elements = $this->xpath('//div[@class="layout-content"]//table/tbody/tr[@class="odd"]/td'); - $this->assertEqual(count($elements), 2, 'Correct number of table row cells found.'); + $elements = $this->xpath('//div[@class="layout-content"]//table/tbody/tr/td'); + $this->assertEqual(count($elements), 4, 'Correct number of table row cells found.'); // Check the contents of each row cell. The first cell contains the label, // the second contains the machine name, and the third contains the // operations list. - $this->assertIdentical((string) $elements[0], $label); + $this->assertIdentical((string) $elements[0]->xpath('a')[0], $label); // Edit the entity using the operations link. $blocks = $this->container @@ -92,7 +97,7 @@ public function testListing() { // Confirm that once the user returns to the listing, the text of the label // (versus elsewhere on the page). - $this->assertFieldByXpath('//td', $new_label, 'Label found for updated custom block.'); + $this->assertFieldByXpath('//td/a', $new_label, 'Label found for updated custom block.'); // Delete the added entity using the operations link. $this->assertLinkByHref('block/' . $block->id() . '/delete'); @@ -107,7 +112,8 @@ public function testListing() { $this->assertNoFieldByXpath('//td', $new_label, 'No label found for deleted custom block.'); // Confirm that the empty text is displayed. - $this->assertText(t('There is no Custom block yet.')); + $this->assertText('There are no custom blocks available.'); + $this->assertLink('Add a custom block'); } }