Nested Menu

Hello Yii community,

Is there any simple way to achieve an nested menu(left menu with parent category and sub category - only 2 levels).

I have mysql table: id, id_parent, name

An example:

Category 1

  • Subcategory 1.1

  • Subcategory 1.2

Category 2

  • Subcategory 2.1

Thanks.

Dear scieri,

You could use the following:

Allthough you might perhaps want to use another menu table,

since you are not saving the url where to link to. Below is based on the MenuItem model I use with:

  • @property integer $item_id // item of link

  • @property integer $parent_id // parent

  • @property integer $menu_id // menu id, since you can have multiple menus on one site

  • @property string $label // equal to your name

  • @property string $alias // label converted to a link (remove spaces and special characters)

  • @property string $url // where it links to

  • @property string $description // just for your self

  • @property string $date_added

  • @property string $last_updated

  • @property integer $sort_order // to order the items

  • @property string $status // whether the item is shown/active on the site

Model MenuItem




public function getItems($menu_id, $parent_id=null, $url){

	$results = Yii::app()->getDb()->createCommand();

        $results->select('item_id, label, alias, url')->from('menu_item');

 

        if($parent_id === null)

                $results->where('menu_id=:mid AND parent_id IS NULL AND status="active"', array(':mid'=>(int)$menu_id));

        else

                $results->where('menu_id=:mid AND parent_id=:pid AND status="active"', array(':mid'=>(int)$menu_id, ':pid'=>$parent_id));

 

        $results->order('sort_order ASC, label ASC');

        $results = $results->queryAll();

 

        $items = array();

 

        if(empty($results))

                return $items;

 

        foreach($results AS $result){

            $childItems=$this->getItems($menu_id, $result['item_id'], $url); 

		$url = ($url === '/') ? '/index.php/page&view=home' : $url;

			

		$items[] = array(

			'label'         => $result['label'],

			'alias'         => $result['alias'],

			'url'           => (empty($childItems)) ? $result['url'] : '#',

			'active'		=> (preg_match("#".$result['alias']."#", $url)) 

								// alias in url

									? true

									: false,

			'itemOptions'   => array('class'=>'listItem'),

			'linkOptions'   => array('class'=>'listItemLink', 'title'=>$result['label']),

			'isParent'		=> !(empty($childItems)),

			'items'		=> $childItems, 

             );

        }

 

        return $items;

	}



In my main layout view (view/layouts/main.php) I call the menu with:




$menu = array(

   'id' => 'menu',

   'activeCssClass'=>'sel',

   'htmlOptions'=>array('class'=>'menu'),

   'items'=>MenuItem::model()->getItems(1, null, $_SERVER['REQUEST_URI']);,						);

$this->widget('zii.widgets.CMenu', $menu);

Hi FOX Creation,’

Many thanks for the code, is exactly what I need, I will tweak it a little bit to suit my needs.

I think that Yii should address this menus needs in the future releases :)