How can I build navigation menu from categories and sub categories, like this:
http://mysite/categories/view/1/2
I tried menu builder 1.01 but it only works for acl users. I also read this tutorial, but it was not helpful.
Your first link doesn't work.
Frankly, I'm not even sure I understand what you're trying to do. The second link you supplied - I admit I only looked at the first code snippet - doesn't use a database table. If you want your menu to be dynamic, as in based off controller actions, that makes sense. If you want it to be "dynamic" as in having dynamic control over menu items that you want to be able to have CRUD access to (you do know what CRUD stands for, right?), that's a different (really really simple) story.
This is the most basic, bare-bones example imaginable. I literally slapped this together in fifteen minutes in my sandbox Cake 1.3.12 installation. I am pretty sure I got all the names changed for Cake 2 conventions, however some tweaking may be necessary. I tried to pare it down to the absolute basics and keep the code as clear as possible. Build it out as it suits you. Refer to the cookbook and remember to follow Cake convention at all times.
menus
.menu.php
.MenusController.php
.Create the /Views/Menus
directory, and /views/Elements/Menus
.
CREATE TABLE menus
(
id
int(11) unsigned NOT NULL auto_increment,
name
varchar(255) NOT NULL default '',
controller
varchar(255) NOT NULL,
action
varchar(255) NOT NULL,
created
datetime NOT NULL,
modified
datetime default NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Model code - Menu.php:
<?
class Menu extends AppModel {
var $name = 'Menu';
}
Controller code - MenusController.php:
<?
class MenusController extends AppController {
var $name = 'Menus';
function index() {
if (isset($this->params['requested']) && $this->params['requested'] == true) {
$menus = $this->Menu->find('all');
return $menus;
} else {
$this->set('menus', $this->Menu->find('all'));
}
}
function add() {
if (!empty($this->data)) {
if ($this->Menu->save($this->data)) {
$this->Session->setFlash(__('The menu item has been saved', true));
}
}
}
// Build out additional CRUD functionality,
// for example edit / view / delete, as desired.
}
Every MenusController action requires an [action name].ctp file in /view/menus/
.
So create /views/menus/index.ctp
and /views/menus/add.ctp
. What you put in /views/menus/index.ctp isn't even terribly important, and /views/menus/add.ctp is the form you will use to add new menu items as desired:
<div class="menus form">
<?php echo $this->Form->create('Menu');?>
<fieldset>
<legend><?php __('Add Menu Item'); ?></legend>
<?php
echo $this->Form->input('name');
echo $this->Form->input('controller');
echo $this->Form->input('action');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
</div>
Now, create /views/elements/menus/main.ctp
:
<ul class="header main-menu">
<? if (!isset($menus) || empty($menus)) :
$menus = $this->requestAction('/menus/index');
endif;
foreach($menus as $menu) :
?>
<li>
<?="<a href='".DS.$menu['Menu']['controller'].DS.$menu['Menu']['action']."'>".$menu['Menu']['name']."</a>"; ?>
</li>
<? endforeach; ?>
</ul>
Finally, place the element in the layout so it appears on every page, regardless of view. If you are using the default cake layout, that means you should edit /views/layouts/default.ctp
. You probably want to put this item someplace sensible, such as the <div id="header">
element. Insert the element()
call as follows:
<div id="header">
<!-- whatever markup, code, etc. you may have in the header is fine. -->
<?= $this->element('menus/main'); ?>
</div>
<!-- ...the rest of your layout continues... -->
It may be necessary to add styling to your element to make it readable. Add styling to whatever stylesheet/s you may have (the default is cake.generic.css) as desired.
HTH. The cookbook is your friend.