Codeigniter Pagination Sayfa Numaraları

Codeigniter Pagination Sayfa Numaraları Hemen hemen her projede Codeigniter sayfalama (Pagination) kütüphanesini kullanıyoruz. Bu yazımızda url adresinde kayıt numaraları yerine sayfa numaralarını kullanarak sayfalama yapacağız.

Mevcut Pagination kütüphanesi sayfa url adreslerini oluştururken parametre değeri olarak veritabanından verileri çekerken kaçıncı veriden başlanacağını belirleyen kayıt numarasını kullanıyor. Örneğin sayfa başına 10 kayıt göstermek istediğimiz zaman sayfaların url adresleri  sayfa/index/10, sayfa/index/20 ... şeklinde oluşturuluyor. Bu yazımızda Codeigniter'ın Pagination kütüphanesini birkaç küçük değişiklikle genişleterek kayıt numarasını değilde sayfa numarasını kullanarak url adreslerini sayfa/1, sayfa/2 ... şeklinde oluşturacak şekilde yapılandıracağız.

Öncelikle application klasöründe bulunan libraries klasörü içerisine MY_Pagination isimli bir php dosyası oluşturarak aşağıdaki kodları içerisine kopyalayarak kaydediyoruz.

MY_Pagination.php :

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

class MY_Pagination extends CI_Pagination
{

    public $offset = 0;

