Skip to content

Instantly share code, notes, and snippets.

@renalpha
Last active May 14, 2019 11:21
Show Gist options
  • Select an option

  • Save renalpha/6e2b6cb655482a3de26c48f7be2bdb53 to your computer and use it in GitHub Desktop.

Select an option

Save renalpha/6e2b6cb655482a3de26c48f7be2bdb53 to your computer and use it in GitHub Desktop.
Composition pattern - Menu
<ul class="navbar-nav mr-auto">
@foreach($items as $item)
{!! $item->render() !!}
@endforeach
</ul>
@if(count($item->items) > 0)
<li class="nav-item dropdown">
<a href="{{ $item->url }}" class="nav-link dropdown-toggle" id="navbar{{ str_slug($item->label) }}" role="button" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">{{ $item->label }}</a>
<div class="dropdown-menu" aria-labelledby="navbar{{ str_slug($item->label) }}">
@foreach($item->items as $item)
{!! $item->render() !!}
@endforeach
</div>
</li>
@else
@if($item->isSubmenu())
<a class="dropdown-item" href="{{ $item->url }}">{{ $item->label }}</a>
@else
<li class="nav-item">
<a href="{{ $item->url }}" class="nav-link">{{ $item->label }}</a>
</li>
@endif
@endif
<?php
namespace Exdeliver\Causeway\Domain\Entities\Menu;
use Exdeliver\Causeway\Domain\Common\Interfaces\RenderableInterface;
use Illuminate\Contracts\Support\Arrayable;
/**
* Class MenuComposite
* @package Exdeliver\Causeway\Domain\Entities\Menu
*/
class MenuComposite implements RenderableInterface
{
/**
* @var RenderableInterface
*/
protected $items;
/**
* @return \Illuminate\Contracts\View\View
*/
public function render(): string
{
$items = collect($this->items)
->filter(function ($item) {
return $item->parent_id === null;
})->map(function ($item) {
$item = new MenuElementComposite($item);
return $item;
});
return view('causeway::layouts.partials._menu', [
'items' => $items,
]);
}
/**
* @param Arrayable $item
*/
public function addItem(Arrayable $item)
{
$this->items[] = $item;
}
}
<?php
namespace Exdeliver\Causeway\Domain\Entities\Menu;
use Exdeliver\Causeway\Domain\Common\Interfaces\MenuItemInterface;
use Exdeliver\Causeway\Domain\Common\Interfaces\RenderableInterface;
/**
* Class MenuElementComposite
* @package Exdeliver\Causeway\Domain\Entities\Menu
*/
class MenuElementComposite implements MenuItemInterface, RenderableInterface
{
/**
* @var MenuItemInterface
*/
protected $item;
/**
* MenuElementComposite constructor.
* @param MenuItemInterface $item
*/
public function __construct(MenuItemInterface $item)
{
if (count($item->items) > 0) {
$items = $item->items->map(function ($item) {
$item = new MenuElementComposite($item);
return $item;
});
$item->items = $items;
}
$this->item = $item;
}
/**
* @return \Illuminate\Contracts\View\View
*/
public function render(): string
{
return view('causeway::layouts.partials._menu_item', [
'item' => $this->item,
]);
}
/**
* @return bool
*/
public function isSubmenu()
{
return $this->item->isSubmenu();
}
}
<?php
namespace Exdeliver\Causeway\Domain\Common\Interfaces;
/**
* Interface MenuItemInterface
* @package Exdeliver\Causeway\Domain\Common\Interfaces
*/
interface MenuItemInterface
{
public function isSubmenu();
}
<?php
namespace Exdeliver\Causeway\Domain\Common\Interfaces;
/**
* Interface RenderableInterface
* @package Exdeliver\Causeway\Domain\Common\Interfaces
*/
interface RenderableInterface
{
public function render(): string;
}
@renalpha
Copy link
Copy Markdown
Author

renalpha commented May 14, 2019

        $menuCollection = new MenuComposite();

        foreach($menu->items as $item) {
            $menuCollection->addItem($item);
        }

       $menuCollection->render();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment