cgiovanii
4/20/2014 - 9:34 PM

Generate navigation menu's using unordered lists: Generate navigation menu's that look clean using a custom class HTML::nav(); Automatically

Generate navigation menu's using unordered lists: Generate navigation menu's that look clean using a custom class HTML::nav(); Automatically set active state, use conditions to display links, and optionally pass only one value for both url and link name if you want to type a little less.

/*
We will create a navigation menu like this:
{{ HTML::nav(array('login', 'register', 'wiki', 'forum', '/' => 'Home')) }}
 
Which will output:
<ul>
<li><a href="yourdomain.com/login" class="active">Login</a></li>
<li><a href="yourdomain.com/register">Register</a></li>
<li><a href="yourdomain.com/wiki">Wiki</a></li>
<li><a href="yourdomain.com/forum">Forum</a></li>
<li><a href="yourdomain.com">Home</a></li>
</ul>
 
Just make sure to load your macro.
*/
 
// HTMLMacro.php
HTML::macro('nav', function($list, $attributes = null)
{
$nav = array();
 
 // iterate through each element of the array and get url => link pairs
 foreach ($list as $key => $val)
 {
 // Sometimes we want to pass a condition and display link based on the condition
 // (ex: dispaly login vs. logout link based on if user is logged in), in this case, an array will be passed instead of a string.
 // The first value will be the condition, 2nd and 3rd will be the links
 if (is_array($val))
 {
$condition = $val[0];
 
 // set url to the keys of the array
$link = array_keys($val);
 
 // sometimes we don't want to display any link if the condition isn't met, then we need to check if a 2nd link is omitted
$link[2] = array_key_exists(2, $link) ? $link[2] : null;
 
 // check to see if condition passes
$key = $condition ? $link[1] : $link[2];
 
 // if a second link isn't passed, then stop the current loop at this point and skip to the next loop
 if (is_null($key))
 {
 continue;
 }
 
$val = $val[$key];
 }
 
 // Check to see if both url and link is passed
 // Many times, both url and link name will be the same, so we can avoid typing it twice and just pass one value
 // In this case, the key will be numeric (when we just pass a value instead of key => value pairs)
 // We will have to set the url to equal the key instead
$url = is_numeric($key) ? $val : $key;
 
 // If we are using controller routing (ex: HomeController@getIndex) the we need to use URL::action() instead of URL::to()
$url = (strpos($url, '@') !== false) ? URL::action($url) : URL::to(strtolower($url));
 
 // Set the active state automatically
$class['class'] = (Request::url() === $url) ? 'active' : null;
 
 // Push the new list into the $nav array
array_push($nav, HTML::link($url, $val, $class));
 }
 
 // Generate the unordered list
$menu = HTML::ul($nav, $attributes);
 // HTML::ul() performs htmlentities on the list by default, so we have to decode it back using HTML::decode()
$menu = HTML::decode($menu);
 
 // Return the generated menu
 return $menu;
});
 
// Example.php
 
// Example 1
{{ HTML::nav(array('login', 'register', 'wiki', 'forum', '/' => 'Home')) }}
 
// Example 2
// What if you want to display a link based on a condition like Auth::check()
{{ HTML::nav(array(array(Auth::check(), 'logout', 'login'), 'register', 'wiki', 'forum', '/' => 'Home')) }}
// Now the login link will be displayed if user is not logged in and vice versa
- See more at: http://laravelsnippets.com/snippets/generate-navigation-menus-using-unordered-lists#sthash.E1kSmfT8.dpuf