Laravel Menu
Are you the type of person that writes menus by hand in view files or do you find yourself looking for the best place to store links to pages on your website? then Laravel Menu is for you!
Key concepts
Item lists
An item list is what a menu is all about and it should be pretty self explanatory because it simply stores a list of items.
there are some configurations available for an item list.
You can, for example set the HMTL element that will be used to render the list, prefix every item in the list with all the parent's url segments, and a lot more.
We will explore these options later.
Menu handlers
Menu handlers allow us to create and interact with item lists and act as a place to store and retrieve our menus.
Because we are able to interact with multiple item lists at the same time some interesting possibilities become available to us.
Items
The Laravel Menu bundle has 2 types of items available out of the box.
-
Link
For creating links to other pages
-
Raw
Be free to add anything you like in the item.
This type is usually used for dividers, titles etc.
The HTML element and attributes for the item can also be changed, more on this topic later.
Installing
The Laravel Menu bundle is installable via the artisan command line tool.
Open the terminal and navigate to your Laravel project's root.
Now type the following command
php artisan bundle:install menu
Activating
To let Laravel know the Laravel Menu bundle should be started, open up application/bundles.php and add the following lines to the bundles array.
'menu' => array(
'auto' => true
),
Diving in
The Laravel Menu bundles consists of a couple of classes, but you can interact with all of them via the Menu class.
Let's take a look at the handler method. it takes a string or an array as the only argument, the string(s) given are the names for the item lists we want to retrieve.
If an itemlist we asked for didn't exist yet, it will create it for us.
After the menu class has found and created the item lists we want, it will hand back a menuhandler that handles the item lists we asked for.
// Get a MenuHandler instance that handles an ItemList named "main"
Menu::handler('main');
When we call a method on this menu handler, it will simply forward the call to all the item lists that it handles.
In order to find out what we can do now that we have a handler, we need to take a look at the methods on the ItemList class.
The ItemList class has a method called add that you are probably going to use a lot. It adds an Item of type "link" to the ItemList.
Menu::handler('main')->add('home', 'Homepage');
/* The add method takes these arguments
| $url |
string |
The URL to another page |
| $title |
string |
The visible string on the link |
| $children (default = null) |
ItemList |
(optional) The children of this page |
| $link_attributes (default = array()) |
array |
(optional) HTML attributes for the <a> element |
| $item_attributes (default = array()) |
array |
(optional) HTML attributes for the list element (usually <li>) |
| $item_element (default = 'li') |
string |
(optional) The type of the list element |
*/
Let's take a look at the raw method, for adding "anything" to the list.
Menu::handler('main')->raw('<img src="img/seperator.gif">');
/* The raw method takes these arguments
| $html |
string |
The contents of the item |
| $children (default = null) |
ItemList |
(optional) The children of this item |
| $item_attributes (default = array()) |
array |
(optional) HTML attributes for the list element (usually <li>) |
| $item_element (default = 'li') |
string |
(optional) The type of the list element |
*/
Great! Now that we have learned how to add items to an item list, let's have a look at how we add children to a item.
Every item can have children, the children object is just another ItemList. As we have seen before, we can create item lists via the handler method, but this method returns a MenuHandler, making it unusable for item children.
So what do we use? the items method returns a fresh ItemList object. Let's have a look.
Menu::handler('main')
->add('home', 'Homepage', Menu::items()
->add('sub-of-home', 'Sub of homepage'));
/* The items method takes these arguments
| $name (default = null) |
string |
(optional) The name (=identifier) of this ItemList |
| $attributes (default = array()) |
array |
(optional) HTML attributes for the ItemList element (usually <ul>) |
| $element (default = 'ul') |
string |
(optional) The type of the ItemList element |
*/
So now we know how to build menus, add items and items with children.
Let's find out how to display the menus.
The MenuHandler and ItemList classes implement the "__toString" method, that calls the render method.
This means you can simply echo the MenuHandler or ItemList object.
Here is an example to make things more clear.
echo Menu::handler('main');
// Is the same as
echo Menu::handler('main')->render();
The render method (only) takes an array with render options, presented below.
-
max_depth
Hide items below a certain depth
-
active_class
Change the (automatically added) class for the active item
-
active_child_class
Change the (automatically added) class for the item that has an active child item
Now that we have the basics under control, we are going to explore some other cool features this bundle provides.
Extra features
You might have noticed earlier that the items method takes a "name" as the first argument.
And you also might have wondered what it is for.
Sorry mates, I've got some work todo below
TODO: explain the
all and
find method (see Practical example #1 & #2 for more info)
TODO: explain the
prefix,
prefix_parents and
prefix_handler methods
Practical examples
#1
function initialize_menu($parent_id = 0)
{
// Load the pages from the database
$pages = DB::table('pages')
->where_parent_id($parent_id)
->get();
// Loop through the pages
foreach ($pages as $page)
{
if($parent_id == 0)
{
// Get a menu handler for the menus this page should go in
$menus = Menu::handler(explode(',', $page->menus));
}
else
{
// Find the item list that has a name of the parent_id we are looking for
$menus = Menu::all()
->find($parent_id);
}
// Add the page to the item list, and add the children item list (empty)
// but named with the page's id
$menus->add($page->url, $page->menu, Menu::items($page->id));
// Attach the children (if any) of this page
initialize_menu($page->id);
}
}
#2
$menu = Menu::handler('menu');
$languages = array(
'en' => 'English',
'nl' => 'Nederlands'
);
foreach ($languages as $code => $name)
{
$menu->add($code, $name, Menu::items($code));
}
// Add some items to the dutch menu
$menu
->find('nl')
->prefix_parents()
->add('welkom', 'Welkom')
->add('over-ons', 'Over ons');
// Add some items to the english menu
$menu
->find('en')
->prefix_parents()
->add('welcome', 'Welcome')
->add('about-us', 'About us');
// Render the top level only (languages)
echo $menu->render(array(
'max_depth' => 1
));
// Render the english menu
echo $menu->find('en');
// I used the $menu variable (for less typing in this example)
// If you want to render the menu in another file, just reference
// It by the handler again.
// Render the dutch menu
echo Menu::handler('menu')->find('nl');
#3
// Render some categories
Menu::handler('categories')
->add('algorithms', 'Algorithms', Menu::items()->prefix_parents()
->add('cryptography', 'Cryptography')
->add('data-structures', 'Data Structures')
->add('digital-image-processing', 'Digital Image Processing')
->add('memory-management', 'Memory Management'))
->add('graphics-and-multimedia', 'Graphics & Multimedia', Menu::items()->prefix_parents()
->add('directx', 'DirectX')
->add('flash', 'Flash')
->add('opengl', 'OpenGL'));
echo Menu::handler('categories');
Some last words
Thanks for following along and using this bundle.
More last words soon ;)