Salı, 8 Mart 2011

Sonsuz Menü Uygulaması

 

Tasarımlarımızda kullandığımız sonsuz döngülü menü ağacı çıkartma, genellikle hep bir sorun olarak karşımıza çıkar. Farklı çözümler getirilen bu soruna, özyinelemeli fonksiyon metodu kullanarak nasıl sonsuz döngülü menu ağacı yapısı oluşturabileceğimizi bu yazıda irdeleyeceğiz.

Öncelikle işe veritabanı üzerinde "menu" isimli tablo oluşturmakla başlayalım. Menü tablomuz üç kolondan oluşsun: id, parent_id, title. "id" kolonu satır numarasını, "parent_id" kolonu menünün bağlı oluğu üst satır numarasını, "title" kolonu ise menü ismini göstersin. Örneğimizde hayvan ve bitki taksonomisine göre menü ağacı oluşturalım.

CREATE TABLE IF NOT EXISTS `menu` (
  `id` int(11) NOT NULL auto_increment,
  `parent_id` int(11) NOT NULL,
  `title` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `parent_id` (`parent_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

--
-- Tablo döküm verisi `menu`
--

INSERT INTO `menu` (`id`, `parent_id`, `title`) VALUES
(1, 0, 'hayvanlar'),
(2, 1, 'omurgalılar'),
(3, 1, 'omurgasızlar'),
(4, 0, 'bitkiler'),
(5, 2, 'kafatassızlar'),
(6, 2, 'gerçek kafataslılar'),
(7, 3, 'gerçek dokusu olmayanlar'),
(8, 4, 'algler ve su yosunları'),
(9, 8, 'yeşil algler'),
(10, 4, 'eğreltiler'),
(11, 4, 'mantarlar'),
(13, 11, 'küf mantarları'),
(14, 11, 'pas mantarları'),
(15, 7, 'süngerler');


Bu yapıda bilgi girişi yapacağınız kodları kendinizin oluşturacağını varsayarak, bu menü ağacının nasıl listelendiğine geçelim. Burada sorunun çözümü için application/models dizini altına kayıt edeceğimiz menu_model.php dosyamızı oluşturuyoruz. Dosyamızın içeriği şöyledir:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Menu_model extends Model {

 public $result;

 
    function Menu_model()
    {
        parent::Model();
    }

 function get_menu(){
 
  $query = $this->db->get('menu');
  
  if($query->num_rows() > 0){
   $res = $query->result_array();

   foreach($res as $row):
    $items[$row['parent_id']][] = $row;
   endforeach;
   
   $this->_menu_listele($items);

   return $this->result;
  }
 
 }
 
 function _menu_listele($items, $parent = null) {

  $index = $parent == null ? '0' : $parent;

  if (isset($items[$index])) {

   $this->result .= '<ul';
   
   $this->result .= $parent == null ? ' id="category" ' : '';

   $this->result .= '>';

   foreach ($items[$index] as $child) {

    $this->result .= '<li rel="'.$child['id'].'">'.$child['title'];
    
    $this->_menu_listele($items, $child['id']);
    
    $this->result .= '</li>';
   
   }

   $this->result .= '</ul>';
  }
 }
 
}

Bu kodları takip edersek: öncelikle veritabanından çektiğimiz satırları, parent_id değeri indeks olmak üzere bir diziye atılır. Bu diziyi ise _menu_listele isimli özel fonksiyona gönderilir. Bu fonksiyonda ise parent değişkeni 0'dan başlatılmak üzere, kendi kendini de çağırarak HTML kodlarıyla listeleme yapılmaktadır. $result isimli genel değişken bu işlemin sonunda get_menu() fonksiyonu yardımıyla controller dosyasına geri gönderilir.

Controller dosyası sadece model dosyasını yükleyerek buradaki get_menu() dosyasını çağırmaktadır. Application/controllers dizini altındaki menu.php dosyasının içeriği şöyledir:

<?php

class Menu extends Controller
{

 function Menu()
 {
  parent::Controller();

 }

 function index()
 {
  $this->load->model('menu_model','Model');

  $data['menu'] = $this->Model->get_menu();
  
  $this->load->view('menu_view',$data);
     
 }
}

Controller dosyamıza geri gelen sonuçlar, application/views dizini altındaki menu_view.php dosyasında bastırılır.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Sonsuz Menü Uygulaması | CodeIgniter.gen.tr</title>
</head>
<body>

 <h1>Sonsuz Menü</h1>

 <p><?php echo $menu?></p>
</body>
</html>

Bütün iş model dosyası içinde yapılması nedeniyle, view dosyasına sadece $menu isimli data değişkenini yazdırmak kalmıştır. Yazıda geçen dosyaları buradan indirebilirsiniz.

Yorumlar

Merhaba

Örneği 2.1.0 versiyonuna göre güncellemeniz mümkünmü.
Core ile ilgili hatalar alıyorum.
Gerekli CI_ eklemelerini yaptım ancak
İçinden çıkamadım.
Çok teşekkürler.

@Can Colpan: İlk fırsatta yapmaya çalışırım. Ancak, işleyişi anladıysanız kendinizin uyarlaması en doğrusu olacaktır.

2.1.0 a uyarlamayı başardım.

Tek tek satır satır aç kapa yaparak Core hatasının nedenini bulmaya çalıştım.
Çok saçma belki ama model get_menu fonksiyonunun başına $this->resul='' ekledim. Bunu eklemeyince sürekli hata alıyorum. 
function get_menu()
{
$this->result='';

İlginiz için teşekkürler.
Şimdi sıra bu işlermi selectbox a çevirebilmek. Admin panelde kategori ve altkategorilerin seçilebileceği bir sonsuz kategori yapım var. Selectbox option içine bunu yapmaya çalışıcam. Başarılı olursa burada paylaşmak isterim.

Yorum Ekle