Welcome Guest, Not a member yet? Register   Sign In
Generating a menu..
#1

[eluser]awpti[/eluser]
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;
Code:
<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.
#2

[eluser]BlueCamel[/eluser]
So, what I do. I have my menu in a single nested array. Here's a simple example:

Code:
$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.
#3

[eluser]awpti[/eluser]
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!

Code:
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:

Code:
$this->otnmenu->uri = $this->uri->segment(1);
$this->view->set('menu', $this->otnmenu->build_menu());
#4

[eluser]Lone[/eluser]
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.

Code:
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 Tongue
#5

[eluser]awpti[/eluser]
Spoke to soon.

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

Code:
&lt;?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;
        }
}
?&gt;

In retrospect, I should probably call it build_links.
#6

[eluser]Johan André[/eluser]
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.




Theme © iAndrew 2016 - Forum software by © MyBB