diff --git a/docs/breadcrumbs.md b/docs/breadcrumbs.md
index 1d8331d..f5747ff 100644
--- a/docs/breadcrumbs.md
+++ b/docs/breadcrumbs.md
@@ -64,8 +64,7 @@ Method | Description | Default
`id(string $value)` | Widget ID. | `''`
`autoIdPrefix(string $value)` | Prefix to the automatically generated widget ID. | `w`
`withoutEncodeLabels()` | Disable encoding for labels. | `false`
-`withoutHomeItem()` | Do not render home item. | `true`
-`homeItem(array $value)` | The first item in the breadcrumbs (called home link). | `[]`
+`homeItem(?array $value)` | The first item in the breadcrumbs (called home link). | `['label' => 'Home', 'url' => '/']`
`itemTemplate(string $value)` | Template used to render each inactive item in the breadcrumbs. | `
{icon}{link} \n`
`activeItemTemplate(string $value)`| Template used to render each active item in the breadcrumbs. | `{icon}{label} \n`
`items(array $value)` | List of items to appear in the breadcrumbs. | `[]`
diff --git a/src/Breadcrumbs.php b/src/Breadcrumbs.php
index 4bdbbf4..d18174a 100644
--- a/src/Breadcrumbs.php
+++ b/src/Breadcrumbs.php
@@ -30,8 +30,7 @@
final class Breadcrumbs extends Widget
{
private bool $encodeLabels = true;
- private array $homeItem = [];
- private bool $withoutHomeItem = false;
+ private ?array $homeItem = ['label' => 'Home', 'url' => '/'];
private string $itemTemplate = "{icon}{link} \n";
private string $activeItemTemplate = "{icon}{label} \n";
private array $items = [];
@@ -67,28 +66,24 @@ public function withoutEncodeLabels(): self
}
/**
- * Do not render home item.
+ * Returns a new instance with the specified first item in the breadcrumbs (called home link).
*
- * @return self
- */
- public function withoutHomeItem(): self
- {
- $new = clone $this;
- $new->withoutHomeItem = true;
- return $new;
- }
-
- /**
- * The first item in the breadcrumbs (called home link).
+ * If a null is specified, the home item will not be rendered.
*
- * Please refer to {@see $items} on the format.
+ * @param array|null $value Please refer to {@see items()} on the format.
*
- * @param array $value
+ * @throws InvalidArgumentException If an empty array is specified.
*
* @return self
*/
- public function homeItem(array $value): self
+ public function homeItem(?array $value): self
{
+ if ($value === []) {
+ throw new InvalidArgumentException(
+ 'The home item cannot be an empty array. To disable rendering of the home item, specify null.',
+ );
+ }
+
$new = clone $this;
$new->homeItem = $value;
return $new;
@@ -210,80 +205,71 @@ private function renderIcon(string $icon, array $iconOptions): string
/**
* Renders a single breadcrumb item.
*
- * @param array $link The link to be rendered. It must contain the "label" element. The "url" element is optional.
+ * @param array $item The item to be rendered. It must contain the "label" element. The "url" element is optional.
* @param string $template The template to be used to rendered the link. The token "{link}" will be replaced by the
* link.
*
- * @throws InvalidArgumentException|JsonException If `$link` does not have "label" element.
+ * @throws InvalidArgumentException|JsonException If `$item` does not have "label" element.
*
- * @return string The rendering result
+ * @return string The rendering result.
*/
- private function renderItem(array $link, string $template): string
+ private function renderItem(array $item, string $template): string
{
- $encodeLabel = ArrayHelper::remove($link, 'encode', $this->encodeLabels);
+ $encodeLabel = ArrayHelper::remove($item, 'encode', $this->encodeLabels);
$icon = '';
$iconOptions = [];
- if (isset($link['icon'])) {
- $icon = $link['icon'];
+ if (isset($item['icon'])) {
+ $icon = $item['icon'];
}
- if (isset($link['iconOptions']) && is_array($link['iconOptions'])) {
+ if (isset($item['iconOptions']) && is_array($item['iconOptions'])) {
$iconOptions = $this->addOptions($iconOptions, 'icon');
}
- unset($link['icon'], $link['iconOptions']);
+ unset($item['icon'], $item['iconOptions']);
- if (array_key_exists('label', $link)) {
- $label = $encodeLabel ? Html::encode($link['label']) : $link['label'];
+ if (array_key_exists('label', $item)) {
+ $label = $encodeLabel ? Html::encode($item['label']) : $item['label'];
} else {
throw new InvalidArgumentException('The "label" element is required for each link.');
}
- if (isset($link['template'])) {
- $template = $link['template'];
+ if (isset($item['template'])) {
+ $template = $item['template'];
}
- if (isset($link['url'])) {
- $options = $link;
+ if (isset($item['url'])) {
+ $options = $item;
unset($options['template'], $options['label'], $options['url'], $options['icon']);
- $linkHtml = Html::a($label, $link['url'], $options)->encode(false)->render();
+ $link = Html::a($label, $item['url'], $options)->encode(false)->render();
} else {
- $linkHtml = $label;
+ $link = $label;
}
return strtr(
$template,
- ['{label}' => $label, '{link}' => $linkHtml, '{icon}' => $this->renderIcon($icon, $iconOptions)]
+ ['{label}' => $label, '{link}' => $link, '{icon}' => $this->renderIcon($icon, $iconOptions)],
);
}
private function renderItems(): array
{
- $links = [];
+ $items = [];
- if ($this->withoutHomeItem === false) {
- $links[] = $this->renderHomeLink();
+ if ($this->homeItem !== null) {
+ $items[] = $this->renderItem($this->homeItem, $this->itemTemplate);
}
- foreach ($this->items as $link) {
- if (!is_array($link)) {
- $link = ['label' => $link];
+ foreach ($this->items as $item) {
+ if (!is_array($item)) {
+ $item = ['label' => $item];
}
- $links[] = $this->renderItem($link, isset($link['url']) ? $this->itemTemplate : $this->activeItemTemplate);
- }
-
- return $links;
- }
-
- private function renderHomeLink(): string
- {
- if ($this->homeItem === []) {
- $this->homeItem = ['label' => 'Home', 'url' => '/'];
+ $items[] = $this->renderItem($item, isset($item['url']) ? $this->itemTemplate : $this->activeItemTemplate);
}
- return $this->renderItem($this->homeItem, $this->itemTemplate);
+ return $items;
}
}
diff --git a/tests/BreadcrumbsTest.php b/tests/BreadcrumbsTest.php
index f9a3e8f..a396cac 100644
--- a/tests/BreadcrumbsTest.php
+++ b/tests/BreadcrumbsTest.php
@@ -186,7 +186,7 @@ public function testBreadcrumbsLinksException(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The "label" element is required for each link.');
- $html = Breadcrumbs::widget()
+ Breadcrumbs::widget()
->items([['url' => '/about', 'template' => '{link}
']])
->render();
}
@@ -273,7 +273,7 @@ public function testBreadcrumbsWithoutHomeItem(): void
$html = Breadcrumbs::widget()
->items([['label' => 'About', 'url' => '/about']])
- ->withoutHomeItem()
+ ->homeItem(null)
->render();
$expected = <<<'HTML'
@@ -285,12 +285,20 @@ public function testBreadcrumbsWithoutHomeItem(): void
$this->assertEqualsWithoutLE($expected, $html);
}
+ public function testHomeItemThrowExceptionForEmptyArray(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage(
+ 'The home item cannot be an empty array. To disable rendering of the home item, specify null.',
+ );
+ Breadcrumbs::widget()->homeItem([]);
+ }
+
public function testImmutability(): void
{
$widget = Breadcrumbs::widget();
- $this->assertNotSame($widget, $widget->homeItem([]));
- $this->assertNotSame($widget, $widget->withoutHomeItem());
+ $this->assertNotSame($widget, $widget->homeItem(null));
$this->assertNotSame($widget, $widget->itemTemplate(''));
$this->assertNotSame($widget, $widget->activeItemTemplate(''));
$this->assertNotSame($widget, $widget->items([]));