diff --git a/client/scss/components/_breadcrumbs.scss b/client/scss/components/_breadcrumbs.scss index e43710f962..cb5e9edee7 100644 --- a/client/scss/components/_breadcrumbs.scss +++ b/client/scss/components/_breadcrumbs.scss @@ -11,5 +11,9 @@ font-size: theme('fontSize.22'); } } + + .w-breadcrumbs__sublabel { + display: inline-block; + } } } diff --git a/wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html b/wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html index fb81c902b3..096f27564a 100644 --- a/wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +++ b/wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html @@ -3,7 +3,7 @@ The breadcrumb component is reused across most of Wagtail's headers. Variables this template accepts: - `items` - A list of {"url": Union[str, None], "label": str} dicts + `items` - A list of {"url": Union[str, None], "label": str, "sublabel": Union[str, None]} dicts `classname` - Modifier classes `is_expanded` - Whether the breadcrumbs are always expanded or not, if True the breadcrumbs will not be collapsible {% endcomment %} @@ -48,13 +48,23 @@ data-w-breadcrumbs-target="content" {% endif %} > + {% fragment as sublabel %} + {% if item.sublabel %} + : + + {{ item.sublabel }} + + {% endif %} + {% endfragment %} {% if item.url is not None %} {{ item.label }} + {{ sublabel }} {% else %}
{{ item.label }} + {{ sublabel }}
{% endif %} {% if not forloop.last %} diff --git a/wagtail/admin/tests/viewsets/test_model_viewset.py b/wagtail/admin/tests/viewsets/test_model_viewset.py index 2bf66aa9d8..02239d4197 100644 --- a/wagtail/admin/tests/viewsets/test_model_viewset.py +++ b/wagtail/admin/tests/viewsets/test_model_viewset.py @@ -773,6 +773,7 @@ class TestBreadcrumbs(AdminTemplateTestUtils, WagtailTestUtils, TestCase): { "url": "", "label": "History", + "sublabel": str(self.object), }, ] self.assertBreadcrumbsItemsRendered(items, response.content) @@ -797,6 +798,7 @@ class TestBreadcrumbs(AdminTemplateTestUtils, WagtailTestUtils, TestCase): { "url": "", "label": "Usage", + "sublabel": str(self.object), }, ] self.assertBreadcrumbsItemsRendered(items, response.content) @@ -821,6 +823,7 @@ class TestBreadcrumbs(AdminTemplateTestUtils, WagtailTestUtils, TestCase): { "url": "", "label": "Inspect", + "sublabel": str(self.object), }, ] self.assertBreadcrumbsItemsRendered(items, response.content) diff --git a/wagtail/snippets/tests/test_viewset.py b/wagtail/snippets/tests/test_viewset.py index 80664520f2..53a526472c 100644 --- a/wagtail/snippets/tests/test_viewset.py +++ b/wagtail/snippets/tests/test_viewset.py @@ -1472,7 +1472,7 @@ class TestBreadcrumbs(AdminTemplateTestUtils, BaseSnippetViewSetTests): "url": self.get_url("edit", args=(self.object.pk,)), "label": str(self.object), }, - {"url": "", "label": "History"}, + {"url": "", "label": "History", "sublabel": str(self.object)}, ] self.assertBreadcrumbsItemsRendered(items, response.content) @@ -1487,7 +1487,7 @@ class TestBreadcrumbs(AdminTemplateTestUtils, BaseSnippetViewSetTests): "url": self.get_url("edit", args=(self.object.pk,)), "label": str(self.object), }, - {"url": "", "label": "Usage"}, + {"url": "", "label": "Usage", "sublabel": str(self.object)}, ] self.assertBreadcrumbsItemsRendered(items, response.content) @@ -1502,7 +1502,7 @@ class TestBreadcrumbs(AdminTemplateTestUtils, BaseSnippetViewSetTests): "url": self.get_url("edit", args=(self.object.pk,)), "label": str(self.object), }, - {"url": "", "label": "Inspect"}, + {"url": "", "label": "Inspect", "sublabel": str(self.object)}, ] self.assertBreadcrumbsItemsRendered(items, response.content) diff --git a/wagtail/test/utils/template_tests.py b/wagtail/test/utils/template_tests.py index c89ef1bb7a..e6f5e69f9b 100644 --- a/wagtail/test/utils/template_tests.py +++ b/wagtail/test/utils/template_tests.py @@ -58,13 +58,26 @@ class AdminTemplateTestUtils: element, f"Expected '{item['label']}' breadcrumbs item to be a div", ) - label = element.text.strip() + + # Sublabel is optional and the : separator is invisible + label = element.get_text(strip=True) + sublabel = None + if item.get("sublabel"): + label, sublabel = label.split(":", maxsplit=1) + self.assertEqual( label, item["label"], f"Expected '{item['label']}' breadcrumbs item label, found '{label}'", ) + if sublabel: + self.assertEqual( + sublabel, + item["sublabel"], + f"Expected '{item['sublabel']}' breadcrumbs item sublabel, found '{sublabel}'", + ) + def assertBreadcrumbsNotRendered( self: Union[WagtailTestUtils, SimpleTestCase], html: Union[str, bytes],