Recently I’ve been working on my own framework (we’ve all done it i’m sure) and part of this was a menu handling system.
The basis really is simple, we have a menu item which really is just link and text. That menu item could have children, could be active and/or be selected.
In this case Selected is the currently menu item, which is also Active, and all it’s parents in the chain upwards are also active.
We also have a menu controller which makes it easier to add to the menus.
class menuHandler {
public $menus=array();
public function NewMenu() {
$k = time();
$this->menus[$k] = new menu_class();
return $k;
}
public function AddMenu($key,menu_class $menu) {
if (!isset($this->menus[$key])) {
$this->menus[$key] = $menu;
}
return $this;
}
public function ItemCount($menuKey) {
$menu = $this->menus[$menuKey];
if (!($menu instanceof menu_class)) {
return -1;
}
else {
return count($menu->children);
}
}
public function AddItem($menuKey,$itemKey=null,menu_class $item) {
if (isset($this->menus[$menuKey])) {
$menu = $this->menus[$menuKey];
if (!isset($itemKey) or (is_numeric($itemKey) &amp;amp;&amp;amp; $itemKey <0)) {
$itemKey = count($menu->children);
}
$menu->AddSubItem($item,$itemKey,$menuKey);
}
return $this;
}
public function SetActive($id,$from=null) {
$menu = new menu_class();
if ($from == null) {
$from = $this->menus;
}
elseif($from instanceof menu_class) {
$from = $from->children;
}
foreach ($from as $key=>&amp;amp;$menu) {
if ($key==$id) {
$menu->active=true;
return true;
}
elseif(count($menu->children) !=0) {
$r = $this->SetActive($id,$menu->children);
if ($r) {
$menu->expanded = true;
return $r;
}
}
}
}
}
class menu_class {
public $children = array();
public $myParent=null;
public $active = false;
public $expanded = false;
public $link ='';
public $text = '';
public $additional = array();
public function AddSubItem($item,$ID=null,$parentID=null) {
if ($item instanceof menu_class) {
}
elseif(is_array($item)) {
$item = new menu_class();
$item->text = $details[0];
$item->link = $details[1];
}
if (isset($ID)) {
if (isset($this->children[$ID])) {
if (is_numeric($ID)) {
$this->children = array_insert($this->children,$item,$ID);
}
}
else {
$this->children[$ID] = $item;
}
}
else {
$this->children[] = $item;
}
if (!isset($parentID)) {
$parentID = "main";
}
$this->myParent = $parentID;
ksort($this->children);
}
public function __construct($text=null,$link=null) {
if(isset($text) &amp;amp;&amp;amp; !is_null($text)) {
$this->text = $text;
}
if(isset($link) &amp;amp;&amp;amp; !is_null($link)) {
$this->link = $link;
}
}
public function Format($text) {
if (!empty($this->link)) {
$text= str_replace("%href%",$this->link);
}
if (!empty($this->text)) {
$text = str_replace("%text%",$this->text);
}
return $text;
}
}
You will notice that i’ve used the array_insert function from my previous posting. This was why it was created, so that i could insert without worry that i would overwrite the code
here’s an example of using the code
$menus = new menuHandler();
$menus->AddMenu("main",new menu_class());
$menus->AddItem("main",-1,new menu_class("TEXT","link.php"));
$menus->AddItem("main",-1,new menu_class("TEXT2","link2.php"));
//we want this item to be 1st!
$menus->AddItem("main",0,new menu_class("1st Link","homelink.php"));
So far I pass the $menus out to smarty in the usual assignment method and process like as follows
{foreach from=$menus.main->children item="mItem"}
<div class="mainbutton"><a href="{$mItem->link}">{$mItem->text}</a></div>
{/foreach}
For a cascaded menu i’ve used the following
{foreach from=$menus.cats->children item='cat'}
<div class="item{if $cat->active || $cat->expanded}_select{/if}">
<div class="arrow"></div>
{if !$cat->active}<a href="{$cat->link}">{/if}{$cat->text}{if !$cat->active}</a>
{/if}
</div>
{if $cat->children|@count ne 0 || $cat->expanded}
{foreach from=$cat->children item='subCat'}
<div class="subitem{if $subCat->active}_select{/if}">
<div class="arrow"></div>
{if !$subCat->active}<a href="{$subCat->link}">{/if}{$subCat->text}{if !$subCat->active}</a>{/if}
</div>
{/foreach}
{/if}
{/foreach}
As usual any comments gratefully recieved