EllisLab text mark
Advanced Search
     
Generating a menu..
Posted: 17 January 2008 11:59 PM   [ Ignore ]
Avatar
Joined: 2002-11-11
180 posts

Topic is kinda vague since i couldn’t think of how to properly word it.

Right now, the menu on onlytechnews.com is generated from a large, ugly switch() statement and the URI Segment.

This means the menu is repeated 5 seperate times for each one to have a class=“current”.

I can’t seem to think of a better way to do it. What do you all do to handle the output of a quick class=”....”?


ex;

<a href="/blah/" class="current">Blah</a>
<
a href="/bleh/">Bleh</a>
<
a href="/blargh/">Blargh</a

My method just seems extremely inefficient and downright stupid.

 Signature 

Blog:
GeekLAN
Projects:
Ignited Jobs - LAMP Tips

 
Posted: 18 January 2008 12:09 AM   [ Ignore ]   [ # 1 ]   [ Rating: 0 ]
Joined: 2007-11-18
24 posts

So, what I do. I have my menu in a single nested array. Here’s a simple example:

$sitemenu = array(
    array(
'/site''Home'),
    array(
'/page''Page 1'),
    array(
        array(
'/subpage/pageone''More info on Page 1'),
    ),
    array(
'/pagetwo''Page 2'),
); 


This is pretty easy to walk. First you break down your current url using URL helper then walk the array to construct a path and what menu items are visible in the path. Take the resulting visible items and run them through an output script in the view template to produce a final menu.

Yes, I’m short on code here but hopefully you get the idea. Sorry about that, the code for this is on a remote site I don’t have access to from here right now.

 
Posted: 18 January 2008 01:39 AM   [ Ignore ]   [ # 2 ]   [ Rating: 0 ]
Avatar
Joined: 2002-11-11
180 posts

Actually, I’m not building any sort of breadcrumb or multi-tiered menu.

Just trying to, literally, figure out how to more efficiently add ‘class=“current”’ to the menu item based on the URI segment.

While your idea might fit within the realm of what I want to do, I simply can’t fathom how. I took the simple approach, but definately not the right approach.

See below: (I’m not proud of this - and yes, it’s a library.


EDIT:

figured it out!

class Otnmenu {

    
public $uri '';

    function 
build_menu()
    
{
        $menu 
= array(
            
'/home'        => 'Home',
            
'/blotter'    => 'TechBlotter',
            
'/devblog'    => 'DevBlog',
            
'/about'    => 'About',
            
'/contact'    => 'Contact'
                    
);
        foreach(
$menu as $key => $value)
        
{
            $class 
'';
            if(
$uri === str_replace('/'''$key))
            
{
                $class 
'class="content" ';
            
}
            
            $menu_final 
.= '<a '.$class.'href="'.$key.'/">'.$value."</a><br />\n";
        
}
        
return $menu_final;
    
}

In the controller:

$this->otnmenu->uri $this->uri->segment(1);
$this->view->set('menu'$this->otnmenu->build_menu()); 
 Signature 

Blog:
GeekLAN
Projects:
Ignited Jobs - LAMP Tips

 
Posted: 18 January 2008 02:26 AM   [ Ignore ]   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2007-12-13
378 posts

This is a quick and dirty way to do it - your best way is to get the $items compiled from a DB (using a model) of some sorts using similar field names.

function build_menu($uri)
    
{
        $items 
= array();
        
$items[0]['url']   '';
        
$items[0]['title''home';
        
$items[0]['name']  'Home';
        
        
$items[1]['url']   'blotter';
        
$items[1]['title''blotter';
        
$items[1]['name']  'TechBlotter';
        
        
$items[2]['url']   'devblog';
        
$items[2]['title''blog';
        
$items[2]['name']  'DevBlog';
        
        
$menu '<ul>'."\n";
        
        foreach(
$items as $item{
            
if(stristr($item['url']$uri)) {
                $class 
' class="current"';
            
else {
                $class 
'';
            
}
            $menu 
.= "\t".'<li><a href="/'.$item['url'].'"'.$class.' title="'.$item['title'].'"><span>'.$item['name'].'</span></a></li>'."\n";
            
        
}
        
        $menu 
.= '</ul>';
        return 
$menu;
    

The “/n” and “/t” aren’t really required but I like html smile

EDIT: You just must have edited yours with the solution after I posted! They way you built your array is the best way for just two vars, but I do have a habit at times of preferring a numbered index raspberry

 Signature 

PX Webdesign | The Lab | Personal Blog

 
Posted: 18 January 2008 02:46 AM   [ Ignore ]   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2002-11-11
180 posts

Spoke to soon.

Rewrote to the class to be more codeignitery rather than trying to be all fancy about it smile

<?php
class Otnnav {

        
var $ci;

        function 
Otnnav()
        
{
                $this
->ci =& get_instance();
        
}

        
function build_menu($uri ''$input_menu$css_class ''$css_class_ns '')
        
{
                
if(!is_array($input_menu))
                
{
                        
return FALSE;
                
}
                
else
                
{
                        
foreach($input_menu as $key => $value)
                        
{
                                $class 
'';
                                if(
$uri == str_replace('/'''$key))
                                
{
                                        $class 
'class="'.$css_class.'" ';
                                
}
                                
elseif($css_class_ns)
                                
{
                                        $class 
'class="'.$css_class_ns.'" ';
                                
}
                                
// Returns a simple array, nothing to see here.
                                
$menu_final[] '<a '.$class.'href="'.$key.'/">'.$value.'</a>';
                        
}
                }
                
return $menu_final;
        
}
}
?> 

In retrospect, I should probably call it build_links.

 Signature 

Blog:
GeekLAN
Projects:
Ignited Jobs - LAMP Tips

 
Posted: 04 March 2009 04:28 AM   [ Ignore ]   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-28
430 posts

Hmm… I’m seeing alot of people adding html in the controller / library. Is that really good MVC-practice? Why not use an array send it to the view along with all the data and let the view handle it (with some simple looping/conditions). What if you need to change the presentation? Maybe want an un-ordered list or a definition-list or whatever.

I’m not saying you made it wrong, but to me it seems that the coolness of MVC is keeping stuff in different, pre-defined places.

 Signature 

———————————————————————————————————————————-
Imac 27” Core i7 / 12GB RAM
Macbook Pro 15” C2D 2.53Ghz / 4GB RAM / NVIDIA GeForce 9400M + 9600M GT 512MB
iPhone 4 16Gb Black

http://www.rockkarusellen.se