This package allows you to easily build a hierarchical menu from PHP. It's inspired by
Crisp's blogpost but
further implemented., (*1)
Requirements
This package requires PHP 7.4+ and the renderers make use of vdhicts/html-element., (*2)
Installation
This package can be used in any PHP project or with any framework., (*3)
You can install the package via composer:, (*4)
composer require vdhicts/menu-builder
, (*5)
Usage
use Vdhicts\Menu;
$item = new Menu\Item(1, 'Search engines');
$subItemGoogle = new Menu\Item(2, 'Google', 'http://www.google.com', $item->getId());
$subItemBing = new Menu\Item(3, 'Bing', 'http://www.bing.com', $item->getId());
$itemCollection = new Menu\ItemCollection();
$itemCollection->addItem($item)
->addItem($subItemGoogle)
->addItem($subItemBing);
$renderer = new Menu\Renderers\Navbar();
$menuBuilder = new Menu\Builder($itemCollection, $navbar);
$menuBuilder->generate();
Renderers
There are 3 renderers available by default:, (*6)
List group
Usefull for things like sidebars or sidemenu's. Renders the menu as a Bootstrap list-group component:, (*7)
<ul class="list-group">
<li class="list-group-item">Search engines
<ul class="list-group">
<li class="list-group-item">
<a href="http://www.google.com">Google</a>
</li>
<li class="list-group-item list-group-item-divider"></li>
<li class="list-group-item">
<a href="http://www.bing.com">Bing</a>
</li>
</ul>
</li>
</ul>
List inline
Usefull for things like footers. Renders the menu as a Bootstrap list-inline component:, (*8)
<ul class="list-inline">
<li>Search engines
<ul class="list-inline">
<li>
<a href="http://www.google.com">Google</a>
</li>
<li class="list-inline-divider"></li>
<li>
<a href="http://www.bing.com">Bing</a>
</li>
</ul>
</li>
</ul>
Navbar
This generates the content of the navbar, so additional HTML is needed to provide the full navbar., (*9)
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Search engines<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>
<a href="http://www.google.com">Google</a>
</li>
<li class="divider" role="separator"></li>
<li>
<a href="http://www.bing.com">Bing</a>
</li>
</ul>
</li>
</ul>
Custom renderer
You can use your own renderer as long as it implements the Renderer
interface., (*10)
Database
When storing the data in a database, you should at least have an id
, parentId
and name
. The id isn't limited to
integers so a UUID or slug should work too., (*11)
To help you get started, use the following sql to generate the menu tables., (*12)
CREATE TABLE `menu` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `menu_items` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`target` varchar(255) DEFAULT NULL,
`is_divider` tinyint(1) unsigned NOT NULL DEFAULT '0',
`parent_id` int(10) unsigned DEFAULT NULL,
`menu_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `menu_items_could_have_a_parent` (`parent_id`),
KEY `menu_items_could_belongs_to_a_menu` (`menu_id`),
CONSTRAINT `menu_items_could_belongs_to_a_menu` FOREIGN KEY (`menu_id`) REFERENCES `menu` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `menu_items_could_have_a_parent` FOREIGN KEY (`parent_id`) REFERENCES `menu_items` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
This generates a menu table in which you can store the menu itself. This enables you to have several different menu's.
Also the menu items table is generated which has a foreign key to the menu and to its parent menu item., (*13)
, (*14)
To retrieve the items, just execute the following query:, (*15)
SELECT
`id`,
`parent_id`,
`name`
FROM
`menu_items`
WHERE
`menu_id` = 1
ORDER BY
`parent_id`, `name`
In which you should replace the menu id., (*16)
Tests
Unit tests are available in the tests
folder. Run with:, (*17)
composer test
, (*18)
When you want a code coverage report which will be generated in the build/report
folder. Run with:, (*19)
composer test-coverage
, (*20)
Contribution
Any contribution is welcome, but it should meet the PSR-12 standard and please create one pull request per feature/bug.
In exchange, you will be credited as contributor on this page., (*21)
Security
If you discover any security related issues in this or other packages of Vdhicts, please email security@vdhicts.nl
instead of using the issue tracker., (*22)
License
This package is open-sourced software licensed under the MIT license., (*23)
About vdhicts
Vdhicts is the name of my personal company for which I work as freelancer. Vdhicts develops
and implements IT solutions for businesses and educational institutions., (*24)