    /**
     * Constructor
     *
     * @access	public
     * @param	array	initialization parameters
     */
    function MY_Pagination($params = array())
    {
        if (count($params) > 0)
        {
            parent::initialize($params);
        }

        log_message('debug', "MY_Pagination Class Initialized"wink;
    }

    // --------------------------------------------------------------------

    /**
     * Generate the pagination links
     *
     * @access	public
     * @return	string
     */
    function create_links()
    {
        // If our item count or per-page total is zero there is no need to continue.
        if ($this->total_rows == 0 OR $this->per_page == 0)
        {
            return '';
        }

        // Calculate the total number of pages
        $num_pages = ceil($this->total_rows / $this->per_page);

        // Is there only one page? Hm... nothing more to do here then.
        if ($num_pages == 1)
        {
            return '';
        }

        // Determine the current page number.
        $CI = & get_instance();

        if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
        {
            if ($CI->input->get($this->query_string_segment) != 0)
            {
                $this->cur_page = $CI->input->get($this->query_string_segment);

                // Prep the current page - no funny business!
                $this->cur_page = (int) $this->cur_page;
            }
        }
        else
        {
            if ($CI->uri->segment($this->uri_segment) != 0)
            {
                $this->cur_page = $CI->uri->segment($this->uri_segment);

                // Prep the current page - no funny business!
                $this->cur_page = (int) $this->cur_page;
            }
        }

        $this->num_links = (int) $this->num_links;

        if ($this->num_links < 1)
        {
            show_error('Your number of links must be a positive number.');
        }

        if (!is_numeric($this->cur_page) || $this->cur_page < 1)
        {
            $this->cur_page = 1;
        }

        // Is the page number beyond the result range?
        // If so we show the last page
        if ($this->cur_page > $num_pages)
        {
            $this->cur_page = $num_pages;
        }
        $this->set_offset();
        $uri_page_number = $this->cur_page;
        //$this->cur_page = floor(($this->cur_page / $this->per_page) + 1);
        // Calculate the start and end numbers. These determine
        // which number to start and end the digit links with
        $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
        $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;

        // Is pagination being used over GET or POST?  If get, add a per_page query
        // string. If post, add a trailing slash to the base URL if needed
        if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
        {
            $this->base_url = rtrim($this->base_url) . '&amp;' . $this->query_string_segment . '=';
        }
        else
        {
            $this->base_url = rtrim($this->base_url, '/') . '/';
        }

        // And here we go...
        $output = '';

        // Render the "First" link
        if ($this->cur_page > ($this->num_links + 1))
        {
            $output .= $this->first_tag_open . '<a href="' . $this->base_url . '">' . $this->first_link . '</a>' . $this->first_tag_close;
        }

        // Render the "previous" link
        if ($this->cur_page != 1)
        {
            $i = $uri_page_number - 1;
            if ($i == 0)
                $i = '';
            $output .= $this->prev_tag_open . '<a href="' . $this->base_url . $i . '">' . $this->prev_link . '</a>' . $this->prev_tag_close;
        }

        // Write the digit links
        for ($loop = $start; $loop <= $end; $loop++)
        {
            if ($this->cur_page == $loop)
            {
                $output .= $this->cur_tag_open . $loop . $this->cur_tag_close; // Current page
            }
            else
            {
                $output .= $this->num_tag_open . '<a href="' . $this->base_url . $loop . '">' . $loop . '</a>' . $this->num_tag_close;
            }
        }

        // Render the "next" link
        if ($this->cur_page < $num_pages)
        {
            $output .= $this->next_tag_open . '<a href="' . $this->base_url . ($this->cur_page + 1) . '">' . $this->next_link . '</a>' . $this->next_tag_close;
        }

        // Render the "Last" link
        if (($this->cur_page + $this->num_links) < $num_pages)
        {
            $i = (($num_pages * $this->per_page) - $this->per_page);
            $output .= $this->last_tag_open . '<a href="' . $this->base_url . $num_pages . '">' . $this->last_link . '</a>' . $this->last_tag_close;
        }

        // Kill double slashes.  Note: Sometimes we can end up with a double slash
        // in the penultimate link so we'll kill all double slashes.
        $output = preg_replace("#([^:])//+#", "\\1/", $output);

        // Add the wrapper HTML if exists
        $output = $this->full_tag_open . $output . $this->full_tag_close;

        return $output;
    }

    public function get_offset()
    {
        return $this->offset;
    }

    private function set_offset()
    {
        $this->offset = ($this->cur_page * $this->per_page) - $this->per_page;
        return;
    }

}

// END MY_Pagination Class

/* End of file MY_Pagination.php */
/* Location: ./system/application/libraries/MY_Pagination.php */

Bu şekilde Codeigniter içerisinde gelen Pagination kütüphanesini sayfa numaralarını gösterecek şekilde yapılandırmış olduk. "Hani sadece birkaç küçük değişiklik yapacaktık? Neredeyse orijinal kütüphanedeki kadar kod var burada" demekte haklısınız. Fakat kütüphane sadece 3 metodla oluşturulmuş. Geliştiriciler tüm kodları create_links metoduna yazmak yerine metodlara parçalasalardı bu şekilde bir kod karmaşası olmayacaktı. Bizde birkaç satırdaki değişiklik için kütüphaneyi neredeyse baştan yazmış olmayacaktık.

Veritabanından verileri çekerken kaçıncı kayıttan başlayacağımızı kütüphaneyi her kullanışımızda controller içerisinde hesaplamakla uğraşmamak için get_offset ve set_offset 2 yeni metodda ben oluşturdum. İsimlerinden de anlaşılacağı üzere set_offset kayıt numarasının kaç olacağını hesaplayıp offset değişkenine atıyor. get_offset ise bu ihticımız olduğunda bu kayıt numarasını döndürüyor. Lafı fazla uzatmadan controller ve view dosyalarımıza bakalım.

pagination.php:

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

class Pagination extends Controller
{

    function __construct()
    {
        parent::__construct();
        $this->load->database();
    }

