目标:
在我的商品详情页面上,我想显示我的商品拥有的所有父分类的痕迹导航。
例如,如果为某个产品分配了指向子子类别的category_id;我希望面包屑是:
Root Category / SubCategory / SubSubCategory
问题:
某些产品可能具有指向根类别(没有子级(的category_id,而其他产品可能具有指向 2 级深度类别(具有两个父级(的category_id。如何处理这些情况?
我尝试过的:
这是我的类别模型
这是我的类别表
到目前为止,如果我想获得特定产品的类别面包屑,我会这样做:
{{$product->category->parent->name}} / {{$product->category->name}}
但它很快就在分配了根类别的产品上出现了错误。因为我试图获得一种不存在的关系。
我会将其视为行为,即product
和category
的方法。例如:
{{ $product->trail() }}
其中product
知道如何计算自己的category
面包屑轨迹。
首先,对于类别,我们给出了一种方法来计算它自己的跟踪上游部分。
$category = function(string $name, $parent = null) {
return new class($name, $parent) {
public $name;
public $parent;
public function __construct(string $name, $parent = null) {
$this->name = $name;
$this->parent = $parent;
}
public function breadcrumbs(array $trail = []) {
$trail[] = $this->name;
return $this->parent ? $this->parent->breadcrumbs($trail) : $trail;
}
};
};
然后从产品中,我们可以要求它使用分隔符进行计算,从而为我们提供返回的线索。
$product = function(string $name, ...$categories) use($category) {
$categories = array_reduce(array_reverse($categories), function($set, $item) use($category) {
if (!$set) {
return $category($item);
}
return $category($item, $set);
});
return new class($name, $categories) {
public $name;
public $categories;
public function __construct(string $name, $categories) {
$this->name = $name;
$this->categories = $categories;
}
public function trail(string $separator = ' / '): string {
return implode($separator, $this->categories->breadcrumbs());
}
};
};
然后像这样使用它:
$book = $product('Harry Potter', 'books', 'hardback', 'young-adult');
$shoes = $product('Air Jordans', 'shoes', 'mens', 'sports', 'basketball');
$tapeMeasure = $product('Stanley 25', 'hardware', 'tools', 'measurement');
var_dump(
$book->trail(), // books / hardback / young-adult
$shoes->trail(), // shoes / mens / sports / basketball
$tapeMeasure->trail() // hardware / tools / measurement
);
https://3v4l.org/FNKZI
如果您正在寻找更复杂的东西,您可以使用装饰器扩展$product->trail()
。
public function linkSimilar(string $separator = ' / '): string {
return $this->trail($separator, function(string $name) {
return sprintf('<a href="/category/%s?similar-to=product/%s">%s</a>', $name, $this->sku, $name);
});
}
...
$product->linkSimilar(' > ')
提供:
<a href="/category/hardware?similar-to=product/U425263">hardware</a>
> <a href="/category/tools?similar-to=product/U425263">tools</a>
> <a href="/category/measurement?similar-to=product/U425263">measurement</a>
https://3v4l.org/22n15