[Yii Framework] Membuat Menu Dinamis dengan Hirarki Parent Child dari Database
April 9, 2012 40 Comments
Biasanya untuk membuat sebuah menu dinamis yang mudah untuk di konfigurasi kita lakukan pemanggilan menunya dari database. Tentu menu-menu yang ada sering kali terdiri dari menu-sub menu-sub dari sub menu dan seterusnya.. Yang mana hasilnya akan seperti gambar berikut :
Nah, untuk membuatnya pertama-tama mari kita buat sebuah tabel “category” dengan field-field sebagai berikut :
– id(integer, not null, auto increment) = identitas unik tabel category
– label(varchar 200, not null) = nama dari suatu category
– parent(integer, null) = induk dari suatu category.
Lalu generate tabel tersebut dengan menggunakan GII. Setelah itu saya akan isikan dengan data sample seperti berikut :
id | label | parent
1 | Nasional | NULL
2 | Olahraga | NULL
3 | Sepak Bola | 2
4 | Ibu Kota | 1
5 | Liga Spanyol | 3
6 | Teknologi | NULL
7 | International | NULL
8 | Liga Italia | 3
9 | Liga Indonesia | 3
10 | IPL | 9
11 | LPI | 9
Lalu kemudian modifikasi code anda. Pada model anda, buatlah fungsi seperti berikut :
public function getMenu($cnd=" IS NULL") { $data2 = array(); $data2[] = array('label'=>'Beranda', 'url'=>array('/site/index')); foreach($this->findAll('parent'.$cnd) as $haha) { $row=array(); $row['label'] = $haha->label; $row['url'] = array('category/view','id'=>$haha->id); if(count($this->getMenu2(' ='.$haha->id))>0) { $row['items'] = $this->getMenu2(' ='.$haha->id); } $data2[] =$row; } $data2[] = array('label'=>'Tentang Kami', 'url'=>array('/site/page', 'view'=>'about')); $data2[] = array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest); $data2[] = array('label'=>'Logout ('.Yii::app()->user->nama.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest); return $data2; } public function getMenu2($cnd=" IS NULL") { $data2 = array(); foreach($this->findAll('parent'.$cnd) as $haha) { $row=array(); $row['label'] = $haha->label; $row['url'] = array('category/view','id'=>$haha->id); if(count($this->getMenu2(' ='.$haha->id))>0) $row['items'] = $this->getMenu2(' ='.$haha->id); $data2[] =$row; } return $data2; }
Penjelasan : di atas terdapat 2 buah fungsi. Kedua fungsi tersebut digunakan untuk men generate category mulai dari category induk (parent = NULL) hingga ke category anaknya. Sebenarnya kedua fungsi tersebut menjalankan kedua fungsi yang sama, hanya sama pada fungsi getMenu() dia mengembalikan menu yang ada di luar database. Ingat kan pada database hanya ada menu-menu yang sudah ada pengkategoriannya. Sedangkan menu-menu seperti “beranda”, “login”, “tentang kami” memang tidak disimpan di dalam database.
Fungsi di atas sendiri akan men generate informasi label menu tersebut yang akan tampil pada menu, dan id nya yang digunakan sebagai url dari menu tersebut.
Nah, setelah itu untuk mempermudah pembuatan menu yang menggunakan sub-menu kita akan gunakan extension mbmenu yang ada di Yii (silahkan googling). Kemudian pada menu, buatlah code seperti berikut :
$this->widget('ext.mbmenu.Mbmenu', array('items'=>Category::model()->getMenu(), ) );
Penjelasan : code di atas digunakan untuk men generate menu dari fungsi yang sudah kita buat sebelumnya pada model Categori. Jadi semua nilai yang ada pada menu kita ambil dari fungsi yang sudah kita buat tadi, sehingga kita tidak perlu repot masukkan nilainya satu persatu ke dalam array Mbmenu..
Hasil dari code yang kita buat di atas adalah sama dengan gambar yang ada pada postingan ini..
Selesai..
Selamat mencoba… semoga membantu… 🙂
pak sabit, kalau errornya seperti ini “Property “ModelMenuManager.label” is not defined.”
kenapa? padahal itu asli generate dari yii
terimakasih pak, mohon bantuannya
berrti ga ada field “label” nya di model tersebut gan..
om,itu kan dibuat dengan 1 tabel.Kalau dibuat 2 tabel bagaimana ya?semisal tabel nya kategori dengan tabel sub-kategori.mohon pencerahannya..
terima kasih
menurut saya kalo dibuat 2 tabel malah ribet gan.. dengan 1 buah tabel, cakupan kedalaman child ny bisa tidak terhingga kita buat. jadi dari kategori->subkategori->sub sub kategori-> dst gan..
gan kalau cara diatas untuk pengkategorian pada aplikasi digital library efektif ga yah..?
sebenernya ga masalah untuk aplikasi apa aja gan.. tapi untuk pengkategorian dengan hirarki parent-child setau saya cara ini yang digunakan..
ok gan.makasih pencerahannya 🙂
mb menu jalan tapi, loncat satu baris@
Kenapa ya om ko bisa gitu?? mohon penjelasannya!!
mksd ny locncat gmana gan?
sorry om dah solved om!!
newbie nih di yii, klo url nya ngambil dari tabel juga gmn pak ??
mksd ny mbak?
jadi aq punya tabel “menu” fieldnya: id, parent, title,url. nah pengennya title itu yang ditampilin sebagai menu. terus klo di klik page yg diambil yah page yang tersimpan di database…. nampilin menunya udah bisa liat tutorialnya mas sabit, tp ngambil urlnya itu yg bingung.
url nya tinggal masukin di tag array “url” nya aja mbak..
hai, saya dari malaysia. menu saya berjalan dengan ok, terima kasih ^^ tapi bagaimn untuk letak url bagi menu yang ambil dari database?
bisa di atur di bagian :
$row[‘url’] = array(‘category/view’,’id’=>$haha->id);
tapi nilai $row[‘url’] nya ambil yang ada di database aja mbak..
nilai apa ya? boleh bagi contoh? Contohnya, kalau saya click menu ‘Mail Centre’ dari database, bagaimana nak direct ke page itu? maaf bertanya, sy masih baru, 🙂 thanks.
$row[‘url’] = $haha->url.
dimana $haha->url adalah nilai url yang ada di database kamu..
adakah ‘category/view’ perlu di create kan? sebab bila sy klik menu tersebut, keluar mesej ni
Error 404
Unable to resolve the request “category/view”.
bisa saya lihat contoh nilai URL yang ada di database nya mbak?
ini koding untuk model Category
true),
array(‘label’, ‘length’, ‘max’=>200),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array(‘id, label, parent’, ‘safe’, ‘on’=>’search’),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
‘id’ => ‘ID’,
‘label’ => ‘Label’,
‘parent’ => ‘Parent’,
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare(‘id’,$this->id);
$criteria->compare(‘label’,$this->label,true);
$criteria->compare(‘parent’,$this->parent);
return new CActiveDataProvider($this, array(
‘criteria’=>$criteria,
));
}
public function getMenu($cnd=” IS NULL”)
{
$data2 = array();
$data2[] = array(‘label’=>’Home’, ‘url’=>array(‘/site/index’));
foreach($this->findAll(‘parent’.$cnd) as $haha)
{
$row=array();
$row[‘label’] = $haha->label;
$row[‘url’] = array(‘category/view’,’id’=>$haha->id);
if(count($this->getMenu2(‘ =’.$haha->id))>0)
{
$row[‘items’] = $this->getMenu2(‘ =’.$haha->id);
}
$data2[] =$row;
}
$data2[] = array(‘label’=>’About Us’, ‘url’=>array(‘/site/page’, ‘view’=>’about’));
$data2[] = array(‘label’=>’Contact Us’, ‘url’=>array(‘/site/contact’));
$data2[] = array(‘label’=>’Login’, ‘url’=>array(‘/site/login’), ‘visible’=>Yii::app()->user->isGuest);
$data2[] = array(‘label’=>’Logout (‘.Yii::app()->user->name.’)’, ‘url’=>array(‘/site/logout’),
‘visible’=>!Yii::app()->user->isGuest);
return $data2;
}
public function getMenu2($cnd=” IS NULL”)
{
$data2 = array();
foreach($this->findAll(‘parent’.$cnd) as $haha)
{
$row=array();
$row[‘label’] = $haha->label;
$row[‘url’] = array(‘category/view’,’id’=>$haha->id);
if(count($this->getMenu2(‘ =’.$haha->id))>0)
$row[‘items’] = $this->getMenu2(‘ =’.$haha->id);
$data2[] =$row;
}
return $data2;
}
}
?>
ni database saya. :
id label parent
1 Mail Centre null
2 Admin null
4 Inbox 1
5 Sent 1
8 Spam 1
9 Trash 1
10 Draft 1
11 User 2
12 Group 2
13 My Admin 2
loh, di database nya ga ada field untuk nyimpen URL nya mbak?
owh. bila dah create field utk url itu, setiap column berlainan url ke?
bukan, kalo memang ga ada UR nya, mbak bisa buat sama dengan tutor saya di atas. Tapi mbak tadi bertanya kalo URL ny di database.. kalo begitu berarti mbak harus nambahin field URL disana..
baik, thanks. sy cuba dulu. 🙂
Apa Artinya pesan
Error 404
Unable to resolve the request “Alamat” ?
Saya newbi yii minta pencerahannya, saya buat model file Alamat.php melalui gii generator dan filenya tersimpan di direktori protected/modesl/Alamat.php, langkah apalagi yg harus saya lakukan ya agar ketka saya panggil filenya di browser tidak muncul lagi pesan erorr, sebelumnya saya buat tabel ALamat melalui phpmyadmin. makasih
agan jangan cuma generate model, harus generate juga crud nya.. di ebook saya udah saya paparin cukup jelas kayak nya gan..
mas maunaya kode ini di bawah ini ditempatin dimana (contoh nya nama yii/protected/model..)
public function getMenu($cnd=” IS NULL”)
{
$data2 = array();
$data2[] = array(‘label’=>’Beranda’, ‘url’=>array(‘/site/index’));
foreach($this->findAll(‘parent’.$cnd) as $haha)
{
$row=array();
$row[‘……
…..
terimakasih sebelumnya mas
itu di model nya mas.. model mana terserah, yang penting saat manggil fungsi tersebut berrti harus lewat model itu juga..
Kunjungi Juga Farifam.com untuk tutorial dan forum Yii Framework yang direspon lebih cepat dari di blog ini..
Mas, sesuai script, semuanya sdh ok. Tp kalo menu Bagian diklik, muncul error :
Error 404
The requested page does not exist.
Contoh : tabel ListMenu :
Listmenu_id NamaMenu Parent
————— ————– ———
2 Master 1
4 Bagian 2
Kalo mengikuti script di atas, nama filenya apa dan letaknya di mana?
Terima kasih banyak.
Kalo saya manggil via browser :
http://localhost/aplikasiku/index.php?r=bagian
Pagenya keluar dengan benar. Tapi kalo lewat index.php, klik di menu bagian, jadi error yang tadi.
mbak salah buat url nya mbak.. dia mengarah ke halaman yang ga ada di aplikasi mbak..
Kunjungi Juga Farifam.com untuk tutorial dan forum Yii Framework yang direspon lebih cepat dari di blog ini..
mas ini ko saya ada error label not define padahal di tabel udah ada kolom label sama di fungsi juga udah di definisikan.
terus ada error juga mbmenu can not found itu kenapa ya?
mbmenu not found karena extension nya belum ada di folder. bisa kasih lihat pesan error yang label?
alhamdulillah udah solved mas.
mas kan saya mau ngambil urlnya dari database.
saya udah ganti $row[‘url’] = array(‘category/view’,’id’=>$haha->id); menjadi $row[‘url’] = $haha->url;
tapi object not found. saya tulis di kolom url nya /pages/. penulisan url yg benar nya di kolom nya itu gmn ya?
terus mbmenu ini bisa di edit ga ya mas letak sama tampilan nya?
kalo object not found berrti ada data yang ga ada mas..
ooh. iya mas makasih mas
Pingback: [Yii Framework] Membuat Menu Dinamis dengan Hirarki Parent Child dari Database | Yu Berbagi
mas sabit. kan untuk yii framework yg buat login itu beda url kan ya dengan Yii code generator. saya udah masukin data untuk model sama crud generatornya. data crud di yii juga udah kesambung ke database. kalo pengin nyatuin yii framweork ama code generatorya gimana ya? supaya ketika login ke yii framework bisa langsung crud ama yang lainnya. mohon pencerahannya ya mas. terimakasih