Skip to content

Commit 4b22e7e

Browse files
authored
Merge pull request #391 from torchbox/TWE-62-as-an-editor-i-want-the-ability-to-add-a-promo-block-to-the-service-area-pages
TWE-62: Add PromoBlock to ServiceAreaPage (with link optional)
2 parents 5a4c315 + c3a89f2 commit 4b22e7e

File tree

5 files changed

+77
-2
lines changed

5 files changed

+77
-2
lines changed

tbx/core/blocks.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,10 @@ class Meta:
209209

210210
class ButtonLinkStructValue(blocks.StructValue):
211211
def get_button_link_block(self):
212-
return self.get("button_link")[0]
212+
try:
213+
return self.get("button_link")[0]
214+
except IndexError:
215+
return None
213216

214217
# return an href-ready value for button_link
215218
def get_button_link(self):

tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/promo_block.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<div class="promo-block__content">
55
{% include "patterns/atoms/section-title/section-title.html" with title=value.title classes="promo-block__title" %}
66
<p class="promo-block__description">{{ value.description }}</p>
7-
<a href="{{ value.get_button_link }}" class="button promo-block__button">{{ value.button_text }}</a>
7+
{% if value.button_text %}
8+
<a href="{{ value.get_button_link }}" class="button promo-block__button">{{ value.button_text }}</a>
9+
{% endif %}
810
{% if value.secondary_link %}
911
<hr class="promo-block__divider" aria-hidden="true" />
1012
{% with secondary_link=value.secondary_link.0.value %}

tbx/services/blocks.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from django.core.exceptions import ValidationError
2+
13
from wagtail import blocks
24

35
from tbx.core.blocks import (
@@ -13,6 +15,7 @@
1315
PromoBlock,
1416
ShowcaseBlock,
1517
StoryBlock,
18+
StructBlockValidationError,
1619
TabbedParagraphBlock,
1720
WorkChooserBlock,
1821
)
@@ -69,9 +72,31 @@ class ServiceStoryBlock(StoryBlock):
6972
)
7073

7174

75+
class OptionalLinkPromoBlock(PromoBlock):
76+
"""
77+
Identical to PromoBlock in all aspects, except that button_link is optional.
78+
"""
79+
80+
button_text = blocks.CharBlock(max_length=55, required=False)
81+
button_link = blocks.StreamBlock(
82+
PromoBlock.declared_blocks["button_link"].child_blocks.items(),
83+
required=False,
84+
max_num=1,
85+
)
86+
87+
def clean(self, value):
88+
cleaned = super().clean(value)
89+
if cleaned.get("button_text") and not cleaned.get("button_link"):
90+
raise StructBlockValidationError(
91+
{"button_link": ValidationError("This field is required.")},
92+
)
93+
return cleaned
94+
95+
7296
class ServiceAreaStoryBlock(StoryBlock):
7397
blog_chooser = BlogChooserBlock()
7498
four_photo_collage = FourPhotoCollageBlock()
7599
key_points = IconKeyPointsBlock(label="Key points with icons")
76100
link_columns = LinkColumnsBlock()
101+
promo = OptionalLinkPromoBlock()
77102
work_chooser = WorkChooserBlock()

tbx/services/tests/__init__.py

Whitespace-only changes.

tbx/services/tests/test_blocks.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from django.test import SimpleTestCase
2+
3+
from wagtail.blocks import StructBlockValidationError
4+
5+
from tbx.services.blocks import OptionalLinkPromoBlock, PromoBlock
6+
7+
8+
class OptionalLinkPromoBlockTestCase(SimpleTestCase):
9+
def test_basic_promo_block_button_link_required(self):
10+
try:
11+
PromoBlock().clean({"button_link": []})
12+
except StructBlockValidationError:
13+
pass
14+
else:
15+
self.fail("PromoBlock.button_link should be required")
16+
17+
def test_custom_promo_block_button_link_optional(self):
18+
try:
19+
OptionalLinkPromoBlock().clean({"button_link": []})
20+
except StructBlockValidationError as e:
21+
self.fail(e.as_json_data())
22+
23+
def test_basic_promo_block_button_text_required(self):
24+
try:
25+
PromoBlock().clean({"button_text": ""})
26+
except StructBlockValidationError:
27+
pass
28+
else:
29+
self.fail("PromoBlock.button_text should be required")
30+
31+
def test_custom_promo_block_button_text_optional(self):
32+
try:
33+
OptionalLinkPromoBlock().clean({"button_text": ""})
34+
except StructBlockValidationError as e:
35+
self.fail(e.as_json_data())
36+
37+
def test_custom_promo_block_link_required_if_text_provided(self):
38+
try:
39+
OptionalLinkPromoBlock().clean({"button_text": "test", "button_link": []})
40+
except StructBlockValidationError:
41+
pass
42+
else:
43+
self.fail(
44+
"PromoBlock.button_link should be required if button_text is provided"
45+
)

0 commit comments

Comments
 (0)