    function index()
    {
        $limit = 5;
        $this->load->library('pagination');
        $this->load->model('post_model');
        $this->load->helper('url');
        //Pagination kütüphanesini kullanmak için gerekli ayarları yapıyoruz.
        $config['base_url'] = site_url('pagination/index');
        $config['total_rows'] = $this->db->count_all_results('posts');
        $config['per_page'] = $limit;
        $this->pagination->initialize($config);
        //Bağlantıları oluşturarak view dosyamızda kullanmak üzere data dizisine kaydediyoruz.
        $data['pagination'] = $this->pagination->create_links();
        //get_offset metodu ile kaçıncı kayıttan başlaması 
        //gerektiğini Pagination kütüphanesinden öğreniyoruz.
        $offset = $this->pagination->get_offset();
        //Verileri veritabanından çekiyoruz.
        $data['posts'] = $this->post_model->get_posts($limit, $offset);
        $this->load->view('pagination_view', $data);
    }
}

/* End of file pagination.php */
/* Location: ./system/application/controllers/pagination.php */

pagination_view.php:

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="robots" content="noindex,nofollow" />
    <title>Codeigniter Sayfalama</title>
    <style type="text/css">
        body {
            background-color: #fff;
            margin: 40px;
            font-family: "Lucida Grande", Verdana, Sans-serif;
            font-size: 14px;
            color: #4F5155;
        }
        a {
            color: #003399;
            background-color: transparent;
            font-weight: normal;
        }
        h1 {
            color: #444;
            background-color: transparent;
            border-bottom: 1px solid #D0D0D0;
            font-size: 16px;
            font-weight: bold;
            margin: 24px 0 2px 0;
            padding: 5px 0 6px 0;
        }
    </style>
</head>
<body>
    <?php echo $pagination; ?>
    <?php foreach ($posts as $post): ?>
        <h1><?php echo$post['title']; ?></h1>
        <p><?php echo$post['content']; ?></p>
    <?php endforeach; ?>
    <?php echo $pagination; ?>
</body>
</html>

Böylece url adreslerimizi sayfa/index/20 yerine sayfa/index/2 şeklinde oluşturmuş olduk. UYgulamanın çalışır örneğini demo butonuna basarak görebilirsiniz. Veritabanından kayıtları çeken model dosyasını ve gerekli sql dosyasını uygulama dosyasına koyduğumdan burada yayınlamaya gerek olmadığını düşünüyorum.

Güncelleme: query_string ile nasıl sayfalama yapılabileceğinin görmek isteyenler için bir örnek hazırladım. Uygulama dosyasına buradan ulaşabilirsiniz http://goo.gl/BCM6P. Çalışır halini görmek isteyenleri de buraya alalım.

Bu yazı en son 05 Mayıs 2011 tarihinde düzenlenmiştir ve güncelliğini yitirmiş olabilir.

  • Erkan

    Hocam, offset değeri hep 0 dönüyor.

  • Mustafa Navruz

    $uri_segment parametresinden kaynaklanıyor olabilir sorun. Varsayılan olarak 3. segmenti kullanıyor. Kontrol edermisiniz.

  • Erkan

    sayfalamayı query string ile yapıyorum, set_offset metoduyla değişken ataması yapıyor ancak get_offset metodu 0 değeri döndürüyor, yani her sayfada limit 0,(per_page) kadar oluyor.
    get_offset metodunda return değilde echo yaptığımda yine 0 yazıyor.

  • Mustafa Navruz

    page_query_string değerini TRUE olarak gönderdiniz mi?

  • Mustafa

    page_query_string değerini TRUE olarak gönderdiniz mi demişsiniz ama sizin örneğinizde TRUE değil ve TRUE yapmadan çalışmayacak gibi görünüyor çünkü "cur_page" 0 oluyor sürekli

  • Mustafa Navruz

    Benim örneğimde TRUE değil, çünkü query_string ile almıyorum sayfa değerini.
    Değiştirip denermisiniz.

    Güncelleme: query_string ile yapılmış örneğe buradan ulaşabilirsiniz. http://goo.gl/BCM6P

  • Atasoy

    kütüphane oldukça başarılı emeğiniz için teşekkürler, elinize kolunuza sağlık...

blog comments powered by Disqus

© Mustafa Navruz 2011 0.0169 sn.

^ Başa Dön