.../Core/Block/TitleBlockPluginInterface.php | 27 +++++++ .../Drupal/Core/Display/PageVariantInterface.php | 10 +++ .../Core/Render/MainContent/HtmlRenderer.php | 15 ++-- .../Plugin/DisplayVariant/SimplePageVariant.php | 17 +++++ .../src/Plugin/DisplayVariant/BlockPageVariant.php | 30 +++++++- .../src/Plugin/Block/SystemPageTitleBlock.php | 82 ++++------------------ core/modules/system/templates/page.html.twig | 2 +- 7 files changed, 108 insertions(+), 75 deletions(-) diff --git a/core/lib/Drupal/Core/Block/TitleBlockPluginInterface.php b/core/lib/Drupal/Core/Block/TitleBlockPluginInterface.php new file mode 100644 index 0000000..d8e6e3f --- /dev/null +++ b/core/lib/Drupal/Core/Block/TitleBlockPluginInterface.php @@ -0,0 +1,27 @@ +titleResolver->getTitle($request, $route_match->getRouteObject()); + }; + // If the _controller result already is #type => page, // we have no work to do: The "main content" already is an entire "page" // (see html.html.twig). if (isset($main_content['#type']) && $main_content['#type'] === 'page') { $page = $main_content; + + $title = $get_title($page); } // Otherwise, render it as the main content of a #type => page, by selecting // page display variant to do that and building that page display variant. @@ -195,12 +203,15 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte ]; } + $title = $get_title($main_content); + // Instantiate the page display, and give it the main content. $page_display = $this->displayVariantManager->createInstance($variant_id); if (!$page_display instanceof PageVariantInterface) { throw new \LogicException('Cannot render the main content for this page because the provided display variant does not implement PageVariantInterface.'); } $page_display->setMainContent($main_content); + $page_display->setTitle($title); // Generate a #type => page render array using the page display variant, // the page display will build the content for the various page regions. @@ -223,10 +234,6 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte // Allow hooks to add attachments to $page['#attached']. $this->invokePageAttachmentHooks($page); - // Determine the title: use the title provided by the main content if any, - // otherwise get it from the routing information. - $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject()); - return [$page, $title]; } diff --git a/core/lib/Drupal/Core/Render/Plugin/DisplayVariant/SimplePageVariant.php b/core/lib/Drupal/Core/Render/Plugin/DisplayVariant/SimplePageVariant.php index 7772875..2992cc8 100644 --- a/core/lib/Drupal/Core/Render/Plugin/DisplayVariant/SimplePageVariant.php +++ b/core/lib/Drupal/Core/Render/Plugin/DisplayVariant/SimplePageVariant.php @@ -28,10 +28,26 @@ class SimplePageVariant extends VariantBase implements PageVariantInterface { protected $mainContent; /** + * The page title. + * + * @var string + */ + protected $title = ''; + + /** * {@inheritdoc} */ public function setMainContent(array $main_content) { $this->mainContent = $main_content; + return $this; + } + + /** + * {@inheritdoc} + */ + public function setTitle($title) { + $this->title = $title; + return $this; } /** @@ -39,6 +55,7 @@ public function setMainContent(array $main_content) { */ public function build() { $build = [ + 'title' => ['#markup' => '

' . $this->title . '

