From 6e456f7be55694fcb3dc500bbf1138b63a031519 Mon Sep 17 00:00:00 2001 From: Andy Broomfield Date: Thu, 2 Nov 2023 14:40:36 +0000 Subject: [PATCH 1/2] Add stacked header subtitle as new page header variable Ref #192 This allows page subscribers to set a subtitle which will be stacked inside the h1. --- localgov_core.module | 1 + src/Event/PageHeaderDisplayEvent.php | 27 +++++++++++++++++++ src/Plugin/Block/PageHeaderBlock.php | 9 +++++++ .../localgov-page-header-block.html.twig | 7 ++++- 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/localgov_core.module b/localgov_core.module index 53d8ad2..ef43ee1 100644 --- a/localgov_core.module +++ b/localgov_core.module @@ -13,6 +13,7 @@ function localgov_core_theme($existing, $type, $theme, $path) { 'localgov_page_header_block' => [ 'variables' => [ 'title' => '', + 'subtitle' => NULL, 'lede' => NULL, ], 'render element' => 'block', diff --git a/src/Event/PageHeaderDisplayEvent.php b/src/Event/PageHeaderDisplayEvent.php index a0aae69..f5e77f6 100644 --- a/src/Event/PageHeaderDisplayEvent.php +++ b/src/Event/PageHeaderDisplayEvent.php @@ -32,6 +32,13 @@ class PageHeaderDisplayEvent extends Event { */ protected $title = NULL; + /** + * The page sub title override. + * + * @var array|string|null + */ + protected $subTitle = NULL; + /** * Should the page header block be displayed? * @@ -103,6 +110,26 @@ public function setTitle($title) { $this->title = $title; } + /** + * Sub title getter. + * + * @return array|string|null + * The sub title. + */ + public function getSubTitle() { + return $this->subTitle; + } + + /** + * Sub title setter. + * + * @param array|string|null $sub_title + * The sub title. + */ + public function setSubTitle($sub_title) { + $this->subTitle = $sub_title; + } + /** * Visibility getter. * diff --git a/src/Plugin/Block/PageHeaderBlock.php b/src/Plugin/Block/PageHeaderBlock.php index 74b02d1..ad7159a 100644 --- a/src/Plugin/Block/PageHeaderBlock.php +++ b/src/Plugin/Block/PageHeaderBlock.php @@ -69,6 +69,13 @@ class PageHeaderBlock extends BlockBase implements ContainerFactoryPluginInterfa */ protected $title; + /** + * The page subtitle override. + * + * @var array|string|null + */ + protected $subTitle; + /** * The page lede override. * @@ -149,6 +156,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition // Set the title, lede, visibility and cache tags. $this->title = is_null($event->getTitle()) ? $this->getTitle() : $event->getTitle(); + $this->subTitle = is_null($event->getSubTitle()) ? NULL : $event->getSubTitle(); $this->lede = is_null($event->getLede()) ? $this->getLede() : $event->getLede(); $this->visible = $event->getVisibility(); $entityCacheTags = is_null($this->entity) ? [] : $this->entity->getCacheTags(); @@ -164,6 +172,7 @@ public function build() { $build[] = [ '#theme' => 'localgov_page_header_block', '#title' => $this->title, + '#subtitle' => $this->subTitle, '#lede' => $this->lede, ]; diff --git a/templates/localgov-page-header-block.html.twig b/templates/localgov-page-header-block.html.twig index c188800..95d1aef 100644 --- a/templates/localgov-page-header-block.html.twig +++ b/templates/localgov-page-header-block.html.twig @@ -15,7 +15,12 @@ ] %} {% if title %} -

{{ title }}

+

+ {{ title }} + {% if subtitle %} +
{{ subtitle }}
+ {% endif %} +

{% if lede %}
{{ lede }}
{% endif %} From 24e0cbcde565da0b66af7743234f5abb38c315a8 Mon Sep 17 00:00:00 2001 From: Andy Broomfield Date: Wed, 15 Nov 2023 20:37:08 +0000 Subject: [PATCH 2/2] Amend test to add a subtitle - Add subtitle test condition and amendment to test page header - Use xpath to get the header, as sometimes page title is found on page as it is the title tag. also, the adjustment of the template means the exact markup for the h1 breaks with newlines. --- .../EventSubscriber/PageHeaderSubscriber.php | 7 ++ tests/src/Functional/PageHeaderBlockTest.php | 75 +++++++++++++++++-- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/tests/localgov_core_page_header_event_test/src/EventSubscriber/PageHeaderSubscriber.php b/tests/localgov_core_page_header_event_test/src/EventSubscriber/PageHeaderSubscriber.php index a9319ec..a21879b 100644 --- a/tests/localgov_core_page_header_event_test/src/EventSubscriber/PageHeaderSubscriber.php +++ b/tests/localgov_core_page_header_event_test/src/EventSubscriber/PageHeaderSubscriber.php @@ -51,6 +51,13 @@ public function setPageHeader(PageHeaderDisplayEvent $event) { $event->setLede($parent->body->summary); $event->setCacheTags(Cache::mergeTags($node->getCacheTags(), $parent->getCacheTags())); } + + // Set subtitle from parent, and cache tags from the parent for page4 nodes. + if ($node->bundle() == 'page4') { + $parent = $node->parent->entity; + $event->setSubTitle($parent->title->value); + $event->setCacheTags(Cache::mergeTags($node->getCacheTags(), $parent->getCacheTags())); + } } } diff --git a/tests/src/Functional/PageHeaderBlockTest.php b/tests/src/Functional/PageHeaderBlockTest.php index 738b222..c3b516d 100644 --- a/tests/src/Functional/PageHeaderBlockTest.php +++ b/tests/src/Functional/PageHeaderBlockTest.php @@ -56,7 +56,9 @@ public function testPageHeaderBlockDisplay() { 'status' => NodeInterface::PUBLISHED, ]); $this->drupalGet($page->toUrl()->toString()); - $this->assertSession()->responseContains('

