diff --git a/core/lib/Drupal/Core/Block/Plugin/Block/PageTitleBlock.php b/core/lib/Drupal/Core/Block/Plugin/Block/PageTitleBlock.php index af1fb6ee37..aee2e23089 100644 --- a/core/lib/Drupal/Core/Block/Plugin/Block/PageTitleBlock.php +++ b/core/lib/Drupal/Core/Block/Plugin/Block/PageTitleBlock.php @@ -4,6 +4,11 @@ use Drupal\Core\Block\BlockBase; use Drupal\Core\Block\TitleBlockPluginInterface; +use Drupal\Core\Controller\TitleResolverInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Routing\RouteMatchInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; /** * Provides a block to display the page title. @@ -16,17 +21,77 @@ * }, * ) */ -class PageTitleBlock extends BlockBase implements TitleBlockPluginInterface { +class PageTitleBlock extends BlockBase implements TitleBlockPluginInterface, ContainerFactoryPluginInterface { /** * The page title: a string (plain title) or a render array (formatted title). * - * @var string|array + * @var string|array|null */ - protected $title = ''; + protected $title = NULL; + + /** + * The request. + * + * @var \Symfony\Component\HttpFoundation\Request + */ + protected $request; + + /** + * The route match. + * + * @var \Drupal\Core\Routing\RouteMatchInterface + */ + protected $routeMatch; + + /** + * The title resolver. + * + * @var \Drupal\Core\Controller\TitleResolverInterface + */ + protected $titleResolver; + + /** + * Constructs a PageTitleBlock. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin ID for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Symfony\Component\HttpFoundation\Request $request + * The request. + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The route match. + * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver + * The title resolver. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request, RouteMatchInterface $route_match, TitleResolverInterface $title_resolver) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->request = $request; + $this->routeMatch = $route_match; + $this->titleResolver = $title_resolver; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('request_stack')->getCurrentRequest(), + $container->get('current_route_match'), + $container->get('title_resolver') + ); + } /** * {@inheritdoc} + * + * @todo Deprecate this method in https://www.drupal.org/node/2359901. */ public function setTitle($title) { $this->title = $title; @@ -46,7 +111,9 @@ public function defaultConfiguration() { public function build() { return [ '#type' => 'page_title', - '#title' => $this->title, + // @todo Always use the title resolver directly after + // https://www.drupal.org/node/2359901 is resolved. + '#title' => !is_null($this->title) ? $this->title : $this->titleResolver->getTitle($this->request, $this->routeMatch->getRouteObject()), ]; } diff --git a/core/modules/system/tests/modules/page_title_block_test/page_title_block_test.info.yml b/core/modules/system/tests/modules/page_title_block_test/page_title_block_test.info.yml new file mode 100644 index 0000000000..cc66e51c32 --- /dev/null +++ b/core/modules/system/tests/modules/page_title_block_test/page_title_block_test.info.yml @@ -0,0 +1,6 @@ +name: Page Title Block Test +type: module +description: 'Test the Page Title Block.' +package: Testing +version: VERSION +core: 8.x diff --git a/core/modules/system/tests/modules/page_title_block_test/page_title_block_test.routing.yml b/core/modules/system/tests/modules/page_title_block_test/page_title_block_test.routing.yml new file mode 100644 index 0000000000..74cf4baf96 --- /dev/null +++ b/core/modules/system/tests/modules/page_title_block_test/page_title_block_test.routing.yml @@ -0,0 +1,7 @@ +page_title_block_test.test: + path: '/page-title-block-test-page' + defaults: + _title: 'Test page' + _controller: '\Drupal\page_title_block_test\Controller\PageBlockTitleTestController::testPage' + requirements: + _access: 'TRUE' diff --git a/core/modules/system/tests/modules/page_title_block_test/src/Controller/PageBlockTitleTestController.php b/core/modules/system/tests/modules/page_title_block_test/src/Controller/PageBlockTitleTestController.php new file mode 100644 index 0000000000..621eae4569 --- /dev/null +++ b/core/modules/system/tests/modules/page_title_block_test/src/Controller/PageBlockTitleTestController.php @@ -0,0 +1,31 @@ +createInstance('page_title_block'); + + if ($set_title = \Drupal::state()->get('page_title_block_test.set_title')) { + $block->setTitle($set_title); + } + if ($render_array_title = \Drupal::state()->get('page_title_block_test.render_array_title')) { + $build['#title'] = Html::escape($render_array_title); + } + + // Nest the block lower than the top-level title. + $build[] = $block->build(); + return $build; + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Core/Block/PageTitleBlockTest.php b/core/tests/Drupal/FunctionalTests/Core/Block/PageTitleBlockTest.php new file mode 100644 index 0000000000..518c018a7c --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Core/Block/PageTitleBlockTest.php @@ -0,0 +1,74 @@ +set('page_title_block_test.set_title', $set_title); + \Drupal::state()->set('page_title_block_test.render_array_title', $render_array_title); + + $this->drupalGet('page-title-block-test-page'); + $page_titles = array_map(function (NodeElement $element) { + return $element->getText(); + }, $this->getSession()->getPage()->findAll('css', '.page-title')); + $this->assertSame($expected, $page_titles); + } + + /** + * Provides test data for ::testBuild(). + */ + public function providerTestBuild() { + // Data provider values are: + // - the expected page titles, in order + // - the value to call ::setTitle() with + // - the value for #title in the render array. + $data = []; + $data['no title manipulation'] = [ + ['Test page', 'Test page'], + NULL, + NULL, + ]; + $data['provide a top-level #title'] = [ + ['render_array_title', 'Test page'], + NULL, + 'render_array_title', + ]; + $data['call setTitle() on the block'] = [ + ['Test page', 'set_title'], + 'set_title', + NULL, + ]; + $data['call setTitle() on the block and provide a top-level #title'] = [ + ['render_array_title', 'set_title'], + 'set_title', + 'render_array_title', + ]; + return $data; + } + +}