'], 'content' => $this->mainContent, ]; return $build; diff --git a/core/modules/block/src/Plugin/DisplayVariant/BlockPageVariant.php b/core/modules/block/src/Plugin/DisplayVariant/BlockPageVariant.php index bf91a04..3e2d08f 100644 --- a/core/modules/block/src/Plugin/DisplayVariant/BlockPageVariant.php +++ b/core/modules/block/src/Plugin/DisplayVariant/BlockPageVariant.php @@ -11,6 +11,7 @@ use Drupal\block\Event\BlockContextEvent; use Drupal\block\Event\BlockEvents; use Drupal\Core\Block\MainContentBlockPluginInterface; +use Drupal\Core\Block\TitleBlockPluginInterface; use Drupal\Core\Display\PageVariantInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityViewBuilderInterface; @@ -58,6 +59,13 @@ class BlockPageVariant extends VariantBase implements PageVariantInterface, Cont protected $mainContent = []; /** + * The page title. + * + * @var string + */ + protected $title = ''; + + /** * Constructs a new BlockPageVariant. * * @param array $configuration @@ -109,9 +117,18 @@ public function setMainContent(array $main_content) { /** * {@inheritdoc} */ + public function setTitle($title) { + $this->title = $title; + return $this; + } + + /** + * {@inheritdoc} + */ public function build() { - // Track whether a block that shows the main content is displayed or not. + // Track whether blocks showing the main content and title are displayed. $main_content_block_displayed = FALSE; + $title_block_displayed = FALSE; $build = [ '#cache' => [ @@ -128,6 +145,10 @@ public function build() { $block_plugin->setMainContent($this->mainContent); $main_content_block_displayed = TRUE; } + if ($block_plugin instanceof TitleBlockPluginInterface) { + $block_plugin->setTitle($this->title); + $title_block_displayed = TRUE; + } $build[$region][$key] = $this->blockViewBuilder->view($block); } if (!empty($build[$region])) { @@ -144,6 +165,13 @@ public function build() { $build['content']['system_main'] = $this->mainContent; } + // Analogously for the page title. + if (!$title_block_displayed) { + $build['title'] = [ + '#markup' => '

' . $this->title . '

', + ]; + } + return $build; } diff --git a/core/modules/system/src/Plugin/Block/SystemPageTitleBlock.php b/core/modules/system/src/Plugin/Block/SystemPageTitleBlock.php index e8bf660..e23785a 100644 --- a/core/modules/system/src/Plugin/Block/SystemPageTitleBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemPageTitleBlock.php @@ -8,13 +8,8 @@ namespace Drupal\system\Plugin\Block; use Drupal\Core\Block\BlockBase; -use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\Controller\TitleResolverInterface; +use Drupal\Core\Block\TitleBlockPluginInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Symfony\Cmf\Component\Routing\RouteObjectInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\RequestStack; /** * Provides a block to display the page title. @@ -24,64 +19,21 @@ * admin_label = @Translation("Page title") * ) */ -class SystemPageTitleBlock extends BlockBase implements ContainerFactoryPluginInterface { +class SystemPageTitleBlock extends BlockBase implements TitleBlockPluginInterface { /** - * Stores the configuration factory. + * The page title. * - * @var \Drupal\Core\Config\ConfigFactoryInterface + * @var string */ - protected $configFactory; - - /** - * The title resolver. - * - * @var \Drupal\Core\Controller\TitleResolverInterface - */ - protected $titleResolver; - - /** - * A request stack object. - * - * @var \Symfony\Component\HttpFoundation\RequestStack - */ - protected $requestStack; - - /** - * Creates a SystemPageTitleBlock instance. - * - * @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 \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The factory for configuration objects. - * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver - * The title resolver. - * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack - * The request stack object. - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, TitleResolverInterface $title_resolver, RequestStack $request_stack) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->configFactory = $config_factory; - $this->titleResolver = $title_resolver; - $this->requestStack = $request_stack; - } + protected $title = ''; /** * {@inheritdoc} */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('config.factory'), - $container->get('title_resolver'), - $container->get('request_stack') - ); + public function setTitle($title) { + $this->title = $title; + return $this; } /** @@ -95,19 +47,11 @@ public function defaultConfiguration() { * {@inheritdoc} */ public function build() { - $build = array(); - $title = ''; - $request = $this->requestStack->getCurrentRequest(); - if ($route = $request->attributes->get(routeObjectInterface::ROUTE_OBJECT)) { - $title = $this->titleResolver->getTitle($request, $route); - } - if (empty($title)) { - return FALSE; - } - - $build['title'] = ['#markup' => $title]; - - return $build; + return [ + 'title' => [ + '#markup' => $this->title, + ], + ]; } /** diff --git a/core/modules/system/templates/page.html.twig b/core/modules/system/templates/page.html.twig index 82a7c95..2e9d88f 100644 --- a/core/modules/system/templates/page.html.twig +++ b/core/modules/system/templates/page.html.twig @@ -70,7 +70,7 @@
{# Use h1 when the content title is empty #} - {% if title %} + {% if page.title %} {{ site_name }}