' . $node_title . '

'); + $query = $this->xpath('.//h1[contains(concat(" ",normalize-space(@class)," ")," header ")]'); + $page_title = $query[0]->getText(); + $this->assertEquals($page_title, $node_title); $this->assertSession()->pageTextNotContains($node_summary); $page->set('body', [ 'summary' => $node_summary, @@ -64,7 +66,9 @@ public function testPageHeaderBlockDisplay() { ]); $page->save(); $this->drupalGet($page->toUrl()->toString()); - $this->assertSession()->responseContains('

' . $node_title . '

'); + $query = $this->xpath('.//h1[contains(concat(" ",normalize-space(@class)," ")," header ")]'); + $page_title = $query[0]->getText(); + $this->assertEquals($page_title, $node_title); $this->assertSession()->pageTextContains($node_summary); // Check title and lede display on a taxonomy term page. @@ -77,7 +81,9 @@ public function testPageHeaderBlockDisplay() { ]); $term->save(); $this->drupalGet($term->toUrl()->toString()); - $this->assertSession()->responseContains('

' . $term_name . '

'); + $query = $this->xpath('.//h1[contains(concat(" ",normalize-space(@class)," ")," header ")]'); + $page_title = $query[0]->getText(); + $this->assertEquals($page_title, $term_name); $this->assertSession()->pageTextContains('All pages relating to ' . $term_name); } @@ -100,9 +106,11 @@ public function testPageHeaderDisplayEvent() { 'status' => NodeInterface::PUBLISHED, ]); $this->drupalGet($page1->toUrl()->toString()); - $this->assertSession()->responseNotContains('

' . $title . '

'); + $query = $this->xpath('.//h1[contains(concat(" ",normalize-space(@class)," ")," header ")]'); + $page_title = $query[0]->getText(); + $this->assertNotEquals($page_title, $title); $this->assertSession()->pageTextNotContains($summary); - $this->assertSession()->responseContains('

Overridden title

'); + $this->assertEquals($page_title, 'Overridden title'); $this->assertSession()->pageTextContains('Overridden lede'); // Check hidden page header block. @@ -117,9 +125,20 @@ public function testPageHeaderDisplayEvent() { 'status' => NodeInterface::PUBLISHED, ]); $this->drupalGet($page2->toUrl()->toString()); - $this->assertSession()->responseNotContains('

' . $title . '

'); + + // There should be no h1 visible. + $query = $this->xpath('.//h1[contains(concat(" ",normalize-space(@class)," ")," header ")]'); + $this->assertEmpty($query); + + // Using pageTextNotContains also fetches the title tag, so do an xpath on + // the body tag to check the title text is not present. + $body_query = $this->xpath('.//body'); + $body_text = $body_query[0]->getText(); + $this->assertStringNotContainsString($title, $body_text); + + // Check summary and overridden title and summary not present in page. $this->assertSession()->pageTextNotContains($summary); - $this->assertSession()->responseNotContains('

Overridden title

'); + $this->assertSession()->pageTextNotContains('Overridden title'); $this->assertSession()->pageTextNotContains('Overridden lede'); // Check cache tags override. @@ -182,6 +201,48 @@ public function testPageHeaderDisplayEvent() { // Check the child page contains the updated parent summary. $this->assertSession()->pageTextContains('page 3 parent updated summary'); + + // Set up a page4 that can reference other page4 nodes with + // subtitle in header. + $this->createContentType(['type' => 'page4']); + + FieldConfig::create([ + 'field_name' => 'parent', + 'entity_type' => 'node', + 'bundle' => 'page4', + 'label' => 'Parent', + 'cardinality' => -1, + ])->save(); + + $page4parent = $this->createNode([ + 'type' => 'page4', + 'title' => 'page 4 parent title', + 'body' => [ + 'summary' => 'page 4 parent summary', + 'value' => '', + ], + 'status' => NodeInterface::PUBLISHED, + ]); + + $page4child = $this->createNode([ + 'type' => 'page4', + 'title' => 'page 4 child title', + 'body' => [ + 'summary' => 'page 4 child summary', + 'value' => '', + ], + 'parent' => [ + 'target_id' => $page4parent->id(), + ], + 'status' => NodeInterface::PUBLISHED, + ]); + + // Load the child page. + $this->drupalGet($page4child->toUrl()->toString()); + $query = $this->xpath('.//h1[contains(concat(" ",normalize-space(@class)," ")," header ")]//div'); + $page_subtitle = $query[0]->getText(); + $this->assertEquals($page_subtitle, 'page 4 parent title'); + } }